caixa_core/supervisor.rs
1//! OTP-shaped supervisor trees, encoded as a typed `:kind Supervisor`
2//! caixa with a strategy + restart-policy children list.
3//!
4//! See `theory/INSPIRATIONS.md` §II.2 + §III.2 for the prior-art frame
5//! (Erlang OTP supervisor + Lunatic supervisor strategies as Rust types).
6//!
7//! ```lisp
8//! (defcaixa
9//! :nome "my-app-root"
10//! :versao "0.1.0"
11//! :kind Supervisor
12//! :estrategia OneForOne
13//! :max-restarts 5
14//! :restart-window "60s"
15//! :children ((:caixa "worker" :versao "^0.1" :restart Permanent)
16//! (:caixa "cache-server" :versao "^0.1" :restart Transient)
17//! (:caixa "scratch-job" :versao "^0.1" :restart Temporary)))
18//! ```
19//!
20//! wasm-operator (M3) walks the tree, materializes one ComputeUnit per
21//! child, and applies the strategy on child failure. The Rust types
22//! here are the typed contract; the runtime owns lifecycle.
23
24use std::time::Duration;
25
26use serde::{Deserialize, Serialize};
27use thiserror::Error;
28
29/// One of the four canonical Erlang/OTP restart strategies.
30///
31/// The strategy decides what happens to *sibling* children when one
32/// child dies. Per-child behaviour is governed by [`RestartPolicy`].
33#[derive(
34 Serialize,
35 Deserialize,
36 Debug,
37 Clone,
38 Copy,
39 PartialEq,
40 Eq,
41 Hash,
42 gen_platform::TypedDispatcher,
43 gen_platform::Discriminant,
44 gen_platform::IsVariant,
45 gen_platform::FromStrKind,
46)]
47pub enum RestartStrategy {
48 /// On child failure, restart only that child. Default; matches
49 /// most "tree of independent workers" use cases.
50 OneForOne,
51 /// On child failure, restart every child. Used when children
52 /// share state and must be in sync.
53 OneForAll,
54 /// On child failure, restart the failed child and every child
55 /// started *after* it (preserving startup order). Used when later
56 /// children depend on earlier ones.
57 RestForOne,
58 /// Dynamic children of the same shape, started on demand. The
59 /// supervisor doesn't know its children at boot; they're added as
60 /// they're needed (e.g. one child per session).
61 SimpleOneForOne,
62}
63
64impl Default for RestartStrategy {
65 fn default() -> Self {
66 // Route the [`Default for RestartStrategy`] impl through the
67 // substrate-canonical [`SUPERVISOR_ESTRATEGIA_DEFAULT`] typed
68 // `pub const` rather than a raw `Self::OneForOne` arm — one
69 // source of truth for the Erlang/OTP `one_for_one` half of Learn
70 // You Some Erlang's `{one_for_one, intensity, 5, 60}` worker-
71 // supervisor canonical default, paired with the sibling
72 // `SUPERVISOR_MAX_RESTARTS_DEFAULT` `MaxIntensity` half (b698ec0)
73 // and `SUPERVISOR_RESTART_WINDOW_DEFAULT` `Period` half (f7dcd0e).
74 // Pinned by `restart_strategy_default_routes_through_lifted_default`.
75 SUPERVISOR_ESTRATEGIA_DEFAULT
76 }
77}
78
79impl RestartStrategy {
80 /// Exhaustive iteration surface for every consumer that walks the
81 /// closed four-arm [`RestartStrategy`] discriminator set (the future
82 /// M4 `mesh.pleme.io/v1alpha1/Supervisor` CR materializer's
83 /// admission-webhook rejection body naming the accepted-`:estrategia`
84 /// list, a future `feira supervisor --estrategia …` CLI arg-parse's
85 /// "did you mean" hint via a [`Self::from_wire`]-scan over the slice,
86 /// the future `feira app graph` per-supervisor `:estrategia` column,
87 /// any future round-trip fuzz harness that sweeps every arm). A
88 /// future arm addition (an OTP-`rest_for_all` arm the theory
89 /// [`ABSORPTION-ROADMAP`](https://github.com/pleme-io/theory/blob/main/ABSORPTION-ROADMAP.md)
90 /// might reach for once the four canonical OTP strategies stop
91 /// covering the substrate's discovered load-shape) extends this
92 /// slice as one edit and every consumer picks up the new entry by
93 /// construction; the compiler-checked exhaustiveness on the sibling
94 /// method `match` arms ([`Self::as_str`] / [`Self::from_wire`]) is
95 /// the build-time guarantee that no arm forgets to grow.
96 ///
97 /// Peer of the sibling closed-set typed enums'
98 /// [`crate::CaixaKind::ALL`] (6b1f4fb) /
99 /// [`crate::aplicacao::PlacementStrategy::ALL`] (18c7342) /
100 /// [`crate::aplicacao::RateLimitUnit::ALL`] (6bce03d) /
101 /// [`crate::dep::DepList::ALL`] (45ee563) exhaustive-iteration
102 /// surfaces — the fifth (and the first M2 OTP-shape) closed-set
103 /// typed enum on the caixa surface to converge onto the same
104 /// one-canonical-arm-list-per-enum discipline.
105 pub const ALL: &'static [Self] = &[
106 Self::OneForOne,
107 Self::OneForAll,
108 Self::RestForOne,
109 Self::SimpleOneForOne,
110 ];
111
112 /// Substrate-canonical exhaustive accept-set on the
113 /// [`RestartStrategy`] `PascalCase` wire byte-string axis — the
114 /// closed four-arm roster of every byte-string [`Self::as_str`]
115 /// returns, routed byte-for-byte through the paired
116 /// [`crate::render::SUPERVISOR_ESTRATEGIA_ONE_FOR_ONE`] /
117 /// [`crate::render::SUPERVISOR_ESTRATEGIA_ONE_FOR_ALL`] /
118 /// [`crate::render::SUPERVISOR_ESTRATEGIA_REST_FOR_ONE`] /
119 /// [`crate::render::SUPERVISOR_ESTRATEGIA_SIMPLE_ONE_FOR_ONE`]
120 /// lifted `pub const` roster the [`Self::as_str`] emitter (and the
121 /// [`std::fmt::Display`] / [`AsRef<str>`] /
122 /// `From<{Self,&Self}> for {&'static str, String, Cow<'static, str>,
123 /// Box<str>, Arc<str>}` trait triple + quintuple routed through it)
124 /// walks — and byte-for-byte the same four strings the un-`rename`d
125 /// `Serialize` derive emits under the paired
126 /// [`crate::render::SUPERVISOR_KEY_ESTRATEGIA`] tag key on every
127 /// JSON / YAML CR round-trip.
128 ///
129 /// Peer of the sibling [`crate::CaixaKind::WIRE_NAMES`] (bd708bd)
130 /// roster on the top-level typed-kind discriminator's `PascalCase`
131 /// wire byte-string axis, and of the sibling
132 /// [`crate::upgrade::UpgradeInstruction::WIRE_FORMS`] (cc42c0e) /
133 /// [`crate::upgrade::UpgradeInstruction::LISP_FORMS`] (1898d77)
134 /// rosters on the OTP-appup discriminator's two-axis roster split —
135 /// the same closed-set exhaustive-accept-set roster discipline
136 /// extended here onto the first M2 OTP-shape sibling-restart
137 /// closed-set typed enum. The sibling
138 /// [`crate::aplicacao::PlacementStrategy`] M3 mesh-shape distribution
139 /// strategy enum is the next natural peer on the same axis, still
140 /// carrying only [`crate::aplicacao::PlacementStrategy::ALL`].
141 ///
142 /// Downstream consumers of the closed accepted-wire-form set — a
143 /// future M4 `mesh.pleme.io/v1alpha1/Supervisor` CR admission-webhook
144 /// rejection body enumerating the accepted JSON `:estrategia` values
145 /// verbatim (as distinct from the kebab-case dispatcher-catalog
146 /// enumeration [`Self::discriminant`] serves, whose per-arm form
147 /// `"one-for-one"` / `"one-for-all"` / `"rest-for-one"` /
148 /// `"simple-one-for-one"` structurally disagrees with the wire byte-
149 /// string these `PascalCase` entries carry), a future `feira
150 /// supervisor --estrategia …` CLI-side "did you mean" hint whose
151 /// candidate-list must byte-match the wire form the operator's
152 /// per-strategy dispatch keys off (rather than the kebab
153 /// dispatcher-catalog identity), a future `feira app graph`
154 /// per-supervisor `:estrategia`-histogram column that renders
155 /// zero-count arms, a future wasm-operator per-reconcile-step
156 /// diagnostic log line enumerating accepted wire forms on an
157 /// unknown-strategy rejection, a future
158 /// `tracing::field::valuable::Value::List` structured-log accepted-
159 /// wire-form emit — now reach for one lifted substrate-primitive
160 /// roster rather than open-coding a four-string array-literal
161 /// (`["OneForOne", "OneForAll", "RestForOne", "SimpleOneForOne"]`)
162 /// whose arm-set has no compile-time link back to the typed
163 /// [`RestartStrategy`] enum. A future arm addition (an OTP-`rest_for_all`
164 /// arm the theory
165 /// [`ABSORPTION-ROADMAP`](https://github.com/pleme-io/theory/blob/main/ABSORPTION-ROADMAP.md)
166 /// might reach for once the four canonical OTP strategies stop
167 /// covering the substrate's discovered load-shape) extends this
168 /// roster as a single edit — paired with the [`Self::as_str`]
169 /// match's compiler-checked exhaustiveness on the new arm — and
170 /// every consumer picks up the new wire form by construction rather
171 /// than a coordinated array-literal rewrite across every downstream
172 /// site.
173 ///
174 /// Length is pinned load-bearing at `RestartStrategy::ALL.len()`
175 /// (four) by
176 /// [`tests::restart_strategy_wire_names_covers_every_arm`], every
177 /// variant's [`Self::as_str`] projection is pinned to a member of
178 /// the roster so a silent skew between the emitter's arm-set and
179 /// this const's arm-set trips at caixa-core test time rather than
180 /// at a downstream consumer's accepted-set enumeration miss, and
181 /// every entry is further pinned to open with an ASCII uppercase
182 /// byte so a silent collapse of the wire-form axis with the peer
183 /// kebab-case dispatcher-catalog axis (an entry byte-identical to a
184 /// sibling [`Self::discriminant`] kebab byte-string that would let
185 /// a wire-axis consumer accept the dispatcher-catalog vocabulary)
186 /// trips here rather than at a downstream K8s-CR round-trip miss.
187 pub const WIRE_NAMES: &'static [&'static str] = &[
188 crate::render::SUPERVISOR_ESTRATEGIA_ONE_FOR_ONE,
189 crate::render::SUPERVISOR_ESTRATEGIA_ONE_FOR_ALL,
190 crate::render::SUPERVISOR_ESTRATEGIA_REST_FOR_ONE,
191 crate::render::SUPERVISOR_ESTRATEGIA_SIMPLE_ONE_FOR_ONE,
192 ];
193
194 /// Canonical PascalCase discriminator scalar this variant serializes
195 /// as under [`crate::render::SUPERVISOR_KEY_ESTRATEGIA`]. The four arms
196 /// return the paired [`crate::render::SUPERVISOR_ESTRATEGIA_ONE_FOR_ONE`]
197 /// / [`crate::render::SUPERVISOR_ESTRATEGIA_ONE_FOR_ALL`] /
198 /// [`crate::render::SUPERVISOR_ESTRATEGIA_REST_FOR_ONE`] /
199 /// [`crate::render::SUPERVISOR_ESTRATEGIA_SIMPLE_ONE_FOR_ONE`] lifted
200 /// constants so every substrate consumer that dispatches on the
201 /// per-supervisor sibling-restart strategy (the future
202 /// wasm-operator's per-supervisor sibling-restart branch, the future
203 /// M4 `mesh.pleme.io/v1alpha1/Supervisor` CR materializer's
204 /// admission-time enum-arm bind, the `caixa-operator`'s hierarchical
205 /// reconciliation scheduler's per-strategy fan-out) reads the same
206 /// byte-string the `Serialize` derive emits — the pin test in
207 /// [`tests::restart_strategy_variants_serialize_to_lifted_scalar_values`]
208 /// asserts the two paths agree, peer of the M3
209 /// `PlacementStrategy::as_str` (cc8f749) on the sibling per-Aplicacao
210 /// distribution-strategy axis.
211 #[must_use]
212 pub const fn as_str(self) -> &'static str {
213 match self {
214 Self::OneForOne => crate::render::SUPERVISOR_ESTRATEGIA_ONE_FOR_ONE,
215 Self::OneForAll => crate::render::SUPERVISOR_ESTRATEGIA_ONE_FOR_ALL,
216 Self::RestForOne => crate::render::SUPERVISOR_ESTRATEGIA_REST_FOR_ONE,
217 Self::SimpleOneForOne => crate::render::SUPERVISOR_ESTRATEGIA_SIMPLE_ONE_FOR_ONE,
218 }
219 }
220
221 /// Substrate-canonical reverse projection on the `:supervisor
222 /// :estrategia` closed-set axis — parses the `PascalCase`
223 /// discriminator scalar back to the typed variant, or `None` when
224 /// `s` is outside
225 /// the closed-set arm-string set [`Self::as_str`] emits. Dispatches
226 /// on the same lifted
227 /// [`crate::render::SUPERVISOR_ESTRATEGIA_ONE_FOR_ONE`] /
228 /// [`crate::render::SUPERVISOR_ESTRATEGIA_ONE_FOR_ALL`] /
229 /// [`crate::render::SUPERVISOR_ESTRATEGIA_REST_FOR_ONE`] /
230 /// [`crate::render::SUPERVISOR_ESTRATEGIA_SIMPLE_ONE_FOR_ONE`]
231 /// constants the [`Self::as_str`] emitter walks, so the parse and
232 /// emit halves of the round-trip migrate through one caixa-core
233 /// edit on any future arm addition.
234 ///
235 /// Prior to this lift the substrate carried only the forward
236 /// `Self → &str` projection on the OTP sibling-restart axis (the
237 /// [`Self::as_str`] emitter, the [`std::fmt::Display`] impl routed
238 /// through it, the `Serialize` derive that emits the same
239 /// byte-string under [`crate::render::SUPERVISOR_KEY_ESTRATEGIA`])
240 /// plus the kebab-case dispatcher-catalog identity via
241 /// [`Self::discriminant`] — every non-serde consumer that wanted to
242 /// parse a wire-form `PascalCase` strategy scalar had to re-inline
243 /// a four-arm `match s { "OneForOne" => …, "OneForAll" => …,
244 /// "RestForOne" => …, "SimpleOneForOne" => …, _ => … }` cascade
245 /// that expressed no compile-time link back to the typed variant's
246 /// canonical lifted constant. A future variant rename or per-arm
247 /// serde-attribute drift would silently split the wire byte-string
248 /// one non-serde consumer parsed from the one the emitter wrote,
249 /// with the failure surfacing at parse time far from the rebrand
250 /// commit.
251 ///
252 /// Distinct axis from the [`std::str::FromStr`] impl the
253 /// [`gen_platform::FromStrKind`] derive already installs on this
254 /// enum by design, not by drift: `FromStr` parses the *kebab-case*
255 /// dispatcher-catalog identity (`"one-for-one"` / `"one-for-all"` /
256 /// `"rest-for-one"` / `"simple-one-for-one"` — the inverse of
257 /// [`Self::discriminant`]), while this method inverts the
258 /// `PascalCase` wire byte-string [`Self::as_str`] emits. The
259 /// two-axis split lets the dispatcher-catalog identity live in
260 /// kebab-case
261 /// (where every peer catalog identifier already lives) without
262 /// forcing a wire-format rename on the tatara-lisp author surface
263 /// (`:estrategia OneForOne`, `PascalCase`) — the same two-axis
264 /// distinction the sibling [`crate::CaixaKind::from_wire`] (2aa6d23)
265 /// / [`crate::aplicacao::PlacementStrategy::from_wire`] (18c7342)
266 /// carry on their peer closed-set typed-enum wire round-trips.
267 ///
268 /// Same closed-set-reverse-projection discipline the sibling
269 /// [`crate::CaixaKind::from_wire`] (2aa6d23) /
270 /// [`crate::aplicacao::PlacementStrategy::from_wire`] (18c7342) /
271 /// [`crate::aplicacao::RateLimitUnit::from_suffix`] typed enums
272 /// carry on the peer wire-side `str → Self` axes — extended onto
273 /// the M2 OTP-shape sibling-restart-strategy closed-set axis, the
274 /// fifth substrate-side closed-set typed enum to converge on the
275 /// two-way `str ↔ Self` round-trip. Method-named `from_wire` (not
276 /// `from_str`) to match the peer [`crate::CaixaKind::from_wire`]
277 /// shape verbatim and side-step the [`std::str::FromStr`] impl the
278 /// derive already installs on the sibling kebab-case axis. Returns
279 /// `Option<Self>` (rather than `Result<Self, _>`) to match the peer
280 /// shapes: the caller picks the diagnostic form appropriate for
281 /// its use site.
282 #[must_use]
283 pub fn from_wire(s: &str) -> Option<Self> {
284 match s {
285 crate::render::SUPERVISOR_ESTRATEGIA_ONE_FOR_ONE => Some(Self::OneForOne),
286 crate::render::SUPERVISOR_ESTRATEGIA_ONE_FOR_ALL => Some(Self::OneForAll),
287 crate::render::SUPERVISOR_ESTRATEGIA_REST_FOR_ONE => Some(Self::RestForOne),
288 crate::render::SUPERVISOR_ESTRATEGIA_SIMPLE_ONE_FOR_ONE => Some(Self::SimpleOneForOne),
289 _ => None,
290 }
291 }
292}
293
294/// [`std::fmt::Display`] routed through [`RestartStrategy::as_str`], so the
295/// pretty-printed byte-string every consumer that formats the strategy as
296/// user-facing text lands on (the future wasm-operator's per-supervisor
297/// sibling-restart-strategy diagnostic line, the future `feira app graph`
298/// per-supervisor strategy line, the future M4
299/// `mesh.pleme.io/v1alpha1/Supervisor` CR materializer's admission-webhook
300/// rejection body) reaches for the same lifted
301/// [`crate::render::SUPERVISOR_ESTRATEGIA_ONE_FOR_ONE`] /
302/// [`crate::render::SUPERVISOR_ESTRATEGIA_ONE_FOR_ALL`] /
303/// [`crate::render::SUPERVISOR_ESTRATEGIA_REST_FOR_ONE`] /
304/// [`crate::render::SUPERVISOR_ESTRATEGIA_SIMPLE_ONE_FOR_ONE`] const the
305/// wire-format `Serialize` derive already emits under
306/// [`crate::render::SUPERVISOR_KEY_ESTRATEGIA`] and the
307/// [`RestartStrategy::as_str`] helper already returns.
308///
309/// Pre-convergence the two paths structurally disagreed — the
310/// `#[derive(gen_platform::Discriminant)]` + `#[discriminant(also_display)]`
311/// route (now retired here) sent [`std::fmt::Display`] through the
312/// gen-platform discriminant catalog string, which arrives kebab-case as
313/// `"one-for-one"` / `"one-for-all"` / `"rest-for-one"` /
314/// `"simple-one-for-one"`, while the wire format ran as `PascalCase`
315/// `"OneForOne"` / `"OneForAll"` / `"RestForOne"` / `"SimpleOneForOne"`
316/// through the un-`rename`d serde derive. Every consumer that formatted
317/// the strategy for a diagnostic line, a graph, or a rejection body under
318/// `format!("{v}")` therefore landed under a different byte-string than
319/// the wire format the operator's per-strategy dispatch keyed off — a
320/// silent split whose apply-time symptom (a `format!("{v}")`-carrying
321/// diagnostic quoting `"one-for-one"` while the wire scalar the operator
322/// probed was `"OneForOne"`) surfaced as a confused correlate at
323/// operator-log time far from the two-declaration site.
324///
325/// Routing `Display` through [`RestartStrategy::as_str`] closes the third
326/// path: every `format!("{v}")` call reaches the same lifted
327/// [`crate::render::SUPERVISOR_ESTRATEGIA_*`] const the wire format and
328/// the [`RestartStrategy::as_str`] helper route through — `Debug` (the
329/// compiler-derived variant name), `Display` (via `as_str`), and `Serialize`
330/// (via the un-`rename`d derive) all resolve to the same `PascalCase`
331/// byte-string per variant. A future variant rename or
332/// `#[serde(rename_all = "kebab-case")]` attribute reaches every path at
333/// exactly one place, structurally.
334///
335/// The dispatcher-catalog identity remains kebab-case — [`Self::discriminant`]
336/// (from `#[derive(gen_platform::Discriminant)]`) still returns
337/// `"one-for-one"` / etc., and the fleet-wide
338/// [`gen_platform::register_dispatcher!("caixa.restart-strategy", …)`]
339/// registration keys the catalog off the same kebab identity. The two
340/// naming worlds now live on separate typed methods (`Display` /
341/// `as_str` for the wire byte-string, `discriminant` for the catalog
342/// identity) rather than sharing one `Display` route that structurally
343/// disagrees with the wire format.
344///
345/// Pin tests
346/// [`tests::restart_strategy_display_routes_through_as_str_helper`]
347/// and
348/// [`tests::restart_strategy_display_matches_serialized_wire_byte_string`]
349/// assert the three paths agree byte-for-byte on every variant, so a
350/// future variant rename or per-arm serde attribute drift is a build
351/// error visible at caixa-core test time, not a silent per-consumer
352/// dispatch miss at apply / reconcile time.
353///
354/// Mirrors the M3 [`crate::aplicacao::PlacementStrategy`] `Display` impl
355/// (aplicacao.rs:2306) on the sibling per-Aplicacao distribution-strategy
356/// axis — same three-path-convergence discipline, extended to close the
357/// second of three OTP-shaped closed-enum discriminator axes on the
358/// caixa typed surface.
359impl std::fmt::Display for RestartStrategy {
360 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
361 f.write_str(self.as_str())
362 }
363}
364
365/// Substrate-canonical [`AsRef<str>`] projection on the M2
366/// per-supervisor sibling-restart [`RestartStrategy`] closed-set typed
367/// enum — routes through the same [`RestartStrategy::as_str`]
368/// `pub const fn` scalar accessor the paired [`std::fmt::Display`]
369/// impl and the un-`rename`d [`serde::Serialize`] derive already key
370/// off, so any future consumer that binds a [`RestartStrategy`]
371/// through the standard-library `impl AsRef<str>` bound (a future
372/// [`caixa-feira`] `feira supervisor --estrategia <arm>` verb that
373/// composes the emitted `PascalCase` wire scalar into a
374/// [`std::process::Command::arg`] shell-out of the future
375/// wasm-operator's admission gate, a per-supervisor structured-log
376/// recorder on the future `caixa-operator`'s hierarchical
377/// reconciliation surface that accepts `impl AsRef<str>` at the
378/// `tracing::field::Value` `Str`-arm, a [`std::collections::HashMap`]
379/// lookup keyed on the estrategia wire byte through
380/// `map.get::<str>(strategy.as_ref())` on a future per-strategy
381/// dispatch table) reaches the paired [`crate::render::SUPERVISOR_ESTRATEGIA_ONE_FOR_ONE`]
382/// / [`crate::render::SUPERVISOR_ESTRATEGIA_ONE_FOR_ALL`] /
383/// [`crate::render::SUPERVISOR_ESTRATEGIA_REST_FOR_ONE`] /
384/// [`crate::render::SUPERVISOR_ESTRATEGIA_SIMPLE_ONE_FOR_ONE`]
385/// lifted-const through one substrate-primitive dispatch rather
386/// than an open-coded `.as_str()` projection at every wire-up.
387///
388/// Peer of the sibling [`std::fmt::Display`] impl on the same
389/// primitive — both delegate to the shared
390/// [`RestartStrategy::as_str`] `pub const fn` accessor, so
391/// [`format!("{s}")`], `s.as_str()`, and
392/// `<RestartStrategy as AsRef<str>>::as_ref(&s)` resolve to the same
393/// byte-string per instance by construction. A future variant rename
394/// or `#[serde(rename_all = "kebab-case")]` attribute-drift on the
395/// enum reaches every one of the three paths (plus the wire-format
396/// `Serialize` derive that already routes through the same lifted
397/// const) through exactly one caixa-core edit.
398///
399/// Same "route the trait impl through the substrate-primitive
400/// accessor" discipline the sibling [`crate::CaixaVersion`]
401/// [`AsRef<str>`] impl (16d5c7e) carries on the paired top-level
402/// `:versao` typed newtype — extends it onto the second `AsRef<str>`
403/// axis on the caixa typed surface (the first M2 OTP-shape
404/// closed-set typed enum to converge onto the standard-library
405/// [`AsRef<str>`] projection). Rust-side newtype/typed-enum
406/// convention pairs [`AsRef<str>`] and [`fmt::Display`] on the same
407/// primitive so a caller who has one has both; before this lift,
408/// [`RestartStrategy`] carried [`fmt::Display`] but not the paired
409/// [`AsRef<str>`] impl the convention names.
410///
411/// Pinned load-bearing by
412/// [`tests::restart_strategy_as_ref_str_routes_through_as_str_accessor`]
413/// (byte-parity pin against [`RestartStrategy::as_str`] across the
414/// four-arm closed set) — any future silent detour that routes the
415/// impl through a divergent projection (a per-arm inline
416/// `match self { … }` re-inlining that opens a compile-time link to
417/// the un-lifted arm-literal, a swap onto the kebab-case
418/// [`gen_platform::Discriminant`] catalog identity that would collide
419/// the wire axis with the dispatcher-catalog axis) trips at
420/// caixa-core test time under `assert_eq!` rather than at a
421/// downstream `impl AsRef<str>`-bound consumer's silent split.
422impl AsRef<str> for RestartStrategy {
423 fn as_ref(&self) -> &str {
424 self.as_str()
425 }
426}
427
428/// Trait-idiomatic reverse projection on the M2-OTP-shape sibling-restart
429/// [`RestartStrategy`] closed-set typed enum — routes byte-for-byte through
430/// the paired substrate-primitive [`RestartStrategy::from_wire`]
431/// `Option<Self>` accessor so every future consumer that binds a
432/// `PascalCase` `:supervisor :estrategia` wire byte-string through the
433/// standard-library `.try_into()` / [`TryFrom`] axis (a future
434/// [`caixa-feira`] `feira supervisor --estrategia <OneForOne|OneForAll|
435/// RestForOne|SimpleOneForOne>` CLI arg-parse that composes into
436/// `let estrategia: RestartStrategy = s.try_into()?`, a future
437/// `mesh.pleme.io/v1alpha1/Supervisor` CR admission-webhook that folds a
438/// `spec.estrategia: String` field through
439/// `RestartStrategy::try_from(&s)?`, a generic
440/// `<T: TryFrom<&str>>`-bound loader over any of the substrate's closed-
441/// set typed enums) reaches the same four-arm accept-set the sibling
442/// [`RestartStrategy::from_wire`] resolver parses through and the sibling
443/// [`RestartStrategy::as_str`] emits, rather than an open-coded per-arm
444/// `match s { "OneForOne" => …, "OneForAll" => …, "RestForOne" => …,
445/// "SimpleOneForOne" => …, _ => … }` cascade whose arm-set has no
446/// compile-time link back to the substrate primitive.
447///
448/// Complements the pre-existing forward-projection triple
449/// ([`std::fmt::Display`], [`AsRef<str>`], [`RestartStrategy::as_str`])
450/// with the paired trait-idiomatic reverse-projection axis: Rust-side
451/// newtype/typed-enum convention pairs [`AsRef<str>`] with either
452/// [`std::str::FromStr`] or [`TryFrom<&str>`] on the same primitive so a
453/// caller who can project *out to* a `&str` can also project *in from*
454/// one. The [`TryFrom<&str>`] axis is deliberately chosen over
455/// [`std::str::FromStr`] to sidestep the `clippy::should_implement_trait`
456/// lint the sibling method-named [`RestartStrategy::from_wire`] would
457/// trigger under a `FromStr` impl and to avoid colliding with the
458/// [`std::str::FromStr`] impl the [`gen_platform::FromStrKind`] derive
459/// already installs on the paired *kebab-case dispatcher-catalog* axis
460/// (which parses `"one-for-one"` / `"one-for-all"` / `"rest-for-one"` /
461/// `"simple-one-for-one"`, the inverse of [`Self::discriminant`]) — this
462/// impl closes the trait-idiomatic reverse axis on the *`PascalCase` wire*
463/// half without disturbing either the method-named `from_wire` shape every
464/// sibling closed-set typed enum on the substrate already carries or the
465/// pre-existing `FromStr` on the dispatcher-catalog half, keeping the
466/// two-axis split the sibling [`Self::from_wire`] doc block motivates.
467///
468/// `type Error = ()` matches the sibling [`RestartStrategy::from_wire`]'s
469/// `Option<Self>` return-shape's deliberate deferral of error typing: the
470/// caller picks the diagnostic form appropriate for its use site (a future
471/// `feira supervisor --estrategia` arg-parse composes its own per-verb
472/// "unknown strategy: <arg> — accepted: {…}" message enumerating
473/// [`RestartStrategy::ALL`], a future M4 admission-webhook rejection body
474/// wraps the `Err(())` outcome with the accepted-set enumeration for
475/// operator diagnostics, a `Result::map_err` at the call site lifts the
476/// unit-error to a per-verb error type). Same shape the peer
477/// [`crate::CaixaKind`] (3c83606), [`crate::CaixaDialeto`] (bf33136),
478/// [`crate::aplicacao::PlacementStrategy`] (6fd00cd), and
479/// [`crate::provedor::ferrite::FerriteRuntime::from_wire`] blocks motivate
480/// on their peer closed-set typed enums' reverse projections.
481///
482/// The paired [`TryFrom<&str>`] impl reaches the same four-arm accept-set
483/// the [`RestartStrategy::from_wire`] resolver dispatches through, so any
484/// future arm addition (an OTP-`rest_for_all` fifth arm the theory
485/// [`ABSORPTION-ROADMAP`](https://github.com/pleme-io/theory/blob/main/ABSORPTION-ROADMAP.md)
486/// might reach for once the four canonical OTP strategies stop covering
487/// the substrate's discovered load-shape) grows the trait-idiomatic axis
488/// by construction — one caixa-core edit on
489/// [`RestartStrategy::from_wire`] extends both the method-named reverse
490/// projection every existing consumer keys off and the trait-idiomatic
491/// reverse projection this impl exposes, without a coordinated rewrite
492/// across every future `TryFrom<&str>`-bound consumer's arm-set.
493///
494/// Extends the substrate-wide closed-set-enum reverse-projection family
495/// ([`crate::CaixaKind`] via 3c83606, [`crate::CaixaDialeto`] via bf33136,
496/// [`crate::aplicacao::PlacementStrategy`] via 6fd00cd) onto the first
497/// M2-OTP-shape closed-set typed enum on the caixa surface — the
498/// `:supervisor :estrategia` closed set the future wasm-operator's
499/// hierarchical reconciliation scheduler keys off end-to-end.
500///
501/// Pinned load-bearing by
502/// [`tests::restart_strategy_try_from_str_routes_through_from_wire_accessor`]
503/// (byte-parity pin against [`RestartStrategy::from_wire`] across the
504/// four-arm accept-set) and
505/// [`tests::restart_strategy_try_from_str_rejects_unknown_byte_strings`]
506/// (rejection witness against silent accept-set widening).
507impl TryFrom<&str> for RestartStrategy {
508 type Error = ();
509
510 fn try_from(s: &str) -> Result<Self, Self::Error> {
511 Self::from_wire(s).ok_or(())
512 }
513}
514
515/// Trait-idiomatic *forward* projection on the M2-OTP-shape sibling-restart
516/// [`RestartStrategy`] closed-set typed enum onto the `&'static str` axis —
517/// routes byte-for-byte through the paired substrate-primitive
518/// [`RestartStrategy::as_str`] `pub const fn` accessor so every future
519/// consumer that binds a [`RestartStrategy`] through the standard-library
520/// `.into()` / [`From<Self> for &'static str`] (equivalently
521/// [`Into<&'static str>`]) axis (a future
522/// `tracing::field::valuable::Value::Str(strategy.into())` structured-log
523/// recorder where the `Str` arm typing demands `&'static str` and the
524/// sibling [`AsRef<str>`] impl's borrowed `&str` return-type does not
525/// satisfy the bound, a future `Cow::Borrowed::<'static, str>(strategy.into())`
526/// composer on the future M4 admission-webhook rejection body where the
527/// `Cow<'static, str>` typing rules out the sibling [`AsRef<str>`] borrowed
528/// return, a generic `<T: Into<&'static str>>`-bound serializer on a
529/// per-strategy diagnostic column) reaches the same lifted
530/// [`crate::render::SUPERVISOR_ESTRATEGIA_ONE_FOR_ONE`] /
531/// [`crate::render::SUPERVISOR_ESTRATEGIA_ONE_FOR_ALL`] /
532/// [`crate::render::SUPERVISOR_ESTRATEGIA_REST_FOR_ONE`] /
533/// [`crate::render::SUPERVISOR_ESTRATEGIA_SIMPLE_ONE_FOR_ONE`] const the
534/// paired [`std::fmt::Display`], [`AsRef<str>`], and
535/// [`RestartStrategy::as_str`] surfaces already return, rather than an
536/// open-coded per-arm `match s { OneForOne => "OneForOne", … }` cascade
537/// whose arm-set has no compile-time link back to the substrate primitive.
538///
539/// Complements the pre-existing quadruple
540/// ([`std::fmt::Display`], [`AsRef<str>`], [`RestartStrategy::as_str`],
541/// [`TryFrom<&str>`] via 5b828ed) with the paired trait-idiomatic
542/// forward-projection axis: Rust-side newtype/typed-enum convention pairs
543/// [`TryFrom<&str>`] (trait-idiomatic reverse) with [`From<Self> for
544/// &'static str`] (trait-idiomatic forward) on the same primitive so a
545/// caller who can project *in from* a `&str` via the trait axis can also
546/// project *out to* one — mirroring the `strum::IntoStaticStr` /
547/// `serde::Serialize`-shape idiom where both projection halves share one
548/// trait-driven vocabulary. Before this lift the substrate carried a
549/// `&str`-returning [`AsRef<str>`] but not the paired `&'static str`-
550/// returning [`From<Self> for &'static str`] axis every downstream
551/// generic that specifically needs `'static` byte-string bytes reaches for.
552///
553/// The paired [`RestartStrategy::as_str`] returns `&'static str` by
554/// construction (each `match` arm resolves to a
555/// [`crate::render::SUPERVISOR_ESTRATEGIA_*`] `pub const &str` with static
556/// lifetime), so the trait's return-type promise is upheld structurally.
557/// Any future silent detour that routes the impl through a non-static
558/// projection (a per-arm inline `String::from("OneForOne")`-shaped
559/// re-inlining that would `.leak()`-cast for the `'static` bound, a
560/// hypothetical rebrand of one arm's [`crate::render::SUPERVISOR_ESTRATEGIA_*`]
561/// const to a non-`const &str`) is a caixa-core-build-time failure through
562/// the `pub const fn as_str` signature the trait routes through.
563///
564/// The paired impl reaches the same four-arm emit-set the
565/// [`RestartStrategy::as_str`] accessor dispatches through, so any future
566/// arm addition (an OTP-`rest_for_all` fifth arm the theory
567/// [`ABSORPTION-ROADMAP`](https://github.com/pleme-io/theory/blob/main/ABSORPTION-ROADMAP.md)
568/// might reach for once the four canonical OTP strategies stop covering
569/// the substrate's discovered load-shape) grows the trait-idiomatic
570/// forward axis by construction — one caixa-core edit on
571/// [`RestartStrategy::as_str`] extends every one of the five sibling
572/// forward-projection paths ([`std::fmt::Display`], [`AsRef<str>`],
573/// [`RestartStrategy::as_str`] itself, this [`From<Self> for &'static str`],
574/// and the un-`rename`d [`serde::Serialize`] derive that also emits
575/// [`Self::as_str`]'s bytes) without a coordinated rewrite across every
576/// future `Into<&'static str>`-bound consumer's arm-set.
577///
578/// Opens the substrate-wide trait-idiomatic *forward*-projection family on
579/// closed-set fieldless typed enums — the mirror of the recently-closed
580/// trait-idiomatic *reverse*-projection family ([`crate::CaixaKind`] via
581/// 3c83606, [`crate::CaixaDialeto`] via bf33136,
582/// [`crate::aplicacao::PlacementStrategy`] via 6fd00cd, this enum via
583/// 5b828ed, [`crate::supervisor::RestartPolicy`] via 6fdd0d9,
584/// [`crate::aplicacao::WitShape`] via 5472902,
585/// [`crate::aplicacao::RateLimitUnit`] via bf78400,
586/// [`crate::render::PathShapeViolation`] via e67e48a, and the four
587/// downstream-crate peers — [`caixa_arch::InvariantKind`] via e21a857,
588/// [`caixa_arch::ArchVerdict`] via 0a4cc45, [`caixa_lint::Severity`] via
589/// a7bf74c, [`caixa_lint::FixSafety`] via df86c94,
590/// [`caixa_theme::Semantic`] via bd7da69, and
591/// [`caixa_provedor::ferrite::FerriteRuntime`] via 42ab951). This lift
592/// picks [`RestartStrategy`] as the first-mover on the forward-projection
593/// family because its wire byte-string (`PascalCase`) and diagnostic
594/// byte-string ([`as_str`] return) coincide by construction — the sibling
595/// [`crate::CaixaKind`] two-axis split (lowercase Portuguese diagnostic
596/// vs `PascalCase` wire) would leave a first-mover peer arbitrarily
597/// picking one axis; on [`RestartStrategy`] the choice is unambiguous.
598///
599/// Pinned load-bearing by
600/// [`tests::restart_strategy_from_into_static_str_routes_through_as_str_accessor`]
601/// (byte-parity pin against [`RestartStrategy::as_str`] across the
602/// four-arm emit-set, plus a `const`-context materialization witness for
603/// the `&'static str` lifetime promise) and
604/// [`tests::restart_strategy_from_into_static_str_and_as_str_partition_the_emit_set`]
605/// (partition pin asserting `<&'static str as From<RestartStrategy>>::from`
606/// and [`RestartStrategy::as_str`] agree on every arm, so no future
607/// silent bifurcation of the two forward-projection paths can land
608/// silently).
609impl From<RestartStrategy> for &'static str {
610 fn from(strategy: RestartStrategy) -> &'static str {
611 strategy.as_str()
612 }
613}
614
615/// Trait-idiomatic *forward* projection on [`RestartStrategy`] from a
616/// *borrowed* input onto the `&'static str` axis — the borrowed-input
617/// companion to the paired owned-input [`From<RestartStrategy> for
618/// &'static str`] impl immediately above. Routes byte-for-byte through
619/// the same substrate-primitive [`RestartStrategy::as_str`] `pub const
620/// fn` accessor so every consumer that binds a `&RestartStrategy`
621/// through the standard-library `.into()` / [`From<&Self> for &'static
622/// str`] axis (a `RestartStrategy::ALL.iter().map(<&'static
623/// str>::from).collect::<Vec<_>>()` per-arm accept-set materializer —
624/// whose iterator over `&'static [RestartStrategy]` yields
625/// `&RestartStrategy`, not `RestartStrategy`, so the owned-input
626/// [`From<RestartStrategy>`] axis alone forces every call site through
627/// an explicit `.copied()` / dereference / [`Copy`]-bound restatement
628/// rather than the direct trait-idiomatic projection; a future generic
629/// `<T: Copy + for<'a> Into<&'static str>>`-bound diagnostic column
630/// that walks the `iter().map(Into::into)` shape verbatim across every
631/// substrate-wide closed-set typed enum; the future wasm-operator's
632/// per-supervisor sibling-restart-strategy diagnostic line that
633/// composes the accepted-set enumeration from an iterated
634/// `RestartStrategy::ALL.iter().map(|s| s.into())` pipe rather than a
635/// per-arm `match s { … }` cascade; a future
636/// `HashMap::<&'static str, RestartStrategy>::from_iter(
637/// RestartStrategy::ALL.iter().map(|s| (s.into(), *s)))`-style
638/// per-strategy reverse-lookup table the sibling [`TryFrom<&str>`]
639/// impl cannot compose without this borrowed-input axis in place)
640/// reaches the same four-arm lifted
641/// [`crate::render::SUPERVISOR_ESTRATEGIA_ONE_FOR_ONE`] /
642/// [`crate::render::SUPERVISOR_ESTRATEGIA_ONE_FOR_ALL`] /
643/// [`crate::render::SUPERVISOR_ESTRATEGIA_REST_FOR_ONE`] /
644/// [`crate::render::SUPERVISOR_ESTRATEGIA_SIMPLE_ONE_FOR_ONE`] const
645/// the paired owned-input [`From<RestartStrategy> for &'static str`],
646/// the sibling [`std::fmt::Display`], [`AsRef<str>`], and
647/// [`RestartStrategy::as_str`] surfaces already return.
648///
649/// Fourth peer on the substrate-wide trait-idiomatic *borrowed-input*
650/// forward-projection family opened on [`crate::dep::DepList`]
651/// (64aa742) and extended onto [`crate::CaixaKind`] (5ab993a) and
652/// [`crate::CaixaDialeto`] (807b0b5). Rust's `From` trait does not
653/// auto-derive the `From<&Self>` sibling from a `From<Self>` impl (the
654/// blanket `impl<T, U> From<&T> for U where T: Copy, U: From<T>` does
655/// not exist in `core`), so every closed-set typed enum that carries
656/// the owned-input axis but not the borrowed-input axis forces every
657/// borrowed-input call site through a `.copied()` /
658/// `<&'static str>::from(*strategy)` / `strategy.as_str()` detour whose
659/// type bounds have no compile-time link to the substrate primitive.
660/// [`RestartStrategy`] is the first M2 OTP-shape peer to converge onto
661/// this campaign (mirroring the first-mover role it played on the
662/// owned-input axis in 523157d); the remaining eleven substrate-wide
663/// closed-set fieldless typed enum peers (`RestartPolicy`, `WitShape`,
664/// `RateLimitUnit`, `PlacementStrategy`, `PathShapeViolation`,
665/// `InvariantKind`, `ArchVerdict`, `Severity`, `FixSafety`, `Semantic`,
666/// `FerriteRuntime`) are the future targets of this campaign.
667///
668/// Unlike the peer [`crate::CaixaKind`] axis pair (whose forward
669/// [`From<Self> for &'static str`] emits the lowercase Portuguese
670/// [`Self::as_str`] diagnostic vocabulary while the reverse
671/// [`TryFrom<&str>`] parses the `PascalCase` [`Self::wire_name`]
672/// author-surface vocabulary, forcing the round-trip through an
673/// intermediate wire-vocab hop), [`RestartStrategy`]'s
674/// [`Self::as_str`] emit and [`Self::from_wire`] parse share the same
675/// `PascalCase` vocabulary by construction, so the borrowed-input
676/// forward axis and the reverse axis compose directly — the round-trip
677/// witness pin below locks this direct composition without the
678/// intermediate hop the peer axis requires.
679///
680/// Pinned load-bearing by
681/// [`tests::restart_strategy_from_borrowed_into_static_str_routes_through_as_str_accessor`]
682/// (byte-parity pin against [`RestartStrategy::as_str`] across the
683/// four-arm emit-set via a borrowed input, plus a `const`-context
684/// materialization witness for the `&'static str` lifetime promise,
685/// plus a blanket `.into()` shape) and
686/// [`tests::restart_strategy_from_owned_and_borrowed_into_static_str_agree_on_every_arm`]
687/// (cross-axis partition pin against the paired owned-input
688/// [`From<RestartStrategy> for &'static str`] impl, plus a
689/// `.iter().map(Into::into)` pipe witness over
690/// [`RestartStrategy::ALL`], plus a direct round-trip witness through
691/// [`TryFrom<&str>`] that closes the two-way `&Self → &'static str →
692/// Self` round-trip without the wire-vocab intermediate the peer
693/// [`crate::CaixaKind`] axis pair requires).
694impl From<&RestartStrategy> for &'static str {
695 fn from(strategy: &RestartStrategy) -> &'static str {
696 strategy.as_str()
697 }
698}
699
700/// Trait-idiomatic *owned-`String`* forward projection on the M2
701/// OTP-shape sibling-restart-strategy closed-set typed enum — the
702/// owned-heap-string companion to the paired `&'static str`-returning
703/// [`From<RestartStrategy> for &'static str`] / [`From<&RestartStrategy>
704/// for &'static str`] impls immediately above. Routes byte-for-byte
705/// through the substrate-primitive [`RestartStrategy::as_str`]
706/// `pub const fn` accessor (via [`str::to_owned`]) so every consumer
707/// that binds a [`RestartStrategy`] through the standard-library
708/// `.into()` / [`From<Self> for String`] (equivalently
709/// [`Into<String>`]) axis — a future
710/// `serde_json::Value::String(strategy.into())` structured-payload
711/// composer where the `Value::String` arm typing demands an owned
712/// [`String`] and the sibling [`&'static str`]-returning axis forces an
713/// explicit `.to_owned()` / `String::from` restatement at every call
714/// site, a future
715/// `HashMap::<String, RestartStrategy>::from_iter(RestartStrategy::ALL
716/// .iter().map(|s| (s.into(), *s)))` per-strategy lookup where the
717/// map's key type is owned [`String`] rather than [`&'static str`], a
718/// future `Cow::<'static, str>::Owned(strategy.into())` composer on
719/// the future M4 admission-webhook rejection body's owned-arm, the
720/// future wasm-operator's per-supervisor `serde_json::json!({
721/// "estrategia": strategy })` diagnostic emit where the JSON
722/// serializer's `Serialize` impl on [`String`] owns the emit-path — reaches
723/// the same four-arm lifted
724/// [`crate::render::SUPERVISOR_ESTRATEGIA_ONE_FOR_ONE`] /
725/// [`crate::render::SUPERVISOR_ESTRATEGIA_ONE_FOR_ALL`] /
726/// [`crate::render::SUPERVISOR_ESTRATEGIA_REST_FOR_ONE`] /
727/// [`crate::render::SUPERVISOR_ESTRATEGIA_SIMPLE_ONE_FOR_ONE`] const the
728/// paired [`std::fmt::Display`], [`AsRef<str>`],
729/// [`RestartStrategy::as_str`], and the two `&'static str`-returning
730/// forward-projection impls already return.
731///
732/// Opens the trait-idiomatic *owned-`String`* forward-projection axis
733/// on the closed-set fieldless typed enum surface — first-mover on the
734/// M2 OTP-shape sibling-restart-strategy axis, mirror of the
735/// [`crate::supervisor::RestartStrategy`] first-mover position that
736/// opened the paired owned-`&'static str` axis (523157d) and the
737/// borrowed-input `&'static str` axis on
738/// [`crate::dep::DepList`] (64aa742). Rust's standard library does not
739/// carry a blanket `impl<T: AsRef<str>> From<T> for String` (nor an
740/// `impl<T: fmt::Display> From<T> for String`), so every closed-set
741/// typed enum that carries the paired `AsRef<str>` / `Display` /
742/// `From<Self> for &'static str` triple but not the owned-[`String`]
743/// axis forces every owned-string call site through a `.to_string()` /
744/// `.as_str().to_owned()` / `String::from(strategy.as_str())` detour
745/// whose type bounds have no compile-time link to the substrate
746/// primitive.
747///
748/// Deliberately routes through the human-readable
749/// [`RestartStrategy::as_str`] axis — for this enum the wire format
750/// (`PascalCase`, tatara-lisp author surface `:estrategia OneForOne`)
751/// and the diagnostic byte-string share the same vocabulary by
752/// construction (unlike the sibling [`crate::CaixaKind`] enum whose two
753/// axes diverge), so the owned-[`String`] projection lands
754/// byte-identically on both the wire vocabulary the paired
755/// [`serde::Serialize`] derive emits and the diagnostic vocabulary the
756/// [`RestartStrategy::as_str`] helper returns.
757///
758/// The remaining fourteen closed-set typed enums on the caixa
759/// substrate surface (`RestartPolicy`, `CaixaKind`, `CaixaDialeto`,
760/// `DepList`, `PlacementStrategy`, `WitShape`, `RateLimitUnit`,
761/// `PathShapeViolation`, `InvariantKind`, `ArchVerdict`, `Severity`,
762/// `FixSafety`, `Semantic`, `FerriteRuntime`) are the future targets of
763/// this campaign — each carries the same paired `AsRef<str>` /
764/// `Display` / `From<Self> for &'static str` / `From<&Self> for
765/// &'static str` quadruple that this owned-[`String`] axis extends onto.
766///
767/// Pinned load-bearing by
768/// [`tests::restart_strategy_from_into_owned_string_routes_through_as_str_accessor`]
769/// (byte-parity pin against [`RestartStrategy::as_str`] across the
770/// four-arm emit-set, plus a blanket `.into::<String>()` shape witness)
771/// and
772/// [`tests::restart_strategy_from_into_owned_string_and_static_str_agree_on_every_arm`]
773/// (cross-axis partition pin against the paired owned-input
774/// [`From<RestartStrategy> for &'static str`] impl and the sibling
775/// [`ToString::to_string`] surface routed through [`std::fmt::Display`],
776/// plus a direct round-trip witness through [`TryFrom<&str>`] on the
777/// owned-[`String`]'s [`String::as_str`] borrow that closes the two-way
778/// `Self → String → Self` round-trip on the trait-idiomatic
779/// owned-[`String`] forward + reverse axis pair).
780impl From<RestartStrategy> for String {
781 fn from(strategy: RestartStrategy) -> String {
782 strategy.as_str().to_owned()
783 }
784}
785
786/// Trait-idiomatic *borrowed-input, owned-`String` output* forward
787/// projection on the M2 OTP-shape sibling-restart-strategy closed-set
788/// typed enum — the fourth (and closing) corner of the
789/// `{Self, &Self} × {&'static str, String}` 2×2 trait-idiomatic
790/// projection family. Routes byte-for-byte through the
791/// substrate-primitive [`RestartStrategy::as_str`] `pub const fn`
792/// accessor (via [`str::to_owned`]) so every consumer that holds a
793/// borrowed [`&RestartStrategy`] and needs an owned [`String`] — a
794/// future `serde_json::Value::String(String::from(&strategy))`
795/// structured-payload composer over a borrowed field, a future
796/// `Iterator::map` over `&[RestartStrategy]` that projects to owned
797/// keys through `.iter().map(String::from)`, a future
798/// `HashMap::<String, RestartStrategy>::from_iter` that keys off a
799/// borrowed-iteration axis where dereferencing the strategy would force
800/// an unnecessary `Copy` at every step, the future wasm-operator's
801/// per-supervisor `strategies.iter().map(String::from).collect()`
802/// diagnostic emit whose iteration axis is borrowed by construction —
803/// reaches the same four-arm lifted
804/// [`crate::render::SUPERVISOR_ESTRATEGIA_ONE_FOR_ONE`] /
805/// [`crate::render::SUPERVISOR_ESTRATEGIA_ONE_FOR_ALL`] /
806/// [`crate::render::SUPERVISOR_ESTRATEGIA_REST_FOR_ONE`] /
807/// [`crate::render::SUPERVISOR_ESTRATEGIA_SIMPLE_ONE_FOR_ONE`] const the
808/// paired [`std::fmt::Display`], [`AsRef<str>`],
809/// [`RestartStrategy::as_str`], and the three other trait-idiomatic
810/// forward-projection impls
811/// ([`From<RestartStrategy> for &'static str`],
812/// [`From<&RestartStrategy> for &'static str`],
813/// [`From<RestartStrategy> for String`]) already return.
814///
815/// Opens the trait-idiomatic *borrowed-input, owned-`String` output*
816/// forward-projection axis on closed-set fieldless typed enums —
817/// first-mover on the 2×2 completion corner, mirror of the
818/// [`crate::supervisor::RestartStrategy`] first-mover position that
819/// opened the paired owned-input owned-`String` axis (7baa18a), the
820/// owned-input owned-`&'static str` axis (523157d), and the paired
821/// [`crate::dep::DepList`] first-mover position that opened the
822/// borrowed-input `&'static str` axis (64aa742). Rust's standard
823/// library does not carry a blanket `impl<T: AsRef<str>> From<&T> for
824/// String` (nor an `impl<T: fmt::Display> From<&T> for String`), so
825/// every closed-set typed enum that carries the paired `AsRef<str>` /
826/// `Display` / `From<Self> for &'static str` / `From<&Self> for
827/// &'static str` / `From<Self> for String` quintuple but not the
828/// borrowed-input owned-[`String`] axis forces every borrowed-input
829/// owned-string call site through a `strategy.as_str().to_owned()` /
830/// `String::from(*strategy)` (with a spurious `Copy`) /
831/// `strategy.to_string()` (through `Display`) detour whose type bounds
832/// have no compile-time link to the substrate primitive.
833///
834/// Deliberately routes through the human-readable
835/// [`RestartStrategy::as_str`] axis — for this enum the wire format
836/// (`PascalCase`, tatara-lisp author surface `:estrategia OneForOne`)
837/// and the diagnostic byte-string share the same vocabulary by
838/// construction (unlike the sibling [`crate::CaixaKind`] enum whose two
839/// axes diverge), so the borrowed-input owned-[`String`] projection
840/// lands byte-identically on both the wire vocabulary the paired
841/// [`serde::Serialize`] derive emits and the diagnostic vocabulary the
842/// [`RestartStrategy::as_str`] helper returns.
843///
844/// The remaining fourteen closed-set typed enums on the caixa
845/// substrate surface (`RestartPolicy`, `CaixaKind`, `CaixaDialeto`,
846/// `DepList`, `PlacementStrategy`, `WitShape`, `RateLimitUnit`,
847/// `PathShapeViolation`, `InvariantKind`, `ArchVerdict`, `Severity`,
848/// `FixSafety`, `Semantic`, `FerriteRuntime`) are the future targets of
849/// this 2×2-completion campaign — each carries the same paired
850/// quintuple that this borrowed-input owned-[`String`] axis extends onto.
851///
852/// Pinned load-bearing by
853/// [`tests::restart_strategy_from_into_borrowed_owned_string_routes_through_as_str_accessor`]
854/// (byte-parity pin against [`RestartStrategy::as_str`] across the
855/// four-arm emit-set through the borrowed-input surface) and
856/// [`tests::restart_strategy_from_into_borrowed_owned_string_agrees_with_paired_axes_on_every_arm`]
857/// (cross-axis partition pin against the paired owned-input owned-
858/// [`String`] [`From<RestartStrategy> for String`] impl, the paired
859/// borrowed-input owned-[`&'static str`] [`From<&RestartStrategy> for
860/// &'static str`] impl, and the sibling [`ToString::to_string`] surface
861/// routed through [`std::fmt::Display`], plus a direct round-trip
862/// witness through [`TryFrom<&str>`] on the owned-[`String`]'s
863/// [`String::as_str`] borrow that closes the two-way
864/// `&Self → String → Self` round-trip on the trait-idiomatic
865/// borrowed-input owned-[`String`] forward + reverse axis pair).
866impl From<&RestartStrategy> for String {
867 fn from(strategy: &RestartStrategy) -> String {
868 strategy.as_str().to_owned()
869 }
870}
871
872/// Trait-idiomatic *owned-input, [`std::borrow::Cow<'static, str>`]
873/// output* forward projection on the M2 OTP-shape sibling-restart
874/// [`RestartStrategy`] closed-set typed enum — extends the substrate-
875/// wide [`std::borrow::Cow<'static, str>`] forward-projection family
876/// opened on [`crate::CaixaKind`] (99c1735) onto the first M2 OTP-
877/// shape closed-set fieldless typed enum peer on the caixa surface
878/// (`:supervisor :estrategia`). Routes byte-for-byte through the
879/// substrate-primitive [`RestartStrategy::as_str`] `pub const fn`
880/// accessor (via [`std::borrow::Cow::Borrowed`]) so every consumer
881/// that binds a [`RestartStrategy`] through the trait-idiomatic
882/// [`std::borrow::Cow<'static, str>`] axis — a future
883/// `axum::response::IntoResponse` composer whose per-strategy
884/// diagnostic-body typing rules out the sibling [`AsRef<str>`]
885/// borrowed return, a future M4 admission-webhook rejection body
886/// that composes the accepted-strategy enumeration through the same
887/// `RestartStrategy::ALL.iter().map(Cow::from)` shape [`CaixaKind`]
888/// already routes through, a generic `<T: for<'a>
889/// Into<std::borrow::Cow<'static, str>>>`-bound structured-log
890/// emitter on a per-supervisor diagnostic column — reaches the same
891/// four-arm lifted [`crate::render::SUPERVISOR_ESTRATEGIA_ONE_FOR_ONE`]
892/// / [`crate::render::SUPERVISOR_ESTRATEGIA_ONE_FOR_ALL`] /
893/// [`crate::render::SUPERVISOR_ESTRATEGIA_REST_FOR_ONE`] /
894/// [`crate::render::SUPERVISOR_ESTRATEGIA_SIMPLE_ONE_FOR_ONE`] const
895/// the paired [`std::fmt::Display`], [`AsRef<str>`],
896/// [`RestartStrategy::as_str`], and the four
897/// `{Self, &Self} × {&'static str, String}` 2×2 trait-idiomatic
898/// forward-projection corners already return.
899///
900/// Deliberately returns [`std::borrow::Cow::Borrowed`] rather than
901/// [`std::borrow::Cow::Owned`] — the substrate-primitive
902/// [`RestartStrategy::as_str`] accessor's return carries the
903/// `&'static str` lifetime by construction (each `match` arm resolves
904/// to a [`crate::render::SUPERVISOR_ESTRATEGIA_*`] `pub const &str`
905/// with static lifetime), so the zero-alloc borrowed arm is the
906/// type-correct projection with no runtime allocation.
907///
908/// Rust's standard library carries no blanket `impl<T: AsRef<str>>
909/// From<T> for Cow<'static, str>` (nor an `impl<T: fmt::Display>
910/// From<T> for Cow<'static, str>`), so the paired sibling
911/// [`From<RestartStrategy> for &'static str`],
912/// [`From<RestartStrategy> for String`], [`AsRef<str>`], and
913/// [`std::fmt::Display`] surfaces do not implicitly extend to a
914/// [`Cow<'static, str>`]-bound call site — every such site is forced
915/// through a `Cow::Borrowed(strategy.as_str())` /
916/// `Cow::Owned(strategy.to_string())` open-code whose type bounds
917/// have no compile-time link back to the substrate primitive until
918/// this lift.
919///
920/// First peer to extend the substrate-wide trait-idiomatic
921/// [`std::borrow::Cow<'static, str>`] forward-projection axis off the
922/// top-level [`crate::CaixaKind`] enum (99c1735 owned-input,
923/// d45c409 borrowed-input) onto the wider substrate — the remaining
924/// twelve peers (`RestartPolicy`, `PlacementStrategy`, `RateLimitUnit`,
925/// `DepList`, `CaixaDialeto`, and the outside-`caixa-core` peers
926/// `WitShape`, `PathShapeViolation`, `InvariantKind`, `ArchVerdict`,
927/// `Severity`, `FixSafety`, `Semantic`, `FerriteRuntime`) are the
928/// future targets of this campaign.
929///
930/// Pinned load-bearing by
931/// [`tests::restart_strategy_from_into_static_cow_str_routes_through_as_str_accessor`]
932/// (byte-parity + zero-alloc [`std::borrow::Cow::Borrowed`]-arm pin
933/// against [`RestartStrategy::as_str`] across the four-arm
934/// [`RestartStrategy::ALL`]) and
935/// [`tests::restart_strategy_from_into_static_cow_str_agrees_with_paired_axes_on_every_arm`]
936/// (cross-axis partition pin against the paired [`From<RestartStrategy>
937/// for &'static str`], [`From<RestartStrategy> for String`], and
938/// [`ToString`]-through-[`std::fmt::Display`] axes, plus a
939/// `.iter().copied().map(Cow::from)` pipe witness over
940/// [`RestartStrategy::ALL`] that materializes the four-arm accept-set
941/// through the [`Cow<'static, str>`] axis alone and pins the
942/// zero-alloc discipline on every element).
943impl From<RestartStrategy> for std::borrow::Cow<'static, str> {
944 fn from(strategy: RestartStrategy) -> std::borrow::Cow<'static, str> {
945 std::borrow::Cow::Borrowed(strategy.as_str())
946 }
947}
948
949/// Trait-idiomatic *borrowed-input, [`std::borrow::Cow<'static, str>`]
950/// output* forward projection on the M2 OTP-shape sibling-restart
951/// [`RestartStrategy`] closed-set typed enum — the borrowed-input
952/// companion to the paired owned-input
953/// [`From<RestartStrategy> for std::borrow::Cow<'static, str>`] impl
954/// immediately above (7dd28b3). Routes byte-for-byte through the same
955/// substrate-primitive [`RestartStrategy::as_str`] `pub const fn`
956/// accessor (via [`std::borrow::Cow::Borrowed`]) so every consumer
957/// that holds a `&RestartStrategy` and needs a
958/// [`std::borrow::Cow<'static, str>`] — a
959/// `RestartStrategy::ALL.iter().map(std::borrow::Cow::from).collect::<Vec<_>>()`
960/// per-arm accept-set materializer (whose iterator over
961/// `&'static [RestartStrategy]` yields `&RestartStrategy`, not
962/// `RestartStrategy`, so the paired owned-input
963/// [`From<RestartStrategy> for std::borrow::Cow<'static, str>`] axis
964/// alone forces every call site through an explicit `.copied()` /
965/// dereference / [`Copy`]-bound restatement rather than the direct
966/// trait-idiomatic projection), a future generic
967/// `<T: for<'a> Into<std::borrow::Cow<'static, str>>>`-bound emitter
968/// on a per-strategy diagnostic column that walks the
969/// `iter().map(Into::into)` shape verbatim, the future M4 admission-
970/// webhook rejection body that composes the accepted-strategy
971/// enumeration from an iterated
972/// `RestartStrategy::ALL.iter().map(|s| s.into())` pipe rather than a
973/// per-arm `match s { … }` cascade — reaches the same four-arm lifted
974/// [`crate::render::SUPERVISOR_ESTRATEGIA_ONE_FOR_ONE`] /
975/// [`crate::render::SUPERVISOR_ESTRATEGIA_ONE_FOR_ALL`] /
976/// [`crate::render::SUPERVISOR_ESTRATEGIA_REST_FOR_ONE`] /
977/// [`crate::render::SUPERVISOR_ESTRATEGIA_SIMPLE_ONE_FOR_ONE`] const
978/// the paired [`std::fmt::Display`], [`AsRef<str>`],
979/// [`RestartStrategy::as_str`], the four
980/// `{Self, &Self} × {&'static str, String}` 2×2 trait-idiomatic
981/// forward-projection corners, and the paired owned-input
982/// [`From<RestartStrategy> for std::borrow::Cow<'static, str>`] impl
983/// already return.
984///
985/// Deliberately returns [`std::borrow::Cow::Borrowed`] rather than
986/// [`std::borrow::Cow::Owned`] — the substrate-primitive
987/// [`RestartStrategy::as_str`] accessor's return carries the
988/// `&'static str` lifetime by construction (each `match` arm resolves
989/// to a [`crate::render::SUPERVISOR_ESTRATEGIA_*`] `pub const &str`
990/// with static lifetime), so the zero-alloc borrowed arm is the
991/// type-correct projection with no runtime allocation.
992///
993/// Second peer on the substrate-wide trait-idiomatic
994/// [`std::borrow::Cow<'static, str>`] forward-projection family
995/// opened one commit prior (7dd28b3) on the paired owned-input
996/// [`From<RestartStrategy> for std::borrow::Cow<'static, str>`] impl
997/// — closes the `{Self, &Self}` input-shape corner of the
998/// [`Cow<'static, str>`] axis on the first M2 OTP-shape closed-set
999/// fieldless typed enum peer on the caixa surface, exactly as
1000/// d45c409 closed it on the top-level [`crate::CaixaKind`] one commit
1001/// after the owning half (99c1735) landed. Rust's standard library
1002/// does not carry a blanket `impl<T: AsRef<str>> From<&T> for
1003/// Cow<'static, str>` (nor an `impl<T: fmt::Display> From<&T> for
1004/// Cow<'static, str>`), so every closed-set fieldless typed enum peer
1005/// on the substrate that carries the paired owned-input
1006/// [`Cow<'static, str>`] axis but not the borrowed-input axis forces
1007/// every borrowed-input [`Cow<'static, str>`]-parameterized call site
1008/// through a spurious [`Copy`] deref
1009/// (`std::borrow::Cow::from(*strategy)`) or a
1010/// `std::borrow::Cow::Borrowed(strategy.as_str())` open-code whose
1011/// type bounds have no compile-time link to the substrate primitive.
1012///
1013/// Pinned load-bearing by
1014/// [`tests::restart_strategy_from_borrowed_into_static_cow_str_routes_through_as_str_accessor`]
1015/// (byte-parity + zero-alloc [`std::borrow::Cow::Borrowed`]-arm pin
1016/// against [`RestartStrategy::as_str`] across the four-arm
1017/// [`RestartStrategy::ALL`] through the borrowed-input surface) and
1018/// [`tests::restart_strategy_from_borrowed_into_static_cow_str_agrees_with_paired_axes_on_every_arm`]
1019/// (cross-axis partition pin against the paired owned-input
1020/// [`From<RestartStrategy> for std::borrow::Cow<'static, str>`], the
1021/// paired borrowed-input owned-`&'static str`
1022/// [`From<&RestartStrategy> for &'static str`], and the paired
1023/// borrowed-input owned-`String` [`From<&RestartStrategy> for String`]
1024/// impls, plus a `.iter().map(std::borrow::Cow::from)` pipe witness
1025/// over [`RestartStrategy::ALL`] — whose iterator yields
1026/// `&RestartStrategy` by construction, so the borrowed-input
1027/// [`Cow<'static, str>`] axis is what routes the pipe through the
1028/// substrate-primitive [`RestartStrategy::as_str`] accessor with the
1029/// zero-alloc [`Cow::Borrowed`] arm by construction and without a
1030/// spurious [`Copy`] deref).
1031impl From<&RestartStrategy> for std::borrow::Cow<'static, str> {
1032 fn from(strategy: &RestartStrategy) -> std::borrow::Cow<'static, str> {
1033 std::borrow::Cow::Borrowed(strategy.as_str())
1034 }
1035}
1036
1037/// Trait-idiomatic *owned-input, [`Box<str>`] output* forward
1038/// projection on the M2 OTP-shape sibling-restart [`RestartStrategy`]
1039/// closed-set fieldless typed enum — opens a fresh
1040/// substrate-wide `Box<str>` forward-projection campaign tier on the
1041/// first M2 OTP-shape closed-set fieldless typed enum peer on the
1042/// caixa surface, immediately after the paired `Cow<'static, str>`
1043/// axis (7dd28b3 / ee577fd) closed the
1044/// `{Self, &Self} × {&'static str, String, Cow<'static, str>}` 2×3
1045/// corner on this enum. Routes byte-for-byte through the
1046/// substrate-primitive [`RestartStrategy::as_str`] `pub const fn`
1047/// accessor via [`Box::<str>::from`] on the returned `&'static str`,
1048/// so every consumer that binds a
1049/// `let key: Box<str> = strategy.into();`-shaped call site — a
1050/// per-supervisor metric-key materializer that stashes the strategy
1051/// discriminator in a `Box<str>`-typed heap-owned scalar for cheap
1052/// clone (a shared-nothing per-strategy accept-set the
1053/// `caixa-operator` reconciliation scheduler carries), a future
1054/// admission-webhook rejection body whose per-arm `Box<str>` field
1055/// composes from an owned `RestartStrategy` handle — reaches the
1056/// same four-arm lifted
1057/// [`crate::render::SUPERVISOR_ESTRATEGIA_ONE_FOR_ONE`] /
1058/// [`crate::render::SUPERVISOR_ESTRATEGIA_ONE_FOR_ALL`] /
1059/// [`crate::render::SUPERVISOR_ESTRATEGIA_REST_FOR_ONE`] /
1060/// [`crate::render::SUPERVISOR_ESTRATEGIA_SIMPLE_ONE_FOR_ONE`] const
1061/// the sibling
1062/// `{Self, &Self} × {&'static str, String, Cow<'static, str>}`
1063/// forward-projection corner already returns. Rust's standard
1064/// library carries `impl From<&str> for Box<str>` and
1065/// `impl From<String> for Box<str>` but no blanket
1066/// `impl<T: AsRef<str>> From<T> for Box<str>`, so this axis is a
1067/// distinct trait-idiomatic surface that a downstream
1068/// `RestartStrategy → Box<str>` `.into()` reaches through this impl
1069/// and no other — without a
1070/// `Box::from(strategy.as_str())` open-code whose type bounds have
1071/// no compile-time link back to the substrate primitive.
1072///
1073/// Pinned load-bearing by
1074/// [`tests::restart_strategy_from_into_box_str_routes_through_as_str_accessor`]
1075/// (byte-parity pin against [`RestartStrategy::as_str`] across the
1076/// four-arm [`RestartStrategy::ALL`] emit-set on the owned-input
1077/// surface, plus a blanket-derived [`Into`] shape witness).
1078impl From<RestartStrategy> for Box<str> {
1079 fn from(strategy: RestartStrategy) -> Box<str> {
1080 Box::<str>::from(strategy.as_str())
1081 }
1082}
1083
1084/// Trait-idiomatic *borrowed-input, [`Box<str>`] output* forward
1085/// projection on the M2 OTP-shape sibling-restart [`RestartStrategy`]
1086/// closed-set fieldless typed enum — closes the `{Self, &Self}`
1087/// input-shape corner of the substrate-wide `Box<str>`
1088/// forward-projection axis opened one commit prior (69ef45c) on the
1089/// paired owned-input [`From<RestartStrategy> for Box<str>`] impl.
1090/// Routes byte-for-byte through the same substrate-primitive
1091/// [`RestartStrategy::as_str`] `pub const fn` accessor via
1092/// [`Box::<str>::from`] on the returned `&'static str`, so every
1093/// consumer that holds a `&RestartStrategy` and needs a
1094/// [`Box<str>`] — a
1095/// `RestartStrategy::ALL.iter().map(Box::<str>::from).collect::<Vec<_>>()`
1096/// per-arm accept-set materializer (whose iterator over
1097/// `&'static [RestartStrategy]` yields `&RestartStrategy`, not
1098/// `RestartStrategy`, so the paired owned-input
1099/// [`From<RestartStrategy> for Box<str>`] axis alone forces every
1100/// call site through an explicit `.copied()` / dereference /
1101/// [`Copy`]-bound restatement rather than the direct trait-idiomatic
1102/// projection), a per-supervisor metric-key materializer holding
1103/// `&RestartStrategy` through a `caixa-operator` reconciliation
1104/// scheduler's borrow lifetime, a future admission-webhook rejection
1105/// body whose per-arm `Box<str>` field composes from a borrowed
1106/// `&RestartStrategy` handle without a spurious [`Copy`] deref —
1107/// reaches the same four-arm lifted
1108/// [`crate::render::SUPERVISOR_ESTRATEGIA_ONE_FOR_ONE`] /
1109/// [`crate::render::SUPERVISOR_ESTRATEGIA_ONE_FOR_ALL`] /
1110/// [`crate::render::SUPERVISOR_ESTRATEGIA_REST_FOR_ONE`] /
1111/// [`crate::render::SUPERVISOR_ESTRATEGIA_SIMPLE_ONE_FOR_ONE`] const
1112/// the paired owned-input [`From<RestartStrategy> for Box<str>`] and
1113/// the sibling
1114/// `{Self, &Self} × {&'static str, String, Cow<'static, str>}`
1115/// forward-projection corner already return.
1116///
1117/// Second peer on the substrate-wide trait-idiomatic
1118/// [`Box<str>`] forward-projection family opened one commit prior
1119/// (69ef45c) on the paired owned-input
1120/// [`From<RestartStrategy> for Box<str>`] impl — closes the
1121/// `{Self, &Self}` input-shape corner of the [`Box<str>`] axis on
1122/// the first M2 OTP-shape closed-set fieldless typed enum peer on
1123/// the caixa surface (`:supervisor :estrategia`), exactly as
1124/// ee577fd closed the paired [`Cow<'static, str>`] axis one commit
1125/// after its owning half (7dd28b3) landed. Rust's standard library
1126/// carries `impl From<&str> for Box<str>` and
1127/// `impl From<String> for Box<str>` but no blanket
1128/// `impl<T: AsRef<str>> From<&T> for Box<str>` (nor a
1129/// `Copy`-based `impl<T: Copy, U: From<T>> From<&T> for U`), so
1130/// every closed-set fieldless typed enum peer on the substrate that
1131/// carries the paired owned-input `Box<str>` axis but not the
1132/// borrowed-input axis forces every borrowed-input
1133/// `Box<str>`-parameterized call site through a spurious [`Copy`]
1134/// deref (`Box::<str>::from((*strategy).as_str())`) or a
1135/// `Box::<str>::from(strategy.as_str())` open-code whose type bounds
1136/// have no compile-time link back to the substrate primitive.
1137///
1138/// Pinned load-bearing by
1139/// [`tests::restart_strategy_from_borrowed_into_box_str_routes_through_as_str_accessor`]
1140/// (byte-parity pin against [`RestartStrategy::as_str`] across the
1141/// four-arm [`RestartStrategy::ALL`] emit-set on the borrowed-input
1142/// surface, plus a blanket-derived [`Into`] shape witness and a
1143/// cross-axis pin against the paired owned-input
1144/// [`From<RestartStrategy> for Box<str>`] and the sibling
1145/// borrowed-input `{&'static str, String, Cow<'static, str>}`
1146/// return-shape axes).
1147impl From<&RestartStrategy> for Box<str> {
1148 fn from(strategy: &RestartStrategy) -> Box<str> {
1149 Box::<str>::from(strategy.as_str())
1150 }
1151}
1152
1153/// Trait-idiomatic *owned-input, [`std::sync::Arc<str>`] output*
1154/// forward projection on the M2 OTP-shape sibling-restart
1155/// [`RestartStrategy`] closed-set fieldless typed enum — opens the
1156/// substrate-wide [`std::sync::Arc<str>`] forward-projection campaign
1157/// tier on the first M2 OTP-shape closed-set fieldless typed enum peer
1158/// on the caixa surface (`:supervisor :estrategia`), immediately after
1159/// the paired [`Box<str>`] axis (69ef45c / 59ae5dc) closed the
1160/// `{Self, &Self} × {&'static str, String, Cow<'static, str>, Box<str>}`
1161/// 2×4 corner on this enum. Routes byte-for-byte through the
1162/// substrate-primitive [`RestartStrategy::as_str`] `pub const fn`
1163/// accessor (via [`std::sync::Arc::<str>::from`] on the returned
1164/// `&'static str`), so every consumer that binds a
1165/// [`RestartStrategy`] through the standard-library `.into()` /
1166/// [`From<Self> for std::sync::Arc<str>`] (equivalently
1167/// [`Into<std::sync::Arc<str>>`]) axis — a future admission-webhook
1168/// running under `axum` + `tokio` whose per-arm structured-log field
1169/// crosses an `.await` boundary and demands the [`Sync`] +
1170/// [`Send`]-safe shared-ownership envelope [`std::sync::Arc<str>`]
1171/// provides (the sibling [`Box<str>`] axis's owned-move return-shape
1172/// forces every downstream `.clone()` through a heap allocation, while
1173/// [`std::sync::Arc<str>`]'s reference-counted shared-ownership
1174/// resolves the same `.clone()` through a refcount bump), a future
1175/// wasm-operator's per-supervisor reconciliation scheduler that
1176/// dispatches the same per-strategy diagnostic key onto multiple
1177/// concurrent reconcile-loop tasks holding shared-ownership through
1178/// [`std::sync::Arc<str>`], a future
1179/// `tracing::field::valuable::Value::Str(strategy.into())` structured-
1180/// log recorder whose typing folds a shared-ownership envelope onto
1181/// the span-context axis, a generic
1182/// `<T: Into<std::sync::Arc<str>>>`-bound diagnostic column on a
1183/// shared-ownership per-strategy cache — reaches the same four-arm
1184/// lifted [`crate::render::SUPERVISOR_ESTRATEGIA_ONE_FOR_ONE`] /
1185/// [`crate::render::SUPERVISOR_ESTRATEGIA_ONE_FOR_ALL`] /
1186/// [`crate::render::SUPERVISOR_ESTRATEGIA_REST_FOR_ONE`] /
1187/// [`crate::render::SUPERVISOR_ESTRATEGIA_SIMPLE_ONE_FOR_ONE`] const
1188/// the sibling
1189/// `{Self, &Self} × {&'static str, String, Cow<'static, str>, Box<str>}`
1190/// forward-projection corner already returns.
1191///
1192/// First-mover on the substrate-wide trait-idiomatic
1193/// [`std::sync::Arc<str>`] forward-projection family — Rust's
1194/// standard library carries `impl From<&str> for std::sync::Arc<str>`
1195/// and `impl From<String> for std::sync::Arc<str>` but no blanket
1196/// `impl<T: AsRef<str>> From<T> for std::sync::Arc<str>` (nor an
1197/// `impl<T: fmt::Display> From<T> for std::sync::Arc<str>`), so every
1198/// closed-set fieldless typed enum on the substrate that carries the
1199/// paired [`AsRef<str>`] / [`std::fmt::Display`] /
1200/// [`From<Self> for &'static str`] / [`From<&Self> for &'static str`] /
1201/// [`From<Self> for String`] / [`From<&Self> for String`] /
1202/// [`From<Self> for Cow<'static, str>`] /
1203/// [`From<&Self> for Cow<'static, str>`] /
1204/// [`From<Self> for Box<str>`] / [`From<&Self> for Box<str>`] decet
1205/// but not the [`std::sync::Arc<str>`] axis forces every
1206/// `std::sync::Arc<str>`-parameterized call site through a
1207/// `std::sync::Arc::<str>::from(strategy.as_str())` open-code (or a
1208/// `std::sync::Arc::<str>::from(String::from(strategy))` two-step
1209/// composition through the owned-`String` axis that allocates
1210/// twice — once into the intermediate `String`, once into the
1211/// [`Arc<str>`] on the `From<String>` conversion) whose type bounds
1212/// have no compile-time link back to the substrate primitive. Opening
1213/// the axis on the first M2 OTP-shape closed-set fieldless typed enum
1214/// peer on the caixa substrate surface establishes the "route through
1215/// `as_str` via [`std::sync::Arc::<str>::from`] on the returned
1216/// `&'static str`" discipline; every future closed-set fieldless
1217/// typed enum peer on the substrate ([`RestartPolicy`],
1218/// [`crate::aplicacao::PlacementStrategy`],
1219/// [`crate::aplicacao::RateLimitUnit`], [`crate::aplicacao::WitShape`],
1220/// [`crate::dep::DepList`], [`crate::dialeto::CaixaDialeto`],
1221/// [`crate::kind::CaixaKind`],
1222/// [`crate::render::PathShapeViolation`], and the outside-`caixa-core`
1223/// peers `InvariantKind`, `ArchVerdict`, `Severity`, `FixSafety`,
1224/// `Semantic`, `FerriteRuntime`) is a future target of the campaign,
1225/// tracking the same 14-peer emit-set every prior projection tier
1226/// ([`&'static str`], [`String`], [`Cow<'static, str>`], [`Box<str>`])
1227/// converged onto.
1228///
1229/// Peer of the sibling [`Box<str>`] forward-projection first-mover
1230/// (69ef45c) — same "opens a new substrate-wide projection tier"
1231/// discipline, extended onto the [`std::sync::Arc<str>`] axis whose
1232/// shared-ownership + [`Sync`] + [`Send`] contract is the distinct
1233/// value the [`Box<str>`] axis's owned-move return-shape cannot
1234/// provide.
1235///
1236/// Pinned load-bearing by
1237/// [`tests::restart_strategy_from_into_arc_str_routes_through_as_str_accessor`]
1238/// (byte-parity pin against [`RestartStrategy::as_str`] across the
1239/// four-arm [`RestartStrategy::ALL`] emit-set on the owned-input
1240/// surface, plus a blanket-derived [`Into`] shape witness and cross-
1241/// axis byte-parity pins against the sibling owned-input
1242/// `{&'static str, String, Cow<'static, str>, Box<str>}` return-shape
1243/// axes).
1244impl From<RestartStrategy> for std::sync::Arc<str> {
1245 fn from(strategy: RestartStrategy) -> std::sync::Arc<str> {
1246 std::sync::Arc::<str>::from(strategy.as_str())
1247 }
1248}
1249
1250/// Trait-idiomatic *borrowed-input, [`std::sync::Arc<str>`] output*
1251/// forward projection on the M2 OTP-shape sibling-restart
1252/// [`RestartStrategy`] closed-set fieldless typed enum — closes the
1253/// `{Self, &Self}` input-shape corner of the [`std::sync::Arc<str>`]
1254/// forward-projection axis on the first M2 OTP-shape closed-set
1255/// fieldless typed enum peer on the caixa surface
1256/// (`:supervisor :estrategia`), companion to the paired owned-input
1257/// [`From<RestartStrategy> for std::sync::Arc<str>`] impl one commit
1258/// prior (bca2ec8). Routes byte-for-byte through the
1259/// substrate-primitive [`RestartStrategy::as_str`] `pub const fn`
1260/// accessor (via [`std::sync::Arc::<str>::from`] on the returned
1261/// `&'static str`), so every consumer that binds a
1262/// [`&RestartStrategy`] through the standard-library `.into()` /
1263/// [`From<&Self> for std::sync::Arc<str>`] (equivalently
1264/// [`Into<std::sync::Arc<str>>`]) axis — a future admission-webhook's
1265/// per-request borrowed-`&RestartStrategy` handle rendering a per-arm
1266/// `Sync` + `Send`-safe structured-log field across an `.await`
1267/// boundary through a `<T: Into<std::sync::Arc<str>>>`-bound
1268/// diagnostic-column dispatch, a future wasm-operator's per-
1269/// supervisor reconciliation pipeline whose
1270/// `.iter().map(std::sync::Arc::<str>::from)` collector reaches into
1271/// the shared-ownership per-strategy key without a spurious [`Copy`]
1272/// deref (which would only be reachable through the owned-input
1273/// [`From<RestartStrategy> for std::sync::Arc<str>`] axis by first
1274/// calling `.copied()` on the iterator), a future
1275/// `<T: Into<std::sync::Arc<str>>>`-bound `tracing`-span attributes
1276/// collector recording a borrowed-`&RestartStrategy` per-arm field
1277/// onto the parent span's shared-ownership context — reaches the
1278/// same four-arm lifted
1279/// [`crate::render::SUPERVISOR_ESTRATEGIA_ONE_FOR_ONE`] /
1280/// [`crate::render::SUPERVISOR_ESTRATEGIA_ONE_FOR_ALL`] /
1281/// [`crate::render::SUPERVISOR_ESTRATEGIA_REST_FOR_ONE`] /
1282/// [`crate::render::SUPERVISOR_ESTRATEGIA_SIMPLE_ONE_FOR_ONE`] const
1283/// the paired owned-input
1284/// [`From<RestartStrategy> for std::sync::Arc<str>`] impl and the
1285/// sibling `{&'static str, String, Cow<'static, str>, Box<str>}`
1286/// forward-projection corner already return.
1287///
1288/// Second peer on the substrate-wide trait-idiomatic
1289/// [`std::sync::Arc<str>`] forward-projection family opened one
1290/// commit prior (bca2ec8) on the paired owned-input
1291/// [`From<RestartStrategy> for std::sync::Arc<str>`] impl — closes
1292/// the `{Self, &Self}` input-shape corner of the
1293/// [`std::sync::Arc<str>`] axis on the first M2 OTP-shape closed-set
1294/// fieldless typed enum peer on the caixa surface, exactly as
1295/// 59ae5dc closed the paired [`Box<str>`] axis one commit after its
1296/// owning half (69ef45c) landed. Rust's standard library carries
1297/// `impl From<&str> for std::sync::Arc<str>` and
1298/// `impl From<String> for std::sync::Arc<str>` but no blanket
1299/// `impl<T: AsRef<str>> From<&T> for std::sync::Arc<str>` (nor a
1300/// `Copy`-based `impl<T: Copy, U: From<T>> From<&T> for U`), so
1301/// every closed-set fieldless typed enum peer on the substrate that
1302/// carries the paired owned-input [`std::sync::Arc<str>`] axis but
1303/// not the borrowed-input axis forces every borrowed-input
1304/// [`std::sync::Arc<str>`]-parameterized call site through a
1305/// spurious [`Copy`] deref
1306/// (`std::sync::Arc::<str>::from((*strategy).as_str())`) or a
1307/// `std::sync::Arc::<str>::from(strategy.as_str())` open-code whose
1308/// type bounds have no compile-time link back to the substrate
1309/// primitive.
1310///
1311/// Pinned load-bearing by
1312/// [`tests::restart_strategy_from_borrowed_into_arc_str_routes_through_as_str_accessor`]
1313/// (byte-parity pin against [`RestartStrategy::as_str`] across the
1314/// four-arm [`RestartStrategy::ALL`] emit-set on the borrowed-input
1315/// surface, plus a blanket-derived [`Into`] shape witness and a
1316/// cross-axis pin against the paired owned-input
1317/// [`From<RestartStrategy> for std::sync::Arc<str>`] and the sibling
1318/// borrowed-input `{&'static str, String, Cow<'static, str>,
1319/// Box<str>}` return-shape axes).
1320impl From<&RestartStrategy> for std::sync::Arc<str> {
1321 fn from(strategy: &RestartStrategy) -> std::sync::Arc<str> {
1322 std::sync::Arc::<str>::from(strategy.as_str())
1323 }
1324}
1325
1326/// Trait-idiomatic *owned-input, [`std::rc::Rc<str>`] output* forward
1327/// projection on the M2 OTP-shape sibling-restart [`RestartStrategy`]
1328/// closed-set fieldless typed enum — the single-threaded reference-
1329/// counted peer of the paired owned-input
1330/// [`From<RestartStrategy> for std::sync::Arc<str>`] impl (bca2ec8) on
1331/// the sibling atomically-reference-counted [`std::sync::Arc<str>`] axis.
1332/// Routes byte-for-byte through the substrate-primitive
1333/// [`RestartStrategy::as_str`] `pub const fn` accessor via
1334/// [`std::rc::Rc::<str>::from`] on the returned `&'static str`.
1335///
1336/// Rust's standard library carries `impl From<&str> for std::rc::Rc<str>`
1337/// and `impl From<String> for std::rc::Rc<str>` but no blanket
1338/// `impl<T: AsRef<str>> From<T> for std::rc::Rc<str>` (nor a `From<&T>`
1339/// blanket), and the [`std::sync::Arc<str>`] and [`std::rc::Rc<str>`]
1340/// trait tables are disjoint — so a single-threaded caixa-operator
1341/// reconciliation pass that shares the `:supervisor :estrategia` wire
1342/// byte-string across intra-reconcile-loop tree nodes through the cheaper
1343/// non-atomic [`std::rc::Rc<str>`] refcount (the atomically-reference-
1344/// counted [`std::sync::Arc<str>`] return-shape cannot provide within a
1345/// single-threaded reconciliation pass without paying the atomic-fence
1346/// cost the [`std::rc::Rc<str>`] axis skips by construction) reaches
1347/// the substrate primitive through this impl and no other.
1348///
1349/// Extends the trait-idiomatic [`std::rc::Rc<str>`] forward-projection
1350/// axis onto the first M2 OTP-shape closed-set fieldless typed enum peer
1351/// on the caixa surface (`:supervisor :estrategia`), matching the
1352/// trajectory the M3-mesh-primitive-defining
1353/// [`crate::aplicacao::PlacementStrategy`],
1354/// [`crate::aplicacao::RateLimitUnit`], and
1355/// [`crate::aplicacao::WitShape`] (1afb5f4) peers established, and the
1356/// eighth in-caixa-core closed-set fieldless typed-enum peer to pick up
1357/// the axis (after [`crate::CaixaKind`],
1358/// [`crate::dialeto::CaixaDialeto`], [`crate::dep::DepList`],
1359/// [`crate::version::CaixaVersion`], [`crate::render::PathShapeViolation`],
1360/// and the three M3-mesh-primitive-defining peers above).
1361///
1362/// Pinned load-bearing by
1363/// [`tests::restart_strategy_from_into_rc_str_routes_through_as_str_accessor`]
1364/// (byte-parity pin against [`RestartStrategy::as_str`] across the
1365/// four-arm [`RestartStrategy::ALL`] emit-set on the owned-input
1366/// surface, plus a blanket-derived [`Into`] shape witness and cross-
1367/// axis byte-parity pins against the sibling owned-input `{&'static
1368/// str, String, Cow<'static, str>, Box<str>, std::sync::Arc<str>}`
1369/// return-shape axes).
1370impl From<RestartStrategy> for std::rc::Rc<str> {
1371 fn from(strategy: RestartStrategy) -> std::rc::Rc<str> {
1372 std::rc::Rc::<str>::from(strategy.as_str())
1373 }
1374}
1375
1376/// Trait-idiomatic *borrowed-input, [`std::rc::Rc<str>`] output* forward
1377/// projection on the M2 OTP-shape sibling-restart [`RestartStrategy`]
1378/// closed-set fieldless typed enum — the borrowed-input companion to the
1379/// paired owned-input [`From<RestartStrategy> for std::rc::Rc<str>`]
1380/// impl immediately above, closing the `{Self, &Self}` input-shape
1381/// corner of the [`std::rc::Rc<str>`] axis on the first M2 OTP-shape
1382/// closed-set fieldless typed enum peer on the caixa surface. Routes
1383/// byte-for-byte through the substrate-primitive
1384/// [`RestartStrategy::as_str`] `pub const fn` accessor via
1385/// [`std::rc::Rc::<str>::from`] on the returned `&'static str`, so a
1386/// `RestartStrategy::ALL.iter().map(std::rc::Rc::<str>::from)`-shaped
1387/// pipe (whose iterator over `&'static [RestartStrategy]` yields
1388/// `&RestartStrategy` by construction) reaches the same four-arm lifted
1389/// [`crate::render::SUPERVISOR_ESTRATEGIA_ONE_FOR_ONE`] /
1390/// [`crate::render::SUPERVISOR_ESTRATEGIA_ONE_FOR_ALL`] /
1391/// [`crate::render::SUPERVISOR_ESTRATEGIA_REST_FOR_ONE`] /
1392/// [`crate::render::SUPERVISOR_ESTRATEGIA_SIMPLE_ONE_FOR_ONE`] const
1393/// roster the paired owned-input axis and the sibling `{Self, &Self} ×
1394/// {&'static str, String, Cow<'static, str>, Box<str>,
1395/// std::sync::Arc<str>}` forward-projection corner already return.
1396///
1397/// Rust's standard library carries no blanket
1398/// `impl<T: AsRef<str>> From<&T> for std::rc::Rc<str>` (nor a `Copy`-
1399/// based `impl<T: Copy, U: From<T>> From<&T> for U`), so this borrowed-
1400/// input axis is a distinct trait-idiomatic surface — without it, the
1401/// `.iter().map(std::rc::Rc::<str>::from)` pipe would force a spurious
1402/// [`Copy`] deref or a `.copied()` restatement whose type bounds have
1403/// no compile-time link back to the substrate primitive.
1404///
1405/// Pinned load-bearing by
1406/// [`tests::restart_strategy_from_borrowed_into_rc_str_routes_through_as_str_accessor`]
1407/// (byte-parity pin against [`RestartStrategy::as_str`] across the
1408/// four-arm [`RestartStrategy::ALL`] emit-set on the borrowed-input
1409/// surface, plus a blanket-derived [`Into`] shape witness, a cross-axis
1410/// partition pin against the paired owned-input
1411/// [`From<RestartStrategy> for std::rc::Rc<str>`] and the sibling
1412/// borrowed-input `{&'static str, String, Cow<'static, str>, Box<str>,
1413/// std::sync::Arc<str>}` return-shape axes, and a
1414/// `.iter().map(std::rc::Rc::<str>::from)` pipe witness over
1415/// [`RestartStrategy::ALL`] that resolves through the borrowed-input
1416/// axis without a spurious [`Copy`] deref).
1417impl From<&RestartStrategy> for std::rc::Rc<str> {
1418 fn from(strategy: &RestartStrategy) -> std::rc::Rc<str> {
1419 std::rc::Rc::<str>::from(strategy.as_str())
1420 }
1421}
1422
1423/// Substrate-canonical [`AsRef<[u8]>`] byte-view projection on the M2
1424/// OTP-shape sibling-restart [`RestartStrategy`] closed-set fieldless
1425/// typed enum — routes byte-for-byte through the substrate-primitive
1426/// [`RestartStrategy::as_str`] `pub const fn` accessor via
1427/// [`str::as_bytes`] on the returned `&'static str`, so any future
1428/// consumer that binds a [`RestartStrategy`] through a standard-library
1429/// `<T: AsRef<[u8]>>` trait bound reaches the same four-arm lifted
1430/// [`crate::render::SUPERVISOR_ESTRATEGIA_ONE_FOR_ONE`] /
1431/// [`crate::render::SUPERVISOR_ESTRATEGIA_ONE_FOR_ALL`] /
1432/// [`crate::render::SUPERVISOR_ESTRATEGIA_REST_FOR_ONE`] /
1433/// [`crate::render::SUPERVISOR_ESTRATEGIA_SIMPLE_ONE_FOR_ONE`]
1434/// `PascalCase` wire byte-string emit-set the paired sibling
1435/// [`AsRef<str>`] (5b828ed) / [`std::fmt::Display`] /
1436/// [`RestartStrategy::as_str`] str-view surfaces and every
1437/// `{Self, &Self} × {&'static str, String, Cow<'static, str>, Box<str>,
1438/// std::sync::Arc<str>}` reverse-projection corner already return —
1439/// through the byte-view axis, which the str-view axes cannot express.
1440///
1441/// Rust's standard library carries `impl AsRef<[u8]> for str` and
1442/// `impl AsRef<[u8]> for String`, so the two-hop composition
1443/// `strategy.as_str().as_bytes()` (or, equivalently,
1444/// `AsRef::<str>::as_ref(&strategy).as_bytes()`) is reachable through
1445/// the pre-existing str-view axis alone. But that two-hop shape has no
1446/// compile-time link back to the byte-projection axis, forces every
1447/// downstream `<T: AsRef<[u8]>>`-bound consumer to open-code the
1448/// two-hop composition at every call site, and admits a silent split
1449/// whenever a future call site takes a sibling reverse-projection axis
1450/// whose `.as_bytes()` byte-tail carries no compile-time byte-view
1451/// surface (`Display` returns a formatter, `String` / `Box<str>` /
1452/// `Arc<str>` allocate). The lifted single-hop impl closes the
1453/// byte-view axis so every future `<T: AsRef<[u8]>>`-bound consumer
1454/// reaches the substrate primitive through one trait dispatch, and
1455/// every future arm addition (an OTP-`rest_for_all` fifth arm the
1456/// theory
1457/// [`ABSORPTION-ROADMAP`](https://github.com/pleme-io/theory/blob/main/ABSORPTION-ROADMAP.md)
1458/// might reach for once the four canonical OTP strategies stop covering
1459/// the substrate's discovered load-shape) grows the byte-view axis
1460/// through one edit on the substrate-primitive `as_str` accessor, not a
1461/// coordinated rewrite across every future `<T: AsRef<[u8]>>`-bound
1462/// consumer's arm-set.
1463///
1464/// The primary compounding target is the same `caixa-lacre` BLAKE3
1465/// content-address closure the peer [`crate::CaixaKind`] (69d8d86),
1466/// [`crate::dialeto::CaixaDialeto`] (8151347),
1467/// [`crate::dep::DepList`] (05ffaca),
1468/// [`crate::aplicacao::PlacementStrategy`] (daa8705), and
1469/// [`crate::aplicacao::RateLimitUnit`] (4867e0f) `AsRef<[u8]>` impls
1470/// open onto: [`blake3::hash`] and [`blake3::Hasher::update`] both bind
1471/// their input through `impl AsRef<[u8]>`, so any future per-supervisor
1472/// content-address tag that folds an `:estrategia` discriminator
1473/// byte-tag into the [`crate::Lacre`] closure (a hypothetical
1474/// `hasher.update(estrategia);`-shape composition partitioning the
1475/// four OTP restart-topology closures at content-address time so
1476/// downstream `Lacre` consumers key per-strategy reconciliation caches
1477/// off the typed discriminator rather than the sibling `&'static str`
1478/// wire scalar) reaches the substrate-primitive `as_str` accessor
1479/// through this impl and no other.
1480///
1481/// Opens the trait-idiomatic byte-view axis on the first M2 OTP-shape
1482/// closed-set fieldless typed enum peer on the caixa surface
1483/// (`:supervisor :estrategia`), extending the substrate-wide byte-view
1484/// campaign the sibling [`crate::CaixaKind`] first-mover (69d8d86)
1485/// opened onto the fifth in-caixa-core enum peer. The remaining
1486/// in-caixa-core closed-set fieldless typed-enum peers
1487/// ([`RestartPolicy`], [`crate::aplicacao::WitShape`],
1488/// [`crate::upgrade::UpgradeInstruction`],
1489/// [`crate::render::PathShapeViolation`]) each carry the same
1490/// [`AsRef<str>`] + `pub const fn as_str` substrate-primitive accessor
1491/// discipline, so a future extension of the byte-view axis onto each
1492/// peer reaches through one impl per enum keyed to that peer's
1493/// substrate-primitive accessor.
1494///
1495/// Pinned load-bearing by
1496/// [`tests::restart_strategy_as_ref_bytes_routes_through_as_str_accessor`]
1497/// (fail-before-pass-after byte-parity pin against
1498/// [`RestartStrategy::as_str`] `.as_bytes()` across the four-arm
1499/// [`RestartStrategy::ALL`] emit-set, cross-axis witness against the
1500/// paired str-view [`AsRef<str>`] / [`std::fmt::Display`] /
1501/// [`RestartStrategy::as_str`] axes' `.as_bytes()` byte-tails,
1502/// cross-axis witness against the paired reverse-projection
1503/// `{&'static str, String, Cow<'static, str>, Box<str>,
1504/// std::sync::Arc<str>}` return-shape axes' `.as_bytes()` byte-tails,
1505/// a `<T: AsRef<[u8]>>`-bound-consumer witness that a generic
1506/// byte-input function accepts a [`RestartStrategy`] directly through
1507/// the trait bound, and a `blake3::Hasher::update`-shape byte-input
1508/// surface witness routed through the `<T: AsRef<[u8]>>`-bound
1509/// consumer axis to reach the caixa-lacre compounding target). Any
1510/// future silent detour that routes the byte-view impl off the
1511/// substrate-primitive [`RestartStrategy::as_str`] accessor (a per-arm
1512/// inline `b"OneForOne".as_slice()`-shaped re-inlining that opens a
1513/// compile-time link to the un-lifted arm-literal, a swap onto the
1514/// kebab-case [`gen_platform::Discriminant`] catalog identity that
1515/// would collide the wire axis with the dispatcher-catalog axis) trips
1516/// at caixa-core test time rather than at a downstream byte-consumer's
1517/// silent split.
1518impl AsRef<[u8]> for RestartStrategy {
1519 fn as_ref(&self) -> &[u8] {
1520 self.as_str().as_bytes()
1521 }
1522}
1523
1524/// Trait-idiomatic *owned-input, owned-`Vec<u8>` output* byte-owned
1525/// reverse projection on the first M2 OTP-shape closed-set fieldless
1526/// typed enum peer on the caixa surface ([`RestartStrategy`]) — the
1527/// byte-mirror of the [`From<RestartStrategy> for String`] str-owned
1528/// reverse-projection axis and the owned-`Vec<u8>` reverse-projection
1529/// sibling of the paired [`AsRef<[u8]>`] borrowed byte-view axis
1530/// (cd4c4e0) lifted on this same enum. Routes byte-for-byte through
1531/// the substrate-primitive [`RestartStrategy::as_str`] `pub const fn`
1532/// accessor via [`str::as_bytes`] + [`slice::to_vec`] so every
1533/// consumer that binds a [`RestartStrategy`] through the standard-
1534/// library `impl From<RestartStrategy> for Vec<u8>` axis
1535/// (equivalently `<T: Into<Vec<u8>>>`) — a future
1536/// [`std::io::Write::write_all`]-shape per-supervisor audit-log byte-
1537/// sink whose input parameter is an owned [`Vec<u8>`] payload, a
1538/// future `bytes::Bytes::from(Vec::<u8>::from(strategy))` composer
1539/// folding the per-arm sibling-restart-topology byte-tag into the
1540/// [`bytes::Bytes`] framing surface, a future
1541/// `hasher.update(&Vec::<u8>::from(strategy))`-shape BLAKE3 content-
1542/// address closure that needs the owned byte-tail buffered before
1543/// folding into the [`crate::Lacre`] closure body, a future per-
1544/// strategy protobuf/CBOR/msgpack payload composer whose framer takes
1545/// an owned [`Vec<u8>`] rather than a borrowed byte-slice — reaches
1546/// the substrate primitive through one trait dispatch rather than an
1547/// open-coded per-call-site `strategy.as_str().as_bytes().to_vec()`
1548/// composition whose type bounds have no compile-time link back to
1549/// the substrate primitive.
1550///
1551/// Extends the substrate-wide trait-idiomatic byte-owned reverse-
1552/// projection axis onto the first M2-OTP-shape closed-set fieldless
1553/// typed-enum peer, matching the trajectory the first-mover
1554/// [`crate::CaixaKind`] `From<{Self, &Self}> for Vec<u8>` lift
1555/// (b245fd6), the second-mover [`crate::dialeto::CaixaDialeto`] lift
1556/// (4cceaf5), and the third-mover [`crate::dep::DepList`] lift
1557/// (e974ca2) established across the caixa-core-internal tier. Every
1558/// future arm addition (an OTP-`rest_for_all` fifth arm the theory
1559/// [`ABSORPTION-ROADMAP`](https://github.com/pleme-io/theory/blob/main/ABSORPTION-ROADMAP.md)
1560/// might reach for once the four canonical OTP strategies stop
1561/// covering the substrate's discovered load-shape) grows the byte-
1562/// owned axis through one edit on the substrate-primitive
1563/// [`RestartStrategy::as_str`] accessor, mirroring the discipline the
1564/// paired [`AsRef<[u8]>`] borrowed byte-view axis campaign already
1565/// tracked across every closed-set fieldless typed enum peer on the
1566/// substrate.
1567///
1568/// Pinned load-bearing by
1569/// [`tests::restart_strategy_from_into_owned_vec_bytes_routes_through_as_str_accessor`]
1570/// (byte-parity pin against [`RestartStrategy::as_str`] across the
1571/// four-arm [`RestartStrategy::ALL`] emit-set binding the byte-owned
1572/// reverse-projection axis against the paired [`AsRef<[u8]>`]
1573/// borrowed byte-view axis and the str-owned reverse-projection
1574/// family (`String`, `Cow<'static, str>`, `Box<str>`,
1575/// `std::sync::Arc<str>`) `.into_bytes()` / `.as_bytes().to_vec()`
1576/// byte-tails, a `<T: Into<Vec<u8>>>`-bound generic-consumer witness,
1577/// and a `std::io::Write::write_all`-shape owned-byte-sink surface
1578/// witness on both owned and borrowed input shapes).
1579impl From<RestartStrategy> for Vec<u8> {
1580 fn from(strategy: RestartStrategy) -> Vec<u8> {
1581 strategy.as_str().as_bytes().to_vec()
1582 }
1583}
1584
1585/// Trait-idiomatic *borrowed-input, owned-`Vec<u8>` output* byte-
1586/// owned reverse projection on the first M2 OTP-shape closed-set
1587/// fieldless typed enum peer on the caixa surface
1588/// ([`RestartStrategy`]) — the borrowed-input peer of
1589/// [`From<RestartStrategy> for Vec<u8>`], closing the
1590/// `{Self, &Self} → Vec<u8>` pair on the byte-owned reverse-projection
1591/// axis in one lift. Routes byte-for-byte through the substrate-
1592/// primitive [`RestartStrategy::as_str`] `pub const fn` accessor so
1593/// every consumer that holds a borrowed [`&RestartStrategy`] and
1594/// needs an owned [`Vec<u8>`] — a future
1595/// `.iter().map(Vec::<u8>::from).collect()` pipe over
1596/// `&[RestartStrategy]` (whose iterator yields `&RestartStrategy`,
1597/// not `RestartStrategy`, so the owned-input axis alone forces every
1598/// call site through an explicit `.copied()` / spurious [`Copy`]
1599/// deref restatement rather than the direct trait-idiomatic
1600/// projection), a future admission-webhook rejection body composer
1601/// that walks [`RestartStrategy::ALL`] through an `Into<Vec<u8>>`-
1602/// bound per-arm byte-writer to surface the accepted `:estrategia`
1603/// set — reaches the substrate primitive through one trait dispatch
1604/// rather than a `Vec::<u8>::from(*strategy)` spurious-`Copy`-deref
1605/// restatement.
1606impl From<&RestartStrategy> for Vec<u8> {
1607 fn from(strategy: &RestartStrategy) -> Vec<u8> {
1608 strategy.as_str().as_bytes().to_vec()
1609 }
1610}
1611
1612/// Trait-idiomatic *borrowed byte-slice input* reverse projection on the
1613/// first M2-OTP-shape closed-set fieldless typed enum peer on the caixa
1614/// surface ([`RestartStrategy`]) — the byte-view mirror of the str-view
1615/// reverse-projection axis carried by the paired
1616/// [`TryFrom<&str> for RestartStrategy`] impl (which routes through the
1617/// substrate-primitive [`RestartStrategy::from_wire`] `Option<Self>`
1618/// accessor on the four-arm `PascalCase` accept-set the sibling
1619/// [`RestartStrategy::as_str`] emitter returns). Routes byte-for-byte
1620/// through the standard-library [`std::str::from_utf8`] UTF-8 validator
1621/// and then through [`RestartStrategy::from_wire`] so every consumer that
1622/// holds a borrowed [`&[u8]`] and needs to project it back into a typed
1623/// [`RestartStrategy`] — a future `bytes::Bytes::as_ref()`-fed reader
1624/// that parses a per-supervisor `:estrategia` `PascalCase` wire scalar
1625/// from an already-borrowed framing byte-tail (a
1626/// `tracing::field::valuable::Value::Bytes` recorder on the future
1627/// wasm-operator's per-supervisor sibling-restart-strategy diagnostic
1628/// emission path, a future audit-report re-loader binding a prior
1629/// [`RestartStrategy::as_str`] output from a mmap'd byte-slice back
1630/// through the typed enum for cross-run comparison), a future M4
1631/// `mesh.pleme.io/v1alpha1/Supervisor` CR admission-webhook rejection
1632/// body that reads a `spec.estrategia` field off a raw HTTP body byte-
1633/// slice before UTF-8 validation commits allocation, a future generic
1634/// `<T: for<'a> TryFrom<&'a [u8]>>`-bound loader over any of the
1635/// substrate's closed-set typed enums — reaches the same four-arm
1636/// `PascalCase` wire accept-set the sibling method-named
1637/// [`RestartStrategy::from_wire`] resolver and the paired trait-idiomatic
1638/// [`TryFrom<&str>`] axis already resolve against, rather than an open-
1639/// coded per-call-site
1640/// `std::str::from_utf8(bytes).ok().and_then(RestartStrategy::from_wire)`
1641/// composition or a
1642/// `<RestartStrategy as TryFrom<&str>>::try_from(std::str::from_utf8(bytes)?)`
1643/// two-hop shape whose type bounds have no compile-time link to the
1644/// substrate primitive.
1645///
1646/// Extends the substrate-wide trait-idiomatic *byte-view reverse-
1647/// projection* family — opened on the structurally most fundamental
1648/// closed-set fieldless typed enum peer ([`crate::CaixaKind`], commit
1649/// 18d1940), extended onto the second caixa-core-internal peer
1650/// ([`crate::CaixaDialeto`], commit d102cb8) and the third
1651/// ([`crate::dep::DepList`], commit b8f25d5) — onto the first
1652/// M2-OTP-shape supervisor-slot closed-set fieldless typed enum peer,
1653/// tracking the "route through `from_wire` via `std::str::from_utf8`"
1654/// discipline the first-mover established. Rust's standard library
1655/// carries no blanket
1656/// `impl<T: for<'a> TryFrom<&'a str>> TryFrom<&[u8]> for T`, so a two-
1657/// hop composition through [`std::str::from_utf8`] + the paired
1658/// [`TryFrom<&str>`] axis is reachable at every call site but has no
1659/// compile-time link back to the byte-view reverse-projection axis.
1660/// Every remaining closed-set fieldless typed enum peer on the substrate
1661/// ([`RestartPolicy`], [`crate::aplicacao::PlacementStrategy`],
1662/// [`crate::aplicacao::RateLimitUnit`], [`crate::aplicacao::WitShape`],
1663/// and the outside-`caixa-core` peers `PathShapeViolation`,
1664/// `InvariantKind`, `ArchVerdict`, `Severity`, `FixSafety`, `Semantic`,
1665/// `FerriteRuntime`) is a future target of the campaign, mirroring the
1666/// trajectory the closed byte-owned reverse-projection family walked
1667/// arm-by-arm onto each peer.
1668///
1669/// `type Error = ()` matches the sibling [`RestartStrategy::from_wire`]'s
1670/// `Option<Self>` return-shape's deliberate deferral of error typing and
1671/// the paired trait-idiomatic [`TryFrom<&str>`] axis's unit-error shape —
1672/// the caller picks the diagnostic form appropriate for its use site (a
1673/// future `feira supervisor --estrategia …` arg-parse composes its own
1674/// per-verb "unknown strategy: <arg> — accepted: {…}" message enumerating
1675/// [`RestartStrategy::WIRE_NAMES`]; a future admission-webhook rejection
1676/// body wraps the `Err(())` outcome with the accepted-set enumeration for
1677/// operator diagnostics; a `Result::map_err` at the call site lifts the
1678/// unit-error to a per-verb error type). Two rejection paths route
1679/// through the single unit-error: an invalid UTF-8 byte-sequence
1680/// ([`std::str::from_utf8`] returns `Err`) and a valid UTF-8 byte-string
1681/// that falls outside the four-arm `PascalCase` accept-set
1682/// ([`RestartStrategy::from_wire`] returns `None`) — both collapse onto
1683/// `Err(())` so the trait signature stays consistent with the sibling
1684/// str-view reverse axis, and a caller that needs to distinguish the two
1685/// failure modes composes [`std::str::from_utf8`] +
1686/// [`RestartStrategy::from_wire`] explicitly.
1687///
1688/// Pinned load-bearing by
1689/// [`tests::restart_strategy_try_from_bytes_routes_through_from_wire_accessor`]
1690/// (byte-parity pin against [`RestartStrategy::from_wire`] across the
1691/// four-arm [`RestartStrategy::ALL`] accept-set on the borrowed byte-
1692/// slice surface, plus a cross-axis witness that the byte-view reverse
1693/// projection agrees with the paired [`TryFrom<&str>`] str-view reverse
1694/// axis on every accepted arm) and
1695/// [`tests::restart_strategy_try_from_bytes_rejects_unknown_and_non_utf8_bytes`]
1696/// (rejection witness against silent accept-set widening on both the
1697/// non-UTF-8 byte-sequence rejection path and the unknown-wire-vocabulary
1698/// rejection path — the latter includes the sibling kebab-case
1699/// dispatcher-catalog byte-strings on the two-axis wire/catalog split so
1700/// a caller that confuses the two axes trips here rather than at a
1701/// downstream K8s-CR round-trip miss).
1702impl TryFrom<&[u8]> for RestartStrategy {
1703 type Error = ();
1704
1705 fn try_from(bytes: &[u8]) -> Result<Self, Self::Error> {
1706 std::str::from_utf8(bytes)
1707 .ok()
1708 .and_then(Self::from_wire)
1709 .ok_or(())
1710 }
1711}
1712
1713/// Trait-idiomatic *owned byte-vec input* reverse projection on the first
1714/// M2-OTP-shape supervisor-slot closed-set fieldless typed enum peer on the
1715/// caixa surface ([`RestartStrategy`]) — the owned-input peer of
1716/// [`TryFrom<&[u8]> for RestartStrategy`], mirroring the closed
1717/// [`From<RestartStrategy> for Vec<u8>`] + [`From<&RestartStrategy> for
1718/// Vec<u8>`] byte-owned *forward*-projection pair on this same enum onto
1719/// the byte-owned *reverse*-projection axis. Routes byte-for-byte through
1720/// [`<Self as TryFrom<&[u8]>>::try_from`] on the [`Vec<u8>::as_slice`]
1721/// borrow, so the owned-input surface reaches the same
1722/// [`std::str::from_utf8`] + [`RestartStrategy::from_wire`] resolution
1723/// chain the borrowed-input peer already carries — one substrate-primitive
1724/// accessor, one trait dispatch, no per-consumer detour.
1725///
1726/// Rust's standard library carries no blanket
1727/// `impl<T: for<'a> TryFrom<&'a [u8]>> TryFrom<Vec<u8>> for T`, so a
1728/// consumer that holds an owned [`Vec<u8>`] and needs a typed
1729/// [`RestartStrategy`] otherwise picks between (a) an open-coded
1730/// `<RestartStrategy as TryFrom<&[u8]>>::try_from(bytes.as_slice())` at
1731/// every call site (whose type bounds have no compile-time link to the
1732/// byte-owned reverse-projection axis), (b) a two-hop
1733/// `String::from_utf8(bytes)` + [`RestartStrategy::from_wire`] composition
1734/// whose error surface leaks the standard-library
1735/// [`std::string::FromUtf8Error`] (widening the sibling [`TryFrom<&[u8]>`]
1736/// axis's unit-error) and silently allocates a [`String`] on inputs that
1737/// will never make it past the wire vocabulary, or (c) an intermediate
1738/// `<RestartStrategy as TryFrom<&str>>::try_from(std::str::from_utf8(&bytes)?)`
1739/// three-hop shape. This impl closes the owned-byte-vec reverse-projection
1740/// axis at the substrate-primitive [`RestartStrategy::from_wire`] accessor
1741/// so every future `<T: TryFrom<Vec<u8>>>`-bound owned-byte-vec consumer —
1742/// a future M4 `mesh.pleme.io/v1alpha1/Supervisor` CR admission-webhook
1743/// body reader that hands the `spec.estrategia` byte-tail off as a
1744/// [`Vec<u8>`] before UTF-8 validation commits allocation, a
1745/// `bytes::Bytes::to_vec()`-shape wire-body composer walking a prior
1746/// audit's per-supervisor rejection payload back to the typed enum, a
1747/// `std::io::Read::read_to_end`-shape audit-log source whose framing
1748/// yields an owned byte-vec per per-strategy scalar, an
1749/// `<T: TryFrom<Vec<u8>>>`-bound generic loader over any of the
1750/// substrate's closed-set typed enums — reaches the same four-arm
1751/// `PascalCase` wire accept-set through one trait dispatch.
1752///
1753/// Extends the substrate-wide trait-idiomatic *byte-owned reverse-
1754/// projection* family — opened on the structurally most fundamental
1755/// closed-set fieldless typed enum peer ([`crate::CaixaKind`], commit
1756/// 99c2849), extended onto the second caixa-core-internal peer
1757/// ([`crate::CaixaDialeto`], commit 83a1526) and the third
1758/// ([`crate::dep::DepList`], commit 42091cb) — onto the first M2-OTP-shape
1759/// supervisor-slot closed-set fieldless typed enum peer, tracking the
1760/// "delegate through `TryFrom<&[u8]>` on the `Vec<u8>::as_slice` borrow"
1761/// discipline the first-mover established. Every remaining closed-set
1762/// fieldless typed enum peer on the substrate ([`RestartPolicy`],
1763/// [`crate::aplicacao::PlacementStrategy`],
1764/// [`crate::aplicacao::RateLimitUnit`], [`crate::aplicacao::WitShape`],
1765/// [`crate::render::PathShapeViolation`], and the outside-`caixa-core`
1766/// peers `InvariantKind`, `ArchVerdict`, `Severity`, `FixSafety`,
1767/// `Semantic`, `FerriteRuntime`) is a future target of the campaign,
1768/// mirroring the trajectory the closed byte-view reverse-projection
1769/// family (`TryFrom<&[u8]>`) and the closed byte-owned forward-projection
1770/// family (`From<{Self, &Self}> for Vec<u8>`) already walked.
1771///
1772/// `type Error = ()` matches the sibling [`TryFrom<&[u8]> for
1773/// RestartStrategy`] unit-error shape, preserving the trait-family
1774/// consistency across the borrowed-and-owned byte-view reverse-projection
1775/// pair. The owned [`Vec<u8>`] input is dropped on the error path (the
1776/// standard-library `String::from_utf8` convention of returning the input
1777/// in the error deliberately declined — a caller that needs the bytes
1778/// back holds a clone before the call, and the closed-set-enum use site
1779/// rarely wants the raw bytes back past a "did you mean" diagnostic that
1780/// operates on the wire vocabulary rather than the input).
1781///
1782/// Pinned load-bearing by
1783/// [`tests::restart_strategy_try_from_vec_bytes_routes_through_borrowed_byte_view_axis`]
1784/// (byte-parity pin against the paired borrowed [`TryFrom<&[u8]>`] axis
1785/// across the four-arm [`RestartStrategy::ALL`] accept-set on the owned
1786/// byte-vec surface, cross-axis witness that the byte-owned reverse
1787/// projection agrees with the paired str-view reverse-projection axis
1788/// ([`TryFrom<&str>`]) on every accepted arm through the shared
1789/// substrate-primitive [`RestartStrategy::from_wire`] accessor, and a
1790/// four-corner {owned-input, borrowed-input} × {`From<Self>` → `Vec<u8>`,
1791/// `From<&Self>` → `Vec<u8>`} round-trip witness available on this enum
1792/// because [`RestartStrategy::as_str`] and [`RestartStrategy::from_wire`]
1793/// share one `PascalCase` byte-vocabulary — unlike the sibling
1794/// [`crate::CaixaKind`] which its peer test deliberately declines the
1795/// four-corner witness on because the wire/diagnostic split makes the
1796/// forward and reverse pairs speak different byte-strings) and
1797/// [`tests::restart_strategy_try_from_vec_bytes_rejects_unknown_and_non_utf8_bytes`]
1798/// (rejection witness against silent accept-set widening on both the
1799/// non-UTF-8 byte-sequence rejection path and the unknown-wire-vocabulary
1800/// rejection path — the latter includes the sibling kebab-case
1801/// dispatcher-catalog byte-strings on the two-axis wire/catalog split so
1802/// a caller that confuses the two axes trips here rather than at a
1803/// downstream K8s-CR round-trip miss, plus a cross-axis witness that the
1804/// owned byte-vec reverse-projection axis agrees with the borrowed byte-
1805/// slice reverse-projection axis on every rejected input).
1806impl TryFrom<Vec<u8>> for RestartStrategy {
1807 type Error = ();
1808
1809 fn try_from(bytes: Vec<u8>) -> Result<Self, Self::Error> {
1810 <Self as TryFrom<&[u8]>>::try_from(bytes.as_slice())
1811 }
1812}
1813
1814/// Trait-idiomatic *owned-`String` input, `Result<Self, ()>` output*
1815/// string-owned reverse projection on the first M2-OTP-shape supervisor-slot
1816/// closed-set fieldless typed enum peer on the caixa surface
1817/// ([`RestartStrategy`]) — the owned-input peer of the paired
1818/// [`TryFrom<&str> for RestartStrategy`] str-view reverse-projection axis, and
1819/// the string-owned reverse companion of the pre-existing string-owned
1820/// *forward* pair ([`From<RestartStrategy> for String`],
1821/// [`From<&RestartStrategy> for String`]) already lifted on this same enum.
1822/// Routes owned [`String`] input through the paired borrowed-input
1823/// [`TryFrom<&str>`] axis via [`String::as_str`] so every consumer that holds
1824/// an owned `String` — a future M4 `mesh.pleme.io/v1alpha1/Supervisor` CR
1825/// admission-webhook body reader that hands the `spec.estrategia`
1826/// `PascalCase` scalar off as an owned [`String`] after UTF-8 validation, a
1827/// `serde_yaml::from_str` / `serde_json::from_str` de-serialize round-trip
1828/// whose composer surfaces the `:estrategia` scalar as an owned [`String`]
1829/// typed field, a `feira supervisor --estrategia <OneForOne|OneForAll|
1830/// RestForOne|SimpleOneForOne>` `clap`-derived arg-parse whose owned-`String`
1831/// positional lands the canonical arm at the typed dispatch, a
1832/// per-`:supervisor`-slot overlay resolver reading an owned [`String`] out of
1833/// a `ConfigMap` `data.supervisor-estrategia` scalar, an
1834/// `<T: TryFrom<String>>`-bound generic loader over any of the substrate's
1835/// closed-set typed enums — reaches the same four-arm `PascalCase` accept-set
1836/// through one trait dispatch.
1837///
1838/// Extends the substrate-wide trait-idiomatic *string-owned reverse-
1839/// projection* family — opened on the compound M3-mesh
1840/// `:politicas :rate-limit` primitive [`crate::aplicacao::RateLimit`]
1841/// (a2e6f02), lifted onto the first closed-set fieldless typed-enum peer
1842/// [`crate::aplicacao::WitShape`] (e6aac29), extended onto the second closed-
1843/// set fieldless typed-enum peer [`crate::aplicacao::RateLimitUnit`]
1844/// (94a9c5e), extended onto the third closed-set fieldless typed-enum peer
1845/// [`crate::aplicacao::PlacementStrategy`] (d81a70a) — onto the first
1846/// M2-OTP-shape supervisor-slot closed-set fieldless typed-enum peer, the
1847/// per-`:supervisor` sibling-restart-strategy discriminator. The peers
1848/// [`RestartPolicy`], [`crate::CaixaKind`], [`crate::CaixaDialeto`], and
1849/// [`crate::dep::DepList`] remain the next targets of the campaign, mirroring
1850/// the trajectory the closed byte-view / byte-owned reverse-projection
1851/// families already walked across the same closed-set peers.
1852///
1853/// Rust's standard library carries no blanket
1854/// `impl<T: for<'a> TryFrom<&'a str>> TryFrom<String> for T`, so a consumer
1855/// that holds an owned [`String`] and needs a typed [`RestartStrategy`]
1856/// otherwise picks between (a) an open-coded
1857/// `<RestartStrategy as TryFrom<&str>>::try_from(s.as_str())` at every call
1858/// site whose type bounds have no compile-time link back to the string-owned
1859/// reverse-projection axis, (b) a `let s: &str = &s;
1860/// RestartStrategy::try_from(s)` two-step whose borrow arithmetic leaks a
1861/// per-call-site lifetime dance rather than a single trait dispatch, or (c) a
1862/// `String::into_bytes` + [`TryFrom<Vec<u8>>`] detour that reaches the
1863/// substrate-primitive `from_wire` accessor through a UTF-8 re-validation hop
1864/// the owned-`String` axis already knows to skip. This impl closes the
1865/// string-owned reverse-projection axis at the substrate-primitive
1866/// [`RestartStrategy::from_wire`] accessor so every future
1867/// `<T: TryFrom<String>>`-bound owned-string consumer reaches the same
1868/// four-arm `PascalCase` accept-set through one trait dispatch.
1869///
1870/// `type Error = ()` matches the sibling [`TryFrom<&str> for
1871/// RestartStrategy`], [`TryFrom<&[u8]> for RestartStrategy`], and
1872/// [`TryFrom<Vec<u8>> for RestartStrategy`] unit-error shapes, preserving the
1873/// trait-family consistency across the {str-view, byte-view, byte-owned,
1874/// string-owned} reverse-projection square. The owned [`String`] input is
1875/// dropped on the error path (the standard-library `String::from_utf8`
1876/// convention of returning the input in the error deliberately declined — a
1877/// caller that needs the string back holds a clone before the call, and the
1878/// closed-set-enum use site rarely wants the raw string back past a "did you
1879/// mean" diagnostic that operates on the wire vocabulary rather than the
1880/// input).
1881///
1882/// Pinned load-bearing by
1883/// [`tests::restart_strategy_try_from_owned_string_routes_through_borrowed_str_view_axis`]
1884/// (byte-parity pin against the paired borrowed [`TryFrom<&str>`] axis across
1885/// the four-arm [`RestartStrategy::ALL`] accept-set on the owned-`String`
1886/// surface, cross-axis witness that the string-owned reverse projection
1887/// agrees with the sibling byte-view / byte-owned reverse-projection axes on
1888/// every accepted arm through the shared substrate-primitive
1889/// [`RestartStrategy::from_wire`] accessor, and a closed-cycle witness
1890/// against the paired string-owned forward-projection pair — `Self → String
1891/// → TryFrom<String> → Self` round-trips to the originating arm on every
1892/// canonical `PascalCase` scalar) and
1893/// [`tests::restart_strategy_try_from_owned_string_rejects_unknown_wire_strings`]
1894/// (rejection witness against silent accept-set widening — mirrors the
1895/// corpus the paired [`TryFrom<&str>`] rejection witness already pins,
1896/// including empty / whitespace-only inputs, the sibling kebab-case
1897/// dispatcher-catalog byte-strings on the two-axis wire/catalog split so a
1898/// caller that confuses the two axes trips here rather than at a downstream
1899/// K8s-CR round-trip miss, case-fold rebrand candidates, whitespace-padded /
1900/// trailing-newline / quote-wrapped forms, and English-rebrand candidates,
1901/// with per-input cross-axis parity against the borrowed [`TryFrom<&str>`]
1902/// reverse-projection axis).
1903impl TryFrom<String> for RestartStrategy {
1904 type Error = ();
1905
1906 fn try_from(s: String) -> Result<Self, Self::Error> {
1907 <Self as TryFrom<&str>>::try_from(s.as_str())
1908 }
1909}
1910
1911/// Per-child restart policy.
1912///
1913/// Permanent / Temporary / Transient match Erlang/OTP semantics 1:1.
1914#[derive(
1915 Serialize,
1916 Deserialize,
1917 Debug,
1918 Clone,
1919 Copy,
1920 PartialEq,
1921 Eq,
1922 Hash,
1923 gen_platform::TypedDispatcher,
1924 gen_platform::Discriminant,
1925 gen_platform::IsVariant,
1926 gen_platform::FromStrKind,
1927)]
1928pub enum RestartPolicy {
1929 /// Always restart the child, regardless of how it died. Used for
1930 /// long-running services that must always be up.
1931 Permanent,
1932 /// Never restart. Used for one-shot work whose completion is
1933 /// itself the success signal (`oneShot` triggers map here).
1934 Temporary,
1935 /// Restart only when the child died *abnormally* (non-zero exit
1936 /// or unhandled exception). A clean exit completes the child.
1937 Transient,
1938}
1939
1940impl Default for RestartPolicy {
1941 fn default() -> Self {
1942 // Route the [`Default for RestartPolicy`] impl's return arm through
1943 // the substrate-canonical [`SUPERVISOR_CHILD_RESTART_DEFAULT`] typed
1944 // `pub const` rather than a raw `Self::Permanent` arm — one source
1945 // of truth for the Erlang/OTP-canonical `permanent` worker-child
1946 // default across the two production consumers that currently
1947 // dispatch on it (this impl at the [`RestartPolicy::default`] call
1948 // and the serde-side `#[serde(default)]` on
1949 // [`ChildSpec::restart`] that resolves an author-omitted
1950 // `:children :restart` slot through `RestartPolicy::default()`).
1951 // Peer of the sibling per-`:supervisor` axis
1952 // [`Default for RestartStrategy`] → [`SUPERVISOR_ESTRATEGIA_DEFAULT`]
1953 // route (95ffacc) — the two impls now share one substrate-primitive
1954 // lift discipline, so any future coherent rebrand of the OTP-shape
1955 // supervisor+child default set migrates through typed constants in
1956 // lockstep instead of splitting a lifted supervisor half against
1957 // an open-coded child half. Pinned by
1958 // `restart_policy_default_routes_through_lifted_default` +
1959 // `child_spec_serde_default_restart_routes_through_lifted_default`
1960 // in the tests module.
1961 SUPERVISOR_CHILD_RESTART_DEFAULT
1962 }
1963}
1964
1965impl RestartPolicy {
1966 /// Exhaustive iteration surface for every consumer that walks the
1967 /// closed three-arm [`RestartPolicy`] discriminator set (the future
1968 /// M4 `mesh.pleme.io/v1alpha1/Supervisor` CR materializer's
1969 /// per-child admission-webhook rejection body naming the accepted-
1970 /// `:restart` list, a future `feira supervisor --restart …` CLI
1971 /// arg-parse's "did you mean" hint via a [`Self::from_wire`]-scan
1972 /// over the slice, the future `feira app graph` per-child restart
1973 /// column, any future round-trip fuzz harness that sweeps every
1974 /// arm). A future arm addition (an OTP-`intrinsic` fourth arm the
1975 /// theory
1976 /// [`ABSORPTION-ROADMAP`](https://github.com/pleme-io/theory/blob/main/ABSORPTION-ROADMAP.md)
1977 /// might reach for once the three canonical OTP restart policies
1978 /// stop covering the substrate's discovered load-shape) extends
1979 /// this slice as one edit and every consumer picks up the new entry
1980 /// by construction; the compiler-checked exhaustiveness on the
1981 /// sibling method `match` arms ([`Self::as_str`] / [`Self::from_wire`])
1982 /// is the build-time guarantee that no arm forgets to grow.
1983 ///
1984 /// Peer of the sibling closed-set typed enums'
1985 /// [`RestartStrategy::ALL`] (4eec29c) /
1986 /// [`crate::CaixaKind::ALL`] (6b1f4fb) /
1987 /// [`crate::aplicacao::PlacementStrategy::ALL`] (18c7342) /
1988 /// [`crate::aplicacao::RateLimitUnit::ALL`] (6bce03d) /
1989 /// [`crate::dep::DepList::ALL`] (45ee563) exhaustive-iteration
1990 /// surfaces — the sixth (and the third and final M2 OTP-shape)
1991 /// closed-set typed enum on the caixa surface to converge onto the
1992 /// same one-canonical-arm-list-per-enum discipline. Sibling axis to
1993 /// the peer [`RestartStrategy::ALL`] on the per-supervisor
1994 /// sibling-restart-strategy axis; this closes the per-child
1995 /// restart-decision-policy axis on the same M2 `:supervisor` slot.
1996 pub const ALL: &'static [Self] = &[Self::Permanent, Self::Temporary, Self::Transient];
1997
1998 /// Substrate-canonical exhaustive accept-set on the [`RestartPolicy`]
1999 /// `PascalCase` wire byte-string axis — the closed three-arm roster
2000 /// of every byte-string [`Self::as_str`] returns, routed byte-for-byte
2001 /// through the paired
2002 /// [`crate::render::SUPERVISOR_CHILD_RESTART_PERMANENT`] /
2003 /// [`crate::render::SUPERVISOR_CHILD_RESTART_TEMPORARY`] /
2004 /// [`crate::render::SUPERVISOR_CHILD_RESTART_TRANSIENT`] lifted
2005 /// `pub const` roster the [`Self::as_str`] emitter (and the
2006 /// [`std::fmt::Display`] impl / `Serialize` derive routed through it)
2007 /// walks — and byte-for-byte the same three strings the un-`rename`d
2008 /// `Serialize` derive emits under the paired
2009 /// [`crate::render::SUPERVISOR_CHILD_KEY_RESTART`] tag key on every
2010 /// JSON / YAML CR round-trip.
2011 ///
2012 /// Peer of the sibling [`crate::CaixaKind::WIRE_NAMES`] (bd708bd)
2013 /// roster on the top-level typed-kind discriminator's `PascalCase`
2014 /// wire byte-string axis, the sibling
2015 /// [`RestartStrategy::WIRE_NAMES`] (3033f45) roster on the per-
2016 /// supervisor sibling-restart-strategy axis (the first M2 OTP-shape
2017 /// closed-set typed enum to converge onto the paired-roster
2018 /// discipline), the sibling
2019 /// [`crate::aplicacao::PlacementStrategy::WIRE_NAMES`] (3e5b194)
2020 /// roster on the first M3 mesh-shape distribution-strategy closed-
2021 /// set typed enum, and the sibling
2022 /// [`crate::upgrade::UpgradeInstruction::WIRE_FORMS`] (cc42c0e) /
2023 /// [`crate::upgrade::UpgradeInstruction::LISP_FORMS`] (1898d77)
2024 /// rosters on the OTP-appup discriminator's two-axis roster split —
2025 /// the same closed-set exhaustive-accept-set roster discipline
2026 /// extended here onto the second and final M2 OTP-shape sibling-
2027 /// enum on the caixa surface, closing the per-child restart-decision-
2028 /// policy axis paired with the peer [`RestartStrategy::WIRE_NAMES`]
2029 /// per-supervisor sibling-restart-strategy axis on the same M2
2030 /// `:supervisor` slot.
2031 ///
2032 /// Downstream consumers of the closed accepted-wire-form set — a
2033 /// future M4 `mesh.pleme.io/v1alpha1/Supervisor` CR admission-
2034 /// webhook rejection body enumerating the accepted JSON `:restart`
2035 /// values verbatim (as distinct from the kebab-case dispatcher-
2036 /// catalog enumeration [`Self::discriminant`] serves, whose per-arm
2037 /// form `"permanent"` / `"temporary"` / `"transient"` structurally
2038 /// disagrees with the wire byte-string these `PascalCase` entries
2039 /// carry — the split the sibling
2040 /// [`tests::restart_policy_display_matches_serialized_wire_byte_string`]
2041 /// pin already makes load-bearing), a future `feira supervisor
2042 /// --restart …` CLI-side "did you mean" hint whose candidate-list
2043 /// must byte-match the wire form the operator's per-child dispatch
2044 /// keys off, a future `feira app graph` per-child `:restart`-
2045 /// histogram column that renders zero-count arms, a future
2046 /// `caixa-operator` per-reconcile-step diagnostic log line
2047 /// enumerating accepted wire forms on an unknown-policy rejection,
2048 /// a future
2049 /// `tracing::field::valuable::Value::List` structured-log accepted-
2050 /// wire-form emit — now reach for one lifted substrate-primitive
2051 /// roster rather than open-coding a three-string array-literal
2052 /// (`["Permanent", "Temporary", "Transient"]`) whose arm-set has no
2053 /// compile-time link back to the typed [`RestartPolicy`] enum. A
2054 /// future arm addition (an OTP-`intrinsic` fourth arm the theory
2055 /// [`ABSORPTION-ROADMAP`](https://github.com/pleme-io/theory/blob/main/ABSORPTION-ROADMAP.md)
2056 /// might reach for once the three canonical OTP restart policies
2057 /// stop covering the substrate's discovered load-shape) extends
2058 /// this roster as a single edit — paired with the [`Self::as_str`]
2059 /// match's compiler-checked exhaustiveness on the new arm — and
2060 /// every consumer picks up the new wire form by construction rather
2061 /// than a coordinated array-literal rewrite across every downstream
2062 /// site.
2063 ///
2064 /// Length is pinned load-bearing at `RestartPolicy::ALL.len()`
2065 /// (three) by
2066 /// [`tests::restart_policy_wire_names_covers_every_arm`], every
2067 /// variant's [`Self::as_str`] projection is pinned to a member of
2068 /// the roster so a silent skew between the emitter's arm-set and
2069 /// this const's arm-set trips at caixa-core test time rather than at
2070 /// a downstream consumer's accepted-set enumeration miss, and every
2071 /// entry is further pinned to open with an ASCII uppercase byte so
2072 /// a silent collapse of the `PascalCase` wire-form axis with the
2073 /// peer kebab-case dispatcher-catalog axis (an entry byte-identical
2074 /// to a sibling [`Self::discriminant`] kebab byte-string that would
2075 /// let a wire-axis consumer accept the dispatcher-catalog
2076 /// vocabulary) trips here rather than at a downstream K8s-CR round-
2077 /// trip miss.
2078 pub const WIRE_NAMES: &'static [&'static str] = &[
2079 crate::render::SUPERVISOR_CHILD_RESTART_PERMANENT,
2080 crate::render::SUPERVISOR_CHILD_RESTART_TEMPORARY,
2081 crate::render::SUPERVISOR_CHILD_RESTART_TRANSIENT,
2082 ];
2083
2084 /// Canonical PascalCase discriminator scalar this variant serializes
2085 /// as under [`crate::render::SUPERVISOR_CHILD_KEY_RESTART`]. The three
2086 /// arms return the paired
2087 /// [`crate::render::SUPERVISOR_CHILD_RESTART_PERMANENT`] /
2088 /// [`crate::render::SUPERVISOR_CHILD_RESTART_TEMPORARY`] /
2089 /// [`crate::render::SUPERVISOR_CHILD_RESTART_TRANSIENT`] lifted
2090 /// constants so every substrate consumer that dispatches on the
2091 /// per-child restart-decision policy (the future wasm-operator's
2092 /// per-child post-exit restart-decision branch, the future M4
2093 /// `mesh.pleme.io/v1alpha1/Supervisor` CR materializer's
2094 /// admission-time enum-arm bind, the `caixa-operator`'s hierarchical
2095 /// reconciliation scheduler's per-child-policy fan-out) reads the
2096 /// same byte-string the `Serialize` derive emits — the pin test in
2097 /// [`tests::restart_policy_variants_serialize_to_lifted_scalar_values`]
2098 /// asserts the two paths agree, peer of the M2
2099 /// [`RestartStrategy::as_str`] (09ffb2d) on the sibling per-supervisor
2100 /// sibling-restart-strategy axis and the M3
2101 /// [`crate::aplicacao::PlacementStrategy::as_str`] (cc8f749) on the
2102 /// per-Aplicacao distribution-strategy axis — the third of three
2103 /// OTP-shaped closed-enum discriminator axes on the caixa typed
2104 /// surface to converge onto the same three-path-convergence
2105 /// (`Serialize` derive → `as_str` helper → lifted constant)
2106 /// drift-detection posture.
2107 #[must_use]
2108 pub const fn as_str(self) -> &'static str {
2109 match self {
2110 Self::Permanent => crate::render::SUPERVISOR_CHILD_RESTART_PERMANENT,
2111 Self::Temporary => crate::render::SUPERVISOR_CHILD_RESTART_TEMPORARY,
2112 Self::Transient => crate::render::SUPERVISOR_CHILD_RESTART_TRANSIENT,
2113 }
2114 }
2115
2116 /// Substrate-canonical reverse projection on the `:children :restart`
2117 /// closed-set axis — parses the `PascalCase` discriminator scalar
2118 /// back to the typed variant, or `None` when `s` is outside the
2119 /// closed-set arm-string set [`Self::as_str`] emits. Dispatches on
2120 /// the same lifted
2121 /// [`crate::render::SUPERVISOR_CHILD_RESTART_PERMANENT`] /
2122 /// [`crate::render::SUPERVISOR_CHILD_RESTART_TEMPORARY`] /
2123 /// [`crate::render::SUPERVISOR_CHILD_RESTART_TRANSIENT`] constants
2124 /// the [`Self::as_str`] emitter walks, so the parse and emit halves
2125 /// of the round-trip migrate through one caixa-core edit on any
2126 /// future arm addition.
2127 ///
2128 /// Prior to this lift the substrate carried only the forward
2129 /// `Self → &str` projection on the OTP per-child restart-policy
2130 /// axis (the [`Self::as_str`] emitter, the [`std::fmt::Display`]
2131 /// impl routed through it, the `Serialize` derive that emits the
2132 /// same byte-string under [`crate::render::SUPERVISOR_CHILD_KEY_RESTART`])
2133 /// plus the kebab-case dispatcher-catalog identity via
2134 /// [`Self::discriminant`] — every non-serde consumer that wanted to
2135 /// parse a wire-form `PascalCase` policy scalar had to re-inline a
2136 /// three-arm `match s { "Permanent" => …, "Temporary" => …,
2137 /// "Transient" => …, _ => … }` cascade that expressed no
2138 /// compile-time link back to the typed variant's canonical lifted
2139 /// constant. A future variant rename or per-arm serde-attribute
2140 /// drift would silently split the wire byte-string one non-serde
2141 /// consumer parsed from the one the emitter wrote, with the failure
2142 /// surfacing at the operator's reconcile posture (a `:temporary`
2143 /// `oneShot` child being restarted on clean exit, treating the
2144 /// successful-completion signal as failure and re-running the
2145 /// completion-terminal one-shot indefinitely; a `:transient` child
2146 /// that clean-exited being restarted, masking the clean-completion
2147 /// contract) far from the rebrand commit and with no field naming
2148 /// the drift.
2149 ///
2150 /// Distinct axis from the [`std::str::FromStr`] impl the
2151 /// [`gen_platform::FromStrKind`] derive already installs on this
2152 /// enum by design, not by drift: `FromStr` parses the *kebab-case*
2153 /// dispatcher-catalog identity (`"permanent"` / `"temporary"` /
2154 /// `"transient"` — the inverse of [`Self::discriminant`]), while
2155 /// this method inverts the `PascalCase` wire byte-string
2156 /// [`Self::as_str`] emits. The two-axis split lets the dispatcher-
2157 /// catalog identity live in kebab-case (where every peer catalog
2158 /// identifier already lives) without forcing a wire-format rename
2159 /// on the tatara-lisp author surface (`:restart Permanent`,
2160 /// `PascalCase`) — the same two-axis distinction the sibling
2161 /// [`RestartStrategy::from_wire`] (4eec29c) /
2162 /// [`crate::CaixaKind::from_wire`] (2aa6d23) /
2163 /// [`crate::aplicacao::PlacementStrategy::from_wire`] (18c7342)
2164 /// carry on their peer closed-set typed-enum wire round-trips.
2165 ///
2166 /// Same closed-set-reverse-projection discipline the sibling
2167 /// [`RestartStrategy::from_wire`] (4eec29c) /
2168 /// [`crate::CaixaKind::from_wire`] (2aa6d23) /
2169 /// [`crate::aplicacao::PlacementStrategy::from_wire`] (18c7342) /
2170 /// [`crate::aplicacao::RateLimitUnit::from_suffix`] typed enums
2171 /// carry on the peer wire-side `str → Self` axes — extended onto
2172 /// the M2 OTP-shape per-child restart-policy closed-set axis, the
2173 /// sixth substrate-side closed-set typed enum (and the third and
2174 /// final OTP-shape closed-enum discriminator axis) to converge on
2175 /// the two-way `str ↔ Self` round-trip. Method-named `from_wire`
2176 /// (not `from_str`) to match the peer [`RestartStrategy::from_wire`]
2177 /// shape verbatim and side-step the [`std::str::FromStr`] impl the
2178 /// derive already installs on the sibling kebab-case axis. Returns
2179 /// `Option<Self>` (rather than `Result<Self, _>`) to match the peer
2180 /// shapes: the caller picks the diagnostic form appropriate for
2181 /// its use site.
2182 #[must_use]
2183 pub fn from_wire(s: &str) -> Option<Self> {
2184 match s {
2185 crate::render::SUPERVISOR_CHILD_RESTART_PERMANENT => Some(Self::Permanent),
2186 crate::render::SUPERVISOR_CHILD_RESTART_TEMPORARY => Some(Self::Temporary),
2187 crate::render::SUPERVISOR_CHILD_RESTART_TRANSIENT => Some(Self::Transient),
2188 _ => None,
2189 }
2190 }
2191}
2192
2193/// [`std::fmt::Display`] routed through [`RestartPolicy::as_str`], so the
2194/// pretty-printed byte-string every consumer that formats the policy as
2195/// user-facing text lands on (the future wasm-operator's per-child
2196/// post-exit restart-decision diagnostic line, the future `feira app
2197/// graph` per-child restart column, the future M4
2198/// `mesh.pleme.io/v1alpha1/Supervisor` CR materializer's per-child
2199/// admission-webhook rejection body) reaches for the same lifted
2200/// [`crate::render::SUPERVISOR_CHILD_RESTART_PERMANENT`] /
2201/// [`crate::render::SUPERVISOR_CHILD_RESTART_TEMPORARY`] /
2202/// [`crate::render::SUPERVISOR_CHILD_RESTART_TRANSIENT`] const the
2203/// wire-format `Serialize` derive already emits under
2204/// [`crate::render::SUPERVISOR_CHILD_KEY_RESTART`] and the
2205/// [`RestartPolicy::as_str`] helper already returns.
2206///
2207/// Pre-convergence the two paths structurally disagreed — the
2208/// `#[derive(gen_platform::Discriminant)]` + `#[discriminant(also_display)]`
2209/// route (now retired here) sent [`std::fmt::Display`] through the
2210/// gen-platform discriminant catalog string, which arrives kebab-case as
2211/// `"permanent"` / `"temporary"` / `"transient"` on this three-arm enum
2212/// (whose variant names each collapse to their own lowercase form under
2213/// the kebab-case transform), while the wire format ran as `PascalCase`
2214/// `"Permanent"` / `"Temporary"` / `"Transient"` through the un-`rename`d
2215/// serde derive. Every consumer that formatted the policy for a
2216/// diagnostic line, a graph column, or a rejection body under
2217/// `format!("{v}")` therefore landed under a different byte-string than
2218/// the wire format the operator's per-child-policy dispatch keyed off —
2219/// a silent split whose apply-time symptom (a `format!("{v}")`-carrying
2220/// diagnostic quoting `"permanent"` while the wire scalar the operator
2221/// probed was `"Permanent"`) surfaced as a confused correlate at
2222/// operator-log time far from the two-declaration site.
2223///
2224/// Routing `Display` through [`RestartPolicy::as_str`] closes the third
2225/// path: every `format!("{v}")` call reaches the same lifted
2226/// [`crate::render::SUPERVISOR_CHILD_RESTART_*`] const the wire format
2227/// and the [`RestartPolicy::as_str`] helper route through — `Debug` (the
2228/// compiler-derived variant name), `Display` (via `as_str`), and `Serialize`
2229/// (via the un-`rename`d derive) all resolve to the same `PascalCase`
2230/// byte-string per variant. A future variant rename or
2231/// `#[serde(rename_all = "kebab-case")]` attribute reaches every path at
2232/// exactly one place, structurally.
2233///
2234/// The dispatcher-catalog identity remains kebab-case — [`Self::discriminant`]
2235/// (from `#[derive(gen_platform::Discriminant)]`) still returns
2236/// `"permanent"` / `"temporary"` / `"transient"`, and the fleet-wide
2237/// [`gen_platform::register_dispatcher!("caixa.restart-policy", …)`]
2238/// registration keys the catalog off the same kebab identity. The two
2239/// naming worlds now live on separate typed methods (`Display` /
2240/// `as_str` for the wire byte-string, `discriminant` for the catalog
2241/// identity) rather than sharing one `Display` route that structurally
2242/// disagrees with the wire format.
2243///
2244/// Pin tests
2245/// [`tests::restart_policy_display_routes_through_as_str_helper`]
2246/// and
2247/// [`tests::restart_policy_display_matches_serialized_wire_byte_string`]
2248/// assert the three paths agree byte-for-byte on every variant, so a
2249/// future variant rename or per-arm serde attribute drift is a build
2250/// error visible at caixa-core test time, not a silent per-consumer
2251/// dispatch miss at apply / reconcile time.
2252///
2253/// Mirrors the M3 [`crate::aplicacao::PlacementStrategy`] `Display` impl
2254/// (aplicacao.rs:2306) on the per-Aplicacao distribution-strategy axis
2255/// and the sibling [`RestartStrategy`] `Display` impl on the
2256/// per-supervisor sibling-restart-strategy axis — same three-path-
2257/// convergence discipline, extended to close the third and final of
2258/// three OTP-shaped closed-enum discriminator axes on the caixa typed
2259/// surface.
2260impl std::fmt::Display for RestartPolicy {
2261 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
2262 f.write_str(self.as_str())
2263 }
2264}
2265
2266/// Substrate-canonical [`AsRef<str>`] projection on the M2
2267/// per-child-restart-policy [`RestartPolicy`] closed-set typed enum —
2268/// routes through the same [`RestartPolicy::as_str`] `pub const fn`
2269/// scalar accessor the paired [`std::fmt::Display`] impl and the
2270/// un-`rename`d [`serde::Serialize`] derive already key off, so any
2271/// future consumer that binds a [`RestartPolicy`] through the
2272/// standard-library `impl AsRef<str>` bound (a future
2273/// [`caixa-feira`] `feira supervisor --restart <arm>` verb that
2274/// composes the emitted `PascalCase` wire scalar into a
2275/// [`std::process::Command::arg`] shell-out of the future
2276/// wasm-operator's per-child admission gate, a per-child structured-
2277/// log recorder on the future `caixa-operator`'s hierarchical
2278/// reconciliation surface that accepts `impl AsRef<str>` at the
2279/// `tracing::field::Value` `Str`-arm, a [`std::collections::HashMap`]
2280/// lookup keyed on the restart-policy wire byte through
2281/// `map.get::<str>(policy.as_ref())` on a future per-policy
2282/// dispatch table) reaches the paired
2283/// [`crate::render::SUPERVISOR_CHILD_RESTART_PERMANENT`] /
2284/// [`crate::render::SUPERVISOR_CHILD_RESTART_TEMPORARY`] /
2285/// [`crate::render::SUPERVISOR_CHILD_RESTART_TRANSIENT`]
2286/// lifted-const through one substrate-primitive dispatch rather
2287/// than an open-coded `.as_str()` projection at every wire-up.
2288///
2289/// Peer of the sibling [`std::fmt::Display`] impl on the same
2290/// primitive — both delegate to the shared [`RestartPolicy::as_str`]
2291/// `pub const fn` accessor, so [`format!("{v}")`], `v.as_str()`, and
2292/// `<RestartPolicy as AsRef<str>>::as_ref(&v)` resolve to the same
2293/// byte-string per instance by construction. A future variant rename
2294/// or `#[serde(rename_all = "kebab-case")]` attribute-drift on the
2295/// enum reaches every one of the three paths (plus the wire-format
2296/// `Serialize` derive that already routes through the same lifted
2297/// const) through exactly one caixa-core edit.
2298///
2299/// Same "route the trait impl through the substrate-primitive
2300/// accessor" discipline the sibling [`crate::CaixaVersion`]
2301/// [`AsRef<str>`] impl (16d5c7e) and the paired M2
2302/// [`RestartStrategy`] [`AsRef<str>`] impl (63eb1a4) carry — extends
2303/// the axis onto the paired per-child-restart-decision-policy
2304/// sibling on the same M2 `:supervisor` slot (the second M2
2305/// OTP-shape closed-set typed enum to converge onto the standard-
2306/// library [`AsRef<str>`] projection). Rust-side newtype/typed-enum
2307/// convention pairs [`AsRef<str>`] and [`fmt::Display`] on the same
2308/// primitive so a caller who has one has both; before this lift,
2309/// [`RestartPolicy`] carried [`fmt::Display`] but not the paired
2310/// [`AsRef<str>`] impl the convention names.
2311///
2312/// Pinned load-bearing by
2313/// [`tests::restart_policy_as_ref_str_routes_through_as_str_accessor`]
2314/// (byte-parity pin against [`RestartPolicy::as_str`] across the
2315/// three-arm closed set) and
2316/// [`tests::restart_policy_as_ref_str_routes_through_display_via_shared_accessor`]
2317/// (three-path convergence: `AsRef<str>` + `Display` + `as_str` all
2318/// resolve to the same lifted `SUPERVISOR_CHILD_RESTART_*` const per
2319/// arm) — any future silent detour that routes the impl through a
2320/// divergent projection (a per-arm inline `match self { … }`
2321/// re-inlining that opens a compile-time link to the un-lifted
2322/// arm-literal, a swap onto the kebab-case
2323/// [`gen_platform::Discriminant`] catalog identity that would
2324/// collide the wire axis with the dispatcher-catalog axis) trips at
2325/// caixa-core test time under `assert_eq!` rather than at a
2326/// downstream `impl AsRef<str>`-bound consumer's silent split.
2327impl AsRef<str> for RestartPolicy {
2328 fn as_ref(&self) -> &str {
2329 self.as_str()
2330 }
2331}
2332
2333/// Trait-idiomatic reverse projection on the M2-OTP-shape per-child
2334/// restart-policy [`RestartPolicy`] closed-set typed enum — routes
2335/// byte-for-byte through the paired substrate-primitive
2336/// [`RestartPolicy::from_wire`] `Option<Self>` accessor so every future
2337/// consumer that binds a `PascalCase` `:children :restart` wire
2338/// byte-string through the standard-library `.try_into()` / [`TryFrom`]
2339/// axis (a future [`caixa-feira`] `feira supervisor --restart
2340/// <Permanent|Temporary|Transient>` CLI arg-parse that composes into
2341/// `let restart: RestartPolicy = s.try_into()?`, a future
2342/// `mesh.pleme.io/v1alpha1/Supervisor` CR admission-webhook that folds a
2343/// `spec.children[*].restart: String` field through
2344/// `RestartPolicy::try_from(&s)?`, a generic
2345/// `<T: TryFrom<&str>>`-bound loader over any of the substrate's closed-
2346/// set typed enums) reaches the same three-arm accept-set the sibling
2347/// [`RestartPolicy::from_wire`] resolver parses through and the sibling
2348/// [`RestartPolicy::as_str`] emits, rather than an open-coded per-arm
2349/// `match s { "Permanent" => …, "Temporary" => …, "Transient" => …, _ =>
2350/// … }` cascade whose arm-set has no compile-time link back to the
2351/// substrate primitive.
2352///
2353/// Complements the pre-existing forward-projection triple
2354/// ([`std::fmt::Display`], [`AsRef<str>`], [`RestartPolicy::as_str`])
2355/// with the paired trait-idiomatic reverse-projection axis: Rust-side
2356/// newtype/typed-enum convention pairs [`AsRef<str>`] with either
2357/// [`std::str::FromStr`] or [`TryFrom<&str>`] on the same primitive so a
2358/// caller who can project *out to* a `&str` can also project *in from*
2359/// one. The [`TryFrom<&str>`] axis is deliberately chosen over
2360/// [`std::str::FromStr`] to sidestep the `clippy::should_implement_trait`
2361/// lint the sibling method-named [`RestartPolicy::from_wire`] would
2362/// trigger under a `FromStr` impl and to avoid colliding with the
2363/// [`std::str::FromStr`] impl the [`gen_platform::FromStrKind`] derive
2364/// already installs on the paired *kebab-case dispatcher-catalog* axis
2365/// (which parses `"permanent"` / `"temporary"` / `"transient"`, the
2366/// inverse of [`Self::discriminant`]) — this impl closes the trait-
2367/// idiomatic reverse axis on the *`PascalCase` wire* half without
2368/// disturbing either the method-named `from_wire` shape every sibling
2369/// closed-set typed enum on the substrate already carries or the
2370/// pre-existing `FromStr` on the dispatcher-catalog half, keeping the
2371/// two-axis split the sibling [`Self::from_wire`] doc block motivates.
2372///
2373/// `type Error = ()` matches the sibling [`RestartPolicy::from_wire`]'s
2374/// `Option<Self>` return-shape's deliberate deferral of error typing: the
2375/// caller picks the diagnostic form appropriate for its use site (a
2376/// future `feira supervisor --restart` arg-parse composes its own
2377/// per-verb "unknown restart: <arg> — accepted: {…}" message enumerating
2378/// [`RestartPolicy::ALL`], a future M4 admission-webhook rejection body
2379/// wraps the `Err(())` outcome with the accepted-set enumeration for
2380/// operator diagnostics, a `Result::map_err` at the call site lifts the
2381/// unit-error to a per-verb error type). Same shape the peer
2382/// [`RestartStrategy`] (5b828ed) on the sibling per-supervisor axis,
2383/// [`crate::CaixaKind`] (3c83606), [`crate::CaixaDialeto`] (bf33136), and
2384/// [`crate::aplicacao::PlacementStrategy`] (6fd00cd) blocks motivate on
2385/// their peer closed-set typed enums' reverse projections.
2386///
2387/// The paired [`TryFrom<&str>`] impl reaches the same three-arm accept-
2388/// set the [`RestartPolicy::from_wire`] resolver dispatches through, so
2389/// any future arm addition (an OTP-`intrinsic` fourth arm the theory
2390/// [`ABSORPTION-ROADMAP`](https://github.com/pleme-io/theory/blob/main/ABSORPTION-ROADMAP.md)
2391/// might reach for once the three canonical OTP restart policies stop
2392/// covering the substrate's discovered load-shape) grows the trait-
2393/// idiomatic axis by construction — one caixa-core edit on
2394/// [`RestartPolicy::from_wire`] extends both the method-named reverse
2395/// projection every existing consumer keys off and the trait-idiomatic
2396/// reverse projection this impl exposes, without a coordinated rewrite
2397/// across every future `TryFrom<&str>`-bound consumer's arm-set.
2398///
2399/// Extends the substrate-wide closed-set-enum reverse-projection family
2400/// ([`crate::CaixaKind`] via 3c83606, [`crate::CaixaDialeto`] via
2401/// bf33136, [`crate::aplicacao::PlacementStrategy`] via 6fd00cd, and
2402/// [`RestartStrategy`] via 5b828ed) onto the third and final OTP-shape
2403/// closed-enum discriminator axis on the caixa surface — the paired
2404/// per-child `:children :restart` closed set the future wasm-operator's
2405/// hierarchical reconciliation scheduler's per-child post-exit
2406/// restart-decision branch keys off end-to-end.
2407///
2408/// Pinned load-bearing by
2409/// [`tests::restart_policy_try_from_str_routes_through_from_wire_accessor`]
2410/// (byte-parity pin against [`RestartPolicy::from_wire`] across the
2411/// three-arm accept-set),
2412/// [`tests::restart_policy_try_from_str_rejects_unknown_byte_strings`]
2413/// (rejection witness against silent accept-set widening), and
2414/// [`tests::restart_policy_try_from_str_and_from_wire_partition_the_accept_set`]
2415/// (cross-axis partition pin locking the trait and method-named
2416/// projections onto one accept-set).
2417impl TryFrom<&str> for RestartPolicy {
2418 type Error = ();
2419
2420 fn try_from(s: &str) -> Result<Self, Self::Error> {
2421 Self::from_wire(s).ok_or(())
2422 }
2423}
2424
2425/// Trait-idiomatic forward projection on the M2-OTP-shape per-child
2426/// restart-policy [`RestartPolicy`] closed-set typed enum — routes
2427/// byte-for-byte through the paired substrate-primitive
2428/// [`RestartPolicy::as_str`] `pub const fn` accessor. Return type is
2429/// `&'static str` by construction — every [`RestartPolicy::as_str`] arm
2430/// resolves to a [`crate::render::SUPERVISOR_CHILD_RESTART_*`] `pub const
2431/// &str` with `'static` lifetime, so the trait's return-type promise is
2432/// upheld structurally without a [`String::leak`] cast or a per-arm inline
2433/// literal.
2434///
2435/// Every future consumer that specifically needs `&'static str` lifetime
2436/// bytes on the per-child restart-decision axis (a
2437/// [`tracing::field::valuable::Value::Str`] recording where the `Str`
2438/// arm's typing demands `&'static str`, a
2439/// [`std::borrow::Cow::Borrowed`]`::<'static, str>(policy.into())` composer
2440/// on the future M4 admission-webhook rejection body where the
2441/// `Cow<'static, str>` typing rules out the sibling [`AsRef<str>`]
2442/// borrowed return, a generic `<T: Into<&'static str>>`-bound serializer
2443/// or error formatter that requires the `'static` bound) reaches the same
2444/// lifted [`crate::render::SUPERVISOR_CHILD_RESTART_PERMANENT`] /
2445/// [`crate::render::SUPERVISOR_CHILD_RESTART_TEMPORARY`] /
2446/// [`crate::render::SUPERVISOR_CHILD_RESTART_TRANSIENT`] substrate-
2447/// primitive dispatch rather than an open-coded per-arm literal cascade
2448/// whose arm-set has no compile-time link back to the substrate primitive.
2449///
2450/// Peer of the sibling M2-OTP-shape [`RestartStrategy`] forward-projection
2451/// impl (523157d) on the per-supervisor sibling-restart-strategy axis —
2452/// the second (and second-of-two-in-M2) closed-set typed enum on the
2453/// caixa surface to converge onto the paired trait-idiomatic forward-
2454/// projection axis. With this lift the paired per-child
2455/// `:children :restart` closed-set typed enum carries the full sibling
2456/// quintet ([`std::fmt::Display`], [`AsRef<str>`], [`Self::as_str`],
2457/// [`TryFrom<&str>`] via 6fdd0d9, `From<Self> for &'static str` via this
2458/// lift) plus the round-trip witness through both the trait-idiomatic
2459/// (`From<Self> for &'static str` + `TryFrom<&str>`) and the method-named
2460/// (`as_str` + `from_wire`) axis pairs — mirrors the sibling
2461/// [`RestartStrategy`] surface arm-for-arm, so every future arm addition
2462/// (an OTP-`intrinsic` fourth arm the theory
2463/// [`ABSORPTION-ROADMAP`](https://github.com/pleme-io/theory/blob/main/ABSORPTION-ROADMAP.md)
2464/// might reach for once the three canonical OTP restart policies stop
2465/// covering the substrate's discovered load-shape) grows the trait-
2466/// idiomatic forward axis by construction: one caixa-core edit on
2467/// [`RestartPolicy::as_str`] extends every one of the five sibling
2468/// forward-projection paths ([`std::fmt::Display`], [`AsRef<str>`],
2469/// [`Self::as_str`] itself, this `From<Self> for &'static str`, and the
2470/// un-`rename`d [`serde::Serialize`] derive that also emits `as_str`'s
2471/// bytes) without a coordinated rewrite across every future
2472/// `Into<&'static str>`-bound consumer's arm-set.
2473///
2474/// Pinned load-bearing by
2475/// [`tests::restart_policy_from_into_static_str_routes_through_as_str_accessor`]
2476/// (byte-parity pin against [`RestartPolicy::as_str`] across the
2477/// three-arm emit-set, plus a `const`-context materialization witness for
2478/// the `&'static str` lifetime promise) and
2479/// [`tests::restart_policy_from_into_static_str_and_as_str_partition_the_emit_set`]
2480/// (partition pin asserting `<&'static str as From<RestartPolicy>>::from`
2481/// and [`RestartPolicy::as_str`] agree on every arm, plus a two-way
2482/// round-trip witness through the paired trait-idiomatic reverse-
2483/// projection axis [`TryFrom<&str>`] (6fdd0d9): every
2484/// `policy.into::<&'static str>()` output re-parses back through
2485/// [`RestartPolicy::try_from`] to the original variant, closing the two-
2486/// way `Self ↔ &'static str` round-trip on the trait-idiomatic axis pair).
2487impl From<RestartPolicy> for &'static str {
2488 fn from(policy: RestartPolicy) -> &'static str {
2489 policy.as_str()
2490 }
2491}
2492
2493/// Trait-idiomatic *forward* projection on [`RestartPolicy`] from a
2494/// *borrowed* input onto the `&'static str` axis — the borrowed-input
2495/// companion to the paired owned-input [`From<RestartPolicy> for
2496/// &'static str`] impl immediately above. Routes byte-for-byte through
2497/// the same substrate-primitive [`RestartPolicy::as_str`] `pub const
2498/// fn` accessor so every consumer that binds a `&RestartPolicy`
2499/// through the standard-library `.into()` / [`From<&Self> for &'static
2500/// str`] axis (a `RestartPolicy::ALL.iter().map(<&'static
2501/// str>::from).collect::<Vec<_>>()` per-arm accept-set materializer —
2502/// whose iterator over `&'static [RestartPolicy]` yields
2503/// `&RestartPolicy`, not `RestartPolicy`, so the owned-input
2504/// [`From<RestartPolicy>`] axis alone forces every call site through
2505/// an explicit `.copied()` / dereference / [`Copy`]-bound restatement
2506/// rather than the direct trait-idiomatic projection; a future generic
2507/// `<T: Copy + for<'a> Into<&'static str>>`-bound diagnostic column
2508/// that walks the `iter().map(Into::into)` shape verbatim across every
2509/// substrate-wide closed-set typed enum; the future wasm-operator's
2510/// per-child post-exit restart-decision diagnostic line that composes
2511/// the accepted-set enumeration from an iterated
2512/// `RestartPolicy::ALL.iter().map(|p| p.into())` pipe rather than a
2513/// per-arm `match p { … }` cascade; a future
2514/// `HashMap::<&'static str, RestartPolicy>::from_iter(
2515/// RestartPolicy::ALL.iter().map(|p| (p.into(), *p)))`-style
2516/// per-policy reverse-lookup table the sibling [`TryFrom<&str>`] impl
2517/// cannot compose without this borrowed-input axis in place) reaches
2518/// the same three-arm lifted
2519/// [`crate::render::SUPERVISOR_CHILD_RESTART_PERMANENT`] /
2520/// [`crate::render::SUPERVISOR_CHILD_RESTART_TEMPORARY`] /
2521/// [`crate::render::SUPERVISOR_CHILD_RESTART_TRANSIENT`] const the
2522/// paired owned-input [`From<RestartPolicy> for &'static str`], the
2523/// sibling [`std::fmt::Display`], [`AsRef<str>`], and
2524/// [`RestartPolicy::as_str`] surfaces already return.
2525///
2526/// Fifth peer on the substrate-wide trait-idiomatic *borrowed-input*
2527/// forward-projection family opened on [`crate::dep::DepList`]
2528/// (64aa742) and extended onto [`crate::CaixaKind`] (5ab993a),
2529/// [`crate::CaixaDialeto`] (807b0b5), and the paired
2530/// per-supervisor sibling-restart-strategy [`RestartStrategy`]
2531/// (e941836). Rust's `From` trait does not auto-derive the
2532/// `From<&Self>` sibling from a `From<Self>` impl (the blanket
2533/// `impl<T, U> From<&T> for U where T: Copy, U: From<T>` does not
2534/// exist in `core`), so every closed-set typed enum that carries the
2535/// owned-input axis but not the borrowed-input axis forces every
2536/// borrowed-input call site through a `.copied()` /
2537/// `<&'static str>::from(*policy)` / `policy.as_str()` detour whose
2538/// type bounds have no compile-time link to the substrate primitive.
2539/// [`RestartPolicy`] is the second (and second-of-two-in-M2)
2540/// OTP-shape peer to converge onto this campaign — sibling of the
2541/// paired per-supervisor [`RestartStrategy`] borrowed-input axis, so
2542/// with this lift both closed-set typed enums on the M2 `:supervisor`
2543/// slot now carry the full sibling quintet ([`std::fmt::Display`],
2544/// [`AsRef<str>`], [`Self::as_str`], `From<Self> for &'static str`,
2545/// `From<&Self> for &'static str`) plus the paired trait-idiomatic
2546/// reverse projection [`TryFrom<&str>`], closing the borrowed-input
2547/// forward-projection axis on the M2 OTP-shape slot as a unit.
2548///
2549/// Same three-path convergence discipline as the paired owned-input
2550/// impl (this borrowed-input axis, the paired owned-input
2551/// [`From<RestartPolicy> for &'static str`], and
2552/// [`RestartPolicy::as_str`] all route through the same lifted
2553/// [`crate::render::SUPERVISOR_CHILD_RESTART_*`] const), so a future
2554/// variant rename or per-arm serde-attribute drift reaches every one
2555/// of the six sibling forward-projection paths
2556/// ([`std::fmt::Display`], [`AsRef<str>`], [`Self::as_str`],
2557/// [`From<Self> for &'static str`], this [`From<&Self> for &'static
2558/// str`], and the un-`rename`d [`serde::Serialize`] derive that also
2559/// emits [`Self::as_str`]'s bytes) through exactly one caixa-core
2560/// edit.
2561///
2562/// The [`RestartPolicy::as_str`] emit and [`RestartPolicy::from_wire`]
2563/// parse share the same `PascalCase` vocabulary by construction, so
2564/// the borrowed-input forward axis and the reverse axis compose
2565/// directly — the round-trip witness pin below locks this direct
2566/// composition without the intermediate wire-vocab hop the peer
2567/// [`crate::CaixaKind`] axis pair requires.
2568///
2569/// Pinned load-bearing by
2570/// [`tests::restart_policy_from_borrowed_into_static_str_routes_through_as_str_accessor`]
2571/// (byte-parity pin against [`RestartPolicy::as_str`] across the
2572/// three-arm emit-set via a borrowed input, plus a `const`-context
2573/// materialization witness for the `&'static str` lifetime promise,
2574/// plus a blanket `.into()` shape) and
2575/// [`tests::restart_policy_from_owned_and_borrowed_into_static_str_agree_on_every_arm`]
2576/// (cross-axis partition pin against the paired owned-input
2577/// [`From<RestartPolicy> for &'static str`] impl, plus a
2578/// `.iter().map(Into::into)` pipe witness over
2579/// [`RestartPolicy::ALL`], plus a direct round-trip witness through
2580/// [`TryFrom<&str>`] that closes the two-way `&Self → &'static str →
2581/// Self` round-trip without the wire-vocab intermediate the peer
2582/// [`crate::CaixaKind`] axis pair requires).
2583impl From<&RestartPolicy> for &'static str {
2584 fn from(policy: &RestartPolicy) -> &'static str {
2585 policy.as_str()
2586 }
2587}
2588
2589/// Trait-idiomatic *owned-`String`* forward projection on the second
2590/// M2 OTP-shape closed-set typed enum ([`RestartPolicy`]) — the
2591/// owned-heap-string companion to the paired `&'static str`-returning
2592/// [`From<RestartPolicy> for &'static str`] / [`From<&RestartPolicy>
2593/// for &'static str`] impls immediately above. Routes byte-for-byte
2594/// through the substrate-primitive [`RestartPolicy::as_str`] `pub
2595/// const fn` accessor (via [`str::to_owned`]) so every consumer that
2596/// binds a [`RestartPolicy`] through the standard-library `.into()` /
2597/// [`From<Self> for String`] (equivalently [`Into<String>`]) axis — a
2598/// future `serde_json::Value::String(policy.into())` structured-payload
2599/// composer where the `Value::String` arm typing demands an owned
2600/// [`String`] and the sibling [`&'static str`]-returning axis forces
2601/// an explicit `.to_owned()` / `String::from` restatement at every
2602/// call site, a future `HashMap::<String, RestartPolicy>::from_iter(
2603/// RestartPolicy::ALL.iter().map(|p| (p.into(), *p)))` per-policy
2604/// lookup where the map's key type is owned [`String`] rather than
2605/// [`&'static str`], a future `Cow::<'static, str>::Owned(policy.into())`
2606/// composer on the future M4 admission-webhook rejection body's
2607/// owned-arm, the future wasm-operator's per-child post-exit
2608/// diagnostic emit `serde_json::json!({ "restart": policy })` where the
2609/// JSON serializer's `Serialize` impl on [`String`] owns the emit-path
2610/// — reaches the same three-arm lifted
2611/// [`crate::render::SUPERVISOR_CHILD_RESTART_PERMANENT`] /
2612/// [`crate::render::SUPERVISOR_CHILD_RESTART_TEMPORARY`] /
2613/// [`crate::render::SUPERVISOR_CHILD_RESTART_TRANSIENT`] const the
2614/// paired [`std::fmt::Display`], [`AsRef<str>`],
2615/// [`RestartPolicy::as_str`], and the two `&'static str`-returning
2616/// forward-projection impls already return.
2617///
2618/// Extends the trait-idiomatic *owned-`String`* forward-projection
2619/// axis onto the second-of-two M2 OTP-shape closed-set typed enums on
2620/// the caixa surface — mirror of the first-mover
2621/// [`From<RestartStrategy> for String`] (7baa18a) that opened this
2622/// axis on the sibling supervisor-level strategy enum. Rust's standard
2623/// library does not carry a blanket `impl<T: AsRef<str>> From<T> for
2624/// String` (nor an `impl<T: fmt::Display> From<T> for String`), so
2625/// every closed-set typed enum that carries the paired `AsRef<str>` /
2626/// `Display` / `From<Self> for &'static str` triple but not the
2627/// owned-[`String`] axis forces every owned-string call site through a
2628/// `.to_string()` / `.as_str().to_owned()` / `String::from(policy.as_str())`
2629/// detour whose type bounds have no compile-time link to the
2630/// substrate primitive.
2631///
2632/// Deliberately routes through the human-readable
2633/// [`RestartPolicy::as_str`] axis — for this enum the wire format
2634/// (`PascalCase`, tatara-lisp author surface `:restart Permanent`) and
2635/// the diagnostic byte-string share the same vocabulary by
2636/// construction (unlike the sibling [`crate::CaixaKind`] enum whose
2637/// two axes diverge), so the owned-[`String`] projection lands
2638/// byte-identically on both the wire vocabulary the paired
2639/// [`serde::Serialize`] derive emits and the diagnostic vocabulary the
2640/// [`RestartPolicy::as_str`] helper returns, and — because the paired
2641/// [`TryFrom<&str>`] / [`RestartPolicy::from_wire`] reverse-projection
2642/// axis parses the same `PascalCase` vocabulary — the direct two-way
2643/// `Self → String → Self` round-trip composes without the wire-vocab
2644/// intermediate hop the peer [`crate::CaixaKind`] owned-[`String`]
2645/// axis pair requires.
2646///
2647/// Pinned load-bearing by
2648/// [`tests::restart_policy_from_into_owned_string_routes_through_as_str_accessor`]
2649/// (byte-parity pin against [`RestartPolicy::as_str`] across the
2650/// three-arm emit-set, plus a blanket `.into::<String>()` shape
2651/// witness) and
2652/// [`tests::restart_policy_from_into_owned_string_and_static_str_agree_on_every_arm`]
2653/// (cross-axis partition pin against the paired owned-input
2654/// [`From<RestartPolicy> for &'static str`] impl and the sibling
2655/// [`ToString::to_string`] surface routed through [`std::fmt::Display`],
2656/// plus a `.iter().copied().map(String::from)` pipe witness over
2657/// [`RestartPolicy::ALL`], plus a direct round-trip witness through
2658/// [`TryFrom<&str>`] on the owned-[`String`]'s [`String::as_str`]
2659/// borrow that closes the two-way `Self → String → Self` round-trip
2660/// on the trait-idiomatic owned-[`String`] forward + reverse axis
2661/// pair).
2662impl From<RestartPolicy> for String {
2663 fn from(policy: RestartPolicy) -> String {
2664 policy.as_str().to_owned()
2665 }
2666}
2667
2668/// Trait-idiomatic *borrowed-input, owned-`String` output* forward
2669/// projection on the second-of-two M2 OTP-shape closed-set typed enum
2670/// ([`RestartPolicy`]) — the fourth (and closing) corner of the
2671/// `{Self, &Self} × {&'static str, String}` 2×2 trait-idiomatic
2672/// projection family on this enum, mirror of the first-mover
2673/// [`From<&RestartStrategy> for String`] (579385f) that opened the
2674/// 2×2-completion corner on the sibling supervisor-level strategy
2675/// enum. Routes byte-for-byte through the substrate-primitive
2676/// [`RestartPolicy::as_str`] `pub const fn` accessor (via
2677/// [`str::to_owned`]) so every consumer that holds a borrowed
2678/// [`&RestartPolicy`] and needs an owned [`String`] — a future
2679/// `serde_json::Value::String(String::from(&policy))` structured-payload
2680/// composer over a borrowed field, a future `Iterator::map` over
2681/// `&[RestartPolicy]` that projects to owned keys through
2682/// `.iter().map(String::from)`, a future `HashMap::<String,
2683/// RestartPolicy>::from_iter` that keys off a borrowed-iteration axis
2684/// where dereferencing the policy would force an unnecessary `Copy` at
2685/// every step, the future wasm-operator's per-supervisor
2686/// `child_policies.iter().map(String::from).collect()` per-child post-
2687/// exit restart-decision diagnostic emit whose iteration axis is
2688/// borrowed by construction — reaches the same three-arm lifted
2689/// [`crate::render::SUPERVISOR_CHILD_RESTART_PERMANENT`] /
2690/// [`crate::render::SUPERVISOR_CHILD_RESTART_TEMPORARY`] /
2691/// [`crate::render::SUPERVISOR_CHILD_RESTART_TRANSIENT`] const the
2692/// paired [`std::fmt::Display`], [`AsRef<str>`],
2693/// [`RestartPolicy::as_str`], and the three other trait-idiomatic
2694/// forward-projection impls
2695/// ([`From<RestartPolicy> for &'static str`],
2696/// [`From<&RestartPolicy> for &'static str`],
2697/// [`From<RestartPolicy> for String`]) already return.
2698///
2699/// Second peer on the substrate-wide trait-idiomatic *borrowed-input,
2700/// owned-`String` output* forward-projection family opened on
2701/// [`crate::supervisor::RestartStrategy`] (579385f) — closes the
2702/// `{Self, &Self} × {&'static str, String}` 2×2 projection corner on
2703/// both M2 OTP-shape sibling peers (the paired supervisor-level
2704/// sibling-restart-strategy axis and the per-child restart-decision-
2705/// policy axis), so the whole M2 OTP-shape axis pair now carries the
2706/// full four-corner family by construction. Rust's standard library
2707/// does not carry a blanket `impl<T: AsRef<str>> From<&T> for String`
2708/// (nor an `impl<T: fmt::Display> From<&T> for String`), so every
2709/// closed-set typed enum that carries the paired `AsRef<str>` /
2710/// `Display` / `From<Self> for &'static str` / `From<&Self> for
2711/// &'static str` / `From<Self> for String` quintuple but not the
2712/// borrowed-input owned-[`String`] axis forces every borrowed-input
2713/// owned-string call site through a `policy.as_str().to_owned()` /
2714/// `String::from(*policy)` (with a spurious `Copy`) /
2715/// `policy.to_string()` (through `Display`) detour whose type bounds
2716/// have no compile-time link to the substrate primitive.
2717///
2718/// Deliberately routes through the human-readable
2719/// [`RestartPolicy::as_str`] axis — for this enum the wire format
2720/// (`PascalCase`, tatara-lisp author surface `:restart Permanent`) and
2721/// the diagnostic byte-string share the same vocabulary by
2722/// construction (unlike the sibling [`crate::CaixaKind`] enum whose
2723/// two axes diverge), so the borrowed-input owned-[`String`]
2724/// projection lands byte-identically on both the wire vocabulary the
2725/// paired [`serde::Serialize`] derive emits and the diagnostic
2726/// vocabulary the [`RestartPolicy::as_str`] helper returns, and —
2727/// because the paired [`TryFrom<&str>`] / [`RestartPolicy::from_wire`]
2728/// reverse-projection axis parses the same `PascalCase` vocabulary —
2729/// the direct two-way `&Self → String → Self` round-trip composes
2730/// without the wire-vocab intermediate hop the peer
2731/// [`crate::CaixaKind`] axis pair requires.
2732///
2733/// The remaining thirteen closed-set typed enums on the caixa
2734/// substrate surface (`CaixaKind`, `CaixaDialeto`, `DepList`,
2735/// `PlacementStrategy`, `WitShape`, `RateLimitUnit`,
2736/// `PathShapeViolation`, `InvariantKind`, `ArchVerdict`, `Severity`,
2737/// `FixSafety`, `Semantic`, `FerriteRuntime`) are the future targets
2738/// of this 2×2-completion campaign — each carries the same paired
2739/// quintuple that this borrowed-input owned-[`String`] axis extends
2740/// onto.
2741///
2742/// Pinned load-bearing by
2743/// [`tests::restart_policy_from_into_borrowed_owned_string_routes_through_as_str_accessor`]
2744/// (byte-parity pin against [`RestartPolicy::as_str`] across the
2745/// three-arm emit-set through the borrowed-input surface) and
2746/// [`tests::restart_policy_from_into_borrowed_owned_string_agrees_with_paired_axes_on_every_arm`]
2747/// (cross-axis partition pin against the paired owned-input owned-
2748/// [`String`] [`From<RestartPolicy> for String`] impl, the paired
2749/// borrowed-input owned-[`&'static str`] [`From<&RestartPolicy> for
2750/// &'static str`] impl, and the sibling [`ToString::to_string`]
2751/// surface routed through [`std::fmt::Display`], plus a direct round-
2752/// trip witness through [`TryFrom<&str>`] on the owned-[`String`]'s
2753/// [`String::as_str`] borrow that closes the two-way
2754/// `&Self → String → Self` round-trip on the trait-idiomatic
2755/// borrowed-input owned-[`String`] forward + reverse axis pair).
2756impl From<&RestartPolicy> for String {
2757 fn from(policy: &RestartPolicy) -> String {
2758 policy.as_str().to_owned()
2759 }
2760}
2761
2762/// Trait-idiomatic *owned-input, [`std::borrow::Cow<'static, str>`]
2763/// output* forward projection on the M2 OTP-shape per-child-restart
2764/// [`RestartPolicy`] closed-set typed enum — extends the substrate-
2765/// wide [`std::borrow::Cow<'static, str>`] forward-projection family
2766/// opened on [`crate::CaixaKind`] (99c1735 owned-input, d45c409
2767/// borrowed-input) and first extended off it onto the sibling M2
2768/// OTP-shape sibling-restart [`RestartStrategy`] (7dd28b3 owned-input,
2769/// 9b3e4b3 borrowed-input) onto the second (and second-of-two-in-M2)
2770/// M2 OTP-shape closed-set fieldless typed enum peer on the caixa
2771/// surface (`:children :restart`). Routes byte-for-byte through the
2772/// substrate-primitive [`RestartPolicy::as_str`] `pub const fn`
2773/// accessor (via [`std::borrow::Cow::Borrowed`]) so every consumer
2774/// that binds a [`RestartPolicy`] through the trait-idiomatic
2775/// [`std::borrow::Cow<'static, str>`] axis — a future
2776/// `axum::response::IntoResponse` composer whose per-policy
2777/// diagnostic-body typing rules out the sibling [`AsRef<str>`]
2778/// borrowed return, a future M4 admission-webhook rejection body
2779/// that composes the accepted-policy enumeration through the same
2780/// `RestartPolicy::ALL.iter().map(Cow::from)` shape [`crate::CaixaKind`]
2781/// and [`RestartStrategy`] already route through, a generic `<T: for<'a>
2782/// Into<std::borrow::Cow<'static, str>>>`-bound structured-log
2783/// emitter on a per-child-policy diagnostic column — reaches the same
2784/// three-arm lifted [`crate::render::SUPERVISOR_CHILD_RESTART_PERMANENT`]
2785/// / [`crate::render::SUPERVISOR_CHILD_RESTART_TEMPORARY`] /
2786/// [`crate::render::SUPERVISOR_CHILD_RESTART_TRANSIENT`] const the
2787/// paired [`std::fmt::Display`], [`AsRef<str>`],
2788/// [`RestartPolicy::as_str`], and the four
2789/// `{Self, &Self} × {&'static str, String}` 2×2 trait-idiomatic
2790/// forward-projection corners already return.
2791///
2792/// Deliberately returns [`std::borrow::Cow::Borrowed`] rather than
2793/// [`std::borrow::Cow::Owned`] — the substrate-primitive
2794/// [`RestartPolicy::as_str`] accessor's return carries the `&'static
2795/// str` lifetime by construction (each `match` arm resolves to a
2796/// [`crate::render::SUPERVISOR_CHILD_RESTART_*`] `pub const &str`
2797/// with static lifetime), so the zero-alloc borrowed arm is the
2798/// type-correct projection with no runtime allocation.
2799///
2800/// Rust's standard library carries no blanket `impl<T: AsRef<str>>
2801/// From<T> for Cow<'static, str>` (nor an `impl<T: fmt::Display>
2802/// From<T> for Cow<'static, str>`), so the paired sibling
2803/// [`From<RestartPolicy> for &'static str`] (9fb37d0),
2804/// [`From<RestartPolicy> for String`] (7851725), [`AsRef<str>`], and
2805/// [`std::fmt::Display`] surfaces do not implicitly extend to a
2806/// [`Cow<'static, str>`]-bound call site — every such site is forced
2807/// through a `Cow::Borrowed(policy.as_str())` /
2808/// `Cow::Owned(policy.to_string())` open-code whose type bounds have
2809/// no compile-time link back to the substrate primitive until this
2810/// lift.
2811///
2812/// Second peer to extend the substrate-wide trait-idiomatic
2813/// [`std::borrow::Cow<'static, str>`] forward-projection axis off the
2814/// top-level [`crate::CaixaKind`] enum (99c1735 owned-input, d45c409
2815/// borrowed-input) onto the wider substrate — closes the M2 OTP-shape
2816/// tier of the campaign (both sibling peers, `RestartStrategy` and
2817/// `RestartPolicy`, now carry the owned-input Cow<'static, str>
2818/// forward projection) so the remaining eleven peers
2819/// (`PlacementStrategy`, `RateLimitUnit`, `DepList`, `CaixaDialeto`,
2820/// and the outside-`caixa-core` peers `WitShape`, `PathShapeViolation`,
2821/// `InvariantKind`, `ArchVerdict`, `Severity`, `FixSafety`, `Semantic`,
2822/// `FerriteRuntime`) are the future targets. Every future arm addition
2823/// (an OTP-`intrinsic` fourth restart policy the ABSORPTION-ROADMAP
2824/// might reach for once the three canonical OTP restart policies stop
2825/// covering the substrate's discovered load-shape) grows the
2826/// Cow<'static, str> axis by construction through one caixa-core edit
2827/// on [`RestartPolicy::as_str`] — rather than a coordinated rewrite
2828/// across every future Cow<'static, str>-bound consumer site.
2829///
2830/// Pinned load-bearing by
2831/// [`tests::restart_policy_from_into_static_cow_str_routes_through_as_str_accessor`]
2832/// (byte-parity + zero-alloc [`std::borrow::Cow::Borrowed`]-arm pin
2833/// against [`RestartPolicy::as_str`] across the three-arm
2834/// [`RestartPolicy::ALL`]) and
2835/// [`tests::restart_policy_from_into_static_cow_str_agrees_with_paired_axes_on_every_arm`]
2836/// (cross-axis partition pin against the paired [`From<RestartPolicy>
2837/// for &'static str`], [`From<RestartPolicy> for String`], and
2838/// [`ToString`]-through-[`std::fmt::Display`] axes, plus a
2839/// `.iter().copied().map(Cow::from)` pipe witness over
2840/// [`RestartPolicy::ALL`] that materializes the three-arm accept-set
2841/// through the [`Cow<'static, str>`] axis alone and pins the
2842/// zero-alloc discipline on every element).
2843impl From<RestartPolicy> for std::borrow::Cow<'static, str> {
2844 fn from(policy: RestartPolicy) -> std::borrow::Cow<'static, str> {
2845 std::borrow::Cow::Borrowed(policy.as_str())
2846 }
2847}
2848
2849/// Trait-idiomatic *borrowed-input, [`std::borrow::Cow<'static, str>`]
2850/// output* forward projection on the M2 OTP-shape per-child-restart
2851/// [`RestartPolicy`] closed-set typed enum — the borrowed-input
2852/// companion to the paired owned-input
2853/// [`From<RestartPolicy> for std::borrow::Cow<'static, str>`] impl
2854/// immediately above (0612398). Routes byte-for-byte through the same
2855/// substrate-primitive [`RestartPolicy::as_str`] `pub const fn`
2856/// accessor (via [`std::borrow::Cow::Borrowed`]) so every consumer
2857/// that holds a `&RestartPolicy` and needs a
2858/// [`std::borrow::Cow<'static, str>`] — a
2859/// `RestartPolicy::ALL.iter().map(std::borrow::Cow::from).collect::<Vec<_>>()`
2860/// per-arm accept-set materializer (whose iterator over
2861/// `&'static [RestartPolicy]` yields `&RestartPolicy`, not
2862/// `RestartPolicy`, so the paired owned-input
2863/// [`From<RestartPolicy> for std::borrow::Cow<'static, str>`] axis
2864/// alone forces every call site through an explicit `.copied()` /
2865/// dereference / [`Copy`]-bound restatement rather than the direct
2866/// trait-idiomatic projection), a future generic
2867/// `<T: for<'a> Into<std::borrow::Cow<'static, str>>>`-bound emitter
2868/// on a per-child-policy diagnostic column that walks the
2869/// `iter().map(Into::into)` shape verbatim, the future M4 admission-
2870/// webhook rejection body that composes the accepted-policy
2871/// enumeration from an iterated
2872/// `RestartPolicy::ALL.iter().map(|p| p.into())` pipe rather than a
2873/// per-arm `match p { … }` cascade — reaches the same three-arm
2874/// lifted [`crate::render::SUPERVISOR_CHILD_RESTART_PERMANENT`] /
2875/// [`crate::render::SUPERVISOR_CHILD_RESTART_TEMPORARY`] /
2876/// [`crate::render::SUPERVISOR_CHILD_RESTART_TRANSIENT`] const the
2877/// paired [`std::fmt::Display`], [`AsRef<str>`],
2878/// [`RestartPolicy::as_str`], the four
2879/// `{Self, &Self} × {&'static str, String}` 2×2 trait-idiomatic
2880/// forward-projection corners, and the paired owned-input
2881/// [`From<RestartPolicy> for std::borrow::Cow<'static, str>`] impl
2882/// already return.
2883///
2884/// Deliberately returns [`std::borrow::Cow::Borrowed`] rather than
2885/// [`std::borrow::Cow::Owned`] — the substrate-primitive
2886/// [`RestartPolicy::as_str`] accessor's return carries the
2887/// `&'static str` lifetime by construction (each `match` arm resolves
2888/// to a [`crate::render::SUPERVISOR_CHILD_RESTART_*`] `pub const &str`
2889/// with static lifetime), so the zero-alloc borrowed arm is the
2890/// type-correct projection with no runtime allocation.
2891///
2892/// Closes the `{Self, &Self}` input-shape corner on the M2 OTP-shape
2893/// per-child-restart [`std::borrow::Cow<'static, str>`] axis opened
2894/// one commit prior (0612398) on the paired owned-input
2895/// [`From<RestartPolicy> for std::borrow::Cow<'static, str>`] impl —
2896/// second-of-two-in-M2 closed-set fieldless typed enum peer on the
2897/// caixa surface (paired with the sibling-restart [`RestartStrategy`]
2898/// which carries both {Self, &Self} × Cow<'static, str> corners since
2899/// 7dd28b3 owned-input, 9b3e4b3 borrowed-input), exactly as d45c409
2900/// closed it on the top-level [`crate::CaixaKind`] one commit after
2901/// the owning half (99c1735) landed. This lift closes the whole M2
2902/// OTP-shape tier of the substrate-wide [`Cow<'static, str>`]
2903/// forward-projection campaign on both input-shape corners
2904/// ({Self, &Self}) of both M2 OTP-shape sibling peers
2905/// ([`RestartStrategy`] and [`RestartPolicy`]), so the remaining
2906/// eleven substrate-wide peers (`PlacementStrategy`, `RateLimitUnit`,
2907/// `DepList`, `CaixaDialeto`, `WitShape`, `PathShapeViolation`,
2908/// `InvariantKind`, `ArchVerdict`, `Severity`, `FixSafety`, `Semantic`,
2909/// `FerriteRuntime`) become the future targets of the campaign. Rust's
2910/// standard library does not carry a blanket
2911/// `impl<T: AsRef<str>> From<&T> for Cow<'static, str>` (nor an
2912/// `impl<T: fmt::Display> From<&T> for Cow<'static, str>`), so every
2913/// closed-set fieldless typed enum peer on the substrate that carries
2914/// the paired owned-input [`Cow<'static, str>`] axis but not the
2915/// borrowed-input axis forces every borrowed-input
2916/// [`Cow<'static, str>`]-parameterized call site through a spurious
2917/// [`Copy`] deref (`std::borrow::Cow::from(*policy)`) or a
2918/// `std::borrow::Cow::Borrowed(policy.as_str())` open-code whose type
2919/// bounds have no compile-time link to the substrate primitive.
2920///
2921/// Pinned load-bearing by
2922/// [`tests::restart_policy_from_borrowed_into_static_cow_str_routes_through_as_str_accessor`]
2923/// (byte-parity + zero-alloc [`std::borrow::Cow::Borrowed`]-arm pin
2924/// against [`RestartPolicy::as_str`] across the three-arm
2925/// [`RestartPolicy::ALL`] through the borrowed-input surface) and
2926/// [`tests::restart_policy_from_borrowed_into_static_cow_str_agrees_with_paired_axes_on_every_arm`]
2927/// (cross-axis partition pin against the paired owned-input
2928/// [`From<RestartPolicy> for std::borrow::Cow<'static, str>`], the
2929/// paired borrowed-input owned-`&'static str`
2930/// [`From<&RestartPolicy> for &'static str`], and the paired
2931/// borrowed-input owned-`String` [`From<&RestartPolicy> for String`]
2932/// impls, plus a `.iter().map(std::borrow::Cow::from)` pipe witness
2933/// over [`RestartPolicy::ALL`] — whose iterator yields
2934/// `&RestartPolicy` by construction, so the borrowed-input
2935/// [`Cow<'static, str>`] axis is what routes the pipe through the
2936/// substrate-primitive [`RestartPolicy::as_str`] accessor with the
2937/// zero-alloc [`Cow::Borrowed`] arm by construction and without a
2938/// spurious [`Copy`] deref).
2939impl From<&RestartPolicy> for std::borrow::Cow<'static, str> {
2940 fn from(policy: &RestartPolicy) -> std::borrow::Cow<'static, str> {
2941 std::borrow::Cow::Borrowed(policy.as_str())
2942 }
2943}
2944
2945/// Trait-idiomatic *owned-input, [`Box<str>`] output* forward
2946/// projection on the M2 OTP-shape per-child-restart [`RestartPolicy`]
2947/// closed-set fieldless typed enum — extends the substrate-wide
2948/// `Box<str>` forward-projection campaign tier opened one commit prior
2949/// (69ef45c) on the paired sibling-restart [`RestartStrategy`] onto
2950/// the second (and third-and-final) M2 OTP-shape closed-set fieldless
2951/// typed enum peer on the caixa surface (`:children :restart`),
2952/// immediately after the paired `Cow<'static, str>` axis (0612398 /
2953/// b4dc55c) closed the
2954/// `{Self, &Self} × {&'static str, String, Cow<'static, str>}` 2×3
2955/// corner on this enum. Routes byte-for-byte through the
2956/// substrate-primitive [`RestartPolicy::as_str`] `pub const fn`
2957/// accessor via [`Box::<str>::from`] on the returned `&'static str`,
2958/// so every consumer that binds a
2959/// `let key: Box<str> = policy.into();`-shaped call site — a
2960/// per-child metric-key materializer that stashes the policy
2961/// discriminator in a `Box<str>`-typed heap-owned scalar for cheap
2962/// clone (a shared-nothing per-policy accept-set the `caixa-operator`
2963/// hierarchical reconciliation scheduler's per-child restart-decision
2964/// fan-out carries), a future admission-webhook rejection body whose
2965/// per-arm `Box<str>` field composes from an owned `RestartPolicy`
2966/// handle — reaches the same three-arm lifted
2967/// [`crate::render::SUPERVISOR_CHILD_RESTART_PERMANENT`] /
2968/// [`crate::render::SUPERVISOR_CHILD_RESTART_TEMPORARY`] /
2969/// [`crate::render::SUPERVISOR_CHILD_RESTART_TRANSIENT`] const the
2970/// sibling
2971/// `{Self, &Self} × {&'static str, String, Cow<'static, str>}`
2972/// forward-projection corner already returns. Rust's standard library
2973/// carries `impl From<&str> for Box<str>` and
2974/// `impl From<String> for Box<str>` but no blanket
2975/// `impl<T: AsRef<str>> From<T> for Box<str>` (nor any
2976/// `impl<T: Copy, U: From<T>> From<T> for U` route from the enum), so
2977/// this axis is a distinct trait-idiomatic surface that a downstream
2978/// `RestartPolicy → Box<str>` `.into()` reaches through this impl and
2979/// no other — without a `Box::from(policy.as_str())` open-code whose
2980/// type bounds have no compile-time link back to the substrate
2981/// primitive.
2982///
2983/// Second peer on the substrate-wide trait-idiomatic [`Box<str>`]
2984/// forward-projection family opened on the sibling-restart
2985/// [`RestartStrategy`] (69ef45c / 59ae5dc) — closes the whole M2
2986/// OTP-shape tier of the substrate-wide [`Box<str>`] forward-
2987/// projection campaign's owned-input corner on both M2 OTP-shape
2988/// sibling peers ([`RestartStrategy`] and [`RestartPolicy`]), the
2989/// paired borrowed-input `From<&RestartPolicy> for Box<str>` closer
2990/// and the remaining fieldless-enum peers on the M3 mesh-shape /
2991/// outside-M3 caixa-core / render-side / outside-caixa-core tiers
2992/// are the future targets of the campaign.
2993///
2994/// Pinned load-bearing by
2995/// [`tests::restart_policy_from_into_box_str_routes_through_as_str_accessor`]
2996/// (byte-parity pin against [`RestartPolicy::as_str`] across the
2997/// three-arm [`RestartPolicy::ALL`] emit-set on the owned-input
2998/// surface, plus a blanket-derived [`Into`] shape witness).
2999impl From<RestartPolicy> for Box<str> {
3000 fn from(policy: RestartPolicy) -> Box<str> {
3001 Box::<str>::from(policy.as_str())
3002 }
3003}
3004
3005/// Trait-idiomatic *borrowed-input, [`Box<str>`] output* forward
3006/// projection on the M2 OTP-shape per-child-restart [`RestartPolicy`]
3007/// closed-set fieldless typed enum — the borrowed-input companion to
3008/// the paired owned-input [`From<RestartPolicy> for Box<str>`] impl
3009/// (0a1b313, one commit prior) that closes the `{Self, &Self}`
3010/// input-shape corner of the substrate-wide [`Box<str>`] forward-
3011/// projection axis on the second (and third-and-final) M2 OTP-shape
3012/// closed-set fieldless typed enum peer on the caixa surface
3013/// (`:children :restart`), routing byte-for-byte through the
3014/// substrate-primitive [`RestartPolicy::as_str`] `pub const fn`
3015/// accessor via [`Box::<str>::from`] on the returned `&'static str`.
3016/// Every consumer that holds a `&RestartPolicy` and needs a
3017/// [`Box<str>`] — a
3018/// `RestartPolicy::ALL.iter().map(Box::<str>::from).collect::<Vec<_>>()`
3019/// per-arm accept-set materializer (whose iterator over
3020/// `&'static [RestartPolicy]` yields `&RestartPolicy`, not
3021/// `RestartPolicy`, so the paired owned-input
3022/// [`From<RestartPolicy> for Box<str>`] axis alone forces every
3023/// call site through an explicit [`Copy`] deref or a
3024/// `.copied()` restatement rather than the direct trait-idiomatic
3025/// projection), a per-child metric-key materializer holding
3026/// `&RestartPolicy` through a `caixa-operator` hierarchical
3027/// reconciliation scheduler's borrow lifetime, a future admission-
3028/// webhook rejection body whose per-arm `Box<str>` field composes
3029/// from a borrowed `&RestartPolicy` handle — reaches the
3030/// substrate-primitive [`RestartPolicy::as_str`] accessor through
3031/// this impl and no other, without a
3032/// `Box::<str>::from(policy.as_str())` open-code whose type bounds
3033/// have no compile-time link back to the substrate primitive.
3034///
3035/// Rust's standard library carries `impl From<&str> for Box<str>`
3036/// and `impl From<String> for Box<str>` but no blanket
3037/// `impl<T: AsRef<str>> From<&T> for Box<str>` (nor a
3038/// `Copy`-based `impl<T: Copy, U: From<&T> for U`), so every closed-
3039/// set fieldless typed enum peer on the substrate that carries the
3040/// paired owned-input `Box<str>` axis but not the borrowed-input
3041/// axis forces every borrowed-input `Box<str>`-parameterized call
3042/// site through a spurious [`Copy`] deref
3043/// (`Box::<str>::from((*policy).as_str())`) or a
3044/// `Box::<str>::from(policy.as_str())` open-code whose type bounds
3045/// have no compile-time link back to the substrate primitive.
3046///
3047/// Fourth (and closing) peer on the substrate-wide trait-idiomatic
3048/// [`Box<str>`] forward-projection family on the M2 OTP-shape tier
3049/// — closes the whole `{Self, &Self}` input-shape corner of the
3050/// [`Box<str>`] axis on both M2 OTP-shape sibling peers
3051/// ([`RestartStrategy`] and [`RestartPolicy`]), exactly as b4dc55c
3052/// closed the paired [`Cow<'static, str>`] axis one commit after
3053/// its owning half (0612398) landed on this enum. The remaining
3054/// fieldless-enum peers on the M3 mesh-shape / outside-M3 caixa-
3055/// core / render-side / outside-caixa-core tiers are the future
3056/// targets of the [`Box<str>`] campaign.
3057///
3058/// Pinned load-bearing by
3059/// [`tests::restart_policy_from_borrowed_into_box_str_routes_through_as_str_accessor`]
3060/// (byte-parity pin against [`RestartPolicy::as_str`] across the
3061/// three-arm [`RestartPolicy::ALL`] emit-set on the borrowed-input
3062/// surface, plus a blanket-derived [`Into`] shape witness, a
3063/// cross-axis partition pin against the paired owned-input
3064/// [`From<RestartPolicy> for Box<str>`] and the sibling borrowed-
3065/// input `{&'static str, String, Cow<'static, str>}` return-shape
3066/// axes, and a `.iter().map(Box::<str>::from)` pipe witness over
3067/// [`RestartPolicy::ALL`] — whose iterator yields `&RestartPolicy`
3068/// by construction, so the borrowed-input [`Box<str>`] axis is
3069/// what routes the pipe through the substrate-primitive
3070/// [`RestartPolicy::as_str`] accessor without a spurious [`Copy`]
3071/// deref).
3072impl From<&RestartPolicy> for Box<str> {
3073 fn from(policy: &RestartPolicy) -> Box<str> {
3074 Box::<str>::from(policy.as_str())
3075 }
3076}
3077
3078/// Trait-idiomatic *owned-input, [`std::sync::Arc<str>`] output*
3079/// forward projection on the M2 OTP-shape per-child-restart
3080/// [`RestartPolicy`] closed-set fieldless typed enum — routes byte-
3081/// for-byte through the substrate-primitive [`RestartPolicy::as_str`]
3082/// `pub const fn` accessor via [`std::sync::Arc::<str>::from`] on the
3083/// returned `&'static str`, so every consumer that binds a
3084/// [`RestartPolicy`] through the standard-library `.into()` /
3085/// [`From<Self> for std::sync::Arc<str>`] (equivalently
3086/// [`Into<std::sync::Arc<str>>`]) axis — a future admission-webhook's
3087/// per-request `Sync` + `Send`-safe structured-log field composed
3088/// across an `.await` boundary through a
3089/// `<T: Into<std::sync::Arc<str>>>`-bound diagnostic-column dispatch,
3090/// a future wasm-operator's per-child post-exit restart-decision
3091/// pipeline holding a shared-ownership per-arm cache key, a
3092/// `<T: Into<std::sync::Arc<str>>>`-bound `tracing`-span attributes
3093/// collector recording a per-child-policy field onto the parent
3094/// span's shared-ownership context — reaches the same three-arm
3095/// lifted [`crate::render::SUPERVISOR_CHILD_RESTART_PERMANENT`] /
3096/// [`crate::render::SUPERVISOR_CHILD_RESTART_TEMPORARY`] /
3097/// [`crate::render::SUPERVISOR_CHILD_RESTART_TRANSIENT`] const the
3098/// sibling
3099/// `{Self, &Self} × {&'static str, String, Cow<'static, str>, Box<str>}`
3100/// forward-projection corner already returns.
3101///
3102/// Second peer on the substrate-wide trait-idiomatic
3103/// [`std::sync::Arc<str>`] forward-projection family opened one
3104/// projection tier prior (bca2ec8) on the paired sibling-restart
3105/// [`RestartStrategy`] owned-input first-mover — extends the tier
3106/// onto the second (and third-and-final) M2 OTP-shape closed-set
3107/// fieldless typed enum peer on the caixa surface
3108/// (`:children :restart`), immediately after the paired [`Box<str>`]
3109/// axis (0a1b313 / cb1d068) closed the whole
3110/// `{Self, &Self} × {&'static str, String, Cow<'static, str>, Box<str>}`
3111/// 2×4 corner on this enum. Rust's standard library carries
3112/// `impl From<&str> for std::sync::Arc<str>` and
3113/// `impl From<String> for std::sync::Arc<str>` but no blanket
3114/// `impl<T: AsRef<str>> From<T> for std::sync::Arc<str>` (nor an
3115/// `impl<T: fmt::Display> From<T> for std::sync::Arc<str>`), so this
3116/// axis is a distinct trait-idiomatic surface that a
3117/// `let key: std::sync::Arc<str> = policy.into();`-shaped call site
3118/// reaches through this impl and no other — a paired
3119/// `std::sync::Arc::<str>::from(policy.as_str())` open-code has no
3120/// compile-time link back to the substrate primitive, and a two-step
3121/// `std::sync::Arc::<str>::from(String::from(policy))` composition
3122/// through the owned-`String` axis allocates twice (once into the
3123/// intermediate `String`, once into the [`Arc<str>`] on the
3124/// `From<String>` conversion) where the single-step trait impl
3125/// allocates once.
3126///
3127/// Peer of the sibling [`Box<str>`] second-tier extender (0a1b313) —
3128/// same "extends the substrate-wide projection tier onto the next
3129/// M2 OTP-shape peer" discipline, extended onto the
3130/// [`std::sync::Arc<str>`] axis whose shared-ownership + [`Sync`] +
3131/// [`Send`] contract is the distinct value the [`Box<str>`] axis's
3132/// owned-move return-shape cannot provide.
3133///
3134/// Pinned load-bearing by
3135/// [`tests::restart_policy_from_into_arc_str_routes_through_as_str_accessor`]
3136/// (byte-parity pin against [`RestartPolicy::as_str`] across the
3137/// three-arm [`RestartPolicy::ALL`] emit-set on the owned-input
3138/// surface, plus a blanket-derived [`Into`] shape witness and cross-
3139/// axis byte-parity pins against the sibling owned-input
3140/// `{&'static str, String, Cow<'static, str>, Box<str>}` return-shape
3141/// axes).
3142impl From<RestartPolicy> for std::sync::Arc<str> {
3143 fn from(policy: RestartPolicy) -> std::sync::Arc<str> {
3144 std::sync::Arc::<str>::from(policy.as_str())
3145 }
3146}
3147
3148/// Trait-idiomatic *borrowed-input, [`std::sync::Arc<str>`] output*
3149/// forward projection on the M2 OTP-shape per-child-restart
3150/// [`RestartPolicy`] closed-set fieldless typed enum — closes the
3151/// `{Self, &Self}` input-shape corner of the [`std::sync::Arc<str>`]
3152/// forward-projection axis on the second (and third-and-final) M2
3153/// OTP-shape closed-set fieldless typed enum peer on the caixa
3154/// surface (`:children :restart`), companion to the paired
3155/// owned-input [`From<RestartPolicy> for std::sync::Arc<str>`] impl
3156/// one commit prior (b05724e). Routes byte-for-byte through the
3157/// substrate-primitive [`RestartPolicy::as_str`] `pub const fn`
3158/// accessor (via [`std::sync::Arc::<str>::from`] on the returned
3159/// `&'static str`), so every consumer that binds a
3160/// [`&RestartPolicy`] through the standard-library `.into()` /
3161/// [`From<&Self> for std::sync::Arc<str>`] (equivalently
3162/// [`Into<std::sync::Arc<str>>`]) axis — a future admission-webhook's
3163/// per-request borrowed-`&RestartPolicy` handle rendering a per-arm
3164/// `Sync` + `Send`-safe structured-log field across an `.await`
3165/// boundary through a `<T: Into<std::sync::Arc<str>>>`-bound
3166/// diagnostic-column dispatch, a future wasm-operator's per-child
3167/// post-exit restart-decision pipeline whose
3168/// `.iter().map(std::sync::Arc::<str>::from)` collector reaches
3169/// into the shared-ownership per-arm key without a spurious [`Copy`]
3170/// deref (which would only be reachable through the owned-input
3171/// [`From<RestartPolicy> for std::sync::Arc<str>`] axis by first
3172/// calling `.copied()` on the iterator), a future
3173/// `<T: Into<std::sync::Arc<str>>>`-bound `tracing`-span attributes
3174/// collector recording a borrowed-`&RestartPolicy` per-arm field
3175/// onto the parent span's shared-ownership context — reaches the
3176/// same three-arm lifted
3177/// [`crate::render::SUPERVISOR_CHILD_RESTART_PERMANENT`] /
3178/// [`crate::render::SUPERVISOR_CHILD_RESTART_TEMPORARY`] /
3179/// [`crate::render::SUPERVISOR_CHILD_RESTART_TRANSIENT`] const the
3180/// paired owned-input [`From<RestartPolicy> for std::sync::Arc<str>`]
3181/// impl and the sibling `{&'static str, String, Cow<'static, str>,
3182/// Box<str>}` forward-projection corner already return.
3183///
3184/// Closes the substrate-wide trait-idiomatic
3185/// [`std::sync::Arc<str>`] forward-projection family opened one
3186/// commit prior (b05724e) on the paired owned-input
3187/// [`From<RestartPolicy> for std::sync::Arc<str>`] impl — closes
3188/// the `{Self, &Self}` input-shape corner of the
3189/// [`std::sync::Arc<str>`] axis on the second (and third-and-final)
3190/// M2 OTP-shape closed-set fieldless typed enum peer on the caixa
3191/// surface, exactly as b3e72d7 closed the paired
3192/// [`std::sync::Arc<str>`] corner on the sibling-restart
3193/// [`RestartStrategy`] first-mover one commit after its owning half
3194/// (bca2ec8) landed, and as cb1d068 closed the paired [`Box<str>`]
3195/// corner on this enum one commit after its owning half (0a1b313)
3196/// landed. Rust's standard library carries `impl From<&str> for
3197/// std::sync::Arc<str>` and `impl From<String> for
3198/// std::sync::Arc<str>` but no blanket `impl<T: AsRef<str>> From<&T>
3199/// for std::sync::Arc<str>` (nor a `Copy`-based `impl<T: Copy,
3200/// U: From<T>> From<&T> for U`), so every closed-set fieldless typed
3201/// enum peer on the substrate that carries the paired owned-input
3202/// [`std::sync::Arc<str>`] axis but not the borrowed-input axis
3203/// forces every borrowed-input [`std::sync::Arc<str>`]-parameterized
3204/// call site through a spurious [`Copy`] deref
3205/// (`std::sync::Arc::<str>::from((*policy).as_str())`) or a
3206/// `std::sync::Arc::<str>::from(policy.as_str())` open-code whose
3207/// type bounds have no compile-time link back to the substrate
3208/// primitive.
3209///
3210/// Pinned load-bearing by
3211/// [`tests::restart_policy_from_borrowed_into_arc_str_routes_through_as_str_accessor`]
3212/// (byte-parity pin against [`RestartPolicy::as_str`] across the
3213/// three-arm [`RestartPolicy::ALL`] emit-set on the borrowed-input
3214/// surface, plus a blanket-derived [`Into`] shape witness, a
3215/// cross-axis pin against the paired owned-input
3216/// [`From<RestartPolicy> for std::sync::Arc<str>`] and the sibling
3217/// borrowed-input `{&'static str, String, Cow<'static, str>,
3218/// Box<str>}` return-shape axes, and a
3219/// `.iter().map(std::sync::Arc::<str>::from)` pipe witness over
3220/// [`RestartPolicy::ALL`]).
3221impl From<&RestartPolicy> for std::sync::Arc<str> {
3222 fn from(policy: &RestartPolicy) -> std::sync::Arc<str> {
3223 std::sync::Arc::<str>::from(policy.as_str())
3224 }
3225}
3226
3227/// Trait-idiomatic *owned-input, [`std::rc::Rc<str>`] output* forward
3228/// projection on the M2 OTP-shape per-child-restart [`RestartPolicy`]
3229/// closed-set fieldless typed enum — the single-threaded reference-
3230/// counted peer of the paired owned-input
3231/// [`From<RestartPolicy> for std::sync::Arc<str>`] impl (b05724e) on the
3232/// sibling atomically-reference-counted [`std::sync::Arc<str>`] axis.
3233/// Routes byte-for-byte through the substrate-primitive
3234/// [`RestartPolicy::as_str`] `pub const fn` accessor via
3235/// [`std::rc::Rc::<str>::from`] on the returned `&'static str`.
3236///
3237/// Rust's standard library carries `impl From<&str> for std::rc::Rc<str>`
3238/// and `impl From<String> for std::rc::Rc<str>` but no blanket
3239/// `impl<T: AsRef<str>> From<T> for std::rc::Rc<str>` (nor a `From<&T>`
3240/// blanket), and the [`std::sync::Arc<str>`] and [`std::rc::Rc<str>`]
3241/// trait tables are disjoint — so a single-threaded caixa-operator
3242/// reconciliation pass that shares the `:children :restart` wire
3243/// byte-string across intra-reconcile-loop tree nodes through the cheaper
3244/// non-atomic [`std::rc::Rc<str>`] refcount (the atomically-reference-
3245/// counted [`std::sync::Arc<str>`] return-shape cannot provide within a
3246/// single-threaded reconciliation pass without paying the atomic-fence
3247/// cost the [`std::rc::Rc<str>`] axis skips by construction) reaches
3248/// the substrate primitive through this impl and no other.
3249///
3250/// Closes the substrate-wide trait-idiomatic [`std::rc::Rc<str>`]
3251/// forward-projection axis on the M2-OTP-shape `:supervisor
3252/// :estrategia` and `:children :restart` slot pair the sibling-restart
3253/// [`RestartStrategy`] first-mover (71ad8f4) opened one projection tier
3254/// prior on the paired sibling enum — closes the paired axis on the
3255/// second (and third-and-final) M2 OTP-shape closed-set fieldless typed
3256/// enum peer on the caixa surface, matching the discipline the paired
3257/// [`std::sync::Arc<str>`] forward-projection axis campaign already
3258/// carried across the same slot pair (bca2ec8 → b3e72d7 on
3259/// [`RestartStrategy`]; b05724e → borrowed-close on this enum).
3260///
3261/// Pinned load-bearing by
3262/// [`tests::restart_policy_from_into_rc_str_routes_through_as_str_accessor`]
3263/// (byte-parity pin against [`RestartPolicy::as_str`] across the
3264/// three-arm [`RestartPolicy::ALL`] emit-set on the owned-input
3265/// surface, plus a blanket-derived [`Into`] shape witness and cross-
3266/// axis byte-parity pins against the sibling owned-input `{&'static
3267/// str, String, Cow<'static, str>, Box<str>, std::sync::Arc<str>}`
3268/// return-shape axes).
3269impl From<RestartPolicy> for std::rc::Rc<str> {
3270 fn from(policy: RestartPolicy) -> std::rc::Rc<str> {
3271 std::rc::Rc::<str>::from(policy.as_str())
3272 }
3273}
3274
3275/// Trait-idiomatic *borrowed-input, [`std::rc::Rc<str>`] output* forward
3276/// projection on the M2 OTP-shape per-child-restart [`RestartPolicy`]
3277/// closed-set fieldless typed enum — the borrowed-input companion to
3278/// the paired owned-input [`From<RestartPolicy> for std::rc::Rc<str>`]
3279/// impl immediately above, closing the `{Self, &Self}` input-shape
3280/// corner of the [`std::rc::Rc<str>`] axis on the second (and third-
3281/// and-final) M2 OTP-shape closed-set fieldless typed enum peer on the
3282/// caixa surface. Routes byte-for-byte through the substrate-primitive
3283/// [`RestartPolicy::as_str`] `pub const fn` accessor via
3284/// [`std::rc::Rc::<str>::from`] on the returned `&'static str`, so a
3285/// `RestartPolicy::ALL.iter().map(std::rc::Rc::<str>::from)`-shaped
3286/// pipe (whose iterator over `&'static [RestartPolicy]` yields
3287/// `&RestartPolicy` by construction) reaches the same three-arm lifted
3288/// [`crate::render::SUPERVISOR_CHILD_RESTART_PERMANENT`] /
3289/// [`crate::render::SUPERVISOR_CHILD_RESTART_TEMPORARY`] /
3290/// [`crate::render::SUPERVISOR_CHILD_RESTART_TRANSIENT`] const roster
3291/// the paired owned-input axis and the sibling `{Self, &Self} ×
3292/// {&'static str, String, Cow<'static, str>, Box<str>,
3293/// std::sync::Arc<str>}` forward-projection corner already return.
3294///
3295/// Rust's standard library carries no blanket
3296/// `impl<T: AsRef<str>> From<&T> for std::rc::Rc<str>` (nor a `Copy`-
3297/// based `impl<T: Copy, U: From<T>> From<&T> for U`), so this borrowed-
3298/// input axis is a distinct trait-idiomatic surface — without it, the
3299/// `.iter().map(std::rc::Rc::<str>::from)` pipe would force a spurious
3300/// [`Copy`] deref or a `.copied()` restatement whose type bounds have
3301/// no compile-time link back to the substrate primitive.
3302///
3303/// Closes the substrate-wide trait-idiomatic [`std::rc::Rc<str>`]
3304/// forward-projection family on the M2-OTP-shape `:supervisor
3305/// :estrategia` + `:children :restart` slot pair — the sibling
3306/// [`RestartStrategy`] first-mover (71ad8f4) opened + closed the pair
3307/// on the sibling `:supervisor :estrategia` half one projection tier
3308/// prior, and the paired owned-input [`From<RestartPolicy> for
3309/// std::rc::Rc<str>`] impl immediately above opens the same axis on
3310/// this half — this borrowed-input impl closes it.
3311///
3312/// Pinned load-bearing by
3313/// [`tests::restart_policy_from_borrowed_into_rc_str_routes_through_as_str_accessor`]
3314/// (byte-parity pin against [`RestartPolicy::as_str`] across the
3315/// three-arm [`RestartPolicy::ALL`] emit-set on the borrowed-input
3316/// surface, plus a blanket-derived [`Into`] shape witness, a cross-
3317/// axis partition pin against the paired owned-input
3318/// [`From<RestartPolicy> for std::rc::Rc<str>`] and the sibling
3319/// borrowed-input `{&'static str, String, Cow<'static, str>, Box<str>,
3320/// std::sync::Arc<str>}` return-shape axes, and a
3321/// `.iter().map(std::rc::Rc::<str>::from)` pipe witness over
3322/// [`RestartPolicy::ALL`] that resolves through the borrowed-input
3323/// axis without a spurious [`Copy`] deref).
3324impl From<&RestartPolicy> for std::rc::Rc<str> {
3325 fn from(policy: &RestartPolicy) -> std::rc::Rc<str> {
3326 std::rc::Rc::<str>::from(policy.as_str())
3327 }
3328}
3329
3330/// Trait-idiomatic byte-view surface on the per-child restart-decision
3331/// policy typed enum.
3332///
3333/// Every consumer that binds its input through the standard-library
3334/// [`AsRef<[u8]>`] trait bound — a byte-keyed
3335/// `HashMap<K: AsRef<[u8]>, V>` per-policy reconciliation-decision
3336/// table lookup on the future wasm-operator supervisor scheduler; a
3337/// `blake3::Hasher::update` / `ring::digest::Context::update` /
3338/// `sha2::Sha256::update` byte-input surface on any future per-child
3339/// content-address digest folded into the [`crate::Lacre`] closure so
3340/// downstream cache-keys partition on the three OTP restart policies
3341/// (`Permanent`, `Temporary`, `Transient`) at content-address time; an
3342/// `std::io::Write::write_all`-bound structured-log per-arm byte-sink —
3343/// reaches the substrate primitive through one trait dispatch rather
3344/// than open-coding the two-hop `restart.as_str().as_bytes()`
3345/// composition at every call site. Routed byte-for-byte through the
3346/// [`RestartPolicy::as_str`] `pub const fn` accessor the paired
3347/// str-view ([`AsRef<str>`], [`std::fmt::Display`],
3348/// [`RestartPolicy::as_str`]) and the five reverse-projection
3349/// (`&'static str`, `String`, `Cow<'static, str>`, `Box<str>`,
3350/// `std::sync::Arc<str>`) return-shape axes already resolve through,
3351/// so any future divergence between the byte-view and str-view axes
3352/// trips at caixa-core test time rather than at a downstream byte-
3353/// consumer's silent split.
3354///
3355/// Peer of the sibling per-supervisor-restart-strategy axis
3356/// [`AsRef<[u8]> for RestartStrategy`] (cd4c4e0, the first M2-OTP-
3357/// shape supervisor slot enum to open this axis) — the sixth
3358/// closed-set fieldless typed enum on the caixa surface to converge
3359/// onto the trait-idiomatic byte-view discipline, and the second (and
3360/// final) M2-OTP-shape sibling to pick it up, closing the byte-view
3361/// axis across the paired `:supervisor :estrategia` +
3362/// `:children :restart` M2 slot pair. Pin load-bearing by the paired
3363/// [`tests::restart_policy_as_ref_bytes_routes_through_as_str_accessor`]
3364/// (fail-before-pass-after byte-parity pin against
3365/// [`RestartPolicy::as_str`] `.as_bytes()` across the three-arm
3366/// [`RestartPolicy::ALL`] emit-set, cross-axis witness against the
3367/// paired str-view [`AsRef<str>`] / [`std::fmt::Display`] /
3368/// [`RestartPolicy::as_str`] axes' `.as_bytes()` byte-tails,
3369/// cross-axis witness against the paired reverse-projection
3370/// `{&'static str, String, Cow<'static, str>, Box<str>,
3371/// std::sync::Arc<str>}` return-shape axes' `.as_bytes()` byte-tails,
3372/// a `<T: AsRef<[u8]>>`-bound-consumer witness that a generic
3373/// byte-input function accepts a [`RestartPolicy`] directly through
3374/// the trait bound, and a `blake3::Hasher::update`-shape byte-input
3375/// surface witness routed through the `<T: AsRef<[u8]>>`-bound
3376/// consumer axis to reach the caixa-lacre compounding target). Any
3377/// future silent detour that routes the byte-view impl off the
3378/// substrate-primitive [`RestartPolicy::as_str`] accessor (a per-arm
3379/// inline `b"Permanent".as_slice()`-shaped re-inlining that opens a
3380/// compile-time link to the un-lifted arm-literal, a swap onto the
3381/// kebab-case [`gen_platform::Discriminant`] catalog identity that
3382/// would collide the wire axis with the dispatcher-catalog axis) trips
3383/// at caixa-core test time rather than at a downstream byte-consumer's
3384/// silent split.
3385impl AsRef<[u8]> for RestartPolicy {
3386 fn as_ref(&self) -> &[u8] {
3387 self.as_str().as_bytes()
3388 }
3389}
3390
3391/// Trait-idiomatic *owned-input, owned-`Vec<u8>` output* byte-owned
3392/// reverse projection on the second (and final) M2 OTP-shape closed-set
3393/// fieldless typed enum peer on the caixa surface ([`RestartPolicy`]) —
3394/// the byte-mirror of the [`From<RestartPolicy> for String`] str-owned
3395/// reverse-projection axis and the owned-`Vec<u8>` reverse-projection
3396/// sibling of the paired [`AsRef<[u8]>`] borrowed byte-view axis
3397/// (98b08fa) lifted on this same enum. Routes byte-for-byte through
3398/// the substrate-primitive [`RestartPolicy::as_str`] `pub const fn`
3399/// accessor via [`str::as_bytes`] + [`slice::to_vec`] so every
3400/// consumer that binds a [`RestartPolicy`] through the standard-
3401/// library `impl From<RestartPolicy> for Vec<u8>` axis
3402/// (equivalently `<T: Into<Vec<u8>>>`) — a future
3403/// [`std::io::Write::write_all`]-shape per-child audit-log byte-sink
3404/// whose input parameter is an owned [`Vec<u8>`] payload, a future
3405/// `bytes::Bytes::from(Vec::<u8>::from(restart))` composer folding
3406/// the per-arm restart-decision-policy byte-tag into the
3407/// [`bytes::Bytes`] framing surface, a future
3408/// `hasher.update(&Vec::<u8>::from(restart))`-shape BLAKE3 content-
3409/// address closure that needs the owned byte-tail buffered before
3410/// folding into the [`crate::Lacre`] closure body, a future per-child
3411/// protobuf/CBOR/msgpack payload composer whose framer takes an owned
3412/// [`Vec<u8>`] rather than a borrowed byte-slice — reaches the
3413/// substrate primitive through one trait dispatch rather than an
3414/// open-coded per-call-site `restart.as_str().as_bytes().to_vec()`
3415/// composition whose type bounds have no compile-time link back to
3416/// the substrate primitive.
3417///
3418/// Closes the substrate-wide trait-idiomatic byte-owned reverse-
3419/// projection axis on the M2-OTP-shape `:supervisor :estrategia` +
3420/// `:children :restart` slot pair the sibling
3421/// [`RestartStrategy`] first-mover (63e5dd0) opened one commit prior,
3422/// matching the discipline the paired [`AsRef<[u8]>`] borrowed byte-
3423/// view axis campaign already carried across the same slot pair
3424/// (cd4c4e0 → 98b08fa). Every future arm addition (an OTP-
3425/// `intrinsic` fourth arm the theory
3426/// [`ABSORPTION-ROADMAP`](https://github.com/pleme-io/theory/blob/main/ABSORPTION-ROADMAP.md)
3427/// might reach for once the three canonical OTP restart policies
3428/// stop covering the substrate's discovered load-shape) grows the
3429/// byte-owned axis through one edit on the substrate-primitive
3430/// [`RestartPolicy::as_str`] accessor.
3431///
3432/// Pinned load-bearing by
3433/// [`tests::restart_policy_from_into_owned_vec_bytes_routes_through_as_str_accessor`]
3434/// (byte-parity pin against [`RestartPolicy::as_str`] across the
3435/// three-arm [`RestartPolicy::ALL`] emit-set binding the byte-owned
3436/// reverse-projection axis against the paired [`AsRef<[u8]>`]
3437/// borrowed byte-view axis and the str-owned reverse-projection
3438/// family (`String`, `Cow<'static, str>`, `Box<str>`,
3439/// `std::sync::Arc<str>`) `.into_bytes()` / `.as_bytes().to_vec()`
3440/// byte-tails, a `<T: Into<Vec<u8>>>`-bound generic-consumer witness,
3441/// and a `std::io::Write::write_all`-shape owned-byte-sink surface
3442/// witness on both owned and borrowed input shapes).
3443impl From<RestartPolicy> for Vec<u8> {
3444 fn from(policy: RestartPolicy) -> Vec<u8> {
3445 policy.as_str().as_bytes().to_vec()
3446 }
3447}
3448
3449/// Trait-idiomatic *borrowed-input, owned-`Vec<u8>` output* byte-
3450/// owned reverse projection on the second (and final) M2 OTP-shape
3451/// closed-set fieldless typed enum peer on the caixa surface
3452/// ([`RestartPolicy`]) — the borrowed-input peer of
3453/// [`From<RestartPolicy> for Vec<u8>`], closing the
3454/// `{Self, &Self} → Vec<u8>` pair on the byte-owned reverse-projection
3455/// axis in one lift. Routes byte-for-byte through the substrate-
3456/// primitive [`RestartPolicy::as_str`] `pub const fn` accessor so
3457/// every consumer that holds a borrowed [`&RestartPolicy`] and needs
3458/// an owned [`Vec<u8>`] — a future
3459/// `.iter().map(Vec::<u8>::from).collect()` pipe over
3460/// `&[RestartPolicy]` (whose iterator yields `&RestartPolicy`,
3461/// not `RestartPolicy`, so the owned-input axis alone forces every
3462/// call site through an explicit `.copied()` / spurious [`Copy`]
3463/// deref restatement rather than the direct trait-idiomatic
3464/// projection), a future admission-webhook rejection body composer
3465/// that walks [`RestartPolicy::ALL`] through an `Into<Vec<u8>>`-
3466/// bound per-arm byte-writer to surface the accepted `:children
3467/// :restart` set — reaches the substrate primitive through one
3468/// trait dispatch rather than a `Vec::<u8>::from(*policy)` spurious-
3469/// [`Copy`]-deref restatement.
3470impl From<&RestartPolicy> for Vec<u8> {
3471 fn from(policy: &RestartPolicy) -> Vec<u8> {
3472 policy.as_str().as_bytes().to_vec()
3473 }
3474}
3475
3476/// Trait-idiomatic *borrowed byte-slice input* reverse projection on the
3477/// second (and final) M2-OTP-shape closed-set fieldless typed enum peer on
3478/// the caixa surface ([`RestartPolicy`]) — the byte-view mirror of the
3479/// str-view reverse-projection axis carried by the paired
3480/// [`TryFrom<&str> for RestartPolicy`] impl (which routes through the
3481/// substrate-primitive [`RestartPolicy::from_wire`] `Option<Self>` accessor
3482/// on the three-arm `PascalCase` accept-set the sibling
3483/// [`RestartPolicy::as_str`] emitter returns). Routes byte-for-byte through
3484/// the standard-library [`std::str::from_utf8`] UTF-8 validator and then
3485/// through [`RestartPolicy::from_wire`] so every consumer that holds a
3486/// borrowed [`&[u8]`] and needs to project it back into a typed
3487/// [`RestartPolicy`] — a future `bytes::Bytes::as_ref()`-fed reader that
3488/// parses a per-child `:restart` `PascalCase` wire scalar from an
3489/// already-borrowed framing byte-tail (a
3490/// `tracing::field::valuable::Value::Bytes` recorder on the future
3491/// wasm-operator's per-child restart-decision diagnostic emission path, a
3492/// future audit-report re-loader binding a prior
3493/// [`RestartPolicy::as_str`] output from a mmap'd byte-slice back through
3494/// the typed enum for cross-run comparison), a future M4
3495/// `mesh.pleme.io/v1alpha1/Supervisor` CR admission-webhook rejection body
3496/// that reads a `spec.children[].restart` field off a raw HTTP body
3497/// byte-slice before UTF-8 validation commits allocation, a future generic
3498/// `<T: for<'a> TryFrom<&'a [u8]>>`-bound loader over any of the
3499/// substrate's closed-set typed enums — reaches the same three-arm
3500/// `PascalCase` wire accept-set the sibling method-named
3501/// [`RestartPolicy::from_wire`] resolver and the paired trait-idiomatic
3502/// [`TryFrom<&str>`] axis already resolve against, rather than an open-
3503/// coded per-call-site
3504/// `std::str::from_utf8(bytes).ok().and_then(RestartPolicy::from_wire)`
3505/// composition or a
3506/// `<RestartPolicy as TryFrom<&str>>::try_from(std::str::from_utf8(bytes)?)`
3507/// two-hop shape whose type bounds have no compile-time link to the
3508/// substrate primitive.
3509///
3510/// Closes the substrate-wide trait-idiomatic *byte-view reverse-projection*
3511/// family on the M2-OTP-shape `:supervisor :estrategia` + `:children
3512/// :restart` slot pair the sibling [`RestartStrategy`] first-mover
3513/// (c699a83) opened one commit prior — extends the family from
3514/// [`crate::CaixaKind`] (18d1940), [`crate::CaixaDialeto`] (d102cb8),
3515/// [`crate::dep::DepList`] (b8f25d5), and [`RestartStrategy`] (c699a83)
3516/// onto the second (and final) M2-OTP-shape closed-set fieldless typed
3517/// enum peer on the caixa surface, matching the trajectory the paired
3518/// byte-owned reverse-projection axis campaign already walked across the
3519/// same slot pair (63e5dd0 → 96a522a). Rust's standard library carries no
3520/// blanket `impl<T: for<'a> TryFrom<&'a str>> TryFrom<&[u8]> for T`, so a
3521/// two-hop composition through [`std::str::from_utf8`] + the paired
3522/// [`TryFrom<&str>`] axis is reachable at every call site but has no
3523/// compile-time link back to the byte-view reverse-projection axis. Every
3524/// remaining closed-set fieldless typed enum peer on the substrate
3525/// ([`crate::aplicacao::PlacementStrategy`],
3526/// [`crate::aplicacao::RateLimitUnit`], [`crate::aplicacao::WitShape`],
3527/// and the outside-`caixa-core` peers `PathShapeViolation`,
3528/// `InvariantKind`, `ArchVerdict`, `Severity`, `FixSafety`, `Semantic`,
3529/// `FerriteRuntime`) is a future target of the campaign.
3530///
3531/// `type Error = ()` matches the sibling [`RestartPolicy::from_wire`]'s
3532/// `Option<Self>` return-shape's deliberate deferral of error typing and
3533/// the paired trait-idiomatic [`TryFrom<&str>`] axis's unit-error shape —
3534/// the caller picks the diagnostic form appropriate for its use site (a
3535/// future `feira supervisor --restart …` arg-parse composes its own
3536/// per-verb "unknown restart policy: <arg> — accepted: {…}" message
3537/// enumerating [`RestartPolicy::WIRE_NAMES`]; a future admission-webhook
3538/// rejection body wraps the `Err(())` outcome with the accepted-set
3539/// enumeration for operator diagnostics; a `Result::map_err` at the call
3540/// site lifts the unit-error to a per-verb error type). Two rejection
3541/// paths route through the single unit-error: an invalid UTF-8
3542/// byte-sequence ([`std::str::from_utf8`] returns `Err`) and a valid UTF-8
3543/// byte-string that falls outside the three-arm `PascalCase` accept-set
3544/// ([`RestartPolicy::from_wire`] returns `None`) — both collapse onto
3545/// `Err(())` so the trait signature stays consistent with the sibling
3546/// str-view reverse axis, and a caller that needs to distinguish the two
3547/// failure modes composes [`std::str::from_utf8`] +
3548/// [`RestartPolicy::from_wire`] explicitly.
3549///
3550/// Pinned load-bearing by
3551/// [`tests::restart_policy_try_from_bytes_routes_through_from_wire_accessor`]
3552/// (byte-parity pin against [`RestartPolicy::from_wire`] across the
3553/// three-arm [`RestartPolicy::ALL`] accept-set on the borrowed byte-slice
3554/// surface, plus a cross-axis witness that the byte-view reverse
3555/// projection agrees with the paired [`TryFrom<&str>`] str-view reverse
3556/// axis on every accepted arm, and a forward/reverse byte-view cross-axis
3557/// witness that feeding the paired [`AsRef<[u8]>`] byte-tail back through
3558/// the new impl round-trips to the originating arm) and
3559/// [`tests::restart_policy_try_from_bytes_rejects_unknown_and_non_utf8_bytes`]
3560/// (rejection witness against silent accept-set widening on both the
3561/// non-UTF-8 byte-sequence rejection path and the unknown-wire-vocabulary
3562/// rejection path — the latter includes the sibling kebab-case
3563/// dispatcher-catalog byte-strings on the two-axis wire/catalog split so
3564/// a caller that confuses the two axes trips here rather than at a
3565/// downstream K8s-CR round-trip miss).
3566impl TryFrom<&[u8]> for RestartPolicy {
3567 type Error = ();
3568
3569 fn try_from(bytes: &[u8]) -> Result<Self, Self::Error> {
3570 std::str::from_utf8(bytes)
3571 .ok()
3572 .and_then(Self::from_wire)
3573 .ok_or(())
3574 }
3575}
3576
3577/// Trait-idiomatic *owned byte-vec input* reverse projection on the second
3578/// (and final) M2-OTP-shape supervisor-slot closed-set fieldless typed enum
3579/// peer on the caixa surface ([`RestartPolicy`]) — the owned-input peer of
3580/// [`TryFrom<&[u8]> for RestartPolicy`], closing the byte-view reverse-
3581/// projection *square* ({owned-input, borrowed-input} × {owned-output
3582/// byte-vec, borrowed-output byte-slice}) on the M2-OTP-shape
3583/// `:supervisor :estrategia` + `:children :restart` slot pair the sibling
3584/// [`RestartStrategy`] first-mover (34951fe) opened on the byte-owned
3585/// reverse-input axis one commit-window prior. Routes byte-for-byte through
3586/// [`<Self as TryFrom<&[u8]>>::try_from`] on the [`Vec<u8>::as_slice`]
3587/// borrow so the owned-input surface reaches the same
3588/// [`std::str::from_utf8`] + [`RestartPolicy::from_wire`] resolution chain
3589/// the borrowed-input peer already carries — one substrate-primitive
3590/// accessor, one trait dispatch, no per-consumer detour.
3591///
3592/// Rust's standard library carries no blanket
3593/// `impl<T: for<'a> TryFrom<&'a [u8]>> TryFrom<Vec<u8>> for T`, so a
3594/// consumer that holds an owned [`Vec<u8>`] and needs a typed
3595/// [`RestartPolicy`] otherwise picks between (a) an open-coded
3596/// `<RestartPolicy as TryFrom<&[u8]>>::try_from(bytes.as_slice())` at every
3597/// call site (whose type bounds have no compile-time link to the byte-
3598/// owned reverse-projection axis), (b) a two-hop
3599/// `String::from_utf8(bytes)` + [`RestartPolicy::from_wire`] composition
3600/// whose error surface leaks the standard-library
3601/// [`std::string::FromUtf8Error`] (widening the sibling [`TryFrom<&[u8]>`]
3602/// axis's unit-error) and silently allocates a [`String`] on inputs that
3603/// will never make it past the wire vocabulary, or (c) an intermediate
3604/// `<RestartPolicy as TryFrom<&str>>::try_from(std::str::from_utf8(&bytes)?)`
3605/// three-hop shape. This impl closes the owned-byte-vec reverse-projection
3606/// axis at the substrate-primitive [`RestartPolicy::from_wire`] accessor so
3607/// every future `<T: TryFrom<Vec<u8>>>`-bound owned-byte-vec consumer — a
3608/// future M4 `mesh.pleme.io/v1alpha1/Supervisor` CR admission-webhook body
3609/// reader that hands the `spec.children[].restart` byte-tail off as a
3610/// [`Vec<u8>`] before UTF-8 validation commits allocation, a
3611/// `bytes::Bytes::to_vec()`-shape wire-body composer walking a prior
3612/// audit's per-child rejection payload back to the typed enum, a
3613/// `std::io::Read::read_to_end`-shape audit-log source whose framing yields
3614/// an owned byte-vec per per-policy scalar, an
3615/// `<T: TryFrom<Vec<u8>>>`-bound generic loader over any of the
3616/// substrate's closed-set typed enums — reaches the same three-arm
3617/// `PascalCase` wire accept-set through one trait dispatch.
3618///
3619/// Extends the substrate-wide trait-idiomatic *byte-owned reverse-
3620/// projection* family — opened on the structurally most fundamental
3621/// closed-set fieldless typed enum peer ([`crate::CaixaKind`], commit
3622/// 99c2849), extended onto the second caixa-core-internal peer
3623/// ([`crate::CaixaDialeto`], commit 83a1526), the third
3624/// ([`crate::dep::DepList`], commit 42091cb), and the first M2-OTP-shape
3625/// supervisor-slot peer ([`RestartStrategy`], commit 34951fe) — onto the
3626/// second (and final) M2-OTP-shape supervisor-slot closed-set fieldless
3627/// typed enum peer, tracking the "delegate through `TryFrom<&[u8]>` on the
3628/// `Vec<u8>::as_slice` borrow" discipline the first-mover established.
3629/// Every remaining closed-set fieldless typed enum peer on the substrate
3630/// ([`crate::aplicacao::PlacementStrategy`],
3631/// [`crate::aplicacao::RateLimitUnit`], [`crate::aplicacao::WitShape`],
3632/// [`crate::render::PathShapeViolation`], and the outside-`caixa-core`
3633/// peers `InvariantKind`, `ArchVerdict`, `Severity`, `FixSafety`,
3634/// `Semantic`, `FerriteRuntime`) is a future target of the campaign,
3635/// mirroring the trajectory the closed byte-view reverse-projection
3636/// family (`TryFrom<&[u8]>`) and the closed byte-owned forward-projection
3637/// family (`From<{Self, &Self}> for Vec<u8>`) already walked across the
3638/// same slot pair.
3639///
3640/// `type Error = ()` matches the sibling [`TryFrom<&[u8]> for
3641/// RestartPolicy`] unit-error shape, preserving the trait-family
3642/// consistency across the borrowed-and-owned byte-view reverse-projection
3643/// pair. The owned [`Vec<u8>`] input is dropped on the error path (the
3644/// standard-library `String::from_utf8` convention of returning the input
3645/// in the error deliberately declined — a caller that needs the bytes back
3646/// holds a clone before the call, and the closed-set-enum use site rarely
3647/// wants the raw bytes back past a "did you mean" diagnostic that operates
3648/// on the wire vocabulary rather than the input).
3649///
3650/// Pinned load-bearing by
3651/// [`tests::restart_policy_try_from_vec_bytes_routes_through_borrowed_byte_view_axis`]
3652/// (byte-parity pin against the paired borrowed [`TryFrom<&[u8]>`] axis
3653/// across the three-arm [`RestartPolicy::ALL`] accept-set on the owned
3654/// byte-vec surface, cross-axis witness that the byte-owned reverse
3655/// projection agrees with the paired str-view reverse-projection axis
3656/// ([`TryFrom<&str>`]) on every accepted arm through the shared substrate-
3657/// primitive [`RestartPolicy::from_wire`] accessor, and a four-corner
3658/// {owned-input, borrowed-input} × {`From<Self>` → `Vec<u8>`,
3659/// `From<&Self>` → `Vec<u8>`} round-trip witness available on this enum
3660/// because [`RestartPolicy::as_str`] and [`RestartPolicy::from_wire`]
3661/// share one `PascalCase` byte-vocabulary — like the sibling
3662/// [`RestartStrategy`] and unlike the sibling [`crate::CaixaKind`] which
3663/// its peer test deliberately declines the four-corner witness on because
3664/// the wire/diagnostic split makes the forward and reverse pairs speak
3665/// different byte-strings) and
3666/// [`tests::restart_policy_try_from_vec_bytes_rejects_unknown_and_non_utf8_bytes`]
3667/// (rejection witness against silent accept-set widening on both the
3668/// non-UTF-8 byte-sequence rejection path and the unknown-wire-vocabulary
3669/// rejection path — the latter includes the sibling kebab-case
3670/// dispatcher-catalog byte-strings on the two-axis wire/catalog split so
3671/// a caller that confuses the two axes trips here rather than at a
3672/// downstream K8s-CR round-trip miss, plus a cross-axis witness that the
3673/// owned byte-vec reverse-projection axis agrees with the borrowed byte-
3674/// slice reverse-projection axis on every rejected input).
3675impl TryFrom<Vec<u8>> for RestartPolicy {
3676 type Error = ();
3677
3678 fn try_from(bytes: Vec<u8>) -> Result<Self, Self::Error> {
3679 <Self as TryFrom<&[u8]>>::try_from(bytes.as_slice())
3680 }
3681}
3682
3683/// Trait-idiomatic *owned-`String` input, `Result<Self, ()>` output*
3684/// string-owned reverse projection on the second (and final) M2-OTP-shape
3685/// supervisor-slot closed-set fieldless typed enum peer on the caixa
3686/// surface ([`RestartPolicy`]) — the owned-input peer of the paired
3687/// [`TryFrom<&str> for RestartPolicy`] str-view reverse-projection axis,
3688/// and the string-owned reverse companion of the pre-existing string-owned
3689/// *forward* pair ([`From<RestartPolicy> for String`],
3690/// [`From<&RestartPolicy> for String`]) already lifted on this same enum.
3691/// Routes owned [`String`] input through the paired borrowed-input
3692/// [`TryFrom<&str>`] axis via [`String::as_str`] so every consumer that
3693/// holds an owned `String` — a future M4 `mesh.pleme.io/v1alpha1/Supervisor`
3694/// CR admission-webhook body reader that hands the
3695/// `spec.children[].restart` `PascalCase` scalar off as an owned [`String`]
3696/// after UTF-8 validation, a `serde_yaml::from_str` / `serde_json::from_str`
3697/// de-serialize round-trip whose composer surfaces the `:children :restart`
3698/// scalar as an owned [`String`] typed field, a
3699/// `feira supervisor --restart <Permanent|Temporary|Transient>`
3700/// `clap`-derived arg-parse whose owned-`String` positional lands the
3701/// canonical arm at the typed dispatch, a per-`:children`-slot overlay
3702/// resolver reading an owned [`String`] out of a `ConfigMap`
3703/// `data.children-restart` scalar, an `<T: TryFrom<String>>`-bound generic
3704/// loader over any of the substrate's closed-set typed enums — reaches the
3705/// same three-arm `PascalCase` accept-set through one trait dispatch.
3706///
3707/// Extends the substrate-wide trait-idiomatic *string-owned reverse-
3708/// projection* family — opened on the compound M3-mesh
3709/// `:politicas :rate-limit` primitive [`crate::aplicacao::RateLimit`]
3710/// (a2e6f02), lifted onto the first closed-set fieldless typed-enum peer
3711/// [`crate::aplicacao::WitShape`] (e6aac29), extended onto the second
3712/// closed-set fieldless typed-enum peer [`crate::aplicacao::RateLimitUnit`]
3713/// (94a9c5e), extended onto the third closed-set fieldless typed-enum peer
3714/// [`crate::aplicacao::PlacementStrategy`] (d81a70a), extended onto the
3715/// first M2-OTP-shape supervisor-slot closed-set fieldless typed-enum peer
3716/// [`RestartStrategy`] (78fe8c8) — onto the second (and final) M2-OTP-shape
3717/// supervisor-slot closed-set fieldless typed-enum peer, the per-`:children`
3718/// restart-decision-policy discriminator. This closes the string-owned
3719/// reverse-projection axis on the M2-OTP-shape `:supervisor :estrategia` +
3720/// `:children :restart` slot pair, mirroring the trajectory the byte-view
3721/// / byte-owned / str-view reverse-projection families already walked
3722/// across the same slot pair. The peers [`crate::CaixaKind`],
3723/// [`crate::CaixaDialeto`], and [`crate::dep::DepList`] remain the next
3724/// targets of the campaign.
3725///
3726/// Rust's standard library carries no blanket
3727/// `impl<T: for<'a> TryFrom<&'a str>> TryFrom<String> for T`, so a consumer
3728/// that holds an owned [`String`] and needs a typed [`RestartPolicy`]
3729/// otherwise picks between (a) an open-coded
3730/// `<RestartPolicy as TryFrom<&str>>::try_from(s.as_str())` at every call
3731/// site whose type bounds have no compile-time link back to the string-
3732/// owned reverse-projection axis, (b) a `let s: &str = &s;
3733/// RestartPolicy::try_from(s)` two-step whose borrow arithmetic leaks a
3734/// per-call-site lifetime dance rather than a single trait dispatch, or
3735/// (c) a `String::into_bytes` + [`TryFrom<Vec<u8>>`] detour that reaches
3736/// the substrate-primitive `from_wire` accessor through a UTF-8 re-
3737/// validation hop the owned-`String` axis already knows to skip. This
3738/// impl closes the string-owned reverse-projection axis at the substrate-
3739/// primitive [`RestartPolicy::from_wire`] accessor so every future
3740/// `<T: TryFrom<String>>`-bound owned-string consumer reaches the same
3741/// three-arm `PascalCase` accept-set through one trait dispatch.
3742///
3743/// `type Error = ()` matches the sibling [`TryFrom<&str> for
3744/// RestartPolicy`], [`TryFrom<&[u8]> for RestartPolicy`], and
3745/// [`TryFrom<Vec<u8>> for RestartPolicy`] unit-error shapes, preserving
3746/// the trait-family consistency across the {str-view, byte-view, byte-
3747/// owned, string-owned} reverse-projection square. The owned [`String`]
3748/// input is dropped on the error path (the standard-library
3749/// `String::from_utf8` convention of returning the input in the error
3750/// deliberately declined — a caller that needs the string back holds a
3751/// clone before the call, and the closed-set-enum use site rarely wants
3752/// the raw string back past a "did you mean" diagnostic that operates on
3753/// the wire vocabulary rather than the input).
3754///
3755/// Pinned load-bearing by
3756/// [`tests::restart_policy_try_from_owned_string_routes_through_borrowed_str_view_axis`]
3757/// (byte-parity pin against the paired borrowed [`TryFrom<&str>`] axis
3758/// across the three-arm [`RestartPolicy::ALL`] accept-set on the owned-
3759/// `String` surface, cross-axis witness that the string-owned reverse
3760/// projection agrees with the sibling byte-view / byte-owned reverse-
3761/// projection axes on every accepted arm through the shared substrate-
3762/// primitive [`RestartPolicy::from_wire`] accessor, and a closed-cycle
3763/// witness against the paired string-owned forward-projection pair —
3764/// `Self → String → TryFrom<String> → Self` round-trips to the
3765/// originating arm on every canonical `PascalCase` scalar) and
3766/// [`tests::restart_policy_try_from_owned_string_rejects_unknown_wire_strings`]
3767/// (rejection witness against silent accept-set widening — mirrors the
3768/// corpus the paired [`TryFrom<&str>`] rejection witness already pins,
3769/// including empty / whitespace-only inputs, the sibling kebab-case
3770/// dispatcher-catalog byte-strings on the two-axis wire/catalog split so
3771/// a caller that confuses the two axes trips here rather than at a
3772/// downstream K8s-CR round-trip miss, case-fold rebrand candidates,
3773/// whitespace-padded / trailing-newline / quote-wrapped forms, and
3774/// English-rebrand candidates, with per-input cross-axis parity against
3775/// the borrowed [`TryFrom<&str>`] reverse-projection axis).
3776impl TryFrom<String> for RestartPolicy {
3777 type Error = ();
3778
3779 fn try_from(s: String) -> Result<Self, Self::Error> {
3780 <Self as TryFrom<&str>>::try_from(s.as_str())
3781 }
3782}
3783
3784// Fleet-wide dispatcher-catalog registrations for caixa's OTP
3785// supervisor surface — two more typed shadows over Erlang/OTP
3786// primitives the substrate now mechanically tracks (see
3787// theory/UNIFIED-COMPUTING-MODEL.md §VI for the roadmap +
3788// theory/TYPED-ABSORPTION.md for the absorption arc).
3789gen_platform::register_dispatcher!("caixa.restart-strategy", RestartStrategy);
3790gen_platform::register_dispatcher!("caixa.restart-policy", RestartPolicy);
3791
3792/// One child entry in the supervisor's `:children` list.
3793///
3794/// Every child references another caixa by `:caixa <nome>` + version
3795/// constraint. The supervisor materializes one ComputeUnit per entry.
3796#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq)]
3797#[serde(rename_all = "camelCase")]
3798pub struct ChildSpec {
3799 /// The child caixa's `:nome`. Must resolve via the same dependency
3800 /// resolution path as `:deps` (caixa-resolver).
3801 pub caixa: String,
3802
3803 /// Semver constraint (`"^0.1"`, `"~0.1.2"`, etc.) — same shape as
3804 /// [`crate::dep::Dep::versao`].
3805 pub versao: String,
3806
3807 /// Restart policy — an author-omitted slot degrades onto the
3808 /// substrate-canonical [`SUPERVISOR_CHILD_RESTART_DEFAULT`]
3809 /// (`permanent`, the Erlang/OTP worker-child default) through the
3810 /// [`Default for RestartPolicy`] impl this `#[serde(default)]` routes
3811 /// to.
3812 #[serde(default)]
3813 pub restart: RestartPolicy,
3814}
3815
3816impl ChildSpec {
3817 /// Substrate-canonical per-`:children` child-caixa `:nome` scalar
3818 /// accessor every consumer that reads the OTP-shape supervised
3819 /// child's identity keys off — returns the author-declared
3820 /// `:children :caixa` byte-string verbatim as a `&str`, borrowed
3821 /// from the typed slot's own [`String`] storage.
3822 ///
3823 /// The `:children :caixa` slot carries the DNS-1123 label — the
3824 /// child caixa's `:nome` — that every emitted cluster artifact
3825 /// derives its `metadata.name` from verbatim: the rendered
3826 /// `wasm.pleme.io/v1alpha1/ComputeUnit.metadata.name` per child, the
3827 /// [`crate::LABEL_PROGRAM`] label value on every child's pod
3828 /// identity, and the per-child K8s Service `metadata.name` the
3829 /// future wasm-operator (M3) provisions for inter-child supervision-
3830 /// tree wiring. Every downstream consumer that fans on the child's
3831 /// caixa-name keys off this scalar (the [`SupervisorSpec::validate`]
3832 /// per-child DNS-1123 gate at
3833 /// `require_valid_dns_1123_label(child.nome(), …)`, the per-child
3834 /// duplicate-detection [`crate::render::insert_first_seen`] key, the
3835 /// [`validate_no_self_supervision`] cross-slot equality check
3836 /// against the parent's `:nome`, every `SupervisorError` variant
3837 /// carrying the offending child caixa verbatim for `feira lint`
3838 /// rendering, the future wasm-operator's hierarchical reconciliation
3839 /// scheduler's per-child ComputeUnit-name projection, the future M4
3840 /// `mesh.pleme.io/v1alpha1/Supervisor` CR materializer's per-child
3841 /// admission webhook).
3842 ///
3843 /// Prior to this lift the `.caixa` byte-string was accessed inline
3844 /// at seven sites in `supervisor.rs` — the DNS-1123 gate's
3845 /// `&child.caixa`, the four `SupervisorError::{ChildCaixaInvalid,
3846 /// EmptyChildVersion, ChildVersaoInvalid, DuplicateChildCaixa}`
3847 /// carriers' `child.caixa.clone()`, the dedup key's
3848 /// `child.caixa.as_str()`, and the [`validate_no_self_supervision`]
3849 /// `child.caixa == parent_nome` cross-slot check — seven open-coded
3850 /// field-accesses that expressed no compile-time link back to the
3851 /// typed slot. A future extension of the `:children :caixa` axis to
3852 /// a richer author surface (a per-cluster alias table the operator
3853 /// pins through a future `:placement`-scoped slot on the supervisor
3854 /// tree, a namespace-qualified rewrite the M4 CR materializer
3855 /// applies per-CR, a per-child overlay from the future `:children
3856 /// :nome-suffix` slot the MESH-COMPOSITION §III.2 roadmap
3857 /// acknowledges) would have had to be threaded through every
3858 /// open-coded copy in lockstep or one consumer would silently
3859 /// disagree with the peers on which caixa a given child resolves to
3860 /// — a child-set lookup that treated the name as `"cart-worker"`
3861 /// while the peer duplicate-detector treated it as
3862 /// `"tenant-a/cart-worker"` would silently split the
3863 /// `DuplicateChildCaixa` membership-lookup diagnostic from the
3864 /// self-supervision detector's parent-equality check, a two-consumer
3865 /// split at the validator far from the source `caixa.lisp` with no
3866 /// field naming the identity-drift root cause. Lifting the resolution
3867 /// rule to a typed method on the substrate primitive means every
3868 /// downstream consumer of the Supervisor's per-`:children` identity
3869 /// surface reaches for exactly one typed dispatch — the resolver's
3870 /// accept-set migrates as a unit on any future axis addition.
3871 ///
3872 /// Sibling of the peer per-`:membros` [`crate::Membro::nome`]
3873 /// (4a32abf) member-caixa `:nome` scalar accessor on the M3
3874 /// mesh-slot surface — same "one typed dispatch on the substrate
3875 /// primitive, thin projections at each consumer" discipline extended
3876 /// onto the M2 supervisor-tree per-`:children` child-identity axis.
3877 /// The two typed axes (`Membro::nome` on the M3 Aplicacao side,
3878 /// `ChildSpec::nome` on the M2 Supervisor side) now share one
3879 /// accessor discipline for the shared substrate concept "another
3880 /// caixa referenced by `:nome`". Peer of the second M2 slot scalar
3881 /// accessor [`crate::UpgradeFromEntry::prior_versao`] (75d27a8) on
3882 /// the sibling per-`:upgrade-from :from` OTP-appup axis — the M2
3883 /// slot family's typed-accessor discipline now spans both the
3884 /// upgrade axis (`:upgrade-from`) and the supervision axis
3885 /// (`:children`), matching the closed M3 mesh-slot accessor family's
3886 /// shape. Named `nome()` to match the tatara-lisp author-surface
3887 /// term the field's docstring already reaches for ("The child
3888 /// caixa's `:nome`") and the peer [`crate::Membro::nome`] /
3889 /// [`crate::Caixa::nome`] / [`crate::dep::Dep::nome`] field-name
3890 /// discipline the substrate already carries — the accessor's name
3891 /// maps directly onto the canonical caixa-identity vocabulary rather
3892 /// than shadowing the field's storage-side `caixa` label.
3893 #[must_use]
3894 pub const fn nome(&self) -> &str {
3895 self.caixa.as_str()
3896 }
3897
3898 /// Substrate-canonical per-`:children` child-caixa `:versao` semver-
3899 /// requirement scalar accessor every consumer that reads the OTP-shape
3900 /// supervised child's version pin keys off — returns the author-declared
3901 /// `:children :versao` byte-string verbatim as a `&str`, borrowed from
3902 /// the typed slot's own [`String`] storage.
3903 ///
3904 /// The `:children :versao` slot carries the Cargo-shaped semver
3905 /// requirement string (`"^0.1"`, `"~0.1.2"`, `"0.1.0"`, `"*"`) that pins
3906 /// which release of the supervised child caixa the OTP-shape supervisor
3907 /// tree materializes against — the same requirement grammar the peer
3908 /// `:deps :versao` / `:membros :versao` axes carry, resolved through the
3909 /// shared [`crate::render::require_valid_versao_requirement`] cascade
3910 /// and the shared [`crate::version::parse_requirement`] parser. Every
3911 /// downstream consumer that fans on the child's version pin keys off
3912 /// this scalar (the [`SupervisorSpec::validate`] per-child requirement
3913 /// gate at `require_valid_versao_requirement(child.versao_requirement(),
3914 /// …)`, the [`SupervisorError::ChildVersaoInvalid`] variant's carrier
3915 /// for `feira lint` rendering, every future per-cluster version-lock
3916 /// overlay the caixa-operator's hierarchical reconciliation scheduler
3917 /// pins through a future `:placement`-scoped supervisor-tree slot, the
3918 /// future M4 `mesh.pleme.io/v1alpha1/Supervisor` CR materializer's
3919 /// per-child version resolver, the future wasm-operator's per-child
3920 /// lacre BLAKE3-closure lookup at `ComputeUnit` materialization time).
3921 ///
3922 /// Prior to this lift the `.versao` byte-string was accessed inline at
3923 /// two `&str`-shaped sites in `caixa-core/src/supervisor.rs` — the
3924 /// [`SupervisorSpec::validate`] requirement-gate call
3925 /// `require_valid_versao_requirement(&child.versao, …)` and the
3926 /// [`SupervisorError::ChildVersaoInvalid`] carrier at
3927 /// `versao: child.versao.clone()` — two open-coded field-accesses that
3928 /// expressed no compile-time link back to the typed slot. A future
3929 /// extension of the `:children :versao` axis to a richer author surface
3930 /// (a per-cluster version-pin overlay per MESH-COMPOSITION §III.2 canary
3931 /// flow, a lacre-projected concrete-version rewrite the operator
3932 /// materializes at CR-admission time, a future `:children :versao-lock`
3933 /// per-cluster override slot the wasm-operator's hierarchical
3934 /// reconciliation scheduler authors per-CR) would have had to be
3935 /// threaded through both open-coded copies in lockstep or one consumer
3936 /// would silently disagree with the peer on which release constraint a
3937 /// given child resolves to — the requirement-gate call reading
3938 /// `"^0.1"` while the error-body carrier read `"tenant-a-pin/^0.1"`
3939 /// would silently split the `ChildVersaoInvalid` diagnostic quote from
3940 /// the actual gate rejection input, a two-consumer split at the
3941 /// validator far from the source `caixa.lisp` with no field naming the
3942 /// version-pin drift root cause. Lifting the resolution rule to a typed
3943 /// method on the substrate primitive means every downstream
3944 /// requirement-facing consumer of the Supervisor's per-`:children`
3945 /// version-pin surface reaches for exactly one typed dispatch — the
3946 /// resolver's accept-set migrates as a unit on any future axis addition.
3947 ///
3948 /// Sibling of the peer per-`:membros` [`crate::Membro::versao_requirement`]
3949 /// (a40b0e3) member-caixa `:versao` scalar accessor on the M3 mesh-slot
3950 /// surface — same "one typed dispatch on the substrate primitive, thin
3951 /// projections at each consumer" discipline extended onto the M2
3952 /// supervisor-tree per-`:children` child-version-pin axis. The two typed
3953 /// axes (`Membro::versao_requirement` on the M3 Aplicacao side,
3954 /// `ChildSpec::versao_requirement` on the M2 Supervisor side) now share
3955 /// one accessor discipline for the shared substrate concept "another
3956 /// caixa referenced by a Cargo-shaped semver requirement". Peer of the
3957 /// sibling per-`:children` [`ChildSpec::nome`] (57c61d0) child-caixa
3958 /// `:nome` scalar accessor — the pair
3959 /// `(nome(), versao_requirement())` jointly projects the
3960 /// `(caixa, versao)` field pair every OTP-shape supervisor-tree consumer
3961 /// that fans on per-child identity + version pin keys off, closing the
3962 /// last unlifted per-`:children` `String`-carry axis so every downstream
3963 /// per-`:children` reader now routes through a typed dispatch on the
3964 /// substrate primitive. Named `versao_requirement()` rather than
3965 /// `versao()` because the field's storage-side `.versao` label is
3966 /// already the author-surface term (`:versao`); the accessor's name
3967 /// carries the semantic role — the semver *requirement* string the
3968 /// shared [`crate::version::parse_requirement`] entry-point consumes —
3969 /// so a raw field access and a typed dispatch read differently at every
3970 /// consumer site. Matches the peer [`crate::Membro::versao_requirement`]
3971 /// naming discipline verbatim.
3972 #[must_use]
3973 pub const fn versao_requirement(&self) -> &str {
3974 self.versao.as_str()
3975 }
3976
3977 /// Substrate-canonical per-`:children` `:restart` OTP-shaped
3978 /// per-child post-exit restart-decision policy scalar accessor every
3979 /// consumer that dispatches on the supervised child's post-exit
3980 /// reconcile posture keys off — returns the author-declared
3981 /// `:children :restart` variant verbatim as a [`RestartPolicy`],
3982 /// `Copy`-projected from the typed slot's own [`RestartPolicy`]
3983 /// storage.
3984 ///
3985 /// The `:children :restart` slot carries the closed-set OTP-shaped
3986 /// per-child restart-decision policy discriminator
3987 /// ([`RestartPolicy::Permanent`] — always restart, the OTP `permanent`
3988 /// worker-child default; [`RestartPolicy::Transient`] — restart only
3989 /// on abnormal exit, the OTP `transient` clean-completion-aware
3990 /// default; [`RestartPolicy::Temporary`] — never restart, the OTP
3991 /// `temporary` one-shot default) that every downstream consumer of
3992 /// the Supervisor's per-child post-exit reconcile branch keys off.
3993 /// Every future downstream consumer that fans on the per-child
3994 /// restart-decision keys off this scalar (the future `feira app
3995 /// graph` per-child restart column, the future wasm-operator's
3996 /// per-child post-exit restart-decision branch, the future M4
3997 /// `mesh.pleme.io/v1alpha1/Supervisor` CR materializer's per-child
3998 /// admission webhook, the `caixa-operator`'s hierarchical
3999 /// reconciliation scheduler's per-child post-exit reconcile branch,
4000 /// the [`RestartPolicy::as_str`] `Serialize`-derive-pinning path the
4001 /// [`tests::restart_policy_variants_serialize_to_lifted_scalar_values`]
4002 /// pin threads through).
4003 ///
4004 /// Peer of the sibling per-`:supervisor` [`SupervisorSpec::estrategia`]
4005 /// (eafb619) `Copy`-return [`RestartStrategy`] sibling-restart-strategy
4006 /// scalar accessor and the M3 mesh-slot
4007 /// [`crate::Placement::estrategia`] (921fe1b) `Copy`-return
4008 /// [`crate::PlacementStrategy`] distribution-strategy scalar accessor
4009 /// — same "one typed dispatch on the substrate primitive,
4010 /// `Copy`-projected closed-set enum-arm discriminator that partitions
4011 /// the downstream renderer's per-arm fan-out" discipline extended
4012 /// onto the M2 supervisor-slot per-`:children` restart-decision-policy
4013 /// `Copy`-composite-enum scalar axis. Third axis on the per-`:children`
4014 /// [`ChildSpec`] type — companion to the sibling per-`:children`
4015 /// [`ChildSpec::nome`] (57c61d0) child-caixa `:nome` scalar accessor
4016 /// and the per-`:children` [`ChildSpec::versao_requirement`]
4017 /// (2c053c8) child-caixa `:versao` semver-requirement scalar accessor
4018 /// on the sibling `String`-carry axes. The triple
4019 /// `(nome(), versao_requirement(), restart())` jointly projects the
4020 /// `(caixa, versao, restart)` field trio every OTP-shape supervisor-
4021 /// tree consumer that fans on per-child identity + version pin +
4022 /// restart-decision keys off, closing the last unlifted per-`:children`
4023 /// axis so every downstream per-`:children` reader now routes through
4024 /// a typed dispatch on the substrate primitive. Named `restart()` to
4025 /// match the storage field's name and the author-surface
4026 /// `:children :restart` slot term verbatim; the accessor's identity
4027 /// name maps onto the canonical OTP-shape per-child restart-decision-
4028 /// policy vocabulary the [`RestartPolicy`] enum's docstring already
4029 /// carries.
4030 ///
4031 /// Declared `pub const fn` to close the last non-`const`
4032 /// `Copy`-return raw-field-getter posture on the M2
4033 /// per-`:children` [`ChildSpec`] substrate-primitive surface — peer
4034 /// of the sibling M2 per-`:supervisor`
4035 /// [`SupervisorSpec::estrategia`] (converted in this commit)
4036 /// `Copy`-composite-enum accessor, the sibling M2 per-`:supervisor`
4037 /// [`SupervisorSpec::max_restarts`] (b698ec0) `Copy`-`u32` accessor
4038 /// already lifted, and the peer M3 mesh-slot per-`:entrada`
4039 /// [`crate::Entrada::port`] (bafa004) / per-`:placement`
4040 /// [`crate::Placement::estrategia`] (bafa004) `Copy`-return
4041 /// `pub const fn` scalar accessors on the sibling M3 surface. Every
4042 /// downstream substrate-side `const`-context consumer of the
4043 /// per-`:children` restart-decision-policy scalar (a future
4044 /// module-scope `const _:() = assert!(matches!(child.restart(),
4045 /// RestartPolicy::Permanent))` invariant pin on a typed fixture, a
4046 /// future M4 `mesh.pleme.io/v1alpha1/Supervisor` CR materializer
4047 /// admission-webhook `const fn` per-child restart-decision floor
4048 /// over a typed [`ChildSpec`], any future `const fn` supervisor-tree
4049 /// composer over the substrate primitive that fans on the per-child
4050 /// restart-decision policy at compile time) now reaches through the
4051 /// same typed dispatch on the substrate primitive at const-eval
4052 /// time as at runtime. A future non-`Copy`-return promotion of the
4053 /// scalar (an `Option<RestartPolicy>`-shape migration on the
4054 /// per-child restart-decision axis once heterogeneous per-cluster
4055 /// restart-policy overlays land, a per-tenant restart-policy-alias
4056 /// table the M4 CR materializer resolves per-CR) that would drop
4057 /// the `const` qualifier fails the fail-before-pass-after pin
4058 /// [`tests::child_spec_restart_accessor_is_const_fn`] at caixa-core
4059 /// build time rather than surfacing as a downstream consumer
4060 /// regression.
4061 #[must_use]
4062 pub const fn restart(&self) -> RestartPolicy {
4063 self.restart
4064 }
4065}
4066
4067/// Supervisor-typed slots that live alongside the standard Caixa
4068/// fields when `:kind Supervisor`. Held flat in [`crate::Caixa`] so
4069/// the manifest stays a single typed form; this struct exists for
4070/// validation + conversion.
4071#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq)]
4072#[serde(rename_all = "camelCase")]
4073pub struct SupervisorSpec {
4074 /// Restart strategy. Defaults to [`RestartStrategy::OneForOne`].
4075 #[serde(default)]
4076 pub estrategia: RestartStrategy,
4077
4078 /// Max restarts within [`Self::restart_window`] before the
4079 /// supervisor itself terminates (and its parent supervisor decides
4080 /// what to do). Default 5.
4081 #[serde(default = "default_max_restarts")]
4082 pub max_restarts: u32,
4083
4084 /// Sliding window for `max_restarts`. Authored as a duration
4085 /// string (`"60s"`, `"5m"`); absent = "never reset". A `Some(0s)`
4086 /// is rejected by [`Self::validate`] — Erlang/OTP's
4087 /// `MaxIntensity / Period` invariant requires a positive window
4088 /// (a zero-period supervisor either trips on the first failure or
4089 /// never trips, depending on operator interpretation, neither of
4090 /// which is the author's intent). Omit the slot to express "no
4091 /// reset"; carry a positive duration to express the sliding window.
4092 #[serde(
4093 default,
4094 skip_serializing_if = "Option::is_none",
4095 with = "duration_codec"
4096 )]
4097 pub restart_window: Option<Duration>,
4098
4099 /// Static children. Empty for `SimpleOneForOne` (children added
4100 /// dynamically); required for the other three strategies.
4101 #[serde(default)]
4102 pub children: Vec<ChildSpec>,
4103}
4104
4105const fn default_max_restarts() -> u32 {
4106 // Route the private serde-`#[serde(default = "…")]` helper through
4107 // the substrate-canonical [`SUPERVISOR_MAX_RESTARTS_DEFAULT`] typed
4108 // `pub const` rather than the raw `5` literal — one source of truth
4109 // for the Erlang/OTP-canonical `{intensity, 5, 60}` `MaxIntensity`
4110 // default across the two production consumers that currently
4111 // dispatch on it (this helper via `#[serde(default = "…")]` on
4112 // `SupervisorSpec::max_restarts` and the [`Default for SupervisorSpec`]
4113 // impl at line 962). Pinned by
4114 // `default_max_restarts_helper_routes_through_lifted_default` +
4115 // `supervisor_spec_default_max_restarts_routes_through_lifted_default`
4116 // in the tests module; peer of the sibling caixa-core
4117 // [`crate::manifest::Caixa::supervisor_view`] `unwrap_or(…)` fold
4118 // that now routes its author-omitted `:max-restarts` arm through
4119 // the same lifted constant.
4120 SUPERVISOR_MAX_RESTARTS_DEFAULT
4121}
4122
4123/// Substrate-canonical Erlang/OTP-shaped `MaxIntensity` restart-budget-
4124/// count default for the `:supervisor :max-restarts` axis — the
4125/// canonical `{intensity, 5, 60}` `MaxIntensity` half of Learn You Some
4126/// Erlang's worker-supervisor default, extracted as a typed `pub const`
4127/// so every substrate-side consumer that resolves "what
4128/// [`SupervisorSpec::max_restarts`] value does an author-omitted
4129/// `:max-restarts` slot degrade onto?" reaches for exactly one
4130/// substrate-primitive `u32`.
4131///
4132/// The `:max-restarts` default axis has two production consumers on the
4133/// substrate side today (both prior to this lift folded onto raw `5`
4134/// literals with no compile-time link back to a shared truth): the
4135/// serde-`#[serde(default = "default_max_restarts")]` helper on
4136/// [`SupervisorSpec::max_restarts`] that every author-omitted
4137/// `:supervisor :max-restarts` slot lands in past the derive-macro's
4138/// wire-format compose, and the [`crate::manifest::Caixa::supervisor_view`]
4139/// `.max_restarts().unwrap_or(5)` fold that every downstream consumer of
4140/// the composed [`SupervisorSpec`] altitude reaches through
4141/// (`feira app graph`, the future wasm-operator's per-supervisor
4142/// restart-intensity counter, the future M4
4143/// `mesh.pleme.io/v1alpha1/Supervisor` CR materializer's admission
4144/// webhook, the caixa-operator's hierarchical reconciliation scheduler).
4145/// A pair of open-coded `5`s across two files that expressed no
4146/// compile-time link back to the shared OTP-canonical default — a
4147/// future rebrand of the default (a tightening to Elixir's
4148/// `Supervisor.max_restarts: 3`, a widening to a per-cluster overlay
4149/// the operator pins through a future
4150/// `:supervisor :max-restarts-overrides` slot the MESH-COMPOSITION
4151/// §III.2 supervision-canary roadmap acknowledges, a promotion of the
4152/// plain `u32` count to a richer `{MaxR, MaxT}` per-child-cohort
4153/// restart-budget-partition once the INSPIRATIONS §II.2 Erlang/OTP
4154/// per-child-cohort roadmap lands) would have had to be threaded
4155/// through both open-coded copies in lockstep or the wire-format
4156/// author-omitted arm and the view-construction author-omitted arm
4157/// would silently disagree on which restart-budget an omitted
4158/// `:max-restarts` resolves to (an author writing `:supervisor
4159/// (:max-restarts ())` would round-trip through serde with the new
4160/// default while `supervisor_view` silently continued to compose the
4161/// stale `5`, or vice versa), a two-consumer split at the composition
4162/// boundary far from the source `caixa.lisp` with no field naming the
4163/// default-drift root cause. Lifting the resolution rule to a typed
4164/// `pub const` on the substrate primitive means every downstream
4165/// consumer of the per-Supervisor default-restart-budget-count surface
4166/// reaches for exactly one substrate-primitive `u32` — the resolver's
4167/// accepted value migrates as a unit on any future axis change.
4168///
4169/// The `5` value pins Learn You Some Erlang's `{intensity, 5, 60}`
4170/// worker-supervisor default (the closest canonical OTP-shape
4171/// production reference the substrate carries, matching the sibling
4172/// `60s` `Period` default the [`Default for SupervisorSpec`] impl pairs
4173/// this constant with on the paired sliding-window axis). Two orders of
4174/// magnitude below the [`SUPERVISOR_MAX_RESTARTS_MAX`] `1000` ceiling
4175/// (the upper bracket on the same axis, sibling of this lower default;
4176/// both are typed `u32` const bounds on the `:supervisor :max-restarts`
4177/// axis and now share one accessor discipline on the substrate) and
4178/// above the OTP-`supervisor` callback-module `MaxR = 1` minimum-
4179/// restart floor — the "one restart, then escalate" default is
4180/// deliberately loose enough to absorb a short burst of transient
4181/// child failures without escalating past the supervisor's parent
4182/// while remaining tight enough to trip the `MaxIntensity / Period`
4183/// ratio's escalation on a genuinely-stuck child within the sibling
4184/// `60s` sliding window.
4185///
4186/// Lifted as a typed `pub const` so the bound has exactly one source
4187/// of truth — the serde-side wire-format author-omitted arm at
4188/// [`default_max_restarts`], the [`Default for SupervisorSpec`] impl's
4189/// struct-literal default field, and the caixa-core
4190/// [`crate::manifest::Caixa::supervisor_view`] fold's author-omitted
4191/// arm all read from one place. Same shape every other typed default
4192/// in this crate carries (the sibling
4193/// [`SUPERVISOR_MAX_RESTARTS_MAX`] upper cap on the same axis, the
4194/// paired [`SUPERVISOR_RESTART_WINDOW_MAX`] upper cap on the
4195/// sibling `:restart-window` axis, and the peer
4196/// [`crate::render::DEFAULT_NAMESPACE`] / [`crate::render::DEFAULT_LIBRARY_NAME`]
4197/// per-renderer defaults on the caixa-flux / caixa-helm rendering
4198/// axes).
4199pub const SUPERVISOR_MAX_RESTARTS_DEFAULT: u32 = 5;
4200
4201/// Upper-bound ceiling on the `:supervisor :max-restarts` axis — every
4202/// validated [`SupervisorSpec::max_restarts`] past
4203/// [`SupervisorSpec::validate`] lies in `1..=SUPERVISOR_MAX_RESTARTS_MAX`.
4204///
4205/// The typed field is `u32` (the zero-floor arm
4206/// [`SupervisorError::ZeroMaxRestarts`] already brackets the bottom edge),
4207/// so a programmatic struct literal
4208/// (`SupervisorSpec { max_restarts: u32::MAX, .. }`) and the equivalent
4209/// author-surface form (`:max-restarts 4294967295` or any
4210/// `:max-restarts 100000`-shape typo landing in the slot) both round-trip
4211/// cleanly through serde — a structurally unbounded `u32` ceiling. The
4212/// runtime substrate consuming the value (Erlang/OTP's
4213/// `MaxIntensity / Period` ratio, the future wasm-operator's
4214/// per-supervisor restart-intensity counter, the M4
4215/// `mesh.pleme.io/v1alpha1/Supervisor` CR materializer's admission webhook)
4216/// then turned a typed `:max-restarts` policy into a no-op supervisor: the
4217/// escalation threshold is structurally so high that no realistic
4218/// restarts-per-`:restart-window` traffic shape can reach it, the
4219/// supervisor never escalates to its parent, and a bad child can loop
4220/// inside the window indefinitely with the parent supervisor structurally
4221/// never receiving the "this subtree has exceeded its restart budget"
4222/// signal the typed slot is meant to express — the canonical
4223/// "supervisor intensity declared, no escalation" footgun, exactly the
4224/// peer of the [`crate::aplicacao::POLICY_BREAKER_MAX_FAILURES_MAX`] cap
4225/// on the `:politicas :circuit-breaker :max-failures` axis (both are
4226/// "trip the next-higher protection layer after N events in a rolling
4227/// window" counters with identical degenerate-at-the-high-end shape).
4228///
4229/// The `1000` ceiling matches the sibling
4230/// [`crate::aplicacao::POLICY_BREAKER_MAX_FAILURES_MAX`] (the closest
4231/// peer — same "events-per-window trip threshold" semantics, same `u32`
4232/// type, same no-op-at-the-high-end failure mode) so the M4
4233/// `mesh.pleme.io/v1alpha1/Supervisor` / `.../Aplicacao` CR materializers
4234/// and the future wasm-operator's per-supervisor restart-intensity
4235/// counter reach for either field knowing the value is in `1..=1000`
4236/// without re-validating at the reconciler layer. The cap sits two
4237/// orders of magnitude above every documented Erlang/OTP production
4238/// playbook recommendation (Learn You Some Erlang's
4239/// `{intensity, 5, 60}` worker-supervisor default, Elixir's `Supervisor`
4240/// `max_restarts: 3` default, OTP's `supervisor` callback module
4241/// `MaxR = 1` / `MaxT = 5` "minimal-restart" default, Riak Core's
4242/// typical `MaxR ∈ 5..=100`, RabbitMQ's broker-supervisor `MaxR = 5`
4243/// default) and below the clearly-pathological "effectively no
4244/// escalation" floor (`10_000`, `100_000`, `u32::MAX`): a value the
4245/// author can plausibly want at hyperscale (a long-running supervisor
4246/// over a very-flaky pool tolerating thousands of transient restarts
4247/// before escalating), but a hard wall above which the typed policy is
4248/// structurally a no-op carried verbatim on every emitted child-restart
4249/// reconciliation contract.
4250///
4251/// Lifted as a typed `pub const` so the bound has exactly one source of
4252/// truth — the future M4 `mesh.pleme.io/v1alpha1/Supervisor` CR
4253/// materializer's admission webhook and the wasm-operator-side
4254/// per-supervisor restart-intensity reconciler read from one place. Same
4255/// shape every other typed upper bound in this crate carries
4256/// ([`crate::aplicacao::POLICY_BREAKER_MAX_FAILURES_MAX`],
4257/// [`crate::aplicacao::POLICY_RETRIES_MAX`],
4258/// [`crate::aplicacao::POLICY_RATE_LIMIT_MAX`],
4259/// [`crate::LIMITS_MEMORY_WASM32_MAX_BYTES`],
4260/// [`crate::render::DNS_1123_LABEL_MAX_LEN`],
4261/// [`crate::render::NATS_SUBJECT_MAX_LEN`]).
4262pub const SUPERVISOR_MAX_RESTARTS_MAX: u32 = 1000;
4263
4264/// Upper-bound ceiling on the `:supervisor :restart-window` axis —
4265/// every validated `Some(`[`SupervisorSpec::restart_window`]`)` past
4266/// [`SupervisorSpec::validate`] lies in `1ms..=SUPERVISOR_RESTART_WINDOW_MAX`
4267/// (inclusive on both ends, integer-millisecond magnitudes by the
4268/// canonical-form gate immediately preceding).
4269///
4270/// The typed field is `Option<Duration>` (the zero-floor arm
4271/// [`SupervisorError::RestartWindowZero`] already rejects
4272/// `Some(Duration::ZERO)`, and the canonical-form arm
4273/// [`SupervisorError::RestartWindowNotCanonical`] already rejects
4274/// sub-millisecond residue), so a programmatic struct literal
4275/// (`SupervisorSpec { restart_window: Some(Duration::from_secs(86_400)),
4276/// .. }` — 24h) and the equivalent author-surface form
4277/// (`(:supervisor (:restart-window "24h"))` — the shared duration codec
4278/// emits `"<n>h"` for any integer-hour magnitude) both round-trip
4279/// cleanly through serde — a structurally unbounded `Duration` ceiling.
4280/// A `:restart-window` value far above the documented Erlang/OTP
4281/// `MaxIntensity / Period` production-playbook band (Learn You Some
4282/// Erlang's `{intensity, 5, 60}` worker-supervisor `Period = 60s`
4283/// default, Elixir's `Supervisor` `max_seconds: 5` default, OTP's
4284/// `supervisor` callback module `MaxT = 5..=60` typical, Riak Core's
4285/// `MaxT ∈ 10s..=300s`, RabbitMQ broker-supervisor `MaxT = 5s` default)
4286/// degenerates the supervisor's restart-intensity counter into a
4287/// lifetime counter: the rolling failure-counting window is structurally
4288/// so long that transient restarts are never forgotten, so the
4289/// `MaxIntensity / Period` ratio degenerates from "trip the parent
4290/// supervisor when the child has exceeded its restart budget *within
4291/// the recent window*" to "trip the parent when the child has exceeded
4292/// its restart budget *over its lifetime*" — every transient restart
4293/// counts against the budget forever, the supervisor's reset semantic
4294/// never reaches the child, and the typed `:restart-window` slot
4295/// becomes a no-op rolling window carried on every emitted hierarchical
4296/// reconciliation contract. The canonical
4297/// rolling-window-degenerates-to-lifetime-counter footgun the sibling
4298/// [`crate::POLICY_BREAKER_WINDOW_MAX`] cap closes on the peer
4299/// `:politicas :circuit-breaker :window` axis with identical shape (both
4300/// are "rolling failure-counting window with a per-`Period` reset" Duration
4301/// axes whose lifetime-counter degenerate at the high end is the same
4302/// "the reset semantic never fires" CSE invariant violation).
4303///
4304/// The `1h` (3600s = `3_600_000` ms) ceiling matches the largest unit
4305/// the shared duration codec emits (`"<n>h"` for any integer-hour
4306/// magnitude) — every value in the canonical authoring form's
4307/// `<integer><unit>` grammar at or below this cap renders to a clean
4308/// canonical string — and matches the three sibling typed-`Duration`
4309/// caps already lifted to this surface
4310/// ([`crate::LIMITS_WALL_CLOCK_MAX`], [`crate::POLICY_TIMEOUT_MAX`],
4311/// [`crate::POLICY_BREAKER_WINDOW_MAX`]). All four typed-`Duration`
4312/// axes — per-process `:limits :wall-clock`, per-edge `:politicas
4313/// :timeout`, per-breaker `:politicas :circuit-breaker :window`, and
4314/// per-supervisor `:supervisor :restart-window` — now share a single
4315/// uniform top edge at the codec's largest emitted unit so the next
4316/// typed-slot wiring (the future wasm-operator's per-supervisor
4317/// `MaxIntensity / Period` reconciler, the M4
4318/// `mesh.pleme.io/v1alpha1/Supervisor` CR materializer's admission
4319/// webhook, the `caixa-operator`'s hierarchical reconciliation
4320/// scheduler) reaches for any of the four knowing the value is in
4321/// `1ms..=1h` without re-validating at the renderer layer. The cap sits
4322/// two orders of magnitude above every documented Erlang/OTP / Elixir /
4323/// Riak Core / RabbitMQ production-playbook recommendation band
4324/// (`5s..=300s`) and below the clearly-pathological "rolling window
4325/// degenerates to lifetime counter" floor (`24h`, `7d`, `Duration::MAX`):
4326/// a value the author can plausibly want for a very-low-traffic
4327/// long-tail failure-restart window over a hyperscale-flaky child pool,
4328/// but a hard wall above which the rolling-window contract is
4329/// structurally a lifetime-counter contract.
4330///
4331/// Lifted as a typed `pub const` so the bound has exactly one source
4332/// of truth — the future M4 `mesh.pleme.io/v1alpha1/Supervisor` CR
4333/// materializer's admission webhook, the wasm-operator-side
4334/// per-supervisor `MaxIntensity / Period` reconciler, and the
4335/// `caixa-operator`'s hierarchical reconciliation scheduler all read
4336/// from one place. Same shape every other typed upper bound in this
4337/// crate carries ([`SUPERVISOR_MAX_RESTARTS_MAX`],
4338/// [`crate::aplicacao::POLICY_BREAKER_MAX_FAILURES_MAX`],
4339/// [`crate::aplicacao::POLICY_RETRIES_MAX`],
4340/// [`crate::aplicacao::POLICY_RATE_LIMIT_MAX`],
4341/// [`crate::LIMITS_MEMORY_WASM32_MAX_BYTES`],
4342/// [`crate::LIMITS_WALL_CLOCK_MAX`], [`crate::POLICY_TIMEOUT_MAX`],
4343/// [`crate::POLICY_BREAKER_WINDOW_MAX`],
4344/// [`crate::render::DNS_1123_LABEL_MAX_LEN`],
4345/// [`crate::render::NATS_SUBJECT_MAX_LEN`]).
4346pub const SUPERVISOR_RESTART_WINDOW_MAX: Duration = Duration::from_secs(3600);
4347
4348/// Substrate-canonical Erlang/OTP-shaped `Period` sliding-window-duration
4349/// default for the `:supervisor :restart-window` axis — the canonical
4350/// `{intensity, 5, 60}` `Period` half of Learn You Some Erlang's
4351/// worker-supervisor default, extracted as a typed `pub const` so every
4352/// substrate-side consumer that resolves "what
4353/// [`SupervisorSpec::restart_window`] value does an author-omitted
4354/// `:restart-window` slot degrade onto?" reaches for exactly one
4355/// substrate-primitive [`Duration`].
4356///
4357/// The `:restart-window` default axis has one production consumer on the
4358/// substrate side today: the [`Default for SupervisorSpec`] impl's
4359/// struct-literal `restart_window` field, which prior to this lift folded
4360/// onto a raw `Duration::from_secs(60)` literal with no compile-time link
4361/// back to the paired [`SUPERVISOR_MAX_RESTARTS_DEFAULT`] `MaxIntensity`
4362/// half of the same `{intensity, 5, 60}` OTP-canonical default. The
4363/// [`crate::manifest::Caixa::supervisor_view`] fold deliberately does
4364/// *not* fall back to this default on the sibling `:restart-window` axis
4365/// — an author-omitted `:supervisor :restart-window` composes to
4366/// `restart_window: None` (the shared codec's soft-swallow shape),
4367/// keeping author-declared intent ("no reset — never escalate on rolling
4368/// window") distinct from the [`Default for SupervisorSpec`] "canonical
4369/// 60s Period" arm every programmatic `SupervisorSpec::default()` caller
4370/// resolves to. Prior to this lift the paired `{intensity, 5, 60}` OTP
4371/// default was split across two files with no compile-time link between
4372/// the halves: [`SUPERVISOR_MAX_RESTARTS_DEFAULT`] pinned the
4373/// `MaxIntensity` half at the substrate primitive while the `Period`
4374/// half rode as an open-coded literal at the composition site, so a
4375/// future coherent rebrand of the paired canonical (a tightening to
4376/// Elixir's `{max_restarts: 3, max_seconds: 5}`, a widening to a
4377/// per-cluster overlay the operator pins through a future
4378/// `:supervisor :restart-window-overrides` slot the MESH-COMPOSITION
4379/// §III.2 supervision-canary roadmap acknowledges, a promotion of the
4380/// paired constants to a per-child-cohort `{MaxR, MaxT}` restart-budget-
4381/// partition once the INSPIRATIONS §II.2 Erlang/OTP per-child-cohort
4382/// roadmap lands) would have had to migrate the `MaxIntensity` half
4383/// through the lifted constant and the `Period` half through a raw
4384/// literal in lockstep or the two halves of the same OTP-canonical
4385/// default would silently drift out of pairing. Lifting the resolution
4386/// rule to a typed `pub const` on the substrate primitive means the
4387/// paired OTP-canonical default migrates as one unit on any future
4388/// axis change.
4389///
4390/// The `60s` value pins Learn You Some Erlang's `{intensity, 5, 60}`
4391/// worker-supervisor default (the closest canonical OTP-shape
4392/// production reference the substrate carries, matching the paired
4393/// [`SUPERVISOR_MAX_RESTARTS_DEFAULT`] `5` `MaxIntensity` half this
4394/// constant is the `Period` denominator of on the same
4395/// `MaxIntensity / Period` restart-intensity ratio). Two orders of
4396/// magnitude below the [`SUPERVISOR_RESTART_WINDOW_MAX`] `3600s`
4397/// (`1h`) ceiling (the upper bracket on the same axis, sibling of
4398/// this lower default; both are typed [`Duration`] const bounds on the
4399/// `:supervisor :restart-window` axis and now share one accessor
4400/// discipline on the substrate) and above the OTP-`supervisor`
4401/// callback-module `MaxT = 5` seconds "minimal-window" floor — the "60s
4402/// rolling window" default is deliberately loose enough to absorb a
4403/// short burst of transient child failures without escalating past the
4404/// supervisor's parent while remaining tight enough for the paired
4405/// `MaxIntensity / Period` ratio's escalation to trip on a genuinely-
4406/// stuck child within a human-scale observation window.
4407///
4408/// Lifted as a typed `pub const` so the paired OTP-canonical default has
4409/// exactly one source of truth on each half — the sibling
4410/// [`SUPERVISOR_MAX_RESTARTS_DEFAULT`] `MaxIntensity` `5` half and this
4411/// `Period` `60s` half now share the same substrate-primitive lift
4412/// discipline. Same shape every other typed default in this crate
4413/// carries (the sibling [`SUPERVISOR_MAX_RESTARTS_DEFAULT`] paired
4414/// `MaxIntensity` half on the same OTP-canonical `{intensity, 5, 60}`,
4415/// the sibling [`SUPERVISOR_RESTART_WINDOW_MAX`] upper cap on the same
4416/// axis, and the peer [`crate::render::DEFAULT_NAMESPACE`] /
4417/// [`crate::render::DEFAULT_LIBRARY_NAME`] per-renderer defaults on the
4418/// caixa-flux / caixa-helm rendering axes).
4419pub const SUPERVISOR_RESTART_WINDOW_DEFAULT: Duration = Duration::from_secs(60);
4420
4421/// Substrate-canonical Erlang/OTP-shaped sibling-restart-strategy default
4422/// for the `:supervisor :estrategia` axis — the canonical `one_for_one`
4423/// half of Learn You Some Erlang's `{one_for_one, intensity, 5, 60}`
4424/// worker-supervisor default, extracted as a typed `pub const` so every
4425/// substrate-side consumer that resolves "what
4426/// [`SupervisorSpec::estrategia`] variant does an author-omitted
4427/// `:estrategia` slot degrade onto?" reaches for exactly one substrate-
4428/// primitive [`RestartStrategy`].
4429///
4430/// The `:estrategia` default axis has three production consumers on the
4431/// substrate side today: the [`Default for RestartStrategy`] impl's
4432/// return arm, the [`Default for SupervisorSpec`] impl's struct-literal
4433/// `estrategia` field, and the
4434/// [`crate::manifest::Caixa::supervisor_view`] fold's
4435/// `.unwrap_or(SUPERVISOR_ESTRATEGIA_DEFAULT)` `Option<RestartStrategy>`
4436/// collapse arm — three entry points onto the same OTP-canonical
4437/// `one_for_one` value that prior to this lift folded onto a raw
4438/// `Self::OneForOne` arm at the [`Default for RestartStrategy`] impl and
4439/// implicit `RestartStrategy::default()` routes at the sibling consumers,
4440/// with no compile-time link back to the paired
4441/// [`SUPERVISOR_MAX_RESTARTS_DEFAULT`] `MaxIntensity` half + the paired
4442/// [`SUPERVISOR_RESTART_WINDOW_DEFAULT`] `Period` half of the same
4443/// `{one_for_one, intensity, 5, 60}` OTP-canonical default. The paired
4444/// triple was split across three altitudes with no compile-time link
4445/// between the halves: the `MaxIntensity` half rode through the lifted
4446/// [`SUPERVISOR_MAX_RESTARTS_DEFAULT`] constant (b698ec0) and the `Period`
4447/// half rode through the lifted [`SUPERVISOR_RESTART_WINDOW_DEFAULT`]
4448/// constant (f7dcd0e) while the `one_for_one` half rode as an open-coded
4449/// discriminator at the [`Default for RestartStrategy`] impl, so a future
4450/// coherent rebrand of the triple (Elixir's `{:one_for_one,
4451/// max_restarts: 3, max_seconds: 5}` — same strategy, different
4452/// intensity/period; an OTP `rest_for_one` widening once the substrate
4453/// discovers startup-order-coupled child cohorts as the more common
4454/// worker-supervisor default; a per-cluster overlay the operator pins
4455/// through a future `:estrategia-overrides` slot the MESH-COMPOSITION
4456/// §III.2 supervision-canary roadmap acknowledges) would have had to
4457/// migrate the `MaxIntensity` + `Period` halves through the lifted
4458/// constants and the `one_for_one` half through an open-coded arm in
4459/// lockstep or the three halves of the same OTP-canonical default would
4460/// silently drift out of pairing. Lifting the resolution rule to a typed
4461/// `pub const` on the substrate primitive means the paired OTP-canonical
4462/// worker-supervisor default migrates as one unit on any future axis
4463/// change.
4464///
4465/// The [`RestartStrategy::OneForOne`] value pins Learn You Some Erlang's
4466/// `{one_for_one, intensity, 5, 60}` worker-supervisor default (the
4467/// closest canonical OTP-shape production reference the substrate
4468/// carries, matching the paired [`SUPERVISOR_MAX_RESTARTS_DEFAULT`] `5`
4469/// `MaxIntensity` half and the paired [`SUPERVISOR_RESTART_WINDOW_DEFAULT`]
4470/// `60s` `Period` half). The `one_for_one` strategy — restart only the
4471/// failed child, leaving siblings untouched — is the default for tree-of-
4472/// independent-workers use cases the substrate's [`RestartStrategy`]
4473/// discriminator's own docstring already carries as the default arm; it
4474/// composes with the `{5, 60}` restart-intensity ratio to name the same
4475/// substrate-canonical "canonical worker-supervisor" shape the paired
4476/// halves close on their respective axes.
4477///
4478/// Lifted as a typed `pub const` so the paired OTP-canonical default has
4479/// exactly one source of truth on each of its three halves — the sibling
4480/// [`SUPERVISOR_MAX_RESTARTS_DEFAULT`] `MaxIntensity` `5` half, the
4481/// sibling [`SUPERVISOR_RESTART_WINDOW_DEFAULT`] `Period` `60s` half, and
4482/// this `one_for_one` strategy half now share the same substrate-
4483/// primitive lift discipline. Same shape every other typed default in
4484/// this crate carries (the sibling [`SUPERVISOR_MAX_RESTARTS_DEFAULT`] +
4485/// [`SUPERVISOR_RESTART_WINDOW_DEFAULT`] paired halves on the same OTP-
4486/// canonical `{one_for_one, intensity, 5, 60}`, the sibling
4487/// [`SUPERVISOR_MAX_RESTARTS_MAX`] + [`SUPERVISOR_RESTART_WINDOW_MAX`]
4488/// upper caps on the paired sibling axes, and the peer
4489/// [`crate::render::DEFAULT_NAMESPACE`] / [`crate::render::DEFAULT_LIBRARY_NAME`]
4490/// per-renderer defaults on the caixa-flux / caixa-helm rendering axes).
4491pub const SUPERVISOR_ESTRATEGIA_DEFAULT: RestartStrategy = RestartStrategy::OneForOne;
4492
4493/// Substrate-canonical Erlang/OTP-shaped per-child restart-decision-policy
4494/// default for the `:children :restart` axis — the OTP `permanent`
4495/// worker-child default (`{ChildId, StartFunc, permanent, …}` in a
4496/// `supervisor`'s `init/1` child-spec tuple), extracted as a typed
4497/// `pub const` so every substrate-side consumer that resolves "what
4498/// [`ChildSpec::restart`] variant does an author-omitted `:children
4499/// :restart` slot degrade onto?" reaches for exactly one substrate-
4500/// primitive [`RestartPolicy`].
4501///
4502/// Completes the OTP-shape supervisor-tree default set at the substrate
4503/// primitive. The per-`:supervisor` axis already carries all three of its
4504/// halves as lifted typed constants — [`SUPERVISOR_ESTRATEGIA_DEFAULT`]
4505/// (`one_for_one`, 95ffacc), [`SUPERVISOR_MAX_RESTARTS_DEFAULT`]
4506/// (`MaxIntensity` `5`, b698ec0), [`SUPERVISOR_RESTART_WINDOW_DEFAULT`]
4507/// (`Period` `60s`, f7dcd0e) — while the per-`:children` axis's own
4508/// OTP-canonical default rode as an open-coded `Self::Permanent` arm in
4509/// the [`Default for RestartPolicy`] impl, the last un-lifted default on
4510/// the M2 `:supervisor` slot family. The split mattered because the two
4511/// axes resolve *together* on every author-omitted supervisor: a
4512/// `(defcaixa :kind Supervisor :children ((:caixa "worker" :versao
4513/// "^0.1")))` with no `:estrategia` and no per-child `:restart` degrades
4514/// onto `{one_for_one, 5, 60}` through three lifted constants and onto
4515/// `permanent` through an open-coded enum arm, so a future coherent
4516/// rebrand of the OTP-shape default set (an Elixir-shaped
4517/// `{:one_for_one, max_restarts: 3, max_seconds: 5}` tightening, a
4518/// per-cluster overlay the operator pins through the MESH-COMPOSITION
4519/// §III.2 supervision-canary roadmap slots, an OTP-`transient` widening
4520/// once the substrate discovers clean-completion-aware children as the
4521/// more common child shape) would have had to migrate three halves
4522/// through typed constants and the fourth through a raw enum arm in
4523/// lockstep or the supervisor-level and child-level defaults would
4524/// silently drift apart.
4525///
4526/// The `:children :restart` default axis has two production consumers on
4527/// the substrate side today: the [`Default for RestartPolicy`] impl's
4528/// return arm, and the serde-side `#[serde(default)]` on
4529/// [`ChildSpec::restart`] that resolves an author-omitted `:children
4530/// :restart` slot through that same impl. Both now key off this one
4531/// substrate primitive, so the future wasm-operator's per-child post-exit
4532/// restart-decision branch, the future M4
4533/// `mesh.pleme.io/v1alpha1/Supervisor` CR materializer's per-child
4534/// admission webhook, and the `caixa-operator`'s hierarchical
4535/// reconciliation scheduler's per-child fan-out all reach for one typed
4536/// identifier when they resolve an omitted per-child restart posture.
4537///
4538/// The [`RestartPolicy::Permanent`] value pins Erlang/OTP's `permanent`
4539/// worker-child restart type — always restart the child regardless of how
4540/// it died, the canonical posture for long-running services that must
4541/// always be up, matching the sibling [`SUPERVISOR_ESTRATEGIA_DEFAULT`]
4542/// `one_for_one` tree-of-independent-workers strategy this constant pairs
4543/// with under the same `{one_for_one, intensity, 5, 60}` worker-supervisor
4544/// shape. The two alternatives the closed [`RestartPolicy::ALL`] accept-set
4545/// carries ([`RestartPolicy::Transient`] — restart only on abnormal exit;
4546/// [`RestartPolicy::Temporary`] — never restart) express deliberate
4547/// one-shot / clean-completion-aware postures an author declares
4548/// explicitly, never a posture an omitted slot should silently assume.
4549pub const SUPERVISOR_CHILD_RESTART_DEFAULT: RestartPolicy = RestartPolicy::Permanent;
4550
4551/// Route the manually-authored [`Default`] impl on [`SupervisorSpec`]
4552/// through the substrate-canonical [`SupervisorSpec::otp_canonical`]
4553/// `pub const fn` constructor rather than a struct-literal cascade over
4554/// the paired [`SUPERVISOR_ESTRATEGIA_DEFAULT`] /
4555/// [`default_max_restarts`] / [`SUPERVISOR_RESTART_WINDOW_DEFAULT`]
4556/// lifted consts — one source of truth for the Erlang/OTP-canonical
4557/// `{one_for_one, 5, 60}` worker-supervisor baseline across the two
4558/// paths every downstream consumer already reaches through (the
4559/// hand-authored-until-now [`Default::default`] the
4560/// `..SupervisorSpec::default()` struct-update-syntax on every
4561/// one-axis-under-test fixture in this crate's test module rests on,
4562/// and the `pub const fn` [`SupervisorSpec::otp_canonical`] constructor
4563/// every `const`-context consumer reaches through).
4564///
4565/// Extends the [`Default`]-through-const-ctor fold discipline the
4566/// [`crate::LimitsSpec`] [`Default`]-through-[`crate::LimitsSpec::empty`]
4567/// (abd52c2), [`crate::aplicacao::MeshPolicy`]
4568/// [`Default`]-through-[`crate::aplicacao::MeshPolicy::empty`] (91641a4),
4569/// and [`crate::BehaviorSpec`]
4570/// [`Default`]-through-[`crate::BehaviorSpec::empty`] (0c1752c) folds
4571/// closed on the M2 / M3 `Option`-only "canonical unset baseline"
4572/// typed-slot spec family — extended here onto the M2 supervisor-slot
4573/// [`SupervisorSpec`] whose canonical baseline is not "everything
4574/// `None`" but the OTP-canonical `{one_for_one, 5, 60}` worker-
4575/// supervisor triple. The `empty()` peer's naming did not fit
4576/// (`SupervisorSpec` carries a discriminator-shaped `estrategia` field
4577/// and a non-zero `max_restarts`/`restart_window` pair whose canonical
4578/// shape is Erlang/OTP-descended, not the "no axis declared" bottom
4579/// the sibling `Option`-only slots fold to), so this peer is named
4580/// [`SupervisorSpec::otp_canonical`] instead — the same phrasing the
4581/// existing per-arm pin tests
4582/// [`tests::supervisor_estrategia_default_pins_otp_canonical_value`] /
4583/// [`tests::supervisor_max_restarts_default_pins_otp_canonical_value`] /
4584/// [`tests::supervisor_restart_window_default_pins_otp_canonical_value`]
4585/// already reach for. Pinned load-bearing by
4586/// [`tests::supervisor_spec_default_routes_through_otp_canonical_ctor`]
4587/// (byte-parity pin against [`SupervisorSpec::otp_canonical`] under
4588/// [`PartialEq`], sharpening the sibling
4589/// `supervisor_spec_default_*_routes_through_lifted_default` per-arm
4590/// pins from a per-field lift into a whole-struct one-source-of-truth
4591/// pin — the derived-until-now [`Default::default`] and the
4592/// [`SupervisorSpec::otp_canonical`] constructor are byte-equal by
4593/// construction, not by coincidence).
4594impl Default for SupervisorSpec {
4595 #[inline]
4596 fn default() -> Self {
4597 Self::otp_canonical()
4598 }
4599}
4600
4601impl SupervisorSpec {
4602 /// `const`-context peer of the [`Default for SupervisorSpec`]
4603 /// impl (which routes through this constructor) — returns the
4604 /// Erlang/OTP-canonical `{one_for_one, 5, 60}` worker-supervisor
4605 /// baseline this crate reaches for in every fixture-builder
4606 /// `..SupervisorSpec::default()` struct-update expression and
4607 /// every downstream `SupervisorSpec::default()` seed.
4608 ///
4609 /// Each field routes through the same substrate-canonical
4610 /// [`SUPERVISOR_ESTRATEGIA_DEFAULT`] / [`default_max_restarts`] /
4611 /// [`SUPERVISOR_RESTART_WINDOW_DEFAULT`] lifted consts the
4612 /// per-arm pin tests
4613 /// [`tests::supervisor_estrategia_default_pins_otp_canonical_value`]
4614 /// / [`tests::supervisor_max_restarts_default_pins_otp_canonical_value`]
4615 /// / [`tests::supervisor_restart_window_default_pins_otp_canonical_value`]
4616 /// already assert, so a future coherent rebrand of the OTP-canonical
4617 /// triple (Elixir's `{max_restarts: 3, max_seconds: 5}`, a per-
4618 /// cluster overlay via a future `:restart-window-overrides` slot, a
4619 /// per-child-cohort promotion the INSPIRATIONS.md §II.2 Erlang/OTP
4620 /// absorption roadmap acknowledges) migrates through three typed
4621 /// constants in lockstep, and the paired [`Default`] impl inherits
4622 /// every future extension by construction.
4623 ///
4624 /// `pub const fn` rather than the derived-style `Default::default`
4625 /// or a `pub const SUPERVISOR_SPEC_DEFAULT: SupervisorSpec` item —
4626 /// [`Default::default`] is not `const` on stable Rust, and
4627 /// `SupervisorSpec` is non-`Copy` so a `pub const` item would force
4628 /// every consumer through a [`Clone::clone`]. The `pub const fn`
4629 /// discipline lets `const`-context callers construct the OTP-
4630 /// canonical baseline at compile time without runtime dispatch on
4631 /// the derived [`Default::default`], the same posture the sibling
4632 /// [`crate::LimitsSpec::empty`] (9739971) /
4633 /// [`crate::aplicacao::MeshPolicy::empty`] (6df969b) /
4634 /// [`crate::BehaviorSpec::empty`] (f9b18e3) `Option`-only typed-slot
4635 /// spec `pub const fn` constructors carry on the sibling
4636 /// "everything `None`" baseline axis.
4637 ///
4638 /// Fourth peer on the M2 / M3 typed-slot-spec "const-context peer
4639 /// of the derived-style [`Default`]" family — sibling of the
4640 /// [`crate::LimitsSpec::empty`] / [`crate::aplicacao::MeshPolicy::empty`]
4641 /// / [`crate::BehaviorSpec::empty`] `Option`-only "canonical unset
4642 /// baseline" trio, extended here onto the M2 supervisor-slot
4643 /// [`SupervisorSpec`] whose canonical baseline is not "everything
4644 /// `None`" but the Erlang/OTP-canonical `{one_for_one, 5, 60}`
4645 /// worker-supervisor triple. Named [`Self::otp_canonical`] rather
4646 /// than `empty()` to name the actual invariant the return value
4647 /// pins — the same phrasing already used in the per-arm pin tests
4648 /// on this file. Pinned load-bearing by
4649 /// [`tests::supervisor_spec_otp_canonical_byte_equals_default`] and
4650 /// [`tests::supervisor_spec_otp_canonical_is_usable_in_const_context`].
4651 #[must_use]
4652 pub const fn otp_canonical() -> Self {
4653 Self {
4654 estrategia: SUPERVISOR_ESTRATEGIA_DEFAULT,
4655 max_restarts: default_max_restarts(),
4656 restart_window: Some(SUPERVISOR_RESTART_WINDOW_DEFAULT),
4657 children: Vec::new(),
4658 }
4659 }
4660
4661 /// Substrate-canonical per-`:supervisor` `:estrategia` OTP-shaped
4662 /// sibling-restart-strategy scalar accessor every consumer that
4663 /// dispatches on the supervisor's per-sibling restart-decision shape
4664 /// keys off — returns the author-declared `:supervisor :estrategia`
4665 /// variant verbatim as a [`RestartStrategy`], `Copy`-projected from
4666 /// the typed slot's own [`RestartStrategy`] storage.
4667 ///
4668 /// The `:supervisor :estrategia` slot carries the closed-set
4669 /// OTP-shaped sibling-restart-strategy discriminator ([`RestartStrategy::OneForOne`]
4670 /// — restart only the failed child, the Erlang/OTP `one_for_one` default;
4671 /// [`RestartStrategy::OneForAll`] — restart every child on any child
4672 /// failure, the Erlang/OTP `one_for_all` shared-state cohort default;
4673 /// [`RestartStrategy::RestForOne`] — restart the failed child and
4674 /// every child started after it, the Erlang/OTP `rest_for_one`
4675 /// startup-order default; [`RestartStrategy::SimpleOneForOne`] —
4676 /// dynamic children of the same shape, the Erlang/OTP
4677 /// `simple_one_for_one` per-session default) that every downstream
4678 /// consumer of the Supervisor's per-sibling restart-decision fan-out
4679 /// shape keys off. Validated by [`SupervisorSpec::validate`] to be
4680 /// paired coherently with the sibling `:children` axis
4681 /// (`SimpleOneForOne ↔ children.is_empty()` — the cross-slot
4682 /// partition the strategy-arm's [`SupervisorError::SimpleOneForOneWithStaticChildren`]
4683 /// / [`SupervisorError::NoChildren`] refusal cascade pins), and every
4684 /// downstream consumer that reads the strategy keys off this scalar
4685 /// (the [`SupervisorSpec::validate`] `SimpleOneForOne ↔ non-SimpleOneForOne`
4686 /// partition-dispatch `match` arm, the non-`SimpleOneForOne`-arm
4687 /// declared-but-empty [`SupervisorError::NoChildren`] error carrier's
4688 /// `estrategia:` field, the future `feira app graph` per-Supervisor
4689 /// strategy print line, the future wasm-operator's per-supervisor
4690 /// sibling-restart-strategy branch, the future M4
4691 /// `mesh.pleme.io/v1alpha1/Supervisor` CR materializer's per-strategy
4692 /// admission-webhook resolver, the `caixa-operator`'s hierarchical
4693 /// reconciliation scheduler's per-strategy fan-out).
4694 ///
4695 /// Prior to this lift the `.estrategia` field was accessed inline at
4696 /// two production sites in `caixa-core/src/supervisor.rs` — the
4697 /// [`SupervisorSpec::validate`] `SimpleOneForOne ↔ non-SimpleOneForOne`
4698 /// `match self.estrategia { … }` partition dispatch, and the
4699 /// non-`SimpleOneForOne`-arm [`SupervisorError::NoChildren`] error
4700 /// carrier at `estrategia: self.estrategia` — two open-coded
4701 /// field-accesses that expressed no compile-time link back to the
4702 /// typed slot. A future extension of the `:supervisor :estrategia`
4703 /// axis to a richer author surface (a per-cluster strategy override
4704 /// the operator pins through a future `:supervisor :estrategia-overrides`
4705 /// slot the MESH-COMPOSITION §III.2 supervision-canary roadmap
4706 /// acknowledges, a per-tenant strategy-alias table the M4 CR
4707 /// materializer resolves per-CR, a per-Supervisor dynamic strategy
4708 /// derivation the future adaptive-supervision engine computes from
4709 /// child-failure-history topology, a per-child-cohort strategy split
4710 /// the future `RestForCohort` extension acknowledged by the
4711 /// INSPIRATIONS.md §II.2 Erlang/OTP absorption roadmap acknowledges)
4712 /// would have had to be threaded through every open-coded copy in
4713 /// lockstep — one consumer reading the raw variant while a peer read
4714 /// the operator-resolved variant would silently split the
4715 /// [`SupervisorError::NoChildren`] diagnostic's quoted strategy from
4716 /// the actual partition-dispatch input the empty-children refusal
4717 /// arm reached under, a two-consumer split at the validator far from
4718 /// the source `caixa.lisp` with no field naming the strategy-drift
4719 /// root cause. Lifting the resolution rule to a typed method on the
4720 /// substrate primitive means every downstream consumer of the
4721 /// Supervisor's per-`:supervisor` sibling-restart-strategy surface
4722 /// reaches for exactly one typed dispatch — the resolver's accept-set
4723 /// migrates as a unit on any future axis addition.
4724 ///
4725 /// Peer of the sibling M3 mesh-slot [`crate::Placement::estrategia`]
4726 /// (921fe1b) `Copy`-return `PlacementStrategy` scalar accessor on the
4727 /// per-`:placement` distribution-strategy axis — same "one typed
4728 /// dispatch on the substrate primitive, thin projections at each
4729 /// consumer" discipline extended onto the M2 supervisor-slot
4730 /// per-`:supervisor` sibling-restart-strategy `Copy`-composite-enum
4731 /// scalar axis. The two typed axes (`Placement::estrategia` on the
4732 /// M3 Aplicacao side, `SupervisorSpec::estrategia` on the M2
4733 /// Supervisor side) now share one accessor discipline for the shared
4734 /// substrate concept "a `Copy`-projected closed-set enum-arm
4735 /// discriminator that partitions the downstream renderer's per-arm
4736 /// fan-out". First `Copy`-return accessor on the M2 supervisor-slot
4737 /// `SupervisorSpec` type — companion to the sibling per-`:children`
4738 /// [`crate::ChildSpec::nome`] (57c61d0) /
4739 /// [`crate::ChildSpec::versao_requirement`] (2c053c8) child-caixa
4740 /// scalar accessors on the sibling per-`:children` `String`-carry
4741 /// axes. Named `estrategia()` to match the storage field's name and
4742 /// the peer [`crate::Placement::estrategia`] method-name discipline
4743 /// verbatim; the accessor's identity name maps onto the canonical
4744 /// OTP-shape supervision vocabulary the [`RestartStrategy`] enum's
4745 /// docstring already carries.
4746 ///
4747 /// Declared `pub const fn` to close the M2 supervisor-slot
4748 /// `Copy`-return raw-field-getter `const`-eval-surface pass —
4749 /// sibling of the peer M2 per-`:children` [`ChildSpec::restart`]
4750 /// (converted in this commit) `Copy`-composite-enum accessor, peer
4751 /// of the sibling M2 per-`:supervisor`
4752 /// [`SupervisorSpec::max_restarts`] (b698ec0) `Copy`-`u32` accessor
4753 /// already lifted, and mirror of the peer M3 mesh-slot
4754 /// per-`:placement` [`crate::Placement::estrategia`] (bafa004)
4755 /// `Copy`-return `pub const fn` scalar accessor whose method-name
4756 /// discipline this accessor was authored to match. Every downstream
4757 /// substrate-side `const`-context consumer of the per-`:supervisor`
4758 /// sibling-restart-strategy scalar (a future module-scope `const
4759 /// _:() = assert!(matches!(sup.estrategia(),
4760 /// RestartStrategy::OneForOne))` invariant pin on a typed fixture,
4761 /// a future M4 `mesh.pleme.io/v1alpha1/Supervisor` CR materializer
4762 /// admission-webhook `const fn` per-supervisor strategy-arm floor
4763 /// over a typed [`SupervisorSpec`], any future `const fn`
4764 /// supervisor-tree composer over the substrate primitive that fans
4765 /// on the sibling-restart-strategy at compile time) now reaches
4766 /// through the same typed dispatch on the substrate primitive at
4767 /// const-eval time as at runtime. A future non-`Copy`-return
4768 /// promotion of the scalar (an `Option<RestartStrategy>`-shape
4769 /// migration once the substrate grows per-cluster strategy overlays
4770 /// the [`SupervisorSpec`] docstring already anticipates, a
4771 /// per-tenant strategy-alias table the M4 CR materializer resolves
4772 /// per-CR) that would drop the `const` qualifier fails the
4773 /// fail-before-pass-after pin
4774 /// [`tests::supervisor_spec_estrategia_accessor_is_const_fn`] at
4775 /// caixa-core build time rather than surfacing as a downstream
4776 /// consumer regression.
4777 #[must_use]
4778 pub const fn estrategia(&self) -> RestartStrategy {
4779 self.estrategia
4780 }
4781
4782 /// Substrate-canonical per-`:supervisor` `:max-restarts` OTP-shaped
4783 /// `MaxIntensity` restart-budget scalar accessor every consumer that
4784 /// reads the supervisor's per-`:restart-window` restart-budget count
4785 /// keys off — returns the author-declared `:supervisor :max-restarts`
4786 /// typed `u32` verbatim, `Copy`-projected from the typed slot's own
4787 /// `u32` storage (`u32` is `Copy`, so the accessor returns by value; no
4788 /// borrow of `&self` past the call). Non-optional (the `u32` field
4789 /// carries the restart-budget count as a required axis with a
4790 /// [`default_max_restarts`]-supplied default; the zero-floor arm
4791 /// [`SupervisorError::ZeroMaxRestarts`] and the cap arm
4792 /// [`SupervisorError::MaxRestartsExceedsCap`] jointly bracket the
4793 /// accept-set to `1..=SUPERVISOR_MAX_RESTARTS_MAX`).
4794 ///
4795 /// The `:supervisor :max-restarts` slot carries the Erlang/OTP
4796 /// `MaxIntensity` restart-budget count that pairs with the sibling
4797 /// `:restart-window` `Period` to form the `MaxIntensity / Period`
4798 /// restart-intensity ratio the supervisor trips its own escalation on
4799 /// (`theory/RUNTIME-PATTERNS.md` §II.2, Learn You Some Erlang's
4800 /// `{intensity, 5, 60}` worker-supervisor default). Every downstream
4801 /// consumer of the Supervisor's per-`:supervisor` restart-budget count
4802 /// keys off this scalar (the [`SupervisorSpec::validate`] zero-floor +
4803 /// upper-cap bracket at
4804 /// `require_positive_bounded_u32(self.max_restarts(), …)`, the future
4805 /// wasm-operator's per-supervisor restart-intensity counter's
4806 /// budget-vs-count comparator, the future M4
4807 /// `mesh.pleme.io/v1alpha1/Supervisor` CR materializer's admission
4808 /// webhook, the `caixa-operator`'s hierarchical reconciliation
4809 /// scheduler's per-supervisor escalation-decision branch, every
4810 /// `SupervisorError::MaxRestartsExceedsCap` variant carrying the
4811 /// offending count verbatim for `feira lint` rendering).
4812 ///
4813 /// Prior to this lift the `.max_restarts` field was accessed inline at
4814 /// one production site in `caixa-core/src/supervisor.rs` — the
4815 /// [`SupervisorSpec::validate`] `require_positive_bounded_u32(self
4816 /// .max_restarts, …)` bracket-gate call — one open-coded field-access
4817 /// that expressed no compile-time link back to the typed slot. A
4818 /// future extension of the `:max-restarts` axis to a richer author
4819 /// surface (a per-cluster restart-budget override the operator pins
4820 /// through a future `:supervisor :max-restarts-overrides` slot the
4821 /// MESH-COMPOSITION §III.2 supervision-canary roadmap acknowledges,
4822 /// a per-tenant restart-budget-alias table the M4 CR materializer
4823 /// resolves per-CR, a per-supervisor dynamic restart-budget derivation
4824 /// the future adaptive-supervision engine computes from child-failure-
4825 /// history topology, a promotion of the plain `u32` count to a richer
4826 /// `{MaxR, MaxT}` tuple once Erlang/OTP's per-child-cohort restart-
4827 /// budget-partition slot comes into scope) would have had to be
4828 /// threaded through every open-coded copy in lockstep or the validate
4829 /// gate and the future M4 emit path would silently disagree on which
4830 /// restart-budget count a given supervisor resolves to — an author's
4831 /// `:max-restarts 5` would satisfy validate while the emit path
4832 /// silently read a drifted other value (a `:max-restarts 10000`
4833 /// no-op supervisor at the emit boundary would carry the author's
4834 /// declared `5` verbatim in `feira lint` output while the future
4835 /// wasm-operator's restart-intensity counter operated under the
4836 /// drifted count), a two-consumer split at the validator far from the
4837 /// source `caixa.lisp` with no field naming the restart-budget-drift
4838 /// root cause. Lifting the resolution rule to a typed method on the
4839 /// substrate primitive means every downstream consumer of the
4840 /// Supervisor's per-`:supervisor` restart-budget-count surface reaches
4841 /// for exactly one typed dispatch — the resolver's accept-set migrates
4842 /// as a unit on any future axis addition.
4843 ///
4844 /// Peer of the sibling M3 mesh-slot [`crate::CircuitBreaker::max_failures`]
4845 /// (3a74062) `Copy`-return `u32` sub-struct required-scalar accessor
4846 /// on the per-`:politicas :circuit-breaker :max-failures` Envoy-
4847 /// outlier-detection trip-threshold axis — same "one typed dispatch on
4848 /// the substrate primitive, thin projections at each consumer"
4849 /// discipline extended onto the M2 supervisor-slot per-`:supervisor`
4850 /// restart-budget-count `Copy`-`u32` scalar axis. The two typed axes
4851 /// (`CircuitBreaker::max_failures` on the M3 Aplicacao side,
4852 /// `SupervisorSpec::max_restarts` on the M2 Supervisor side) now share
4853 /// one accessor discipline for the shared substrate concept "a
4854 /// `Copy`-projected required `u32` count that trips the next-higher
4855 /// protection layer after N events in a rolling window" — both are
4856 /// counters with identical degenerate-at-the-high-end shape and share
4857 /// the paired [`crate::POLICY_BREAKER_MAX_FAILURES_MAX`] /
4858 /// [`SUPERVISOR_MAX_RESTARTS_MAX`] `1000` cap. Second `Copy`-return
4859 /// accessor on the M2 supervisor-slot `SupervisorSpec` type, sibling
4860 /// to the [`SupervisorSpec::estrategia`] (eafb619) `Copy`-composite-
4861 /// enum `RestartStrategy` accessor. Named `max_restarts()` to match
4862 /// the storage field's name verbatim and the peer
4863 /// [`crate::CircuitBreaker::max_failures`] method-name discipline; the
4864 /// accessor's identity maps onto the canonical OTP-shape supervision
4865 /// vocabulary the [`SupervisorSpec::max_restarts`] field's docstring
4866 /// already carries.
4867 #[must_use]
4868 pub const fn max_restarts(&self) -> u32 {
4869 self.max_restarts
4870 }
4871
4872 /// Substrate-canonical per-`:supervisor` `:restart-window` OTP-shaped
4873 /// `Period` sliding-window scalar accessor every consumer of the
4874 /// supervisor's `MaxIntensity / Period` restart-intensity denominator
4875 /// keys off — returns the author-declared `:supervisor :restart-window`
4876 /// typed [`Duration`] verbatim as an `Option<Duration>`, copied out of
4877 /// the typed slot's own `Option<Duration>` storage (`Duration` is
4878 /// `Copy`, so `Option<Duration>` is `Copy` and the accessor returns by
4879 /// value; no borrow of `&self` past the call). `None` when the slot is
4880 /// absent (the canonical "never reset — every restart across the
4881 /// supervisor's lifetime counts against the sibling `:max-restarts`
4882 /// budget" sentinel the field's own docstring names and the peer
4883 /// `validate_accepts_none_restart_window` pin locks in on the
4884 /// [`SupervisorSpec::validate`] entry-side).
4885 ///
4886 /// The `:supervisor :restart-window` slot carries the Erlang/OTP
4887 /// `Period` sliding-observation-interval that pairs with the sibling
4888 /// `:max-restarts` `MaxIntensity` restart-budget count to form the
4889 /// `MaxIntensity / Period` restart-intensity ratio the supervisor
4890 /// trips its own escalation on (`theory/RUNTIME-PATTERNS.md` §II.2,
4891 /// Learn You Some Erlang's `{intensity, 5, 60}` worker-supervisor
4892 /// default). The typed slot's `Option<Duration>` accept-set —
4893 /// zero-floor rejected through [`SupervisorError::RestartWindowZero`]
4894 /// (Erlang/OTP's `MaxIntensity / Period` invariant requires
4895 /// `Period > 0`; a zero period either trips on the first failure or
4896 /// never trips depending on operator interpretation, neither of which
4897 /// is the author's intent — omit the slot to express "no reset";
4898 /// carry a positive duration to express the sliding window),
4899 /// integer-millisecond canonical form enforced through
4900 /// [`SupervisorError::RestartWindowNotCanonical`] (the duration
4901 /// codec's canonical form emits `"1500ms"` not `"1.5s"` and the
4902 /// future wasm-operator's per-supervisor restart-intensity counter
4903 /// quantizes at milliseconds), upper-bounded by
4904 /// [`SUPERVISOR_RESTART_WINDOW_MAX`] (1h — the coarsest per-
4905 /// supervisor rolling window any operationally-reachable supervisor
4906 /// can honor without spanning multiple scheduler epochs the
4907 /// hierarchical-reconciliation scheduler treats as independent) —
4908 /// maps onto the future wasm-operator (M3) per-supervisor
4909 /// restart-intensity counter's rolling-observation-interval, the
4910 /// future M4 `mesh.pleme.io/v1alpha1/Supervisor` CR materializer's
4911 /// per-`spec.restartWindow` admission webhook, and the sibling
4912 /// `duration_codec`-serialized wire scalar every downstream consumer
4913 /// of the supervisor's per-`:supervisor` restart-intensity denominator
4914 /// keys off.
4915 ///
4916 /// Prior to this lift the `.restart_window` field was accessed inline
4917 /// at one production site in `caixa-core/src/supervisor.rs` — the
4918 /// [`SupervisorSpec::validate`] `if let Some(w) = self.restart_window {
4919 /// … }` zero-floor + canonical-form + upper-cap bracket arm — one
4920 /// open-coded field-access that expressed no compile-time link back to
4921 /// the typed slot. A future extension of the `:restart-window` axis to
4922 /// a richer author surface (a per-cluster restart-window override the
4923 /// operator pins through a future `:supervisor :restart-window-overrides`
4924 /// slot the MESH-COMPOSITION §III.2 supervision-canary roadmap
4925 /// acknowledges, a per-tenant restart-window-alias table the M4 CR
4926 /// materializer resolves per-CR, a per-supervisor dynamic
4927 /// restart-window derivation the future adaptive-supervision engine
4928 /// computes from child-failure-history topology, a promotion of the
4929 /// plain `Option<Duration>` window to a richer `{observation, cooldown}`
4930 /// pair once Erlang/OTP's per-child-cohort observation-interval-
4931 /// partition slot comes into scope) would have had to be threaded
4932 /// through every open-coded copy in lockstep or the validate gate and
4933 /// the future M4 emit path would silently disagree on which
4934 /// restart-window a given supervisor resolves to — an author's
4935 /// `:restart-window "60s"` would satisfy validate while the emit path
4936 /// silently read a drifted other value (a `Some(Duration::from_secs(60))`
4937 /// authored slot at the emit boundary would carry the author's
4938 /// declared window verbatim in `feira lint` output while the future
4939 /// wasm-operator's restart-intensity counter operated under a
4940 /// drifted window, or vice versa: an author's `:restart-window ()`
4941 /// would carry the "never reset" sentinel through validate while the
4942 /// emit path silently substituted a default sliding window), a
4943 /// two-consumer split at the validator far from the source
4944 /// `caixa.lisp` with no field naming the restart-window-drift root
4945 /// cause. Lifting the resolution rule to a typed method on the
4946 /// substrate primitive means every downstream consumer of the
4947 /// Supervisor's per-`:supervisor` restart-intensity-denominator
4948 /// surface reaches for exactly one typed dispatch — the resolver's
4949 /// accept-set migrates as a unit on any future axis addition.
4950 ///
4951 /// Third `Copy`-return accessor on the M2 supervisor-slot
4952 /// `SupervisorSpec` type, closing the last unlifted per-`:supervisor`
4953 /// scalar-value axis (`children: Vec<ChildSpec>` carries a `Vec`
4954 /// payload rather than a `Copy`-scalar, and the per-`:children`
4955 /// [`crate::ChildSpec::nome`] (57c61d0) /
4956 /// [`crate::ChildSpec::versao_requirement`] (2c053c8) child-caixa
4957 /// scalar accessors already close the per-element `String`-carry
4958 /// axes). Sibling to the peer M2 [`crate::LimitsSpec::wall_clock`]
4959 /// (8cb717b) `Option<Duration>` accessor on the `:limits` slot's
4960 /// per-outermost-call wall-clock-deadline axis and the peer M3
4961 /// [`crate::MeshPolicy::timeout`] (7073d0f) `Option<Duration>`
4962 /// accessor on the `:politicas` slot's per-call-deadline axis — all
4963 /// three share the shared substrate concept "a `Copy`-projected
4964 /// optional `Duration` that carries a positive integer-millisecond
4965 /// canonical value with a `1ms..=<axis-specific>_MAX` accept-set and
4966 /// the paired zero-floor / non-canonical / above-cap refusal cascade"
4967 /// through the same [`crate::render::require_positive_canonical_bounded_duration`]
4968 /// bracket-helper the three axes each route through. Named
4969 /// `restart_window()` to match the storage field's name verbatim and
4970 /// the peer [`crate::LimitsSpec::wall_clock`] /
4971 /// [`crate::MeshPolicy::timeout`] method-name discipline; the
4972 /// accessor's identity maps onto the canonical OTP-shape supervision
4973 /// vocabulary the [`SupervisorSpec::restart_window`] field's docstring
4974 /// already carries.
4975 #[must_use]
4976 pub const fn restart_window(&self) -> Option<Duration> {
4977 self.restart_window
4978 }
4979
4980 /// Substrate-canonical per-`:supervisor` `:children` OTP-shaped
4981 /// static-child-list slice accessor every consumer that walks the
4982 /// supervisor's declared child set keys off — returns the author-
4983 /// declared `:supervisor :children` `Vec<ChildSpec>` verbatim as a
4984 /// `&[ChildSpec]` slice-view, borrowed from the typed slot's own
4985 /// `Vec<ChildSpec>` storage (a zero-copy slice-view over the same
4986 /// backing buffer the `Serialize`/`Deserialize` derives round-trip
4987 /// through). Non-optional: an empty slice is the load-bearing
4988 /// "author declared `:children ()`" sentinel every consumer of the
4989 /// cross-slot `SimpleOneForOne ↔ children.is_empty()` partition
4990 /// keys off (`SimpleOneForOne` requires the empty slice; the peer
4991 /// three strategies require a non-empty slice — the paired
4992 /// [`SupervisorError::SimpleOneForOneWithStaticChildren`] /
4993 /// [`SupervisorError::NoChildren`] refusal cascade pins the
4994 /// partition on both arms).
4995 ///
4996 /// The `:supervisor :children` slot carries the OTP-shaped static
4997 /// child list the supervisor materializes one ComputeUnit per
4998 /// entry from — the Erlang/OTP `supervisor:init/1`'s
4999 /// `{ok, {SupFlags, ChildSpecs}}` `ChildSpecs` list, projected
5000 /// through the tatara-lisp `:children` author surface onto a typed
5001 /// `Vec<ChildSpec>` whose per-element `(nome(),
5002 /// versao_requirement(), restart)` triple the per-child
5003 /// [`SupervisorSpec::validate`] loop already gates through the
5004 /// lifted [`ChildSpec::nome`] (57c61d0) /
5005 /// [`ChildSpec::versao_requirement`] (2c053c8) scalar accessors.
5006 /// Every downstream consumer that fans on the static child list
5007 /// keys off this slice (the [`SupervisorSpec::validate`]
5008 /// `SimpleOneForOne ↔ non-SimpleOneForOne` partition dispatch's
5009 /// `.is_empty()` probe on both arms, the [`SupervisorSpec::validate`]
5010 /// per-child DNS-1123 / semver-requirement / duplicate-detection
5011 /// fan-out loop, every future wasm-operator (M3) per-supervisor
5012 /// hierarchical-reconciliation scheduler's per-child ComputeUnit
5013 /// materialization loop, the future M4
5014 /// `mesh.pleme.io/v1alpha1/Supervisor` CR materializer's per-child
5015 /// admission-webhook fan-out, the future `feira app graph`
5016 /// per-supervisor tree-print traversal).
5017 ///
5018 /// Prior to this lift the `.children` `Vec<ChildSpec>` was accessed
5019 /// inline at three production sites in `caixa-core/src/supervisor.rs`
5020 /// — the [`SupervisorSpec::validate`] `SimpleOneForOne`-arm
5021 /// `!self.children.is_empty()` cross-slot refusal probe, the peer
5022 /// non-`SimpleOneForOne`-arm `self.children.is_empty()`
5023 /// [`SupervisorError::NoChildren`] refusal probe, and the per-child
5024 /// validate loop's `for child in &self.children` traversal head —
5025 /// three open-coded field-accesses that expressed no compile-time
5026 /// link back to the typed slot. A future extension of the
5027 /// `:supervisor :children` axis to a richer author surface (a
5028 /// per-cluster child-set overlay the operator pins through a future
5029 /// `:supervisor :children-overrides` slot the MESH-COMPOSITION §III.2
5030 /// supervision-canary roadmap acknowledges, a per-tenant
5031 /// child-set-alias table the M4 CR materializer resolves per-CR,
5032 /// a per-supervisor dynamic-child derivation the future adaptive-
5033 /// supervision engine computes from child-failure-history topology,
5034 /// a promotion of the plain `Vec<ChildSpec>` to a richer
5035 /// `{static, dynamic}` partition once Erlang/OTP's
5036 /// `simple_one_for_one` dynamic-child slot comes into typed scope)
5037 /// would have had to be threaded through all three open-coded copies
5038 /// in lockstep or one consumer would silently disagree with the
5039 /// peers on which child-set a given supervisor resolves to — the
5040 /// `SimpleOneForOne`-arm probe reading the raw slot while the peer
5041 /// non-`SimpleOneForOne`-arm probe read an operator-resolved slot
5042 /// would silently split the partition-dispatch's two-arm coherence
5043 /// (a supervisor that satisfies neither arm's precondition, or that
5044 /// satisfies both, at the cost of the paired
5045 /// `SimpleOneForOneWithStaticChildren`/`NoChildren` refusal cascade
5046 /// silently drifting from the per-child validate loop's actual
5047 /// traversal input), a three-consumer split at the validator far
5048 /// from the source `caixa.lisp` with no field naming the
5049 /// child-set-drift root cause. Lifting the resolution rule to a
5050 /// typed method on the substrate primitive means every downstream
5051 /// consumer of the Supervisor's per-`:supervisor` static-child-list
5052 /// surface reaches for exactly one typed dispatch — the resolver's
5053 /// accept-set migrates as a unit on any future axis addition.
5054 ///
5055 /// First slice-return (`&[T]`) accessor on any M2 or M3 typed slot
5056 /// — the seed for the same "one typed dispatch on the substrate
5057 /// primitive, thin projections at each consumer" discipline the
5058 /// closed [`crate::LimitsSpec`] / [`BehaviorSpec`] /
5059 /// [`crate::UpgradeFromEntry`] scalar-accessor families each carry
5060 /// on their `Copy` / `Option<Copy>` / `Option<&str>` axes, extended
5061 /// onto the first `Vec`-carry axis on the substrate. The four peer
5062 /// `Vec`-carry axes still unlifted at the time of this seed —
5063 /// [`crate::Placement::clusters`] (`Vec<String>` per-cluster
5064 /// distribution-target list), [`crate::AplicacaoSpec::membros`]
5065 /// (`Vec<Membro>` per-Aplicacao member list),
5066 /// [`crate::AplicacaoSpec::contratos`] (`Vec<WitContract>`
5067 /// per-Aplicacao WIT-typed edge list),
5068 /// [`crate::UpgradeFromEntry::instructions`]
5069 /// (`Vec<UpgradeInstruction>` per-appup migration-instruction list)
5070 /// — inherit this accessor's discipline as future compounding runs
5071 /// migrate their consumers onto the shared slice-return shape.
5072 /// Fourth (and final) accessor on the M2 supervisor-slot
5073 /// `SupervisorSpec` type, sibling to the three `Copy`-return
5074 /// [`SupervisorSpec::estrategia`] (eafb619) /
5075 /// [`SupervisorSpec::max_restarts`] (7844f4e) /
5076 /// [`SupervisorSpec::restart_window`] (7e7b32f) accessors — closes
5077 /// the last unlifted per-`:supervisor` field axis (the
5078 /// `Vec<ChildSpec>` static-child-list carrier) so every downstream
5079 /// per-`:supervisor` reader now routes through a typed dispatch on
5080 /// the substrate primitive. Named `children()` to match the storage
5081 /// field's name verbatim and the tatara-lisp author-surface term
5082 /// (`:children`) the field's own docstring already carries; the
5083 /// accessor's identity maps onto the canonical OTP-shape
5084 /// supervision vocabulary the [`SupervisorSpec::children`] field's
5085 /// docstring already reaches for ("Static children ..."). Returns
5086 /// `&[ChildSpec]` (not `&Vec<ChildSpec>`) because every downstream
5087 /// consumer of the child list treats it as a read-only sequence —
5088 /// the slice-view is the narrowest borrow that supports every
5089 /// present + roadmapped consumer (`.is_empty()`, `.iter()`,
5090 /// index, `.len()`) without leaking the backing `Vec`'s
5091 /// grow/push/reserve surface that no consumer of the typed view
5092 /// reaches for (the storage-side `Vec` remains reachable through
5093 /// the `pub children` field for the mutation-carrying
5094 /// `Caixa::supervisor_view` fold-in path in
5095 /// `manifest.rs:supervisor_view`).
5096 #[must_use]
5097 pub const fn children(&self) -> &[ChildSpec] {
5098 self.children.as_slice()
5099 }
5100
5101 /// Validate the supervisor's typed shape — strategy ↔ children
5102 /// invariants, max_restarts > 0, restart_window > 0 when set,
5103 /// per-child non-empty + duplicate-free names.
5104 ///
5105 /// Mirrors the value-shape discipline applied to every other
5106 /// typed slot:
5107 ///
5108 /// - `Some(Duration::ZERO)` on a Duration-bearing axis is the
5109 /// same "0 means the opposite of what you think" footgun
5110 /// closed for `:politicas :timeout` (Envoy interprets a zero
5111 /// timeout as `infinite`), `:politicas :circuit-breaker
5112 /// :window`, and `:limits :wall-clock`. The
5113 /// `MaxIntensity / Period` ratio in Erlang/OTP's
5114 /// `supervisor` requires `Period > 0`; a zero period either
5115 /// trips on the first failure or never trips depending on
5116 /// operator interpretation, neither of which is the
5117 /// author's intent. Omit `:restart-window` to express "no
5118 /// reset"; carry a positive duration to express the window.
5119 /// - duplicate `:children` `:caixa` names are the same
5120 /// graph-node-set / multiset distinction closed for
5121 /// `:membros` (4bb3f3d), `:placement :clusters` (c7c7799),
5122 /// and `:entrada :paths` (eb3456d). Two children with the
5123 /// same `:caixa` materialize as two ComputeUnits with the
5124 /// same name in the cluster's HelmRelease values, one
5125 /// silently overwriting the other. Erlang/OTP's
5126 /// `child_spec.id` is required-unique per supervisor;
5127 /// pleme-io enforces the same set-not-multiset shape on
5128 /// `:caixa` (the load-bearing identity in our renderer).
5129 pub fn validate(&self) -> Result<(), SupervisorError> {
5130 // Route the `SimpleOneForOne ↔ non-SimpleOneForOne` partition
5131 // dispatch and the non-`SimpleOneForOne`-arm [`SupervisorError::NoChildren`]
5132 // error carrier's `estrategia:` field through the lifted
5133 // [`SupervisorSpec::estrategia`] accessor rather than the raw
5134 // `self.estrategia` field access — the two production consumers
5135 // of the per-`:supervisor` sibling-restart-strategy scalar now
5136 // key off exactly one typed dispatch on the substrate primitive,
5137 // so any future rebrand on the axis (a per-cluster strategy
5138 // override the operator pins through a future `:supervisor
5139 // :estrategia-overrides` slot, a per-tenant strategy-alias table
5140 // the M4 CR materializer resolves per-CR) migrates as a single
5141 // caixa-core edit rather than a coordinated rewrite of the two
5142 // call sites — sibling of the peer M3 [`crate::Placement::estrategia`]
5143 // (921fe1b) four-consumer migration on the per-`:placement`
5144 // distribution-strategy axis.
5145 // Route the `SimpleOneForOne ↔ non-SimpleOneForOne` partition-
5146 // dispatch's paired `.is_empty()` cross-slot refusal probes
5147 // (the `SimpleOneForOne`-arm
5148 // [`SupervisorError::SimpleOneForOneWithStaticChildren`] refusal
5149 // and the non-`SimpleOneForOne`-arm [`SupervisorError::NoChildren`]
5150 // refusal) through the lifted [`SupervisorSpec::children`]
5151 // slice-return accessor rather than the raw `self.children`
5152 // field access — the two paired production consumers of the
5153 // per-`:supervisor` static-child-list scalar-shape now key off
5154 // exactly one typed dispatch on the substrate primitive, so any
5155 // future rebrand on the axis (a per-cluster child-set overlay
5156 // the operator pins through a future `:supervisor
5157 // :children-overrides` slot, a per-tenant child-set-alias table
5158 // the M4 CR materializer resolves per-CR) migrates as a single
5159 // caixa-core edit rather than a coordinated rewrite of the
5160 // paired arms — first slice-return migration on any typed slot,
5161 // seed for the peer per-`:placement :clusters`,
5162 // per-`:membros`, per-`:contratos`, and per-`:upgrade-from
5163 // :instructions` `Vec`-carry axes.
5164 match self.estrategia() {
5165 RestartStrategy::SimpleOneForOne => {
5166 // SimpleOneForOne: children added at runtime. Static
5167 // list must be empty (one shape declared elsewhere).
5168 if !self.children().is_empty() {
5169 return Err(SupervisorError::SimpleOneForOneWithStaticChildren);
5170 }
5171 }
5172 _ => {
5173 if self.children().is_empty() {
5174 return Err(SupervisorError::no_children(self.estrategia()));
5175 }
5176 }
5177 }
5178 // Zero-floor + upper-cap bracket on the typed `:max-restarts`
5179 // axis. See [`crate::render::require_positive_bounded_u32`] for
5180 // the ordering discipline (zero-floor arm strictly precedes cap
5181 // arm so `0` surfaces the self-locating `ZeroMaxRestarts`
5182 // diagnostic with its counter-axis remediation directly named,
5183 // not the misleading `0 > SUPERVISOR_MAX_RESTARTS_MAX == false`
5184 // cap-arm miss). Until this bracket landed the top edge ran all
5185 // the way to `u32::MAX` and a struct-literal
5186 // `SupervisorSpec { max_restarts: 100_000, .. }` (or the
5187 // equivalent author-surface `:max-restarts 100000` /
5188 // `:max-restarts 4294967295` typo landing in the slot) silently
5189 // passed validate. The runtime substrate consuming the value
5190 // (Erlang/OTP's `MaxIntensity / Period` ratio, the future
5191 // wasm-operator's per-supervisor restart-intensity counter, the
5192 // M4 `mesh.pleme.io/v1alpha1/Supervisor` CR materializer's
5193 // admission webhook) then turned a typed `:max-restarts`
5194 // policy into a no-op supervisor: the escalation threshold is
5195 // structurally so high that no realistic
5196 // restarts-per-`:restart-window` traffic shape can reach it,
5197 // the supervisor never escalates to its parent, and a bad
5198 // child can loop inside the window indefinitely with the
5199 // parent supervisor structurally never receiving the "this
5200 // subtree has exceeded its restart budget" signal the typed
5201 // slot is meant to express. The bracket set is
5202 // `1..=SUPERVISOR_MAX_RESTARTS_MAX`, peer with the
5203 // [`crate::aplicacao::POLICY_BREAKER_MAX_FAILURES_MAX`] cap on
5204 // the sibling `:politicas :circuit-breaker :max-failures` axis:
5205 // both are "trip the next-higher protection layer after N
5206 // events in a rolling window" counters with identical
5207 // degenerate-at-the-high-end shape and now share one canonical
5208 // bracket helper. The bracket precedes the sibling
5209 // `:restart-window` zero-floor / canonical-millisecond arms so
5210 // an over-cap `max_restarts` paired with a structurally invalid
5211 // window surfaces the bracket diagnostic first, mirroring the
5212 // `PolicyBreakerMaxFailuresExceedsCap` / window-axis cross-arm
5213 // ordering on the peer `:politicas :circuit-breaker` slot.
5214 // Route the [`SupervisorSpec::validate`] `:max-restarts` zero-floor +
5215 // upper-cap bracket-gate through the lifted [`SupervisorSpec::max_restarts`]
5216 // accessor rather than the raw `self.max_restarts` field access —
5217 // the one production consumer of the per-`:supervisor`
5218 // restart-budget-count scalar now keys off exactly one typed
5219 // dispatch on the substrate primitive, so any future rebrand on
5220 // the axis (a per-cluster restart-budget override the operator
5221 // pins through a future `:supervisor :max-restarts-overrides`
5222 // slot, a per-tenant restart-budget-alias table the M4 CR
5223 // materializer resolves per-CR) migrates as a single caixa-core
5224 // edit rather than a coordinated rewrite — sibling of the peer M3
5225 // [`crate::CircuitBreaker::max_failures`] (3a74062) migration on
5226 // the per-`:politicas :circuit-breaker :max-failures` axis.
5227 crate::render::require_positive_bounded_u32(
5228 self.max_restarts(),
5229 SUPERVISOR_MAX_RESTARTS_MAX,
5230 || SupervisorError::ZeroMaxRestarts,
5231 SupervisorError::max_restarts_exceeds_cap,
5232 )?;
5233 // Route the [`SupervisorSpec::validate`] `:restart-window`
5234 // zero-floor + integer-millisecond canonical-form + upper-cap
5235 // bracket-gate through the lifted [`SupervisorSpec::restart_window`]
5236 // accessor rather than the raw `self.restart_window` field access —
5237 // the one production consumer of the per-`:supervisor`
5238 // restart-intensity-denominator scalar now keys off exactly one
5239 // typed dispatch on the substrate primitive, so any future rebrand
5240 // on the axis (a per-cluster restart-window override the operator
5241 // pins through a future `:supervisor :restart-window-overrides`
5242 // slot, a per-tenant restart-window-alias table the M4 CR
5243 // materializer resolves per-CR) migrates as a single caixa-core
5244 // edit rather than a coordinated rewrite — sibling of the peer M2
5245 // [`crate::LimitsSpec::wall_clock`] (8cb717b) validate-arm-route
5246 // on the per-`:limits :wall-clock` axis and the peer M3
5247 // [`crate::MeshPolicy::timeout`] (7073d0f) accessor-route on the
5248 // per-`:politicas :timeout` axis.
5249 if let Some(w) = self.restart_window() {
5250 // Zero-floor + integer-millisecond canonical-form +
5251 // upper-cap bracket on the typed `:restart-window` axis.
5252 // See
5253 // [`crate::render::require_positive_canonical_bounded_duration`]
5254 // for the full three-arm ordering discipline (zero-floor
5255 // strictly precedes canonical-form so `Duration::ZERO`
5256 // surfaces the self-locating `RestartWindowZero`
5257 // diagnostic; canonical-form strictly precedes the cap arm
5258 // so a sub-millisecond above-cap value surfaces the more
5259 // fundamental round-trip-shape diagnostic first) and the
5260 // three peer typed-`Duration` sites that share this
5261 // canonical bracket ([`crate::MeshPolicy::timeout`],
5262 // [`crate::CircuitBreaker::window`],
5263 // [`crate::LimitsSpec::wall_clock`]). Every validated
5264 // value lies in `1ms..=SUPERVISOR_RESTART_WINDOW_MAX`
5265 // (1ms..=1h), integer-millisecond granularity.
5266 crate::render::require_positive_canonical_bounded_duration(
5267 w,
5268 SUPERVISOR_RESTART_WINDOW_MAX,
5269 || SupervisorError::RestartWindowZero,
5270 SupervisorError::restart_window_not_canonical,
5271 SupervisorError::restart_window_exceeds_cap,
5272 )?;
5273 }
5274 // Route the per-child DNS-1123 / semver-requirement / duplicate-
5275 // detection fan-out loop through the lifted named per-slot gate
5276 // [`SupervisorSpec::validate_children`] rather than an inline
5277 // three-per-child cascade — every future consumer that wants to
5278 // re-check only the `:children` slot's per-entry axes (the M4
5279 // `mesh.pleme.io/v1alpha1/Supervisor` CR materializer's
5280 // admission webhook re-validating one added/renamed child, the
5281 // future wasm-operator's per-child dynamic-add re-validator on
5282 // the `SimpleOneForOne` runtime-add path once dynamic-children
5283 // graduate to a typed slot, a future partial re-validator on a
5284 // per-`:children`-entry patch) reaches every per-entry axis
5285 // through one dispatch rather than re-inlining the three-arm
5286 // cascade in lockstep with `validate` or paying the peer
5287 // `:estrategia`/`:max-restarts`/`:restart-window` gates to
5288 // reach one entry check. Sibling of the peer M3 mesh-slot
5289 // per-slot gate family (`validate_membros` — the exact peer on
5290 // the M3 side, [`crate::AplicacaoSpec::validate_membros`];
5291 // `validate_contratos` — 906a5c6; `validate_entrada` — 20cd523;
5292 // `validate_placement`; `validate_politicas` routing through
5293 // `MeshPolicy::validate` — f03a154) — the M2 supervisor-slot
5294 // per-slot gate discipline now spans both the M3 mesh-slot
5295 // family and the M2 `:children` per-child-cascade axis on one
5296 // shape: one named per-slot gate per typed per-entry loop.
5297 self.validate_children()?;
5298 Ok(())
5299 }
5300
5301 /// Named per-slot gate on the M2 `:supervisor :children` per-entry
5302 /// axis — folds the per-child DNS-1123 name gate, semver-requirement
5303 /// gate, and duplicate-`:caixa` dedup arm into one call every
5304 /// consumer that wants to re-validate one `:children` entry (or the
5305 /// whole list) against the same accept-set [`SupervisorSpec::validate`]
5306 /// admits reaches through.
5307 ///
5308 /// Peer of the M3 mesh-slot [`crate::AplicacaoSpec::validate_membros`]
5309 /// per-slot gate on the analogous per-entry axis (`:membros`) — same
5310 /// three-per-entry shape (DNS-1123 name + semver-requirement +
5311 /// duplicate-`:caixa` dedup), lifted to one named substrate
5312 /// primitive per slot. The M4 `mesh.pleme.io/v1alpha1/Supervisor` CR
5313 /// materializer's admission webhook re-checking one added or renamed
5314 /// child, the future wasm-operator's per-child dynamic-add
5315 /// re-validator on the `SimpleOneForOne` runtime-add path once
5316 /// dynamic-children graduate to a typed slot, a future partial
5317 /// re-validator on a per-`:children`-entry patch — each reaches the
5318 /// three per-entry axes through this one dispatch rather than
5319 /// re-inlining the three-arm cascade in lockstep with `validate`
5320 /// (the duplication the PRIME DIRECTIVE names as a bug) or paying
5321 /// the peer `:estrategia`/`:max-restarts`/`:restart-window` gates to
5322 /// reach one entry check.
5323 ///
5324 /// Self-contained on `&self` — resolves its own dedup `HashSet`
5325 /// through [`SupervisorSpec::children`] rather than borrowing one
5326 /// threaded down from `validate`, the same posture the peer M3
5327 /// mesh-slot per-slot gates ([`crate::AplicacaoSpec::validate_membros`],
5328 /// [`crate::AplicacaoSpec::validate_contratos`],
5329 /// [`crate::AplicacaoSpec::validate_entrada`],
5330 /// [`crate::AplicacaoSpec::validate_placement`]) each carry, so a
5331 /// consumer that reaches this gate directly (without first calling
5332 /// `validate`) still runs the full per-child cascade — pinned by
5333 /// `validate_children_matches_gate_on_per_axis_refusal_shapes` +
5334 /// `validate_children_matches_gate_on_versao_invalid_and_clean_pass`
5335 /// + `validate_children_is_self_contained_on_children_slot`.
5336 ///
5337 /// The three per-entry arms run in the same canonical order the
5338 /// pre-lift inline cascade encoded (DNS-1123 → semver → dedup), so
5339 /// the diagnostic every author-declared per-`:children` entry surfaces
5340 /// through `validate` is byte-equal to the diagnostic this gate
5341 /// surfaces when called directly — the equivalence-pin pair
5342 /// `validate_children_matches_gate_on_per_axis_refusal_shapes` +
5343 /// `validate_children_matches_gate_on_versao_invalid_and_clean_pass`
5344 /// asserts the two altitudes discriminate the same set on every
5345 /// per-entry-covered input.
5346 pub fn validate_children(&self) -> Result<(), SupervisorError> {
5347 let mut seen = std::collections::HashSet::new();
5348 for child in self.children() {
5349 // Every emitted cluster artifact's `metadata.name` for a
5350 // supervised child derives from this `:children :caixa` value
5351 // verbatim — the rendered `wasm.pleme.io/v1alpha1/ComputeUnit
5352 // .metadata.name` per child, the [`crate::LABEL_PROGRAM`]
5353 // label value on every child's pod identity, and the per-
5354 // child K8s [`Service`][svc] `metadata.name` the future
5355 // wasm-operator (M3) provisions for inter-child supervision
5356 // tree wiring. Each apiserver-side schema on each landing
5357 // site enforces the DNS-1123 label rule on admission; a
5358 // structurally invalid child name (`"Worker"`, `"my_worker"`,
5359 // `"team.worker"`, `"-worker"`, `"worker-"`, the >63-byte
5360 // UUID-shaped mistaken-identity slug) silently passes the
5361 // prior empty-/duplicate-only gate and the failure surfaces
5362 // at `kubectl apply` time as a `metadata.name: Invalid value`
5363 // rejection, far from the source caixa.lisp, with no field
5364 // naming the offending `:children` entry. Lifting the gate
5365 // to caixa-build time mirrors the `:membros :caixa` value-
5366 // shape trajectory (3f9d7a0) and the `:placement :clusters`
5367 // trajectory (6cbb900) onto the third DNS-1123-label-shaped
5368 // identifier axis — the supervisor tree's child names —
5369 // through the lifted
5370 // [`crate::render::require_valid_dns_1123_label`] gate the
5371 // seven peer name axes (`:membros :caixa`, `:placement
5372 // :clusters`, `:placement :affinity`, `:contratos :de`/`:para`,
5373 // `:entrada :para`, `:nome`, `:upgrade-from :module`) each
5374 // route through, so drift between the eight axes' accepted
5375 // DNS-1123-label sets is structurally impossible.
5376 //
5377 // [svc]: https://kubernetes.io/docs/concepts/services-networking/service/
5378 crate::render::require_valid_dns_1123_label(
5379 child.nome(),
5380 || SupervisorError::EmptyChildName,
5381 |reason| SupervisorError::child_caixa_invalid(child.nome(), reason),
5382 )?;
5383 // The author surface for `:children :versao` is the same
5384 // Cargo-shaped semver requirement string `:deps :versao` and
5385 // `:membros :versao` carry — and the lacre pipeline resolves
5386 // all three axes through the same
5387 // [`crate::version::parse_requirement`] entry-point. The
5388 // shared [`crate::render::require_valid_versao_requirement`]
5389 // helper brackets the empty-first + parse cascade both peer
5390 // axes ([`crate::dep::Dep::validate`] on `:deps :versao`,
5391 // [`crate::AplicacaoSpec::validate_membros`] on `:membros
5392 // :versao`) route through, so drift between the three axes'
5393 // accepted requirement sets is structurally impossible and
5394 // the parse-side no-op the empty-first arm closes (semver's
5395 // empty parse yields an implicit `*`) lives in exactly one
5396 // predicate. Every `ChildSpec::versao` past validate is
5397 // round-trippable through [`crate::parse_requirement`]
5398 // without re-checking at the resolver layer, and the three
5399 // `:versao` typed surfaces (`:deps`, `:membros`, `:children`)
5400 // are now structurally equivalent by construction.
5401 crate::render::require_valid_versao_requirement(
5402 child.versao_requirement(),
5403 || SupervisorError::empty_child_version(child.nome()),
5404 |reason| {
5405 SupervisorError::child_versao_invalid(
5406 child.nome(),
5407 child.versao_requirement(),
5408 reason,
5409 )
5410 },
5411 )?;
5412 crate::render::insert_first_seen(&mut seen, child.nome(), || {
5413 SupervisorError::duplicate_child_caixa(child.nome())
5414 })?;
5415 }
5416 Ok(())
5417 }
5418}
5419
5420/// Cross-slot coherence gate on the supervision tree: no
5421/// `:children :caixa` entry may name the supervisor's own `:nome`.
5422///
5423/// A supervisor that lists itself as a child is a degenerate self-parent
5424/// — the supervision tree is a DAG rooted at the supervisor (OTP child
5425/// specs reference *distinct* child processes; a supervisor is never its
5426/// own child), and the wasm-operator's hierarchical reconciliation would
5427/// otherwise be handed a node that is its own parent: a one-node cycle it
5428/// either rejects far from the source `caixa.lisp` or recurses on. Because
5429/// every `:nome` is a globally-unique substrate identity (DNS-1123 label +
5430/// lacre closure root), a child whose `:caixa` equals the supervisor's
5431/// `:nome` *is* the supervisor itself, not a coincidentally-named peer.
5432///
5433/// Lives outside [`SupervisorSpec::validate`] because the typed view
5434/// carries the children but not the parent `:nome`; mirrors the
5435/// cross-slot precedence gate `validate_upgrade_from_against_versao`
5436/// (which likewise reads one slot against another at the
5437/// [`crate::layout`] wire-up site) and the mesh self-edge gate
5438/// `AplicacaoSpec`'s `ContratoSelfLoop` — the same "an edge from a graph
5439/// node to itself is structurally not a tree/mesh edge" discipline, here
5440/// on the supervision-tree axis.
5441pub fn validate_no_self_supervision(
5442 children: &[ChildSpec],
5443 parent_nome: &str,
5444) -> Result<(), SupervisorError> {
5445 for child in children {
5446 if child.nome() == parent_nome {
5447 return Err(SupervisorError::child_supervises_self(parent_nome));
5448 }
5449 }
5450 Ok(())
5451}
5452
5453#[derive(Debug, Error, PartialEq, Eq)]
5454pub enum SupervisorError {
5455 #[error("supervisor :estrategia {estrategia:?} requires at least one :children entry")]
5456 NoChildren { estrategia: RestartStrategy },
5457 #[error(
5458 "SimpleOneForOne supervisors must declare zero static children (children spawn dynamically)"
5459 )]
5460 SimpleOneForOneWithStaticChildren,
5461 #[error(":max-restarts must be > 0")]
5462 ZeroMaxRestarts,
5463 #[error(
5464 ":supervisor :max-restarts ({max_restarts}) exceeds the supervisor-policy ceiling \
5465 (SUPERVISOR_MAX_RESTARTS_MAX = 1000) — a value above this cap turns the typed \
5466 restart-intensity policy into a no-op supervisor: the escalation threshold is \
5467 structurally so high that no realistic restarts-per-:restart-window traffic shape \
5468 can reach it, so the supervisor never escalates to its parent and a bad child can \
5469 loop inside the window indefinitely. Every typed-slot consumer (Erlang/OTP's \
5470 MaxIntensity/Period ratio, the future wasm-operator's per-supervisor \
5471 restart-intensity counter, the M4 mesh.pleme.io/v1alpha1/Supervisor CR \
5472 materializer's admission webhook) emits a `:max-restarts` declaration that is \
5473 structurally never reached. Pin a value in 1..=1000 (Erlang/OTP / Elixir / Riak \
5474 Core / RabbitMQ production playbooks recommend 3..=100; the OTP `supervisor` \
5475 callback module's `MaxR = 1` minimal-restart default sits at the bottom of the \
5476 band) or restructure the supervision tree (split the flaky child into its own \
5477 sub-supervisor with a tighter budget) if you need a higher restart tolerance."
5478 )]
5479 MaxRestartsExceedsCap { max_restarts: u32 },
5480 #[error(
5481 ":restart-window must be > 0 when set — Erlang/OTP's MaxIntensity/Period \
5482 requires Period > 0; a zero window either trips on the first failure or \
5483 never trips depending on operator interpretation. Omit :restart-window to \
5484 express `never reset`; carry a positive duration to express the window."
5485 )]
5486 RestartWindowZero,
5487 #[error(
5488 ":supervisor :restart-window ({window:?}) carries a sub-millisecond residue the shared `duration_codec` cannot round-trip — \
5489 the codec truncates to `as_millis()` before picking the canonical unit, so a value with `subsec_nanos() % 1_000_000 != 0` either \
5490 truncates on first serialize (e.g. `Duration::from_micros(1500)` → \"1ms\" → `Duration::from_millis(1)` ≠ original) or renders \
5491 as \"0s\" the `RestartWindowZero` arm then rejects on re-validate. Pin an integer-millisecond magnitude in the canonical authoring form \
5492 (`<integer><unit>` for unit ∈ {{ms, s, m, h}}, e.g. `\"500ms\"`, `\"30s\"`, `\"2m\"`, `\"1h\"`) or omit the field for `never reset`"
5493 )]
5494 RestartWindowNotCanonical { window: Duration },
5495 #[error(
5496 ":supervisor :restart-window ({window:?}) exceeds the supervisor-policy ceiling \
5497 (SUPERVISOR_RESTART_WINDOW_MAX = 1h = 3600s) — a value above this cap turns the typed \
5498 per-supervisor rolling-window restart-intensity counter into a lifetime counter: the \
5499 failure-counting window is structurally so long that transient restarts are never \
5500 forgotten, the MaxIntensity/Period ratio degenerates from `trip the parent supervisor \
5501 when the child has exceeded its restart budget within the recent window` to `trip the \
5502 parent when the child has exceeded its restart budget over its lifetime`, and the \
5503 supervisor's reset semantic never reaches the child — every typed-slot consumer \
5504 (Erlang/OTP's MaxIntensity/Period reconciler, the future wasm-operator's \
5505 per-supervisor restart-intensity counter, the M4 mesh.pleme.io/v1alpha1/Supervisor CR \
5506 materializer's admission webhook, the caixa-operator's hierarchical reconciliation \
5507 scheduler) emits a `:restart-window` declaration that is structurally a no-op rolling \
5508 window. Pin a value in 1ms..=1h (Learn You Some Erlang's `{{intensity, 5, 60}}` \
5509 worker-supervisor `Period = 60s` default, Elixir's `Supervisor` `max_seconds: 5` \
5510 default, OTP's `supervisor` callback module `MaxT = 5..=60` typical, Riak Core's \
5511 `MaxT ∈ 10s..=300s`, RabbitMQ broker-supervisor `MaxT = 5s` default — every Erlang/OTP \
5512 / Elixir production playbook sits in the 5s..=300s band; the longest documented \
5513 per-supervisor restart-window any pleme-io substrate playbook recommends maxes at \
5514 ~30m) or omit :restart-window to express `never reset` (the supervisor's restart \
5515 budget then becomes a strict lifetime counter by design, not a degenerate one — the \
5516 author surfaces the lifetime-counter semantic explicitly at the slot, rather than \
5517 hiding it behind a rolling-window declaration the cap arm rejects)"
5518 )]
5519 RestartWindowExceedsCap { window: Duration },
5520 #[error("child entry has empty :caixa name")]
5521 EmptyChildName,
5522 #[error(
5523 "child :caixa {caixa:?} is not a valid DNS-1123 label: {reason} \
5524 (the K8s apiserver enforces this rule on every `metadata.name` / Service \
5525 name / label value the child name lands in — the per-child \
5526 `wasm.pleme.io/v1alpha1/ComputeUnit.metadata.name`, the `LABEL_PROGRAM` \
5527 label value, and the future wasm-operator per-child Service `metadata.name` \
5528 — each apiserver-side schema rejects names that don't match; use a \
5529 lowercase alphanumeric + hyphen identifier like `\"worker\"` or `\"cache-v2\"`)"
5530 )]
5531 ChildCaixaInvalid { caixa: String, reason: String },
5532 #[error("child {caixa:?} has empty :versao constraint")]
5533 EmptyChildVersion { caixa: String },
5534 #[error(
5535 "child {caixa:?} :versao {versao:?} is not a valid semver requirement: \
5536 {reason} (use Cargo-shaped forms like `\"^0.1\"`, `\"~0.1.2\"`, \
5537 `\"0.1.0\"`, or `\"*\"` — the same shape `:deps :versao` and \
5538 `:membros :versao` carry; the lacre pipeline resolves all three \
5539 through the same parser)"
5540 )]
5541 ChildVersaoInvalid {
5542 caixa: String,
5543 versao: String,
5544 reason: String,
5545 },
5546 #[error(
5547 "child {caixa:?} appears more than once (Erlang/OTP requires unique \
5548 child_spec.id per supervisor; duplicate children materialize as duplicate \
5549 ComputeUnits in the rendered chart, one silently overwriting the other)"
5550 )]
5551 DuplicateChildCaixa { caixa: String },
5552 #[error(
5553 "supervisor {caixa:?} lists itself as a :children entry — a supervisor is \
5554 never its own child (the supervision tree is a DAG rooted at the supervisor; \
5555 OTP child specs reference distinct child processes). Since every :nome is a \
5556 globally-unique substrate identity, a child naming the supervisor's own :nome \
5557 is a one-node reconciliation cycle, not a coincidentally-named peer; drop the \
5558 self-referential :children entry or rename it to the actual child caixa."
5559 )]
5560 ChildSupervisesSelf { caixa: String },
5561}
5562
5563// Fold the three `SupervisorError::<Variant> { caixa: <&str>.to_string() }`
5564// caixa-only struct-variant wire-up sites at [`SupervisorSpec::validate_children`]
5565// and [`validate_no_self_supervision`] onto one substrate primitive per
5566// typed variant — the sibling on `SupervisorError` of the four uniform-shape
5567// `LayoutError`-envelope constructor families the peer
5568// [`crate::layout::layout_violation_ctors!`] macro closed (131ca0d, 16
5569// variants on `{ caixa, issue }`), the [`crate::layout::layout_slot_kind_ctors!`]
5570// macro closed (0419438, 4 variants on `{ caixa, kind, slots }`), the
5571// [`crate::LayoutError::missing_entry`] one-variant ctor closed (1b09f9d,
5572// on `{ kind, path }`), and the [`crate::layout::layout_nome_only_ctors!`]
5573// macro closed (3fe3dd7, 6 variants on `<Variant>(String)`), plus the
5574// [`crate::AplicacaoError::entrada_host_invalid`] one-variant ctor
5575// (17dd504, `{ host, reason }`), the [`crate::aplicacao::contrato_target_ctors!`]
5576// macro (14b81d5, 2 variants on `{ de, para, wit, expected }`), and the
5577// [`crate::aplicacao::contrato_empty_pair_ctors!`] macro (8580068, 4
5578// variants on `{ de, para }`) already at that discipline on the peer
5579// `AplicacaoError` envelopes.
5580//
5581// Each of the three wire-up sites on this shape (`EmptyChildVersion` at
5582// the per-`:children` semver-requirement empty-first arm, `DuplicateChildCaixa`
5583// at the per-`:children` dedup arm, `ChildSupervisesSelf` at the cross-slot
5584// self-supervision arm) opened the identical
5585// `SupervisorError::<Variant> { caixa: <&str>.to_string() }` struct-literal —
5586// the exact "same block re-inlined at every consumer" shape the PRIME
5587// DIRECTIVE names as a bug, on the same altitude the peer `LayoutError` /
5588// `AplicacaoError` families each closed on their sibling envelopes. The
5589// three variants share one `{ caixa: String }` shape, so the fold routes
5590// each wire-up site through one dispatch per typed variant.
5591//
5592// The macro below generates one static constructor per variant of shape
5593// `fn <slot>(caixa: &str) -> SupervisorError`, so every wire-up site
5594// collapses onto one dispatch:
5595// `SupervisorError::<slot>(<&str>)`, byte-equal to the pre-lift
5596// struct-literal on the same `&str` fixture. The uniform one-field
5597// construction (`caixa: caixa.to_string()`) is spelled once — inside the
5598// macro — rather than at every wire-up site. Every constructor is
5599// `#[must_use]` so a caller who mistakenly discards the constructed error
5600// trips a compile warning at the wire-up site.
5601//
5602// Every future consumer that wants to construct one of these three
5603// variants outside `SupervisorSpec::validate_children` /
5604// `validate_no_self_supervision` — a deferred
5605// `mesh.pleme.io/v1alpha1/Supervisor` CR materializer's admission
5606// webhook re-checking one added/renamed child, a future
5607// `feira validate --supervisor` per-caixa admission verb, a per-child
5608// dynamic-add re-validator on the `SimpleOneForOne` runtime-add path
5609// once dynamic-children graduate to a typed slot, a per-Supervisor
5610// overlay resolver rejecting a duplicate/self-supervising child against
5611// a cluster-local snapshot — now reaches each variant through one call
5612// rather than re-inlining the three-line struct-literal in lockstep
5613// with the three in-crate wire-up sites.
5614macro_rules! supervisor_caixa_only_ctors {
5615 ($($ctor:ident => $variant:ident),* $(,)?) => {
5616 impl SupervisorError {
5617 $(
5618 #[doc = concat!(
5619 "Construct a [`SupervisorError::",
5620 stringify!($variant),
5621 "`] naming the offending `:children :caixa` (or ",
5622 "supervisor `:nome`, on the self-supervision arm). ",
5623 "Folds the uniform `Self::",
5624 stringify!($variant),
5625 " { caixa: caixa.to_string() }` one-field ",
5626 "struct-literal onto one substrate primitive so ",
5627 "every [`SupervisorSpec::validate_children`] / ",
5628 "[`validate_no_self_supervision`] wire-up on this ",
5629 "variant reads through one dispatch rather than the ",
5630 "pre-lift open-coded struct-literal block."
5631 )]
5632 #[must_use]
5633 pub fn $ctor(caixa: &str) -> Self {
5634 Self::$variant { caixa: caixa.to_string() }
5635 }
5636 )*
5637 }
5638 };
5639}
5640
5641supervisor_caixa_only_ctors! {
5642 empty_child_version => EmptyChildVersion,
5643 duplicate_child_caixa => DuplicateChildCaixa,
5644 child_supervises_self => ChildSupervisesSelf,
5645}
5646
5647// Fold the two `SupervisorError::{ChildCaixaInvalid, ChildVersaoInvalid}`
5648// struct-variant wire-up sites at [`SupervisorSpec::validate_children`] onto
5649// one substrate primitive per typed variant — the M2 supervisor-side siblings
5650// of the peer [`crate::AplicacaoError::membro_caixa_invalid`] two-slot ctor
5651// already lifted through the sibling
5652// [`crate::aplicacao::aplicacao_field_reason_ctors!`] macro (981060b) on the
5653// peer `AplicacaoError { caixa: String, reason: String }` envelope. The
5654// `ChildCaixaInvalid` variant carries the same `{ <name>: String, reason:
5655// String }` two-slot shape the peer seven-variant
5656// [`crate::aplicacao::aplicacao_field_reason_ctors!`] fold closed on the
5657// `AplicacaoError` envelope (`MembroCaixaInvalid`, `EntradaParaInvalid`,
5658// `EntradaHostInvalid`, `EntradaPathInvalid`, `PlacementClusterInvalid`,
5659// `PlacementAffinityInvalid`, `ShardKeyInvalid`); the `ChildVersaoInvalid`
5660// variant carries the `{ caixa: String, versao: String, reason: String }`
5661// three-slot shape the sibling `AplicacaoError::MembroVersaoInvalid` axis
5662// carries on the same `:versao` value-shape.
5663//
5664// Each of the two wire-up sites opened the same closure-shaped
5665// `|reason| SupervisorError::<Variant> { caixa: child.nome().to_string(),
5666// [versao: child.versao_requirement().to_string(),] reason }` block inside
5667// the paired [`crate::render::require_valid_dns_1123_label`] and
5668// [`crate::render::require_valid_versao_requirement`] callbacks — the exact
5669// "same block re-inlined at every consumer" shape the PRIME DIRECTIVE names
5670// as a bug, on the same altitude the peer `AplicacaoError` /
5671// `SupervisorError` / `LayoutError` / `DepError` / `LimitsError` ctor
5672// families already closed on their sibling envelopes.
5673//
5674// The two `#[must_use]` inherent constructors below fold each wire-up onto
5675// one dispatch: `SupervisorError::child_caixa_invalid(<name>, <reason>)`
5676// and `SupervisorError::child_versao_invalid(<name>, <versao>, <reason>)`,
5677// byte-equal to the pre-lift struct-literal on the same scalar fixtures.
5678// The uniform per-field `.to_string()` / `.into()` construction is spelled
5679// once — inside each ctor body — rather than at every wire-up site. The
5680// `reason: impl Into<String>` bound accepts both `&str` literals and
5681// `format!(…)` outputs verbatim so no wire-up site changes its per-arm
5682// diagnostic shape at the lift, matching the peer
5683// [`aplicacao_field_reason_ctors!`] and
5684// [`crate::aplicacao::contrato_pair_value_reason_ctors!`] bounds on the
5685// sibling envelopes.
5686//
5687// Every future consumer that wants to construct one of these two variants
5688// outside `SupervisorSpec::validate_children` — a deferred
5689// `mesh.pleme.io/v1alpha1/Supervisor` CR materializer's admission webhook
5690// re-checking one added/renamed child's `:caixa` or `:versao`, a future
5691// `feira validate --supervisor` per-caixa admission verb, a per-child
5692// dynamic-add re-validator on the `SimpleOneForOne` runtime-add path once
5693// dynamic-children graduate to a typed slot, a per-Supervisor overlay
5694// resolver rejecting a shape-invalid child `:caixa`/`:versao` against a
5695// cluster-local snapshot — now reaches each variant through one call rather
5696// than re-inlining the per-shape struct-literal block in lockstep with the
5697// two in-crate wire-up sites.
5698impl SupervisorError {
5699 /// Construct a [`SupervisorError::ChildCaixaInvalid`] naming the
5700 /// offending `:children :caixa` value under the given `reason`. Folds
5701 /// the uniform `Self::ChildCaixaInvalid { caixa: caixa.to_string(),
5702 /// reason: reason.into() }` two-slot struct-literal onto one substrate
5703 /// primitive so every wire-up on this variant reads through one
5704 /// dispatch, matching the peer
5705 /// [`crate::AplicacaoError::membro_caixa_invalid`] ctor's shape on the
5706 /// sibling `AplicacaoError { caixa: String, reason: String }`
5707 /// envelope. `reason` accepts both `&str` literals and `format!(…)`
5708 /// outputs through the `impl Into<String>` bound.
5709 #[must_use]
5710 pub fn child_caixa_invalid(caixa: &str, reason: impl Into<String>) -> Self {
5711 Self::ChildCaixaInvalid {
5712 caixa: caixa.to_string(),
5713 reason: reason.into(),
5714 }
5715 }
5716
5717 /// Construct a [`SupervisorError::ChildVersaoInvalid`] naming the
5718 /// offending `:children :caixa` and its `:versao` requirement under
5719 /// the given `reason`. Folds the uniform `Self::ChildVersaoInvalid {
5720 /// caixa: caixa.to_string(), versao: versao.to_string(), reason:
5721 /// reason.into() }` three-slot struct-literal onto one substrate
5722 /// primitive so every wire-up on this variant reads through one
5723 /// dispatch, matching the sibling `AplicacaoError::MembroVersaoInvalid
5724 /// { caixa, versao, reason }` three-slot axis on the peer
5725 /// `AplicacaoError` envelope. `reason` accepts both `&str` literals
5726 /// and `format!(…)` outputs through the `impl Into<String>` bound.
5727 #[must_use]
5728 pub fn child_versao_invalid(caixa: &str, versao: &str, reason: impl Into<String>) -> Self {
5729 Self::ChildVersaoInvalid {
5730 caixa: caixa.to_string(),
5731 versao: versao.to_string(),
5732 reason: reason.into(),
5733 }
5734 }
5735}
5736
5737// Fold the four `SupervisorError::<Variant> { <field>: <Copy> }` one-field
5738// Copy-scalar struct-variant wire-up sites at [`SupervisorSpec::validate`]'s
5739// three bracket-arms — one struct-literal at the `:children`-empty
5740// non-`SimpleOneForOne` refusal cascade (`NoChildren { estrategia }`) plus
5741// three `impl FnOnce(<ty>) -> SupervisorError` bracket-closures at the
5742// [`crate::render::require_positive_bounded_u32`] `:max-restarts` cap arm
5743// (`MaxRestartsExceedsCap { max_restarts }`) and the paired
5744// [`crate::render::require_positive_canonical_bounded_duration`]
5745// `:restart-window` canonical-form + cap arms (`RestartWindowNotCanonical
5746// { window }`, `RestartWindowExceedsCap { window }`) — onto one substrate
5747// primitive per typed variant, matching the sibling
5748// [`crate::aplicacao::aplicacao_policy_scalar_ctors!`] macro (7ef425e, 8
5749// variants on the same `{ <field>: Duration | u32 }` shape) at that
5750// discipline on the peer `AplicacaoError` envelope's per-`:politicas`
5751// scalar axis. Every variant is a one-field `Copy`-pass-through struct-
5752// literal — `RestartStrategy | u32 | Duration` — so the fold routes each
5753// wire-up site through one dispatch per typed variant without a runtime-
5754// work delta.
5755//
5756// Each of the four wire-up sites opened the identical
5757// `SupervisorError::<Variant> { <field>: <val> }` struct-literal — the
5758// exact "same block re-inlined at every consumer" shape the PRIME
5759// DIRECTIVE names as a bug, on the same altitude the peer
5760// `aplicacao_policy_scalar_ctors!` fold closed on the sibling
5761// `AplicacaoError` envelope's per-`:politicas` per-axis cap / canonical-
5762// form arms. The four variants share one `{ <field>: <Copy> }` shape, so
5763// the fold routes each wire-up site through one dispatch per typed
5764// variant.
5765//
5766// The macro below generates one static constructor per variant of shape
5767// `const fn <ctor>(<field>: <ty>) -> SupervisorError`, so every wire-up
5768// site collapses onto one dispatch: `SupervisorError::<ctor>(<val>)`,
5769// byte-equal to the pre-lift struct-literal on the same `Copy`-`<ty>`
5770// fixture — as a direct call at the [`SupervisorSpec::validate`]
5771// `:children`-empty refusal, or as a bare function pointer in the
5772// `impl FnOnce(<ty>) -> SupervisorError` bracket-closure slot every
5773// [`crate::render::require_positive_bounded_u32`] /
5774// [`crate::render::require_positive_canonical_bounded_duration`] gate
5775// carries — rather than the pre-lift open-coded one-line closure over
5776// the same one-field struct-literal. `const fn` preserves the `Copy`-
5777// pass-through's zero-runtime-work property verbatim. Every constructor
5778// is `#[must_use]` so a caller who mistakenly discards the constructed
5779// error trips a compile warning at the wire-up site.
5780//
5781// Every future consumer that wants to construct one of these four
5782// variants outside `SupervisorSpec::validate` — a deferred
5783// `mesh.pleme.io/v1alpha1/Supervisor` CR materializer's admission
5784// webhook re-checking one edited `:estrategia` / `:max-restarts` /
5785// `:restart-window` slot against the cap + canonical-form cascade, a
5786// future `feira validate --supervisor` per-caixa admission verb re-
5787// running the shape gates on demand, a per-Supervisor overlay resolver
5788// rejecting an author-supplied slot against a cluster-local snapshot —
5789// now reaches each variant through one call rather than re-inlining the
5790// per-shape struct-literal block in lockstep with the four in-crate
5791// wire-up sites.
5792macro_rules! supervisor_scalar_ctors {
5793 ($($ctor:ident => $variant:ident { $field:ident: $ty:ty }),* $(,)?) => {
5794 impl SupervisorError {
5795 $(
5796 #[doc = concat!(
5797 "Construct a [`SupervisorError::",
5798 stringify!($variant),
5799 "`] naming the offending per-`:supervisor` `",
5800 stringify!($field),
5801 "` scalar. Folds the uniform `Self::",
5802 stringify!($variant),
5803 " { ",
5804 stringify!($field),
5805 " }` one-field `Copy`-pass-through struct-literal onto ",
5806 "one substrate primitive so every per-axis wire-up on ",
5807 "this variant reads through one dispatch — as a direct ",
5808 "call (`SupervisorError::",
5809 stringify!($ctor),
5810 "(<val>)`, byte-equal to the pre-lift struct-literal on ",
5811 "the same `Copy`-`",
5812 stringify!($ty),
5813 "` fixture) or as a bare function pointer in the ",
5814 "`impl FnOnce(",
5815 stringify!($ty),
5816 ") -> SupervisorError` bracket-closure slot every ",
5817 "`crate::render::require_positive_bounded_*` / ",
5818 "`crate::render::require_positive_canonical_bounded_*` ",
5819 "gate carries — rather than the pre-lift open-coded ",
5820 "one-line closure over the same one-field struct-",
5821 "literal. `const fn` preserves the `Copy`-pass-through's ",
5822 "zero-runtime-work property verbatim."
5823 )]
5824 #[must_use]
5825 pub const fn $ctor($field: $ty) -> Self {
5826 Self::$variant { $field }
5827 }
5828 )*
5829 }
5830 };
5831}
5832
5833supervisor_scalar_ctors! {
5834 no_children => NoChildren { estrategia: RestartStrategy },
5835 max_restarts_exceeds_cap => MaxRestartsExceedsCap { max_restarts: u32 },
5836 restart_window_not_canonical => RestartWindowNotCanonical { window: Duration },
5837 restart_window_exceeds_cap => RestartWindowExceedsCap { window: Duration },
5838}
5839
5840/// Shared duration string codec for the typed slots that take a
5841/// duration (`restart_window`, `MeshPolicy::timeout`,
5842/// `CircuitBreaker::window`, …). Public so [`crate::aplicacao`] can
5843/// reuse it without duplicating the parser.
5844pub mod duration_codec {
5845 use super::Duration;
5846 use serde::{Deserializer, Serializer};
5847
5848 pub fn serialize<S: Serializer>(v: &Option<Duration>, s: S) -> Result<S::Ok, S::Error> {
5849 // Route through the canonical [`crate::render::serialize_option_via_str`]
5850 // — the substrate-side single-owner primitive for the forward
5851 // arm of the typed-magnitude codec family. See its docstring
5852 // for the full sibling roster.
5853 crate::render::serialize_option_via_str(v, s, render)
5854 }
5855
5856 pub fn deserialize<'de, D: Deserializer<'de>>(d: D) -> Result<Option<Duration>, D::Error> {
5857 // Route through the canonical [`crate::render::deserialize_option_via_str`]
5858 // — the substrate-side single-owner primitive for the reverse
5859 // arm of the typed-magnitude codec family. See its docstring
5860 // for the full sibling roster.
5861 crate::render::deserialize_option_via_str(d, parse)
5862 }
5863
5864 pub(crate) fn parse(s: &str) -> Result<Duration, String> {
5865 // Paired whitespace-rejection arm — same canonical-form
5866 // render-determinism discipline as the peer
5867 // `limits::parse_byte_size` / `limits::parse_duration` /
5868 // `limits::parse_millicores` /
5869 // `aplicacao::rate_limit_codec::parse` sites: the ASCII
5870 // byte-scan closes the WhatWG-conformant whitespace bytes
5871 // (`0x20`, `0x09`, `0x0A`, `0x0C`, `0x0D`), the non-ASCII
5872 // `char::is_whitespace` scan closes the strictly-complementary
5873 // Unicode `White_Space` class (NBSP `\u{00A0}`, LINE SEPARATOR
5874 // `\u{2028}`, EM-SPACE `\u{2003}`, and the peer typography
5875 // codepoints) that `str::trim` at parse entry silently strips.
5876 // Either drift class would round-trip through `render` to a
5877 // *different* canonical form on next emit — breaking the
5878 // THEORY.md Part V render-determinism contract on three typed-
5879 // duration slots at once (`:supervisor :restart-window`,
5880 // `:politicas :timeout`, `:politicas :circuit-breaker :window`)
5881 // via the shared codec.
5882 //
5883 // Routed through the lifted [`crate::render::reject_whitespace`]
5884 // primitive — the substrate-side single-owner paired-arm gate
5885 // every typed-magnitude codec in caixa-core shares.
5886 crate::render::reject_whitespace::<String, _, _>(
5887 s,
5888 |b| {
5889 format!(
5890 "duration: value {s:?} contains whitespace byte 0x{b:02x} — the canonical \
5891 authoring form for the typed duration slots routed through this shared codec \
5892 (`:supervisor :restart-window`, `:politicas :timeout`, \
5893 `:politicas :circuit-breaker :window`) is `<integer><unit>` (e.g. \
5894 `\"30s\"`, `\"500ms\"`, `\"2m\"`, `\"1h\"`) with no whitespace bytes \
5895 anywhere. A whitespace-carrying shape (`\" 30s\"`, `\"30s \"`, `\"30 s\"`, \
5896 `\"\\t30s\"`, `\"30s\\n\"`) round-trips through `render` to a *different* \
5897 canonical form (`\"30s\"`) on first serialize — breaking the THEORY.md \
5898 Part V render-determinism contract every typed slot carries. Strip every \
5899 whitespace byte (write `\"30s\"` verbatim)"
5900 )
5901 },
5902 |ch| {
5903 format!(
5904 "duration: value {s:?} contains non-ASCII Unicode whitespace character \
5905 {ch:?} (U+{cp:04X}) — the canonical authoring form for the typed \
5906 duration slots routed through this shared codec (`:supervisor \
5907 :restart-window`, `:politicas :timeout`, `:politicas :circuit-breaker \
5908 :window`) is `<integer><unit>` (e.g. `\"30s\"`, `\"500ms\"`, `\"2m\"`, \
5909 `\"1h\"`) with no whitespace characters anywhere (ASCII or Unicode). A \
5910 non-ASCII-whitespace-carrying shape (`\"\\u{{00A0}}30s\"`, \
5911 `\"30s\\u{{2028}}\"`, `\"30\\u{{2003}}s\"`) survives the ASCII byte-scan \
5912 but `str::trim` (which uses `char::is_whitespace` — the Unicode \
5913 `White_Space` property, strictly wider than the ASCII byte set) silently \
5914 strips it at parse entry, and the value round-trips through `render` to \
5915 a *different* canonical form (`\"30s\"`) on first serialize — breaking \
5916 the THEORY.md Part V render-determinism contract every typed slot \
5917 carries. Strip every non-ASCII whitespace character (write `\"30s\"` \
5918 verbatim with only ASCII bytes)",
5919 cp = ch as u32
5920 )
5921 },
5922 )?;
5923 let s = s.trim();
5924 // Routed through the lifted
5925 // [`crate::render::split_magnitude_and_alpha_unit`] primitive —
5926 // the single-owner split every ASCII-alphabetic-unit typed-
5927 // magnitude codec in caixa-core (`limits::parse_byte_size` /
5928 // `limits::parse_duration` / this shared duration codec) shares.
5929 // See its docstring for the full sibling roster on the same
5930 // primitive altitude.
5931 let (num_part, unit) = crate::render::split_magnitude_and_alpha_unit(s);
5932 let num_trim = num_part.trim();
5933 // The canonical authoring form for every typed slot routed
5934 // through this shared codec — `:supervisor :restart-window`,
5935 // `:politicas :timeout`, `:politicas :circuit-breaker :window`
5936 // — is `<integer><unit>`. Every magnitude [`render`] emits is a
5937 // non-negative integer with no decimal point and no leading
5938 // sign, so the parser's accepted set must match for
5939 // serialize/deserialize to round-trip without canonical-form
5940 // drift. Until this gate landed the parser accepted any
5941 // `f64`-shaped magnitude (`"1.5s"` → 1500ms, `"1.0s"` → 1s,
5942 // `"0.5m"` → 30s, `"+30s"` → 30s) and serde silently round-
5943 // tripped the value to a *different* canonical string on the
5944 // next emit (`"1.5s"` → 1500ms → `"1500ms"`, `"1.0s"` → 1s →
5945 // `"1s"`, `"0.5m"` → 30s → `"30s"`, `"+30s"` → 30s → `"30s"`)
5946 // — breaking the THEORY.md Part V render-determinism contract
5947 // on three typed slots at once. Same canonical-form discipline
5948 // `crate::limits::parse_duration` (818dd38, the immediate
5949 // predecessor on the peer `:limits :wall-clock` codec) applies;
5950 // this gate lifts the discipline onto the shared codec that
5951 // backs the remaining three typed-duration slots in caixa-core.
5952 //
5953 // Strict canonical form: every byte of the magnitude is an
5954 // ASCII digit (no `.`, no `+`, no `-`). On non-digit-only
5955 // inputs the gate distinguishes "non-canonical-but-numeric"
5956 // (parses as f64 or i64 — surfaced with a self-locating
5957 // diagnostic naming the canonical authoring form, the
5958 // round-trip drift each rejected shape would produce on first
5959 // serialize, and the canonical-form remediation) from
5960 // "garbage" (parses as neither — surfaced with the existing
5961 // narrower "bad duration magnitude" wording so its diagnostic
5962 // shape remains stable for the parser-shape footgun case).
5963 // The pre-existing `num < 0.0` arm is now unreachable — the
5964 // digit-only gate strictly precedes magnitude parsing, and a
5965 // leading `-` is not an ASCII digit, so `"-30s"` lands on the
5966 // non-canonical-but-numeric branch with the `-30` named
5967 // verbatim in the diagnostic rather than the prior
5968 // value-laundered "negative duration in \"-30s\"" wording.
5969 //
5970 // Routed through the lifted
5971 // [`crate::render::is_digit_only_magnitude`] predicate — the
5972 // same source of truth the four peer typed-magnitude codec
5973 // sites share.
5974 let digit_only = crate::render::is_digit_only_magnitude(num_trim);
5975 if !digit_only {
5976 let numeric = num_trim.parse::<f64>().is_ok() || num_trim.parse::<i64>().is_ok();
5977 if numeric {
5978 return Err(format!(
5979 "duration: magnitude {num_trim:?} is not a non-negative integer — the \
5980 canonical authoring form for the typed duration slots routed through \
5981 this shared codec (`:supervisor :restart-window`, `:politicas :timeout`, \
5982 `:politicas :circuit-breaker :window`) is `<integer><unit>` (e.g. \
5983 `\"30s\"`, `\"500ms\"`, `\"2m\"`, `\"1h\"`) with no decimal point and \
5984 no leading `+` / `-` sign. A fractional / decimal-shaped magnitude \
5985 (`\"1.5s\"`, `\"1.0s\"`, `\"0.5m\"`, `\"+30s\"`, `\"-30s\"`) round-trips \
5986 through `render` to a *different* canonical form (`\"1500ms\"`, `\"1s\"`, \
5987 `\"30s\"`, `\"30s\"`, `\"30s\"`) on first serialize — breaking the \
5988 THEORY.md Part V render-determinism contract every typed slot carries. \
5989 Pick an integer magnitude in the unit that divides cleanly (write \
5990 `\"1500ms\"` instead of `\"1.5s\"`; `\"30s\"` instead of `\"0.5m\"`)"
5991 ));
5992 }
5993 return Err(format!("bad duration magnitude in {s:?}"));
5994 }
5995 // Leading-zero arm — peer with the `rate_limit_codec` leading-
5996 // zero arm (4f46830) on the same canonical-form render-
5997 // determinism axis. The digit-only gate accepts `"030s"`,
5998 // `"00s"`, `"01h"`, `"0500ms"` as `u64::from_str` parses them
5999 // losslessly (= 30, 0, 1, 500), but `render` emits the leading-
6000 // zero-stripped form (`"30s"`, `"0s"`, `"1h"`, `"500ms"`) — a
6001 // *different* canonical string on the next emit, breaking the
6002 // THEORY.md Part V render-determinism contract the same way
6003 // `"+30s"` did before the leading-`+` arm landed. The single-
6004 // byte magnitude `"0"` (or `"0s"` / `"0ms"`) round-trips
6005 // losslessly through `render` (`render(Duration::ZERO)` emits
6006 // `"0s"`) — the downstream semantic-zero gates (e.g.
6007 // `SupervisorError::ZeroRestartWindow` on
6008 // `:supervisor :restart-window`,
6009 // `AplicacaoError::PolicyTimeoutZero` /
6010 // `PolicyCircuitBreakerWindowZero` on the typed `:politicas`
6011 // duration slots) refuse zero-magnitude authoring at the typed-
6012 // validate layer above, so the single-byte `"0"` stays in the
6013 // accepted set at this codec layer and the diagnostic
6014 // partitioning between canonical-form drift (this arm) and
6015 // semantic-zero (the downstream gates) remains stable.
6016 // Peer with the future leading-zero arms on the two remaining
6017 // typed-magnitude codecs the trajectory acknowledges:
6018 // `limits::parse_duration` backing `:limits :wall-clock`,
6019 // `limits::parse_byte_size` backing `:limits :memory` — each
6020 // carries the same canonical-form-drift class today; this
6021 // gate lands the discipline on the shared duration codec
6022 // first because the `rate_limit_codec` predecessor on the
6023 // same canonical-form-drift axis is the closest peer on the
6024 // trajectory.
6025 //
6026 // Routed through the lifted
6027 // [`crate::render::is_leading_zero_padded_magnitude`]
6028 // predicate — the same source of truth the four peer
6029 // typed-magnitude codec sites share.
6030 if crate::render::is_leading_zero_padded_magnitude(num_trim) {
6031 return Err(format!(
6032 "duration: magnitude {num_trim:?} has a non-canonical leading zero — the \
6033 canonical authoring form for the typed duration slots routed through \
6034 this shared codec (`:supervisor :restart-window`, `:politicas :timeout`, \
6035 `:politicas :circuit-breaker :window`) is `<integer><unit>` (e.g. \
6036 `\"30s\"`, `\"500ms\"`, `\"2m\"`, `\"1h\"`) with no leading-zero padding \
6037 on the magnitude. A leading-zero magnitude (`\"030s\"`, `\"00s\"`, \
6038 `\"01h\"`, `\"0500ms\"`) round-trips through `render` to a *different* \
6039 canonical form (`\"30s\"`, `\"0s\"`, `\"1h\"`, `\"500ms\"`) on first \
6040 serialize — breaking the THEORY.md Part V render-determinism contract \
6041 every typed slot carries. Strip the leading zeros (write \
6042 `\"30s\"` instead of `\"030s\"`)"
6043 ));
6044 }
6045 // The digit-only gate guarantees every byte is `[0-9]`, and
6046 // the leading-zero arm above guarantees the magnitude is
6047 // either the single byte `"0"` or starts with `[1-9]`, so
6048 // the only way `u64::from_str` can fail here is overflow (the
6049 // magnitude exceeds `u64::MAX`). Surface that with an
6050 // overflow-shaped wording so the diagnostic names the offending
6051 // magnitude verbatim rather than collapsing onto the
6052 // non-canonical arm. The codec now operates on `u64` end-to-end
6053 // — every accepted magnitude is integer-exact; no f64 mantissa
6054 // drift between author-supplied magnitude and the consumer's
6055 // `Duration` value. Same shape `crate::limits::parse_duration`
6056 // (818dd38) carries on the peer `:limits :wall-clock` axis.
6057 let num: u64 = num_trim.parse::<u64>().map_err(|_| {
6058 format!("bad duration magnitude in {s:?} (digit-only magnitude overflows u64)")
6059 })?;
6060 // Route the `{"ms" | "s" | "" | "m" | "h"} → Duration`
6061 // unit-arm dispatch through the canonical
6062 // [`crate::render::duration_from_integer_magnitude_and_unit`]
6063 // primitive — the substrate-side single-owner unit-dispatch
6064 // table every typed-duration codec in caixa-core routes
6065 // through (peer: `crate::limits::parse_duration` backing
6066 // `:limits :wall-clock`). Every unit conversion is integer-
6067 // exact for an integer magnitude; overflow surfaces via the
6068 // typed `DurationUnitError::Overflow { multiplier }`
6069 // discriminant so this arm reconstructs the pre-lift
6070 // `"duration <num><unit> overflows u64 (magnitude × 60 …)"`
6071 // wording verbatim from `num` / `unit_trim` / the returned
6072 // `multiplier`, and the unknown-unit arm reconstructs the
6073 // pre-lift `"unknown duration unit \"<other>\""` wording from
6074 // the caller-scoped `unit_trim`. Load-bearing pinned by
6075 // `crate::render::tests::duration_from_integer_magnitude_and_unit_matches_pre_lift_unit_dispatch_table`.
6076 let unit_trim = unit.trim();
6077 let dur = crate::render::duration_from_integer_magnitude_and_unit(num, unit_trim).map_err(
6078 |e| match e {
6079 crate::render::DurationUnitError::Overflow { multiplier } => format!(
6080 "duration {num}{unit_trim} overflows u64 (magnitude × {multiplier} > 2^64-1)"
6081 ),
6082 crate::render::DurationUnitError::UnknownUnit => {
6083 format!("unknown duration unit {unit_trim:?}")
6084 }
6085 },
6086 )?;
6087 Ok(dur)
6088 }
6089
6090 /// Render a [`Duration`] in the canonical pleme-io duration string
6091 /// form (`"30s"`, `"1m"`, `"1h"`, `"500ms"`). The same form every
6092 /// caixa typed-duration slot serializes to and the same form K8s
6093 /// Gateway API HTTPRoute `timeouts` / `backendRequest` and Cilium
6094 /// EnvoyConfig per-route timeouts both expect (an integer
6095 /// followed by `s`/`m`/`h`/`ms`, no fractional values, no leading
6096 /// `+`). Lifted to `pub` so caixa-side renderers
6097 /// (`caixa-mesh::gateway_routes`'s :politicas :timeout overlay,
6098 /// the future per-:politicas `CiliumClusterwideEnvoyConfig`
6099 /// emitter, the future caixa-otel collector pipeline emitter) can
6100 /// consume the same canonical formatter without re-inlining the
6101 /// magnitude/unit decision tree (and inheriting the same drift
6102 /// footguns: a subtly different `300ms` vs `0.3s` rendering breaks
6103 /// downstream apply-time parsing in non-obvious ways).
6104 pub fn render(d: Duration) -> String {
6105 let total_ms = d.as_millis();
6106 if total_ms == 0 {
6107 return "0s".into();
6108 }
6109 if total_ms.is_multiple_of(3600 * 1000) {
6110 return format!("{}h", total_ms / (3600 * 1000));
6111 }
6112 if total_ms.is_multiple_of(60 * 1000) {
6113 return format!("{}m", total_ms / (60 * 1000));
6114 }
6115 if total_ms.is_multiple_of(1000) {
6116 return format!("{}s", total_ms / 1000);
6117 }
6118 format!("{total_ms}ms")
6119 }
6120
6121 /// True iff `d` round-trips losslessly through [`render`] + [`parse`].
6122 ///
6123 /// [`render`] truncates a `Duration` to `as_millis()` before picking the
6124 /// largest divisor unit, so any sub-millisecond residue
6125 /// (`d.subsec_nanos() % 1_000_000 != 0`) silently breaks the THEORY.md
6126 /// §V.2.7 render-determinism contract:
6127 ///
6128 /// - `Duration::from_micros(1500)` (= `1_500_000` ns) → `as_millis() == 1`
6129 /// → renders `"1ms"` → parses back to `Duration::from_millis(1)` =
6130 /// `1_000_000` ns ≠ original `1_500_000` ns;
6131 /// - `Duration::from_nanos(1)` (= 1 ns) → `as_millis() == 0` →
6132 /// renders the literal `"0s"`, which the per-axis zero-floor gate
6133 /// on every typed-`Duration` slot then rejects on re-validate.
6134 ///
6135 /// Lifted to a `pub` predicate next to the [`render`] / [`parse`] pair so
6136 /// the codec's round-trippable accepted set lives in exactly one place —
6137 /// every typed-`Duration` slot that routes through this shared codec
6138 /// (`SupervisorSpec::restart_window` via [`super::duration_codec`],
6139 /// [`crate::MeshPolicy::timeout`] / [`crate::CircuitBreaker::window`] via
6140 /// `supervisor::duration_codec` + [`super::duration_codec_required`]) and
6141 /// every typed-`Duration` slot whose own codec shares the same
6142 /// `as_millis()`-truncation shape ([`crate::LimitsSpec::wall_clock`] via
6143 /// [`crate::limits`]'s in-module `parse_duration` / `render_duration`
6144 /// pair) calls this predicate from its `validate()` to bracket the
6145 /// accepted set against the codec's accepted set, structurally. Drift
6146 /// between the codec's granularity and any typed slot's accepted set is
6147 /// then a single-source-of-truth edit at this predicate rather than a
6148 /// silent round-trip break the next consumer discovers at apply time.
6149 ///
6150 /// Peer of [`crate::aplicacao::POLICY_RETRIES_MAX`] /
6151 /// [`crate::LIMITS_MEMORY_WASM32_MAX_BYTES`] and the
6152 /// `is_dns_1123_label` / `is_canonical_rate_limit_window` predicate
6153 /// family — same "typed-slot's valid set matches its codec's accepted
6154 /// set, structurally" discipline carried at the codec layer.
6155 #[must_use]
6156 pub fn is_integer_millisecond_duration(d: Duration) -> bool {
6157 d.subsec_nanos().is_multiple_of(1_000_000)
6158 }
6159}
6160
6161/// Required-Duration variant for fields that aren't Option<Duration>.
6162pub mod duration_codec_required {
6163 use super::Duration;
6164 use serde::{Deserialize, Deserializer, Serializer};
6165
6166 pub fn serialize<S: Serializer>(v: &Duration, s: S) -> Result<S::Ok, S::Error> {
6167 s.serialize_str(&super::duration_codec::render(*v))
6168 }
6169
6170 pub fn deserialize<'de, D: Deserializer<'de>>(d: D) -> Result<Duration, D::Error> {
6171 let s = String::deserialize(d)?;
6172 super::duration_codec::parse(&s).map_err(serde::de::Error::custom)
6173 }
6174}
6175
6176#[cfg(test)]
6177mod tests {
6178 use super::*;
6179
6180 fn child(name: &str, ver: &str, restart: RestartPolicy) -> ChildSpec {
6181 ChildSpec {
6182 caixa: name.into(),
6183 versao: ver.into(),
6184 restart,
6185 }
6186 }
6187
6188 #[test]
6189 fn child_spec_string_scalar_accessor_pair_is_const_fn() {
6190 // Fail-before-pass-after pin on [`ChildSpec::nome`] +
6191 // [`ChildSpec::versao_requirement`]'s `const`-eval-surface
6192 // posture. Each accessor projects the per-`:children :caixa`
6193 // / per-`:children :versao` [`String`] storage through the
6194 // `pub const fn` [`String::as_str`] (const-stable since Rust
6195 // 1.87, well within the workspace MSRV) — any future
6196 // accidental downgrade to non-`const` fails the corresponding
6197 // `<name>_via_const_fn` wrapper at caixa-core build time with
6198 // E0015 (`cannot call non-const method`), strictly stronger
6199 // than a runtime `assert!`. Sibling of the peer
6200 // per-M2/M3/universal-axis `String → &str` scalar-accessor
6201 // family pins on the sibling `const`-eval-surface passes
6202 // ([`crate::Caixa::nome`] / [`crate::Caixa::versao`] at the
6203 // top-level manifest, [`crate::CaixaVersion::as_str`] at the
6204 // typed-newtype wrapper, [`crate::aplicacao::Membro::nome`] /
6205 // [`crate::aplicacao::Membro::versao_requirement`] at the M3
6206 // membership axis, [`crate::aplicacao::Entrada::hostname`] /
6207 // [`crate::aplicacao::Entrada::destination`] at the M3
6208 // ingress axis,
6209 // [`crate::upgrade::UpgradeFromEntry::prior_versao`] at the
6210 // M2 upgrade axis, [`crate::dep::Dep::nome`] /
6211 // [`crate::dep::Dep::versao_requirement`] at the dep-graph
6212 // axis, and the per-`:contratos`
6213 // [`crate::aplicacao::WitContract::source`] /
6214 // [`crate::aplicacao::WitContract::destination`] /
6215 // [`crate::aplicacao::WitContract::world_ref`] trio the
6216 // sibling pin at 279823b already anchors).
6217 const fn nome_via_const_fn(c: &ChildSpec) -> &str {
6218 c.nome()
6219 }
6220 const fn versao_via_const_fn(c: &ChildSpec) -> &str {
6221 c.versao_requirement()
6222 }
6223 for (caixa, versao) in [
6224 ("worker-a", "^0.1"),
6225 ("worker-b", "~0.2.3"),
6226 ("collector", "*"),
6227 ] {
6228 let c = child(caixa, versao, RestartPolicy::Permanent);
6229 assert_eq!(nome_via_const_fn(&c), c.nome());
6230 assert_eq!(versao_via_const_fn(&c), c.versao_requirement());
6231 assert_eq!(c.nome(), caixa);
6232 assert_eq!(c.versao_requirement(), versao);
6233 }
6234 }
6235
6236 #[test]
6237 fn supervisor_children_slice_return_accessor_is_const_fn() {
6238 // Fail-before-pass-after pin on [`SupervisorSpec::children`]'s
6239 // `const`-eval-surface posture. The accessor destructures the
6240 // per-`:children` `Vec<ChildSpec>` storage through the
6241 // `pub const fn` [`Vec::as_slice`] (const-stable since Rust
6242 // 1.66, well within the workspace MSRV) — any future
6243 // accidental downgrade to non-`const` fails
6244 // `children_via_const_fn` at caixa-core build time with E0015
6245 // (`cannot call non-const method`), strictly stronger than a
6246 // runtime `assert!`. Sibling of the peer per-M3-mesh-slot
6247 // `Vec → &[T]` slice-return accessor family pin
6248 // [`crate::aplicacao::tests::m3_reference_return_accessor_family_is_const_fn`]
6249 // on the M3 mesh-slot per-`:clusters` / per-`:paths` /
6250 // per-`:membros` / per-`:contratos` slice-return axes, and of
6251 // the peer M2 upgrade-appup axis pin
6252 // [`crate::upgrade::tests::upgrade_from_entry_instructions_slice_return_accessor_is_const_fn`]
6253 // on the per-`:upgrade-from :instructions` slice-return axis.
6254 const fn children_via_const_fn(s: &SupervisorSpec) -> &[ChildSpec] {
6255 s.children()
6256 }
6257 // Sweep both the empty-children (leaf-supervisor with no
6258 // static children — the `SimpleOneForOne` dynamic-child
6259 // arm's canonical shape) and the populated-children
6260 // (`OneForOne` / `OneForAll` / `RestForOne` static-child
6261 // arm's canonical shape) axes so the accessor carries a
6262 // const-dispatch pin on both arms.
6263 let s_empty = SupervisorSpec {
6264 estrategia: RestartStrategy::SimpleOneForOne,
6265 max_restarts: SUPERVISOR_MAX_RESTARTS_DEFAULT,
6266 restart_window: Some(SUPERVISOR_RESTART_WINDOW_DEFAULT),
6267 children: vec![],
6268 };
6269 assert!(children_via_const_fn(&s_empty).is_empty());
6270 assert_eq!(children_via_const_fn(&s_empty), s_empty.children());
6271 let s_full = SupervisorSpec {
6272 estrategia: RestartStrategy::OneForOne,
6273 max_restarts: SUPERVISOR_MAX_RESTARTS_DEFAULT,
6274 restart_window: Some(SUPERVISOR_RESTART_WINDOW_DEFAULT),
6275 children: vec![
6276 child("worker-a", "^0.1", RestartPolicy::Permanent),
6277 child("worker-b", "~0.2.3", RestartPolicy::Transient),
6278 child("collector", "*", RestartPolicy::Temporary),
6279 ],
6280 };
6281 assert_eq!(children_via_const_fn(&s_full).len(), 3);
6282 assert_eq!(children_via_const_fn(&s_full), s_full.children());
6283 }
6284
6285 #[test]
6286 fn default_has_one_for_one_and_5_restarts_in_60s() {
6287 let s = SupervisorSpec::default();
6288 assert_eq!(s.estrategia, RestartStrategy::OneForOne);
6289 assert_eq!(s.max_restarts, 5);
6290 assert_eq!(s.restart_window, Some(Duration::from_secs(60)));
6291 assert!(s.children.is_empty());
6292 }
6293
6294 #[test]
6295 fn validate_one_for_one_requires_children() {
6296 // Explicit-empty via struct-update rather than `let mut s = default(); s.children = vec![];`
6297 // — the peer `validate_simple_one_for_one_forbids_static_children` below already uses
6298 // struct-update to name the axis under test at construction, and this shape matches
6299 // it. Also keeps the "empty children is the axis under test" intent visible at the
6300 // binding site rather than one line down, and side-steps `clippy::field_reassign_with_default`.
6301 let mut s = SupervisorSpec {
6302 children: vec![],
6303 ..SupervisorSpec::default()
6304 };
6305 assert!(matches!(
6306 s.validate().unwrap_err(),
6307 SupervisorError::NoChildren { .. }
6308 ));
6309 s.children = vec![child("worker", "^0.1", RestartPolicy::Permanent)];
6310 s.validate().unwrap();
6311 }
6312
6313 #[test]
6314 fn validate_simple_one_for_one_forbids_static_children() {
6315 let mut s = SupervisorSpec {
6316 estrategia: RestartStrategy::SimpleOneForOne,
6317 ..SupervisorSpec::default()
6318 };
6319 s.children
6320 .push(child("w", "^0.1", RestartPolicy::Permanent));
6321 assert_eq!(
6322 s.validate().unwrap_err(),
6323 SupervisorError::SimpleOneForOneWithStaticChildren
6324 );
6325 s.children.clear();
6326 s.validate().unwrap();
6327 }
6328
6329 #[test]
6330 fn validate_rejects_zero_max_restarts() {
6331 let s = SupervisorSpec {
6332 max_restarts: 0,
6333 children: vec![child("w", "^0.1", RestartPolicy::Permanent)],
6334 ..SupervisorSpec::default()
6335 };
6336 assert_eq!(s.validate().unwrap_err(), SupervisorError::ZeroMaxRestarts);
6337 }
6338
6339 // ── upper-cap: SUPERVISOR_MAX_RESTARTS_MAX brackets the typed slot ─────
6340 //
6341 // The cap arm lifts the `:politicas :circuit-breaker :max-failures` /
6342 // `POLICY_BREAKER_MAX_FAILURES_MAX` (2b51ace) discipline onto the peer
6343 // `:supervisor :max-restarts` axis — both fields are "trip the
6344 // next-higher protection layer after N events in a rolling window"
6345 // counters with identical degenerate-at-the-high-end shape, so the
6346 // typed-slot's accepted set lies in `1..=1000` on the supervisor side
6347 // exactly as it lies in `1..=1000` on the breaker side.
6348
6349 #[test]
6350 fn validate_rejects_max_restarts_above_cap() {
6351 // The fail-before-pass-after pin: `SUPERVISOR_MAX_RESTARTS_MAX +
6352 // 1` is structurally one past the cap and silently passed
6353 // validate on every pre-gate codebase because the typed slot's
6354 // only check was the zero-floor arm. The no-op-supervisor vector
6355 // only surfaced at the runtime substrate (Erlang/OTP
6356 // MaxIntensity/Period ratio, the future wasm-operator's
6357 // per-supervisor restart-intensity counter) far from the source
6358 // caixa.lisp with no field naming the offending supervisor.
6359 let s = SupervisorSpec {
6360 max_restarts: SUPERVISOR_MAX_RESTARTS_MAX + 1,
6361 children: vec![child("w", "^0.1", RestartPolicy::Permanent)],
6362 ..SupervisorSpec::default()
6363 };
6364 assert_eq!(
6365 s.validate().unwrap_err(),
6366 SupervisorError::MaxRestartsExceedsCap {
6367 max_restarts: SUPERVISOR_MAX_RESTARTS_MAX + 1,
6368 }
6369 );
6370 }
6371
6372 #[test]
6373 fn validate_rejects_max_restarts_far_above_cap() {
6374 // The `u32::MAX` worst case — the four-billion-restart
6375 // threshold a typo (`:max-restarts 4294967295`) or a
6376 // struct-literal copy-paste lands in the slot. Pin the cap
6377 // arm's coverage explicitly across the full `u32` overflow so
6378 // a future relaxation that drops the upper bound surfaces
6379 // here. Same shape every other typed-cap arm on this surface
6380 // carries (POLICY_BREAKER_MAX_FAILURES_MAX,
6381 // POLICY_RETRIES_MAX, POLICY_RATE_LIMIT_MAX).
6382 let s = SupervisorSpec {
6383 max_restarts: u32::MAX,
6384 children: vec![child("w", "^0.1", RestartPolicy::Permanent)],
6385 ..SupervisorSpec::default()
6386 };
6387 assert_eq!(
6388 s.validate().unwrap_err(),
6389 SupervisorError::MaxRestartsExceedsCap {
6390 max_restarts: u32::MAX,
6391 }
6392 );
6393 }
6394
6395 #[test]
6396 fn validate_accepts_max_restarts_at_cap() {
6397 // The boundary value — exactly SUPERVISOR_MAX_RESTARTS_MAX —
6398 // must validate. The cap is inclusive on the top edge,
6399 // matching the POLICY_BREAKER_MAX_FAILURES_MAX /
6400 // POLICY_RETRIES_MAX / LIMITS_MEMORY_WASM32_MAX_BYTES
6401 // discipline on the sibling capped axes. Pin the boundary
6402 // explicitly so a future off-by-one tightening
6403 // (`>= SUPERVISOR_MAX_RESTARTS_MAX` instead of `>`) surfaces
6404 // here as a test failure rather than a silent contract
6405 // narrowing.
6406 let s = SupervisorSpec {
6407 max_restarts: SUPERVISOR_MAX_RESTARTS_MAX,
6408 children: vec![child("w", "^0.1", RestartPolicy::Permanent)],
6409 ..SupervisorSpec::default()
6410 };
6411 s.validate()
6412 .expect("max_restarts == SUPERVISOR_MAX_RESTARTS_MAX must validate");
6413 }
6414
6415 #[test]
6416 fn validate_accepts_max_restarts_typical_values() {
6417 // The documented production-playbook band positive-control
6418 // sweep — every value Erlang/OTP / Elixir / Riak Core /
6419 // RabbitMQ recommend (1..=100) must pass, plus a sweep
6420 // through the hyperscale band (200, 500, 1000) the cap
6421 // accepts. Pin the inclusive validated set explicitly so a
6422 // future tightening of the ceiling surfaces here.
6423 for n in [1u32, 3, 5, 10, 20, 50, 100, 200, 500, 1000] {
6424 let s = SupervisorSpec {
6425 max_restarts: n,
6426 children: vec![child("w", "^0.1", RestartPolicy::Permanent)],
6427 ..SupervisorSpec::default()
6428 };
6429 s.validate()
6430 .unwrap_or_else(|e| panic!("max_restarts={n} must validate; got {e:?}"));
6431 }
6432 }
6433
6434 #[test]
6435 fn zero_max_restarts_takes_precedence_over_cap() {
6436 // The cross-arm ordering pin: `0` is structurally outside
6437 // both `1..` (zero-floor) and `..=SUPERVISOR_MAX_RESTARTS_MAX`
6438 // (cap), but the zero-floor diagnostic is the more
6439 // self-locating one (it directly names the counter-axis
6440 // remediation), so the validate gate must fire on zero first.
6441 // Same shape every other zero-then-shape ordering on this
6442 // surface uses (PolicyRetriesZero then
6443 // PolicyRetriesExceedsCap; PolicyBreakerZeroFailures then
6444 // PolicyBreakerMaxFailuresExceedsCap).
6445 let s = SupervisorSpec {
6446 max_restarts: 0,
6447 children: vec![child("w", "^0.1", RestartPolicy::Permanent)],
6448 ..SupervisorSpec::default()
6449 };
6450 assert_eq!(
6451 s.validate().unwrap_err(),
6452 SupervisorError::ZeroMaxRestarts,
6453 "max_restarts == 0 must surface the zero-floor diagnostic, not the cap diagnostic"
6454 );
6455 }
6456
6457 #[test]
6458 fn max_restarts_cap_takes_precedence_over_restart_window_gates() {
6459 // The cross-arm ordering pin between the cap and the sibling
6460 // `:restart-window` gates (zero-window, canonical-window). A
6461 // supervisor carrying both an over-cap `max_restarts` AND a
6462 // structurally invalid window (zero, sub-ms) must surface the
6463 // cap diagnostic first — the cap arm is wired immediately
6464 // after the zero-restart arm and strictly before the window
6465 // arms, so the offending value the diagnostic names matches
6466 // the order the author would discover the gates by reading
6467 // top-to-bottom through `SupervisorSpec::validate`. Pin the
6468 // order so a future refactor that reorders the arms surfaces
6469 // here as a test failure rather than a silent diagnostic
6470 // regression. Peer of
6471 // `circuit_breaker_max_failures_cap_takes_precedence_over_window_gates`
6472 // on the sibling `:politicas :circuit-breaker` slot.
6473 let s = SupervisorSpec {
6474 max_restarts: SUPERVISOR_MAX_RESTARTS_MAX + 1,
6475 restart_window: Some(Duration::ZERO),
6476 children: vec![child("w", "^0.1", RestartPolicy::Permanent)],
6477 ..SupervisorSpec::default()
6478 };
6479 assert_eq!(
6480 s.validate().unwrap_err(),
6481 SupervisorError::MaxRestartsExceedsCap {
6482 max_restarts: SUPERVISOR_MAX_RESTARTS_MAX + 1,
6483 },
6484 "over-cap max_restarts must surface the cap diagnostic before any window-axis diagnostic"
6485 );
6486 }
6487
6488 #[test]
6489 fn max_restarts_cap_diagnostic_carries_offending_value() {
6490 // The diagnostic-shape pin: the offending `u32` is carried
6491 // verbatim into the `SupervisorError::MaxRestartsExceedsCap`
6492 // variant so the surfaced error message names the value the
6493 // author wrote (`":supervisor :max-restarts (50000) exceeds the
6494 // supervisor-policy ceiling …"`), not just the cap. Same
6495 // self-locating diagnostic shape every other typed-cap arm on
6496 // this surface carries
6497 // (`AplicacaoError::PolicyBreakerMaxFailuresExceedsCap` carries
6498 // the offending failure count verbatim,
6499 // `AplicacaoError::PolicyRetriesExceedsCap` carries the offending
6500 // retries count verbatim).
6501 let s = SupervisorSpec {
6502 max_restarts: 50_000,
6503 children: vec![child("w", "^0.1", RestartPolicy::Permanent)],
6504 ..SupervisorSpec::default()
6505 };
6506 let err = s.validate().unwrap_err();
6507 assert!(
6508 matches!(
6509 err,
6510 SupervisorError::MaxRestartsExceedsCap {
6511 max_restarts: 50_000
6512 }
6513 ),
6514 "got {err:?}"
6515 );
6516 let msg = err.to_string();
6517 assert!(
6518 msg.contains("50000"),
6519 ":supervisor :max-restarts cap diagnostic must carry the offending value verbatim (got: {msg})"
6520 );
6521 }
6522
6523 #[test]
6524 fn supervisor_max_restarts_default_pins_otp_canonical_value() {
6525 // Pin [`SUPERVISOR_MAX_RESTARTS_DEFAULT`] at `5` — the
6526 // Erlang/OTP-canonical `{intensity, 5, 60}` `MaxIntensity`
6527 // half of Learn You Some Erlang's worker-supervisor default,
6528 // sibling of the `60s` `Period` half that the paired
6529 // [`Default for SupervisorSpec`] impl already pins on the
6530 // sibling `restart_window` axis. Pinning the literal here
6531 // surfaces a future rebrand (a tightening to Elixir's `3`,
6532 // a widening to a per-cluster overlay the operator pins
6533 // through a future `:max-restarts-overrides` slot) as a
6534 // deliberate test edit, not a silent contract migration.
6535 // Peer of the sibling
6536 // [`supervisor_max_restarts_cap_pins_canonical_value`]
6537 // upper-bracket pin on the same axis.
6538 assert_eq!(SUPERVISOR_MAX_RESTARTS_DEFAULT, 5);
6539 }
6540
6541 #[test]
6542 fn default_max_restarts_helper_routes_through_lifted_default() {
6543 // Composition pin: the private `default_max_restarts()`
6544 // serde-`#[serde(default = "…")]` helper on
6545 // [`SupervisorSpec::max_restarts`] must route through the
6546 // substrate-canonical [`SUPERVISOR_MAX_RESTARTS_DEFAULT`]
6547 // typed `pub const` rather than a raw `5` literal. Prior to
6548 // the lift the helper carried an inline `5` with no compile-
6549 // time link back to the shared default, so the wire-format
6550 // author-omitted arm and the caixa-core
6551 // [`crate::manifest::Caixa::supervisor_view`] fold's `unwrap_or(5)`
6552 // arm could silently split on any future default rebrand.
6553 // Byte-parity against the lifted constant closes the split.
6554 assert_eq!(default_max_restarts(), SUPERVISOR_MAX_RESTARTS_DEFAULT);
6555 }
6556
6557 #[test]
6558 fn supervisor_spec_default_max_restarts_routes_through_lifted_default() {
6559 // Composition pin: the [`Default for SupervisorSpec`] impl's
6560 // struct-literal `max_restarts` field must route through the
6561 // substrate-canonical [`SUPERVISOR_MAX_RESTARTS_DEFAULT`]
6562 // typed `pub const` (via the private helper this test's
6563 // sibling `default_max_restarts_helper_routes_through_lifted_default`
6564 // already pins onto the constant). Structurally: every
6565 // `SupervisorSpec::default()` call must yield a
6566 // `max_restarts` field byte-equal to the lifted constant
6567 // (the two paired defaults — the serde-side wire-format arm
6568 // and the struct-literal default arm — cannot silently split
6569 // on any future default rebrand). Peer of the sibling
6570 // `default_has_one_for_one_and_5_restarts_in_60s` shape pin
6571 // — this pin closes the byte-parity arm on the two paired
6572 // altitude entry points onto the shared substrate constant.
6573 assert_eq!(
6574 SupervisorSpec::default().max_restarts(),
6575 SUPERVISOR_MAX_RESTARTS_DEFAULT,
6576 );
6577 }
6578
6579 #[test]
6580 fn supervisor_restart_window_default_pins_otp_canonical_value() {
6581 // Pin [`SUPERVISOR_RESTART_WINDOW_DEFAULT`] at `60s` — the
6582 // Erlang/OTP-canonical `{intensity, 5, 60}` `Period` half of
6583 // Learn You Some Erlang's worker-supervisor default, paired
6584 // with the sibling `SUPERVISOR_MAX_RESTARTS_DEFAULT` `5`
6585 // `MaxIntensity` half this constant is the sliding-window
6586 // denominator of on the same `MaxIntensity / Period`
6587 // restart-intensity ratio. Pinning the literal here surfaces a
6588 // future coherent rebrand of the paired default (Elixir's
6589 // `{max_restarts: 3, max_seconds: 5}`, a per-cluster overlay
6590 // the operator pins through a future
6591 // `:restart-window-overrides` slot) as a deliberate test edit,
6592 // not a silent contract migration. Peer of the sibling
6593 // [`supervisor_max_restarts_default_pins_otp_canonical_value`]
6594 // paired-half pin on the same OTP-canonical default and the
6595 // [`supervisor_restart_window_cap_pins_canonical_value`]
6596 // upper-bracket pin on the same axis.
6597 assert_eq!(SUPERVISOR_RESTART_WINDOW_DEFAULT, Duration::from_secs(60),);
6598 }
6599
6600 #[test]
6601 fn supervisor_spec_default_restart_window_routes_through_lifted_default() {
6602 // Composition pin: the [`Default for SupervisorSpec`] impl's
6603 // struct-literal `restart_window` field must route through the
6604 // substrate-canonical [`SUPERVISOR_RESTART_WINDOW_DEFAULT`]
6605 // typed `pub const` rather than a raw
6606 // `Duration::from_secs(60)` literal. Prior to this lift the
6607 // paired `{intensity, 5, 60}` OTP-canonical default was split
6608 // across two altitudes with no compile-time link between the
6609 // halves — the `MaxIntensity` half rode through the lifted
6610 // [`SUPERVISOR_MAX_RESTARTS_DEFAULT`] constant while the
6611 // `Period` half rode as an open-coded literal at the
6612 // composition site, so a future coherent rebrand of the paired
6613 // canonical would have had to migrate one half through the
6614 // constant and the other through a raw literal in lockstep.
6615 // Byte-parity against the lifted constant on the `Period` half
6616 // closes the split — the paired OTP-canonical default now
6617 // migrates as one unit on any future axis change. Peer of the
6618 // sibling
6619 // [`supervisor_spec_default_max_restarts_routes_through_lifted_default`]
6620 // byte-parity pin on the paired `MaxIntensity` half.
6621 assert_eq!(
6622 SupervisorSpec::default().restart_window(),
6623 Some(SUPERVISOR_RESTART_WINDOW_DEFAULT),
6624 );
6625 }
6626
6627 #[test]
6628 fn supervisor_estrategia_default_pins_otp_canonical_value() {
6629 // Pin [`SUPERVISOR_ESTRATEGIA_DEFAULT`] at [`RestartStrategy::OneForOne`]
6630 // — the Erlang/OTP-canonical `one_for_one` half of Learn You Some
6631 // Erlang's `{one_for_one, intensity, 5, 60}` worker-supervisor
6632 // canonical default, paired with the sibling
6633 // `SUPERVISOR_MAX_RESTARTS_DEFAULT` `5` `MaxIntensity` half and the
6634 // sibling `SUPERVISOR_RESTART_WINDOW_DEFAULT` `60s` `Period` half
6635 // this constant is the strategy discriminator of on the same
6636 // OTP-canonical worker-supervisor default. Pinning the arm here
6637 // surfaces a future coherent rebrand of the paired triple (Elixir's
6638 // `{:one_for_one, max_restarts: 3, max_seconds: 5}` on the sibling
6639 // intensity/period axes leaving this strategy arm untouched, an OTP
6640 // `rest_for_one` widening once the substrate discovers startup-
6641 // order-coupled child cohorts as the more common worker-supervisor
6642 // shape, a per-cluster overlay the operator pins through a future
6643 // `:estrategia-overrides` slot the MESH-COMPOSITION §III.2
6644 // supervision-canary roadmap acknowledges) as a deliberate test
6645 // edit, not a silent contract migration. Peer of the sibling
6646 // [`supervisor_max_restarts_default_pins_otp_canonical_value`] +
6647 // [`supervisor_restart_window_default_pins_otp_canonical_value`]
6648 // paired-half pins on the same OTP-canonical default.
6649 assert_eq!(SUPERVISOR_ESTRATEGIA_DEFAULT, RestartStrategy::OneForOne);
6650 }
6651
6652 #[test]
6653 fn restart_strategy_default_routes_through_lifted_default() {
6654 // Composition pin: the [`Default for RestartStrategy`] impl's
6655 // return arm must route through the substrate-canonical
6656 // [`SUPERVISOR_ESTRATEGIA_DEFAULT`] typed `pub const` rather than
6657 // a raw `Self::OneForOne` arm. Prior to the lift the impl carried
6658 // an inline `Self::OneForOne` with no compile-time link back to
6659 // the shared OTP-canonical `one_for_one` strategy the paired
6660 // [`Default for SupervisorSpec`] impl's struct-literal `estrategia`
6661 // field and the [`crate::manifest::Caixa::supervisor_view`] fold's
6662 // `.unwrap_or_default()` (now
6663 // `.unwrap_or(SUPERVISOR_ESTRATEGIA_DEFAULT)`) arm both key off —
6664 // so a future rebrand of the OTP-canonical strategy default (an
6665 // OTP `rest_for_one` widening once the substrate discovers
6666 // startup-order-coupled child cohorts as the more common worker-
6667 // supervisor shape, a per-cluster overlay the operator pins
6668 // through a future `:estrategia-overrides` slot) would have had to
6669 // be threaded through the `Default` impl and the two peer routes
6670 // in lockstep or the three consumers would silently split. Byte-
6671 // parity against the lifted constant closes the split. Peer of
6672 // the sibling
6673 // [`default_max_restarts_helper_routes_through_lifted_default`] +
6674 // [`supervisor_spec_default_restart_window_routes_through_lifted_default`]
6675 // composition pins on the paired `MaxIntensity` + `Period` halves.
6676 assert_eq!(RestartStrategy::default(), SUPERVISOR_ESTRATEGIA_DEFAULT,);
6677 }
6678
6679 #[test]
6680 fn supervisor_spec_default_estrategia_routes_through_lifted_default() {
6681 // Composition pin: the [`Default for SupervisorSpec`] impl's
6682 // struct-literal `estrategia` field must route through the
6683 // substrate-canonical [`SUPERVISOR_ESTRATEGIA_DEFAULT`] typed
6684 // `pub const` (either directly, or via the
6685 // [`RestartStrategy::default`] impl that the sibling
6686 // `restart_strategy_default_routes_through_lifted_default` pin
6687 // already routes onto the constant). Structurally: every
6688 // `SupervisorSpec::default()` call must yield an `estrategia`
6689 // field byte-equal to the lifted constant (the three paired
6690 // defaults — the [`Default for RestartStrategy`] impl arm, the
6691 // struct-literal default arm here, and the
6692 // [`crate::manifest::Caixa::supervisor_view`] fold arm — cannot
6693 // silently split on any future default rebrand). Peer of the
6694 // sibling
6695 // [`supervisor_spec_default_max_restarts_routes_through_lifted_default`]
6696 // + [`supervisor_spec_default_restart_window_routes_through_lifted_default`]
6697 // byte-parity pins on the paired `MaxIntensity` + `Period` halves
6698 // of the same `SupervisorSpec::default()` composed altitude.
6699 assert_eq!(
6700 SupervisorSpec::default().estrategia(),
6701 SUPERVISOR_ESTRATEGIA_DEFAULT,
6702 );
6703 }
6704
6705 #[test]
6706 fn supervisor_spec_default_routes_through_otp_canonical_ctor() {
6707 // Composition pin: the [`Default for SupervisorSpec`] impl must
6708 // route through the substrate-canonical
6709 // [`SupervisorSpec::otp_canonical`] `pub const fn` constructor
6710 // rather than a re-hand-authored struct-literal cascade. Sharpens
6711 // the sibling per-arm
6712 // `supervisor_spec_default_*_routes_through_lifted_default` pins
6713 // from a per-field lift into a whole-struct one-source-of-truth
6714 // pin — the derived-until-now [`Default::default`] and the
6715 // [`SupervisorSpec::otp_canonical`] constructor are byte-equal by
6716 // construction, not by coincidence.
6717 //
6718 // A future extension of the OTP-canonical baseline (a fifth
6719 // `restart_intensity` field the Erlang/OTP `#supervisor` record
6720 // grows, a per-child-cohort split of the `restart_window` /
6721 // `max_restarts` pair, an M4 `mesh.pleme.io/v1alpha1/Supervisor`
6722 // CR materializer's admission-time overlay pass) reaches both
6723 // paths through exactly one edit on
6724 // [`SupervisorSpec::otp_canonical`] — the derived path could
6725 // silently disagree with the constructor's shape on any new
6726 // field whose [`Default::default`] resolves to a different arm
6727 // than the OTP-canonical baseline the constructor names, while
6728 // this delegated impl reaches the constructor directly and
6729 // picks up every future extension by construction.
6730 //
6731 // Fourth peer on the M2 / M3 typed-slot-spec
6732 // [`Default`]-through-const-ctor fold family — sibling of the
6733 // [`crate::LimitsSpec`] [`Default`]-through-[`crate::LimitsSpec::empty`]
6734 // (abd52c2), [`crate::aplicacao::MeshPolicy`]
6735 // [`Default`]-through-[`crate::aplicacao::MeshPolicy::empty`]
6736 // (91641a4), and [`crate::BehaviorSpec`]
6737 // [`Default`]-through-[`crate::BehaviorSpec::empty`] (0c1752c)
6738 // per-`Option`-only-typed-slot folds — extended here onto the
6739 // M2 supervisor-slot [`SupervisorSpec`] whose canonical baseline
6740 // is not "everything `None`" but the Erlang/OTP-canonical
6741 // `{one_for_one, 5, 60}` worker-supervisor triple.
6742 assert_eq!(SupervisorSpec::default(), SupervisorSpec::otp_canonical());
6743 }
6744
6745 #[test]
6746 fn supervisor_spec_otp_canonical_byte_equals_default() {
6747 // Value pin: [`SupervisorSpec::otp_canonical`] must byte-equal
6748 // the hand-authored `{one_for_one, 5, 60, []}` OTP-canonical
6749 // baseline the sibling `default_has_one_for_one_and_5_restarts_in_60s`
6750 // pin already asserts against the [`Default::default`] path.
6751 // Sharpens the pair-invariant into a per-constructor pin so a
6752 // future extension of [`SupervisorSpec`] with a fifth field
6753 // whose OTP-canonical shape is non-`Default::default`-equivalent
6754 // trips at caixa-core test time rather than at a downstream
6755 // consumer that composed [`SupervisorSpec::otp_canonical`] with
6756 // [`SupervisorSpec::validate`] as its "canonical baseline
6757 // seed".
6758 let canonical = SupervisorSpec::otp_canonical();
6759 assert_eq!(canonical.estrategia, RestartStrategy::OneForOne);
6760 assert_eq!(canonical.max_restarts, 5);
6761 assert_eq!(canonical.restart_window, Some(Duration::from_secs(60)));
6762 assert!(canonical.children.is_empty());
6763 }
6764
6765 #[test]
6766 fn supervisor_spec_otp_canonical_is_usable_in_const_context() {
6767 // Const-context pin: [`SupervisorSpec::otp_canonical`] must
6768 // remain callable from a `const`-bound position so downstream
6769 // `const`-context callers wanting a canonical OTP-baseline seed
6770 // can construct one at compile time without runtime dispatch on
6771 // the derived [`Default::default`]. Peer of the sibling
6772 // `pub const fn` [`crate::LimitsSpec::empty`] /
6773 // [`crate::aplicacao::MeshPolicy::empty`] /
6774 // [`crate::BehaviorSpec::empty`] constructors on the sibling
6775 // typed-slot-spec `pub const fn` axis. If a future edit breaks
6776 // the `const`-eligibility of [`SupervisorSpec::otp_canonical`]
6777 // (a non-`const` field-default helper, a non-`const`-stable
6778 // container type promotion), this evaluation fails at
6779 // build time on this file rather than at a downstream
6780 // `const`-context call site.
6781 const CANONICAL: SupervisorSpec = SupervisorSpec::otp_canonical();
6782 assert_eq!(CANONICAL.estrategia, SUPERVISOR_ESTRATEGIA_DEFAULT);
6783 assert_eq!(CANONICAL.max_restarts, SUPERVISOR_MAX_RESTARTS_DEFAULT);
6784 assert_eq!(
6785 CANONICAL.restart_window,
6786 Some(SUPERVISOR_RESTART_WINDOW_DEFAULT),
6787 );
6788 assert!(CANONICAL.children.is_empty());
6789 }
6790
6791 #[test]
6792 fn supervisor_child_restart_default_pins_otp_canonical_value() {
6793 // Pin [`SUPERVISOR_CHILD_RESTART_DEFAULT`] at
6794 // [`RestartPolicy::Permanent`] — Erlang/OTP's `permanent`
6795 // worker-child restart type (`{ChildId, StartFunc, permanent, …}`
6796 // in a `supervisor`'s `init/1` child-spec tuple), the per-child
6797 // half of the same OTP-shape supervisor-tree default set whose
6798 // per-`:supervisor` halves the sibling
6799 // [`SUPERVISOR_ESTRATEGIA_DEFAULT`] /
6800 // [`SUPERVISOR_MAX_RESTARTS_DEFAULT`] /
6801 // [`SUPERVISOR_RESTART_WINDOW_DEFAULT`] constants pin. Pinning the
6802 // arm here surfaces a future rebrand of the per-child default (an
6803 // OTP-`transient` widening once the substrate discovers clean-
6804 // completion-aware children as the more common child shape, a
6805 // per-cluster overlay the operator pins through a future
6806 // `:restart-overrides` slot the MESH-COMPOSITION §III.2
6807 // supervision-canary roadmap acknowledges) as a deliberate test
6808 // edit, not a silent contract migration. Peer of the sibling
6809 // [`supervisor_estrategia_default_pins_otp_canonical_value`] /
6810 // [`supervisor_max_restarts_default_pins_otp_canonical_value`] /
6811 // [`supervisor_restart_window_default_pins_otp_canonical_value`]
6812 // value pins on the per-`:supervisor` halves.
6813 assert_eq!(SUPERVISOR_CHILD_RESTART_DEFAULT, RestartPolicy::Permanent);
6814 }
6815
6816 #[test]
6817 fn restart_policy_default_routes_through_lifted_default() {
6818 // Composition pin: the [`Default for RestartPolicy`] impl's return
6819 // arm must route through the substrate-canonical
6820 // [`SUPERVISOR_CHILD_RESTART_DEFAULT`] typed `pub const` rather
6821 // than a raw `Self::Permanent` arm. Prior to the lift the impl
6822 // carried an inline `Self::Permanent` with no compile-time link
6823 // back to the OTP-shape supervisor-tree default set whose three
6824 // per-`:supervisor` halves already rode through lifted constants
6825 // — so a future coherent rebrand of the set would have had to
6826 // migrate three halves through typed constants and this fourth
6827 // through a raw enum arm in lockstep or the supervisor-level and
6828 // child-level defaults would silently drift apart. Byte-parity
6829 // against the lifted constant closes the split. Peer of the
6830 // sibling
6831 // [`restart_strategy_default_routes_through_lifted_default`]
6832 // composition pin on the per-`:supervisor` `:estrategia` axis.
6833 assert_eq!(RestartPolicy::default(), SUPERVISOR_CHILD_RESTART_DEFAULT);
6834 }
6835
6836 #[test]
6837 fn child_spec_serde_default_restart_routes_through_lifted_default() {
6838 // Composition pin: the serde-side `#[serde(default)]` on
6839 // [`ChildSpec::restart`] — the wire-format author-omitted
6840 // `:children :restart` arm — must resolve onto the substrate-
6841 // canonical [`SUPERVISOR_CHILD_RESTART_DEFAULT`] typed `pub const`
6842 // (via the [`Default for RestartPolicy`] impl the sibling
6843 // `restart_policy_default_routes_through_lifted_default` pin
6844 // already routes onto the constant). Structurally: a `ChildSpec`
6845 // deserialized from a payload that omits the `restart` key must
6846 // yield a `restart` field byte-equal to the lifted constant, so
6847 // the wire-format author-omitted arm and the
6848 // [`RestartPolicy::default`] impl arm cannot silently split on any
6849 // future default rebrand. Peer of the sibling
6850 // [`supervisor_spec_default_estrategia_routes_through_lifted_default`]
6851 // / [`supervisor_spec_default_max_restarts_routes_through_lifted_default`]
6852 // / [`supervisor_spec_default_restart_window_routes_through_lifted_default`]
6853 // byte-parity pins on the per-`:supervisor` halves of the same
6854 // author-omitted-slot resolution surface.
6855 let omitted: ChildSpec = serde_json::from_str(r#"{"caixa":"worker","versao":"^0.1"}"#)
6856 .expect("ChildSpec must deserialize with the restart key omitted");
6857 assert_eq!(
6858 omitted.restart(),
6859 SUPERVISOR_CHILD_RESTART_DEFAULT,
6860 "an author-omitted :children :restart slot must degrade onto \
6861 the SUPERVISOR_CHILD_RESTART_DEFAULT typed pub const (got \
6862 {:?}, expected {:?})",
6863 omitted.restart(),
6864 SUPERVISOR_CHILD_RESTART_DEFAULT,
6865 );
6866 }
6867
6868 #[test]
6869 fn supervisor_max_restarts_cap_pins_canonical_value() {
6870 // The SUPERVISOR_MAX_RESTARTS_MAX constant pins the value at
6871 // 1000 — the same ceiling the peer
6872 // POLICY_BREAKER_MAX_FAILURES_MAX cap carries on the
6873 // `:politicas :circuit-breaker :max-failures` axis (both are
6874 // "trip the next-higher protection layer after N events in a
6875 // rolling window" counters with identical
6876 // degenerate-at-the-high-end shape; uniform top edge so the
6877 // M4 CR materializers and the wasm-operator reconciler reach
6878 // for either field knowing the value is in `1..=1000`). Two
6879 // orders of magnitude above every documented Erlang/OTP /
6880 // Elixir / Riak Core / RabbitMQ production-playbook
6881 // recommendation band and below the clearly-pathological
6882 // "effectively no escalation" floor (10_000, 100_000,
6883 // u32::MAX). Pinning the literal value here surfaces a future
6884 // drift (a relaxation to 10_000, a tightening to 100) as a
6885 // deliberate test edit, not a silent contract narrowing.
6886 assert_eq!(SUPERVISOR_MAX_RESTARTS_MAX, 1000);
6887 }
6888
6889 #[test]
6890 fn validate_rejects_empty_child_name() {
6891 let s = SupervisorSpec {
6892 children: vec![child("", "^0.1", RestartPolicy::Permanent)],
6893 ..SupervisorSpec::default()
6894 };
6895 assert_eq!(s.validate().unwrap_err(), SupervisorError::EmptyChildName);
6896 }
6897
6898 #[test]
6899 fn validate_rejects_empty_child_version() {
6900 let s = SupervisorSpec {
6901 children: vec![child("w", "", RestartPolicy::Permanent)],
6902 ..SupervisorSpec::default()
6903 };
6904 assert!(matches!(
6905 s.validate().unwrap_err(),
6906 SupervisorError::EmptyChildVersion { .. }
6907 ));
6908 }
6909
6910 // ── value-shape: parse-as-VersionReq on :children :versao ─────────────
6911
6912 #[test]
6913 fn validate_rejects_invalid_child_versao_requirement() {
6914 // The fail-before-pass-after pin: a non-empty but malformed
6915 // semver requirement (`"^bad-version"`) silently passed
6916 // `validate()` on every pre-gate codebase because the prior
6917 // shape only refused the empty string. The parse failure
6918 // surfaced far downstream at lacre-resolve time with a
6919 // `semver::Error` that didn't name which `:children` entry
6920 // carried the typo. The new gate moves the check to caixa-build
6921 // time at the source caixa.lisp — the third `:versao` typed
6922 // axis (`:children`) joins `:deps` and `:membros` (9888b13) at
6923 // structural parity.
6924 let s = SupervisorSpec {
6925 children: vec![
6926 child("worker", "^0.1", RestartPolicy::Permanent),
6927 child("cache", "^bad-version", RestartPolicy::Transient),
6928 ],
6929 ..SupervisorSpec::default()
6930 };
6931 let err = s.validate().unwrap_err();
6932 assert!(
6933 matches!(
6934 err,
6935 SupervisorError::ChildVersaoInvalid { ref caixa, ref versao, .. }
6936 if caixa == "cache" && versao == "^bad-version"
6937 ),
6938 "got {err:?}"
6939 );
6940 }
6941
6942 #[test]
6943 fn validate_rejects_child_versao_with_double_caret_typo() {
6944 // `"^^0.1"` is the canonical doubled-caret typo — looks
6945 // Cargo-shaped on first glance but fails the parser because
6946 // semver doesn't accept stacked operators. Pin this
6947 // adjacent-shape footgun explicitly so a future relaxation that
6948 // accepts "looks-canonical-but-isn't" forms surfaces here.
6949 let s = SupervisorSpec {
6950 children: vec![child("worker", "^^0.1", RestartPolicy::Permanent)],
6951 ..SupervisorSpec::default()
6952 };
6953 let err = s.validate().unwrap_err();
6954 assert!(
6955 matches!(
6956 err,
6957 SupervisorError::ChildVersaoInvalid { ref caixa, ref versao, .. }
6958 if caixa == "worker" && versao == "^^0.1"
6959 ),
6960 "got {err:?}"
6961 );
6962 }
6963
6964 #[test]
6965 fn validate_rejects_child_versao_with_v_prefixed_tag() {
6966 // `"v0.1"` is the canonical "git-tag-shape leaking into the
6967 // semver requirement slot" typo — an author copies the
6968 // publish-side git-tag string verbatim into `:versao`, but
6969 // Cargo's semver parser rejects the leading `v`. Same
6970 // adjacent-shape footgun pinned for `:membros :versao`
6971 // (9888b13).
6972 let s = SupervisorSpec {
6973 children: vec![child("worker", "v0.1", RestartPolicy::Permanent)],
6974 ..SupervisorSpec::default()
6975 };
6976 let err = s.validate().unwrap_err();
6977 assert!(
6978 matches!(
6979 err,
6980 SupervisorError::ChildVersaoInvalid { ref caixa, ref versao, .. }
6981 if caixa == "worker" && versao == "v0.1"
6982 ),
6983 "got {err:?}"
6984 );
6985 }
6986
6987 #[test]
6988 fn validate_accepts_canonical_child_versao_forms() {
6989 // The Cargo-shaped requirement forms `:deps :versao` and
6990 // `:membros :versao` already accept via
6991 // `crate::parse_requirement` must pass the children gate
6992 // without re-validating at the resolver layer. Pin every leg so
6993 // a future tightening of the canonical set surfaces here as a
6994 // test failure.
6995 for form in [
6996 "^0.1", // caret — minor-range pin (the most common shape)
6997 "~0.1.2", // tilde — patch-range pin
6998 "0.1.0", // exact — single-version pin
6999 "*", // wildcard — any version (semver::VersionReq::STAR)
7000 ">=0.1, <2", // multi-range — comma-separated comparators
7001 ] {
7002 let s = SupervisorSpec {
7003 children: vec![child("worker", form, RestartPolicy::Permanent)],
7004 ..SupervisorSpec::default()
7005 };
7006 s.validate()
7007 .unwrap_or_else(|e| panic!("canonical form {form:?} must validate, got {e:?}"));
7008 }
7009 }
7010
7011 #[test]
7012 fn child_versao_empty_takes_precedence_over_invalid() {
7013 // Order pin: the existing `EmptyChildVersion` diagnostic (which
7014 // doesn't try to parse) fires before the new
7015 // `ChildVersaoInvalid` parse-side diagnostic, so an empty
7016 // `:versao` keeps its narrower error message —
7017 // `parse_requirement` would also reject `""`, but the
7018 // empty-string arm is the more self-locating diagnostic for the
7019 // author. Same ordering discipline as
7020 // `membro_versao_empty_takes_precedence_over_invalid` in
7021 // aplicacao.rs.
7022 let s = SupervisorSpec {
7023 children: vec![child("worker", "", RestartPolicy::Permanent)],
7024 ..SupervisorSpec::default()
7025 };
7026 let err = s.validate().unwrap_err();
7027 assert!(
7028 matches!(err, SupervisorError::EmptyChildVersion { ref caixa } if caixa == "worker"),
7029 "got {err:?}"
7030 );
7031 }
7032
7033 #[test]
7034 fn child_versao_invalid_fires_before_duplicate_check() {
7035 // Order pin: a malformed requirement on a non-duplicate entry
7036 // surfaces *its own* diagnostic (which names the offending
7037 // `:versao` string), even when a later entry would otherwise
7038 // collapse onto an earlier name. The per-entry shape gate runs
7039 // inline before the duplicate-key insert — parallel to
7040 // `membro_versao_invalid_fires_before_duplicate_check` in
7041 // aplicacao.rs and the b0c8389 / c4213a4 ordering discipline.
7042 let s = SupervisorSpec {
7043 children: vec![
7044 child("worker", "^bad", RestartPolicy::Permanent),
7045 child("cache", "^0.1", RestartPolicy::Transient),
7046 child("worker", "^0.2", RestartPolicy::Permanent), // would otherwise raise DuplicateChildCaixa
7047 ],
7048 ..SupervisorSpec::default()
7049 };
7050 let err = s.validate().unwrap_err();
7051 assert!(
7052 matches!(
7053 err,
7054 SupervisorError::ChildVersaoInvalid { ref caixa, .. } if caixa == "worker"
7055 ),
7056 "got {err:?}"
7057 );
7058 }
7059
7060 #[test]
7061 fn child_versao_invalid_diagnostic_carries_offending_versao() {
7062 // The diagnostic-shape pin: the error names the offending
7063 // `:versao` value verbatim so the author can grep their
7064 // caixa.lisp without re-running the build, and carries a
7065 // non-empty `reason` from `semver::VersionReq::parse` so the
7066 // parser's own wording flows through to the diagnostic.
7067 let s = SupervisorSpec {
7068 children: vec![child("worker", "not-a-req", RestartPolicy::Permanent)],
7069 ..SupervisorSpec::default()
7070 };
7071 let err = s.validate().unwrap_err();
7072 let SupervisorError::ChildVersaoInvalid {
7073 caixa,
7074 versao,
7075 reason,
7076 } = err
7077 else {
7078 panic!("expected ChildVersaoInvalid, got other variant");
7079 };
7080 assert_eq!(caixa, "worker");
7081 assert_eq!(versao, "not-a-req");
7082 assert!(
7083 !reason.is_empty(),
7084 "ChildVersaoInvalid `reason` must carry the parser's wording verbatim"
7085 );
7086 }
7087
7088 // ── value-shape: DNS-1123 label rule on :children :caixa ──────────────
7089
7090 #[test]
7091 fn validate_rejects_child_caixa_with_uppercase() {
7092 // The canonical "I copied the Servico's display name verbatim"
7093 // typo — child caixa names are lowercase per K8s DNS-1123 label
7094 // rule. The diagnostic names the offending name and suggests the
7095 // lower-cased fix in one edit, mirroring the
7096 // `rejects_membro_caixa_with_uppercase` gate's shape (3f9d7a0).
7097 let s = SupervisorSpec {
7098 children: vec![child("Worker", "^0.1", RestartPolicy::Permanent)],
7099 ..SupervisorSpec::default()
7100 };
7101 let err = s.validate().unwrap_err();
7102 let SupervisorError::ChildCaixaInvalid { caixa, reason } = err else {
7103 panic!("expected ChildCaixaInvalid, got other variant");
7104 };
7105 assert_eq!(caixa, "Worker");
7106 assert!(
7107 reason.contains("uppercase"),
7108 "diagnostic must name the violation as `uppercase` (got: {reason:?})"
7109 );
7110 assert!(
7111 reason.contains("\"worker\""),
7112 "diagnostic must suggest the lower-cased fix verbatim (got: {reason:?})"
7113 );
7114 }
7115
7116 #[test]
7117 fn validate_rejects_child_caixa_with_underscore() {
7118 // The canonical "I'm thinking of a Python module / Postgres
7119 // table" leak — `_` is forbidden by every DNS-1123 / DNS-1035
7120 // label schema. K8s rejects `metadata.name: my_worker` at
7121 // admission time with an opaque `field is invalid` (no source-
7122 // citing diagnostic). The gate moves it to caixa-build time.
7123 let s = SupervisorSpec {
7124 children: vec![child("my_worker", "^0.1", RestartPolicy::Permanent)],
7125 ..SupervisorSpec::default()
7126 };
7127 let err = s.validate().unwrap_err();
7128 assert!(
7129 matches!(
7130 err,
7131 SupervisorError::ChildCaixaInvalid { ref caixa, ref reason }
7132 if caixa == "my_worker" && reason.contains('_')
7133 ),
7134 "got {err:?}"
7135 );
7136 }
7137
7138 #[test]
7139 fn validate_rejects_child_caixa_with_dot() {
7140 // A `:children :caixa` entry is a single DNS-1123 label, not a
7141 // subdomain. The K8s Service / ComputeUnit `metadata.name` rules
7142 // forbid dots. Same shape as `rejects_membro_caixa_with_dot`
7143 // (3f9d7a0) on the peer name axis.
7144 let s = SupervisorSpec {
7145 children: vec![child("team.worker", "^0.1", RestartPolicy::Permanent)],
7146 ..SupervisorSpec::default()
7147 };
7148 let err = s.validate().unwrap_err();
7149 assert!(
7150 matches!(
7151 err,
7152 SupervisorError::ChildCaixaInvalid { ref caixa, ref reason }
7153 if caixa == "team.worker" && reason.contains('.')
7154 ),
7155 "got {err:?}"
7156 );
7157 }
7158
7159 #[test]
7160 fn validate_rejects_child_caixa_with_leading_hyphen() {
7161 // DNS-1123 / DNS-1035 boundary rule: labels must start and end
7162 // with an alphanumeric. The K8s apiserver rejects `-worker`
7163 // outright; the renderer would emit a `metadata.name: "-worker"`
7164 // that fails admission far from the source caixa.lisp.
7165 let s = SupervisorSpec {
7166 children: vec![child("-worker", "^0.1", RestartPolicy::Permanent)],
7167 ..SupervisorSpec::default()
7168 };
7169 let err = s.validate().unwrap_err();
7170 assert!(
7171 matches!(
7172 err,
7173 SupervisorError::ChildCaixaInvalid { ref caixa, ref reason }
7174 if caixa == "-worker" && reason.contains("start and end")
7175 ),
7176 "got {err:?}"
7177 );
7178 }
7179
7180 #[test]
7181 fn validate_rejects_child_caixa_with_trailing_hyphen() {
7182 // The symmetric arm of the boundary rule. Pin separately so
7183 // both ends of the label are covered against a future relaxation
7184 // that only checks one boundary.
7185 let s = SupervisorSpec {
7186 children: vec![child("worker-", "^0.1", RestartPolicy::Permanent)],
7187 ..SupervisorSpec::default()
7188 };
7189 let err = s.validate().unwrap_err();
7190 assert!(
7191 matches!(
7192 err,
7193 SupervisorError::ChildCaixaInvalid { ref caixa, .. }
7194 if caixa == "worker-"
7195 ),
7196 "got {err:?}"
7197 );
7198 }
7199
7200 #[test]
7201 fn validate_rejects_child_caixa_with_unicode() {
7202 // DNS-1123 is ASCII-only; IDN must be pre-encoded as Punycode
7203 // (`xn--…`) by the author before it reaches K8s. The byte-by-
7204 // byte ASCII validity check rejects multi-byte UTF-8 sequences
7205 // by the first byte that fails the `[a-z0-9-]` predicate.
7206 let s = SupervisorSpec {
7207 children: vec![child("café", "^0.1", RestartPolicy::Permanent)],
7208 ..SupervisorSpec::default()
7209 };
7210 let err = s.validate().unwrap_err();
7211 assert!(
7212 matches!(
7213 err,
7214 SupervisorError::ChildCaixaInvalid { ref caixa, .. }
7215 if caixa == "café"
7216 ),
7217 "got {err:?}"
7218 );
7219 }
7220
7221 #[test]
7222 fn validate_rejects_child_caixa_with_whitespace() {
7223 // Whitespace is the canonical "I pasted from a sketch / doc"
7224 // footgun. The apiserver rejects every `metadata.name` value
7225 // carrying whitespace; pin the gate fires at the right boundary.
7226 let s = SupervisorSpec {
7227 children: vec![child("my worker", "^0.1", RestartPolicy::Permanent)],
7228 ..SupervisorSpec::default()
7229 };
7230 let err = s.validate().unwrap_err();
7231 assert!(
7232 matches!(
7233 err,
7234 SupervisorError::ChildCaixaInvalid { ref caixa, .. }
7235 if caixa == "my worker"
7236 ),
7237 "got {err:?}"
7238 );
7239 }
7240
7241 #[test]
7242 fn validate_rejects_child_caixa_too_long() {
7243 // The 64-byte boundary pin. DNS-1123 / DNS-1035 cap labels at
7244 // 63 bytes; the K8s apiserver rejects every `metadata.name`
7245 // axis over the limit at admission time. The diagnostic names
7246 // both the cap and the actual length so the author can shorten
7247 // in one edit, mirroring `rejects_membro_caixa_too_long`
7248 // (3f9d7a0) and `rejects_placement_cluster_too_long` (6cbb900).
7249 let too_long = "a".repeat(64);
7250 let s = SupervisorSpec {
7251 children: vec![child(&too_long, "^0.1", RestartPolicy::Permanent)],
7252 ..SupervisorSpec::default()
7253 };
7254 let err = s.validate().unwrap_err();
7255 let SupervisorError::ChildCaixaInvalid { caixa, reason } = err else {
7256 panic!("expected ChildCaixaInvalid, got other variant");
7257 };
7258 assert_eq!(caixa, too_long);
7259 assert!(
7260 reason.contains("63"),
7261 "diagnostic must name the 63-byte cap (got: {reason:?})"
7262 );
7263 assert!(
7264 reason.contains("64"),
7265 "diagnostic must name the actual length (got: {reason:?})"
7266 );
7267 }
7268
7269 #[test]
7270 fn child_caixa_max_length_validates() {
7271 // The 63-byte boundary control pin — exactly-at-the-cap is
7272 // accepted, mirroring `membro_caixa_max_length_validates`
7273 // (3f9d7a0) and `placement_cluster_max_length_validates`
7274 // (6cbb900). Pinned separately so a future off-by-one tightening
7275 // surfaces here.
7276 let max_label = "a".repeat(63);
7277 let s = SupervisorSpec {
7278 children: vec![child(&max_label, "^0.1", RestartPolicy::Permanent)],
7279 ..SupervisorSpec::default()
7280 };
7281 s.validate().unwrap();
7282 }
7283
7284 #[test]
7285 fn validate_accepts_canonical_child_caixa_forms() {
7286 // The realistic shapes a supervised child's `:caixa` carries —
7287 // single-word `worker`, version-suffixed `cache-v2`, single-char
7288 // `a`, two-char `db`, digit-start `2-pool`, longer hyphen-joined
7289 // `payment-retry`, all-digit `0`. Pin every leg so a future
7290 // tightening (e.g. requiring a leading lowercase letter) surfaces
7291 // here as a test failure. Mirrors `accepts_canonical_membro_caixa_forms`
7292 // (3f9d7a0) and `accepts_canonical_placement_cluster_forms`
7293 // (6cbb900).
7294 for form in [
7295 "worker",
7296 "cache-v2",
7297 "a",
7298 "db",
7299 "2-pool",
7300 "payment-retry",
7301 "0",
7302 ] {
7303 let s = SupervisorSpec {
7304 children: vec![child(form, "^0.1", RestartPolicy::Permanent)],
7305 ..SupervisorSpec::default()
7306 };
7307 s.validate()
7308 .unwrap_or_else(|e| panic!("canonical form {form:?} must validate, got {e:?}"));
7309 }
7310 }
7311
7312 #[test]
7313 fn child_caixa_empty_takes_precedence_over_invalid() {
7314 // Order pin: the existing `EmptyChildName` diagnostic (which
7315 // doesn't try to parse the DNS-1123 shape) fires before the new
7316 // `ChildCaixaInvalid` per-axis gate, so an empty `:caixa` keeps
7317 // its narrower error message — `is_dns_1123_label` would reject
7318 // the empty string too (boundary check on the first byte), but
7319 // the empty-string arm is the more self-locating diagnostic for
7320 // the author. Same ordering discipline as
7321 // `membro_caixa_empty_takes_precedence_over_invalid` in
7322 // aplicacao.rs.
7323 let s = SupervisorSpec {
7324 children: vec![child("", "^0.1", RestartPolicy::Permanent)],
7325 ..SupervisorSpec::default()
7326 };
7327 let err = s.validate().unwrap_err();
7328 assert_eq!(err, SupervisorError::EmptyChildName);
7329 }
7330
7331 #[test]
7332 fn child_caixa_invalid_fires_before_versao_check() {
7333 // Order pin: the per-axis shape gate runs inline before the
7334 // per-entry versao check, so a malformed `:caixa` on an entry
7335 // whose `:versao` would also fail surfaces the more self-
7336 // locating name-axis diagnostic first. Parallel to
7337 // `membro_versao_invalid_fires_before_duplicate_check` (9888b13)
7338 // and `placement_cluster_invalid_fires_before_duplicate_check`
7339 // (6cbb900).
7340 let s = SupervisorSpec {
7341 children: vec![child("My_Worker", "", RestartPolicy::Permanent)],
7342 ..SupervisorSpec::default()
7343 };
7344 let err = s.validate().unwrap_err();
7345 assert!(
7346 matches!(
7347 err,
7348 SupervisorError::ChildCaixaInvalid { ref caixa, .. } if caixa == "My_Worker"
7349 ),
7350 "got {err:?}"
7351 );
7352 }
7353
7354 #[test]
7355 fn child_caixa_invalid_fires_before_duplicate_check() {
7356 // Order pin: a malformed name on a non-duplicate entry surfaces
7357 // its own diagnostic, even when a later entry would otherwise
7358 // collapse onto an earlier name. The per-entry shape gate runs
7359 // inline before the duplicate-key HashSet insert, mirroring
7360 // `placement_cluster_invalid_fires_before_duplicate_check`
7361 // (6cbb900).
7362 let s = SupervisorSpec {
7363 children: vec![
7364 child("Worker", "^0.1", RestartPolicy::Permanent),
7365 child("cache", "^0.1", RestartPolicy::Transient),
7366 child("worker", "^0.2", RestartPolicy::Permanent), // would otherwise raise DuplicateChildCaixa
7367 ],
7368 ..SupervisorSpec::default()
7369 };
7370 let err = s.validate().unwrap_err();
7371 assert!(
7372 matches!(
7373 err,
7374 SupervisorError::ChildCaixaInvalid { ref caixa, .. } if caixa == "Worker"
7375 ),
7376 "got {err:?}"
7377 );
7378 }
7379
7380 #[test]
7381 fn child_caixa_invalid_diagnostic_carries_offending_caixa() {
7382 // The diagnostic-shape pin: the error names the offending
7383 // `:caixa` verbatim plus a non-empty parser-shaped `reason` so
7384 // the author can grep their caixa.lisp without re-running the
7385 // build. Mirrors the diagnostic-shape sweep on every prior
7386 // value-shape gate (3f9d7a0, 6cbb900, c7d05ec).
7387 let s = SupervisorSpec {
7388 children: vec![child("My_Worker", "^0.1", RestartPolicy::Permanent)],
7389 ..SupervisorSpec::default()
7390 };
7391 let err = s.validate().unwrap_err();
7392 let SupervisorError::ChildCaixaInvalid { caixa, reason } = err else {
7393 panic!("expected ChildCaixaInvalid, got other variant");
7394 };
7395 assert_eq!(caixa, "My_Worker");
7396 assert!(
7397 !reason.is_empty(),
7398 "ChildCaixaInvalid `reason` must carry the parser's wording verbatim"
7399 );
7400 }
7401
7402 // ── value-shape: zero restart_window + duplicate child names ──────────
7403
7404 #[test]
7405 fn validate_accepts_none_restart_window() {
7406 // Omitted `:restart-window` is the "never reset" sentinel —
7407 // valid by design. Mirrors :limits axes where None = unbounded.
7408 let s = SupervisorSpec {
7409 restart_window: None,
7410 children: vec![child("w", "^0.1", RestartPolicy::Permanent)],
7411 ..SupervisorSpec::default()
7412 };
7413 s.validate().unwrap();
7414 }
7415
7416 #[test]
7417 fn validate_rejects_zero_restart_window() {
7418 // Same "0 means the opposite of what you think" footgun closed
7419 // for :politicas :timeout (Envoy treats 0s as infinite) and
7420 // :limits :wall-clock (wasmtime traps before the call starts).
7421 // Erlang/OTP's MaxIntensity/Period requires Period > 0.
7422 let s = SupervisorSpec {
7423 restart_window: Some(Duration::ZERO),
7424 children: vec![child("w", "^0.1", RestartPolicy::Permanent)],
7425 ..SupervisorSpec::default()
7426 };
7427 assert_eq!(
7428 s.validate().unwrap_err(),
7429 SupervisorError::RestartWindowZero
7430 );
7431 }
7432
7433 // ── value-shape: integer-ms canonical-form on :restart-window ─────────
7434 //
7435 // The fourth (and last) typed-`Duration` axis in caixa-core to get
7436 // the integer-millisecond canonical-form gate — peer with
7437 // `:limits :wall-clock` (82fc3ef), `:politicas :timeout` (a4ae535),
7438 // and `:politicas :circuit-breaker :window` (a4ae535). The serde
7439 // path is already gated at the shared codec layer (see
7440 // `restart_window_serde_rejects_fractional_seconds`); this arm
7441 // closes the programmatic-struct-literal path the codec gate can't
7442 // see.
7443
7444 #[test]
7445 fn validate_rejects_sub_millisecond_restart_window() {
7446 // The fail-before-pass-after pin: a programmatic
7447 // `Duration::from_micros(1500)` (= 1_500_000 ns) silently passed
7448 // `validate` on every pre-gate codebase, then truncated to
7449 // `as_millis() == 1` on first serialize — the shared codec
7450 // emits `"1ms"`, parses it back to `Duration::from_millis(1)` =
7451 // 1_000_000 ns, the typed `restart_window` no longer matches
7452 // its rendered form.
7453 let s = SupervisorSpec {
7454 restart_window: Some(Duration::from_micros(1500)),
7455 children: vec![child("w", "^0.1", RestartPolicy::Permanent)],
7456 ..SupervisorSpec::default()
7457 };
7458 match s.validate().unwrap_err() {
7459 SupervisorError::RestartWindowNotCanonical { window } => {
7460 assert_eq!(window, Duration::from_micros(1500));
7461 }
7462 other => panic!("expected RestartWindowNotCanonical, got {other:?}"),
7463 }
7464 }
7465
7466 #[test]
7467 fn validate_rejects_one_nanosecond_restart_window() {
7468 // The far-sub-ms case: `Duration::from_nanos(1)` is non-zero
7469 // (so `RestartWindowZero` doesn't fire) but `as_millis() == 0`,
7470 // so the shared codec emits the literal `"0s"` — the next
7471 // serde round-trip would parse back to `Duration::ZERO`, which
7472 // the `RestartWindowZero` arm then rejects on re-validate. The
7473 // canonical-form gate at this layer surfaces a self-locating
7474 // diagnostic naming the offending Duration verbatim rather
7475 // than a downstream `RestartWindowZero` whose remediation
7476 // points at omitting the slot.
7477 let s = SupervisorSpec {
7478 restart_window: Some(Duration::from_nanos(1)),
7479 children: vec![child("w", "^0.1", RestartPolicy::Permanent)],
7480 ..SupervisorSpec::default()
7481 };
7482 match s.validate().unwrap_err() {
7483 SupervisorError::RestartWindowNotCanonical { window } => {
7484 assert_eq!(window, Duration::from_nanos(1));
7485 }
7486 other => panic!("expected RestartWindowNotCanonical, got {other:?}"),
7487 }
7488 }
7489
7490 #[test]
7491 fn validate_rejects_nanosecond_past_canonical_boundary_restart_window() {
7492 // The 1-ns-past-1ms boundary case: a `Duration` carrying
7493 // 1_000_001 ns is structurally past the integer-ms granularity
7494 // floor — `subsec_nanos() % 1_000_000 == 1`. The codec round-
7495 // trip would truncate to `1ms` and the consumer would observe
7496 // a 1-ns drift on every emit. Same boundary the peer
7497 // `validate_rejects_nanosecond_past_canonical_boundary` test
7498 // in limits.rs pins for the `:limits :wall-clock` axis.
7499 let w = Duration::from_nanos(1_000_001);
7500 let s = SupervisorSpec {
7501 restart_window: Some(w),
7502 children: vec![child("w", "^0.1", RestartPolicy::Permanent)],
7503 ..SupervisorSpec::default()
7504 };
7505 assert_eq!(
7506 s.validate().unwrap_err(),
7507 SupervisorError::RestartWindowNotCanonical { window: w }
7508 );
7509 }
7510
7511 #[test]
7512 fn validate_accepts_integer_millisecond_restart_window_values() {
7513 // The positive-control sweep: every `Duration` the shared
7514 // codec can round-trip losslessly — the canonical
7515 // `<integer>{ms,s,m,h}` set the codec's `render` / `parse`
7516 // pair emits and accepts — passes `validate` without
7517 // surfacing the new canonical-form arm. Mirrors
7518 // `validate_accepts_integer_millisecond_wall_clock_values` on
7519 // the sibling `:limits :wall-clock` axis.
7520 for w in [
7521 Duration::from_millis(1),
7522 Duration::from_millis(500),
7523 Duration::from_millis(1500),
7524 Duration::from_secs(1),
7525 Duration::from_secs(30),
7526 Duration::from_secs(60),
7527 Duration::from_secs(120),
7528 Duration::from_secs(3600),
7529 ] {
7530 let s = SupervisorSpec {
7531 restart_window: Some(w),
7532 children: vec![child("w", "^0.1", RestartPolicy::Permanent)],
7533 ..SupervisorSpec::default()
7534 };
7535 s.validate()
7536 .unwrap_or_else(|e| panic!("integer-ms {w:?} must validate, got {e:?}"));
7537 }
7538 }
7539
7540 #[test]
7541 fn validate_restart_window_zero_takes_precedence_over_canonical_gate() {
7542 // Cross-arm ordering pin: `Duration::ZERO` has
7543 // `subsec_nanos() == 0` and would otherwise pass the
7544 // canonical-form arm — the zero-floor arm must fire first so
7545 // the more self-locating `RestartWindowZero` diagnostic (with
7546 // its omit-axis remediation directly named) leads. Same
7547 // posture every peer zero-then-shape gate uses
7548 // (`WallClockZero` → `WallClockNotCanonical`,
7549 // `PolicyTimeoutZero` → `PolicyTimeoutNotCanonical`,
7550 // `PolicyBreakerZeroWindow` → `PolicyBreakerWindowNotCanonical`).
7551 let s = SupervisorSpec {
7552 restart_window: Some(Duration::ZERO),
7553 children: vec![child("w", "^0.1", RestartPolicy::Permanent)],
7554 ..SupervisorSpec::default()
7555 };
7556 assert_eq!(
7557 s.validate().unwrap_err(),
7558 SupervisorError::RestartWindowZero
7559 );
7560 }
7561
7562 #[test]
7563 fn restart_window_canonical_diagnostic_carries_offending_duration() {
7564 // Diagnostic-shape pin: the canonical-form arm names the
7565 // offending `Duration` verbatim so the author's grep lands on
7566 // the field's value, not a generic "duration not canonical"
7567 // message. Same shape every other typed-canonical-form arm
7568 // on this surface carries (`WallClockNotCanonical` carries
7569 // the offending `Duration` verbatim,
7570 // `PolicyTimeoutNotCanonical` carries the offending
7571 // `Duration` verbatim).
7572 let w = Duration::from_micros(500);
7573 let s = SupervisorSpec {
7574 restart_window: Some(w),
7575 children: vec![child("w", "^0.1", RestartPolicy::Permanent)],
7576 ..SupervisorSpec::default()
7577 };
7578 let err = s.validate().unwrap_err();
7579 let msg = err.to_string();
7580 assert!(
7581 msg.contains("500"),
7582 "diagnostic must carry the offending magnitude verbatim (got {msg:?})"
7583 );
7584 assert!(
7585 msg.contains("sub-millisecond"),
7586 "diagnostic must name the sub-millisecond residue class (got {msg:?})"
7587 );
7588 }
7589
7590 #[test]
7591 fn restart_window_validated_value_round_trips_through_codec() {
7592 // The structural property the canonical-ms gate enforces:
7593 // every `SupervisorSpec::restart_window` past
7594 // `SupervisorSpec::validate` round-trips losslessly through
7595 // the shared duration codec (serialize → string →
7596 // deserialize → equal value). Pin this end-to-end so a future
7597 // change to either side (the validate gate's accepted
7598 // granularity, the codec's parse/render unit set) that breaks
7599 // the alignment surfaces here. Peer of
7600 // `wall_clock_validated_value_round_trips_through_codec` on
7601 // the sibling `:limits :wall-clock` axis.
7602 for w in [
7603 Duration::from_millis(1),
7604 Duration::from_millis(1500),
7605 Duration::from_secs(30),
7606 Duration::from_secs(3600),
7607 ] {
7608 let s = SupervisorSpec {
7609 restart_window: Some(w),
7610 children: vec![child("w", "^0.1", RestartPolicy::Permanent)],
7611 ..SupervisorSpec::default()
7612 };
7613 s.validate().unwrap();
7614 let json = serde_json::to_string(&s).unwrap();
7615 let back: SupervisorSpec = serde_json::from_str(&json).unwrap();
7616 assert_eq!(back.restart_window, Some(w));
7617 }
7618 }
7619
7620 // ── value-shape: upper cap on :restart-window ─────────────────────────
7621 //
7622 // The fourth (and last) typed-`Duration` axis in caixa-core to get
7623 // the 1h upper cap — peer with `:limits :wall-clock` (51e0dbd),
7624 // `:politicas :timeout` (2e8ee7e), and `:politicas
7625 // :circuit-breaker :window` (379a814). Brackets the typed
7626 // `:restart-window` axis structurally: every validated value lies
7627 // in `1ms..=SUPERVISOR_RESTART_WINDOW_MAX`, integer-millisecond
7628 // granularity, closing the
7629 // rolling-window-degenerates-to-lifetime-counter footgun the prior
7630 // zero-floor-and-canonical-form-only checks left open.
7631
7632 #[test]
7633 fn validate_rejects_restart_window_above_cap() {
7634 // The fail-before-pass-after pin: 3601s = 1h + 1s is
7635 // structurally one canonical-tick past the
7636 // [`SUPERVISOR_RESTART_WINDOW_MAX`] ceiling (1h = 3600s) — an
7637 // integer-millisecond magnitude the canonical-form arm above
7638 // accepts cleanly, that the shared duration codec round-trips
7639 // losslessly as `"3601s"`, and that silently passed validate on
7640 // every pre-gate codebase because the typed slot's only checks
7641 // were the zero-floor and canonical-form arms. The runtime
7642 // substrate consuming the value (Erlang/OTP's MaxIntensity/
7643 // Period reconciler, the future wasm-operator's per-supervisor
7644 // restart-intensity counter) reaches for a `Duration` so long
7645 // no realistic restart-recovery pattern resets the counter,
7646 // far from the source caixa.lisp.
7647 let w = SUPERVISOR_RESTART_WINDOW_MAX + Duration::from_secs(1);
7648 let s = SupervisorSpec {
7649 restart_window: Some(w),
7650 children: vec![child("w", "^0.1", RestartPolicy::Permanent)],
7651 ..SupervisorSpec::default()
7652 };
7653 assert_eq!(
7654 s.validate().unwrap_err(),
7655 SupervisorError::RestartWindowExceedsCap { window: w }
7656 );
7657 }
7658
7659 #[test]
7660 fn validate_rejects_restart_window_one_millisecond_above_cap() {
7661 // Boundary case: exactly 1ms past the cap (the granularity the
7662 // canonical-form gate enforces). Catches a future "strictly
7663 // less than" half-measure and pins the diagnostic to name the
7664 // offending `Duration` verbatim. Peer of
7665 // `validate_rejects_wall_clock_one_millisecond_above_cap` /
7666 // `rejects_policy_timeout_one_millisecond_above_cap` /
7667 // `rejects_circuit_breaker_window_one_millisecond_above_cap`
7668 // on the sibling typed-`Duration` axes' top edges.
7669 let w = SUPERVISOR_RESTART_WINDOW_MAX + Duration::from_millis(1);
7670 let s = SupervisorSpec {
7671 restart_window: Some(w),
7672 children: vec![child("w", "^0.1", RestartPolicy::Permanent)],
7673 ..SupervisorSpec::default()
7674 };
7675 assert_eq!(
7676 s.validate().unwrap_err(),
7677 SupervisorError::RestartWindowExceedsCap { window: w }
7678 );
7679 }
7680
7681 #[test]
7682 fn validate_rejects_restart_window_far_above_cap() {
7683 // The "obvious authoring footgun" case: a `(:restart-window "24h")`,
7684 // `(:restart-window "7d")`, or any "I want a lifetime counter
7685 // but wrote a `<integer>h` magnitude anyway" typo — values the
7686 // canonical-form arm accepts as integer-millisecond magnitudes,
7687 // the codec round-trips losslessly through serde, but the
7688 // operator's `MaxIntensity / Period` reconciler cannot honor
7689 // as a meaningful rolling window. Until this gate landed
7690 // validate accepted them. Pin the common above-cap values (24h,
7691 // 7d, ~11.5d) so a future relaxation that drops the upper bound
7692 // surfaces here.
7693 for w in [
7694 Duration::from_secs(86_400), // 24h
7695 Duration::from_secs(604_800), // 7d
7696 Duration::from_secs(1_000_000), // ~11.5 days
7697 ] {
7698 let s = SupervisorSpec {
7699 restart_window: Some(w),
7700 children: vec![child("w", "^0.1", RestartPolicy::Permanent)],
7701 ..SupervisorSpec::default()
7702 };
7703 assert_eq!(
7704 s.validate().unwrap_err(),
7705 SupervisorError::RestartWindowExceedsCap { window: w }
7706 );
7707 }
7708 }
7709
7710 #[test]
7711 fn validate_accepts_restart_window_at_cap() {
7712 // The boundary value — exactly [`SUPERVISOR_RESTART_WINDOW_MAX`]
7713 // (1h) — must validate. The cap is inclusive on the top edge,
7714 // matching the [`crate::LIMITS_WALL_CLOCK_MAX`] /
7715 // [`crate::POLICY_TIMEOUT_MAX`] /
7716 // [`crate::POLICY_BREAKER_WINDOW_MAX`] discipline on the sibling
7717 // capped axes. Pin the boundary explicitly so a future
7718 // off-by-one tightening (`>= SUPERVISOR_RESTART_WINDOW_MAX`
7719 // instead of `>`) surfaces here as a test failure rather than a
7720 // silent contract narrowing.
7721 let s = SupervisorSpec {
7722 restart_window: Some(SUPERVISOR_RESTART_WINDOW_MAX),
7723 children: vec![child("w", "^0.1", RestartPolicy::Permanent)],
7724 ..SupervisorSpec::default()
7725 };
7726 s.validate()
7727 .expect("restart_window == SUPERVISOR_RESTART_WINDOW_MAX must validate");
7728 }
7729
7730 #[test]
7731 fn validate_accepts_restart_window_typical_values() {
7732 // The documented Erlang/OTP / Elixir / Riak Core / RabbitMQ
7733 // per-supervisor production-playbook band positive-control
7734 // sweep — every value Learn You Some Erlang's `{intensity, 5,
7735 // 60}` worker-supervisor `Period = 60s` default, Elixir's
7736 // `Supervisor` `max_seconds: 5` default, OTP's `supervisor`
7737 // callback module `MaxT = 5..=60` typical, Riak Core's `MaxT ∈
7738 // 10s..=300s`, and RabbitMQ broker-supervisor `MaxT = 5s`
7739 // default recommend (5s..=300s) must pass, plus a sweep
7740 // through the long-tail-flaky-pool band (5m, 15m, 30m, 1h) the
7741 // cap accepts. Mirrors `validate_accepts_wall_clock_typical_values`
7742 // on the sibling `:limits :wall-clock` axis.
7743 for w in [
7744 Duration::from_millis(1),
7745 Duration::from_millis(500),
7746 Duration::from_secs(1),
7747 Duration::from_secs(5), // RabbitMQ broker-supervisor default
7748 Duration::from_secs(10), // Riak Core lower
7749 Duration::from_secs(30),
7750 Duration::from_secs(60), // Learn You Some Erlang default
7751 Duration::from_secs(120), // OTP supervisor MaxT typical
7752 Duration::from_secs(300), // Riak Core upper
7753 Duration::from_secs(900), // 15m
7754 Duration::from_secs(1800),
7755 Duration::from_secs(3600), // exactly 1h, the cap
7756 ] {
7757 let s = SupervisorSpec {
7758 restart_window: Some(w),
7759 children: vec![child("w", "^0.1", RestartPolicy::Permanent)],
7760 ..SupervisorSpec::default()
7761 };
7762 s.validate()
7763 .unwrap_or_else(|e| panic!("restart_window={w:?} must validate; got {e:?}"));
7764 }
7765 }
7766
7767 #[test]
7768 fn restart_window_zero_takes_precedence_over_cap() {
7769 // The cross-arm ordering pin: `Duration::ZERO` is structurally
7770 // outside both `>= 1ms` (zero-floor) and `<=
7771 // SUPERVISOR_RESTART_WINDOW_MAX` (cap), but the zero-floor
7772 // diagnostic is the more self-locating one (it directly names
7773 // the omit-axis remediation), so the validate gate must fire
7774 // on zero first. Same shape every other zero-then-cap ordering
7775 // on this surface uses (`WallClockZero` then
7776 // `WallClockExceedsCap`, `PolicyTimeoutZero` then
7777 // `PolicyTimeoutExceedsCap`, `PolicyBreakerZeroWindow` then
7778 // `PolicyBreakerWindowExceedsCap`).
7779 let s = SupervisorSpec {
7780 restart_window: Some(Duration::ZERO),
7781 children: vec![child("w", "^0.1", RestartPolicy::Permanent)],
7782 ..SupervisorSpec::default()
7783 };
7784 assert_eq!(
7785 s.validate().unwrap_err(),
7786 SupervisorError::RestartWindowZero,
7787 "Duration::ZERO must surface the zero-floor diagnostic, not the cap diagnostic"
7788 );
7789 }
7790
7791 #[test]
7792 fn restart_window_canonical_takes_precedence_over_cap() {
7793 // The cross-arm ordering pin: a `Duration` that is *both*
7794 // sub-millisecond (non-canonical-form) and structurally above
7795 // the cap surfaces the canonical-form diagnostic first,
7796 // because the round-trip-shape break is the more fundamental
7797 // issue (the value can't even round-trip through the codec,
7798 // so the cap diagnostic naming `1ms..=1h` would be misleading
7799 // — there's no integer-ms form of the offending value). Pin
7800 // the order so a future refactor that reorders the arms
7801 // surfaces here as a test failure rather than a silent
7802 // diagnostic regression. Peer of
7803 // `wall_clock_canonical_takes_precedence_over_cap` /
7804 // `policy_timeout_canonical_takes_precedence_over_cap`.
7805 let w = SUPERVISOR_RESTART_WINDOW_MAX + Duration::from_nanos(1);
7806 let s = SupervisorSpec {
7807 restart_window: Some(w),
7808 children: vec![child("w", "^0.1", RestartPolicy::Permanent)],
7809 ..SupervisorSpec::default()
7810 };
7811 assert_eq!(
7812 s.validate().unwrap_err(),
7813 SupervisorError::RestartWindowNotCanonical { window: w },
7814 "sub-ms above-cap value must surface the canonical-form diagnostic, not the cap diagnostic"
7815 );
7816 }
7817
7818 #[test]
7819 fn max_restarts_cap_takes_precedence_over_restart_window_cap() {
7820 // The cross-arm ordering pin between the `:max-restarts` cap
7821 // and the sibling `:restart-window` cap. A supervisor carrying
7822 // both an over-cap `max_restarts` AND an over-cap window must
7823 // surface the `MaxRestartsExceedsCap` diagnostic first — the
7824 // cap arm is wired immediately after the zero-restart arm and
7825 // strictly before every window-axis arm (zero / canonical /
7826 // cap), so the offending value the diagnostic names matches
7827 // the order the author would discover the gates by reading
7828 // top-to-bottom through `SupervisorSpec::validate`. Pin the
7829 // order so a future refactor that reorders the arms surfaces
7830 // here as a test failure rather than a silent diagnostic
7831 // regression. Peer of
7832 // `max_restarts_cap_takes_precedence_over_restart_window_gates`
7833 // on the sibling zero / canonical window arms.
7834 let w = SUPERVISOR_RESTART_WINDOW_MAX + Duration::from_secs(1);
7835 let s = SupervisorSpec {
7836 max_restarts: SUPERVISOR_MAX_RESTARTS_MAX + 1,
7837 restart_window: Some(w),
7838 children: vec![child("w", "^0.1", RestartPolicy::Permanent)],
7839 ..SupervisorSpec::default()
7840 };
7841 assert_eq!(
7842 s.validate().unwrap_err(),
7843 SupervisorError::MaxRestartsExceedsCap {
7844 max_restarts: SUPERVISOR_MAX_RESTARTS_MAX + 1,
7845 },
7846 "over-cap max_restarts must surface the cap diagnostic before any window-axis diagnostic"
7847 );
7848 }
7849
7850 #[test]
7851 fn restart_window_cap_diagnostic_carries_offending_value() {
7852 // The diagnostic-shape pin: the offending `Duration` is
7853 // carried verbatim into the
7854 // [`SupervisorError::RestartWindowExceedsCap`] variant so the
7855 // surfaced error message names the value the author wrote,
7856 // not just the cap. Same self-locating diagnostic shape every
7857 // other typed-cap arm on this surface carries
7858 // (`WallClockExceedsCap` carries the offending `Duration`
7859 // verbatim, `PolicyTimeoutExceedsCap` carries the offending
7860 // `Duration` verbatim, `PolicyBreakerWindowExceedsCap` carries
7861 // the offending `Duration` verbatim).
7862 let w = Duration::from_secs(7200); // 2h
7863 let s = SupervisorSpec {
7864 restart_window: Some(w),
7865 children: vec![child("w", "^0.1", RestartPolicy::Permanent)],
7866 ..SupervisorSpec::default()
7867 };
7868 let err = s.validate().unwrap_err();
7869 assert!(
7870 matches!(err, SupervisorError::RestartWindowExceedsCap { window } if window == w),
7871 "got {err:?}"
7872 );
7873 let msg = err.to_string();
7874 assert!(
7875 msg.contains("7200"),
7876 ":supervisor :restart-window cap diagnostic must carry the offending value verbatim (got: {msg})"
7877 );
7878 }
7879
7880 #[test]
7881 fn supervisor_restart_window_cap_pins_canonical_value() {
7882 // The SUPERVISOR_RESTART_WINDOW_MAX constant pins the value at
7883 // exactly 1 hour (3600s = 3_600_000ms) — the largest unit the
7884 // shared duration codec emits as a clean canonical string
7885 // (`"<n>h"`). Pinning the literal value here surfaces a future
7886 // drift (a relaxation to 24h, a tightening to 5m) as a
7887 // deliberate test edit, not a silent contract narrowing.
7888 //
7889 // The four typed-`Duration` caps on the validation surface
7890 // (`LIMITS_WALL_CLOCK_MAX` per-process, `POLICY_TIMEOUT_MAX`
7891 // per-edge, `POLICY_BREAKER_WINDOW_MAX` per-breaker,
7892 // `SUPERVISOR_RESTART_WINDOW_MAX` per-supervisor) share a
7893 // single uniform top edge at the codec's largest emitted unit
7894 // — a structural-property invariant the equality assertions
7895 // here enshrine, so a future drift on any of the four
7896 // surfaces as a deliberate test edit. Same shape every other
7897 // typed-cap value pin uses
7898 // (`wall_clock_cap_pins_canonical_value`,
7899 // `policy_timeout_cap_pins_canonical_value`,
7900 // `circuit_breaker_window_cap_pins_canonical_value`).
7901 assert_eq!(SUPERVISOR_RESTART_WINDOW_MAX, Duration::from_secs(3600));
7902 assert_eq!(SUPERVISOR_RESTART_WINDOW_MAX.as_millis(), 3_600_000);
7903 assert_eq!(SUPERVISOR_RESTART_WINDOW_MAX, crate::LIMITS_WALL_CLOCK_MAX);
7904 assert_eq!(SUPERVISOR_RESTART_WINDOW_MAX, crate::POLICY_TIMEOUT_MAX);
7905 assert_eq!(
7906 SUPERVISOR_RESTART_WINDOW_MAX,
7907 crate::POLICY_BREAKER_WINDOW_MAX
7908 );
7909 }
7910
7911 #[test]
7912 fn restart_window_cap_value_round_trips_through_codec() {
7913 // The codec round-trip property the cap arm preserves: the
7914 // [`SUPERVISOR_RESTART_WINDOW_MAX`] constant itself round-trips
7915 // through the shared duration codec — every value at the cap
7916 // serializes to the canonical `"1h"` form and parses back
7917 // identically. Pin the round-trip so a future change to the
7918 // codec's unit set or to the cap's magnitude that breaks the
7919 // round-trip property surfaces here. Peer of
7920 // `wall_clock_cap_value_round_trips_through_codec` on the
7921 // sibling `:limits :wall-clock` axis.
7922 let s = SupervisorSpec {
7923 restart_window: Some(SUPERVISOR_RESTART_WINDOW_MAX),
7924 children: vec![child("w", "^0.1", RestartPolicy::Permanent)],
7925 ..SupervisorSpec::default()
7926 };
7927 s.validate().unwrap();
7928 let json = serde_json::to_string(&s).unwrap();
7929 assert!(
7930 json.contains("\"1h\""),
7931 "SUPERVISOR_RESTART_WINDOW_MAX must serialize to the canonical `\"1h\"` form (got {json})"
7932 );
7933 let back: SupervisorSpec = serde_json::from_str(&json).unwrap();
7934 assert_eq!(back.restart_window, Some(SUPERVISOR_RESTART_WINDOW_MAX));
7935 }
7936
7937 #[test]
7938 fn validate_rejects_duplicate_child_caixa() {
7939 // Two children with the same :caixa render to two ComputeUnits
7940 // with the same name in the cluster's HelmRelease values —
7941 // one silently overwrites the other. Erlang/OTP's child_spec.id
7942 // is required-unique per supervisor; same set-not-multiset
7943 // discipline applied here as for :membros / :placement
7944 // :clusters / :entrada :paths.
7945 let s = SupervisorSpec {
7946 children: vec![
7947 child("worker", "^0.1", RestartPolicy::Permanent),
7948 child("cache", "^0.1", RestartPolicy::Transient),
7949 child("worker", "^0.2", RestartPolicy::Permanent),
7950 ],
7951 ..SupervisorSpec::default()
7952 };
7953 let err = s.validate().unwrap_err();
7954 assert!(
7955 matches!(err, SupervisorError::DuplicateChildCaixa { ref caixa } if caixa == "worker"),
7956 "got {err:?}"
7957 );
7958 }
7959
7960 #[test]
7961 fn validate_duplicate_child_diagnostic_names_first_collision() {
7962 // Iteration walks the :children list in declaration order —
7963 // the diagnostic names the first repeat, deterministically,
7964 // even when multiple names duplicate.
7965 let s = SupervisorSpec {
7966 children: vec![
7967 child("a", "^0.1", RestartPolicy::Permanent),
7968 child("b", "^0.1", RestartPolicy::Permanent),
7969 child("a", "^0.1", RestartPolicy::Permanent),
7970 child("b", "^0.1", RestartPolicy::Permanent),
7971 ],
7972 ..SupervisorSpec::default()
7973 };
7974 let err = s.validate().unwrap_err();
7975 assert!(
7976 matches!(err, SupervisorError::DuplicateChildCaixa { ref caixa } if caixa == "a"),
7977 "got {err:?}"
7978 );
7979 }
7980
7981 // ── self-supervision cross-slot gate ──────────────────────────
7982
7983 #[test]
7984 fn validate_no_self_supervision_rejects_self_referential_child() {
7985 // A supervisor whose `:children` lists its own `:nome` is a
7986 // one-node reconciliation cycle — rejected, naming the parent.
7987 let children = vec![
7988 child("worker", "^0.1", RestartPolicy::Permanent),
7989 child("orquestra", "^0.1", RestartPolicy::Permanent),
7990 ];
7991 let err = validate_no_self_supervision(&children, "orquestra").unwrap_err();
7992 assert!(
7993 matches!(err, SupervisorError::ChildSupervisesSelf { ref caixa } if caixa == "orquestra"),
7994 "got {err:?}"
7995 );
7996 }
7997
7998 #[test]
7999 fn validate_no_self_supervision_accepts_distinct_children() {
8000 // Positive control: distinct child names (including a child that
8001 // is itself a supervisor — nested trees are valid OTP) pass.
8002 let children = vec![
8003 child("worker", "^0.1", RestartPolicy::Permanent),
8004 child("sub-tree", "^0.1", RestartPolicy::Permanent),
8005 ];
8006 validate_no_self_supervision(&children, "orquestra").unwrap();
8007 }
8008
8009 #[test]
8010 fn validate_no_self_supervision_empty_children_is_ok() {
8011 // SimpleOneForOne / no-static-children supervisors have nothing
8012 // to self-reference — the gate is vacuously satisfied.
8013 validate_no_self_supervision(&[], "orquestra").unwrap();
8014 }
8015
8016 #[test]
8017 fn validate_simple_one_for_one_skips_uniqueness_check() {
8018 // SimpleOneForOne supervisors carry no static children — the
8019 // duplicate-child loop never runs. A zero-window declaration
8020 // on a SimpleOneForOne supervisor still trips the window check
8021 // (window applies to dynamic children too).
8022 let s = SupervisorSpec {
8023 estrategia: RestartStrategy::SimpleOneForOne,
8024 restart_window: None,
8025 children: vec![],
8026 ..SupervisorSpec::default()
8027 };
8028 s.validate().unwrap();
8029 let s_zero = SupervisorSpec {
8030 estrategia: RestartStrategy::SimpleOneForOne,
8031 restart_window: Some(Duration::ZERO),
8032 children: vec![],
8033 ..SupervisorSpec::default()
8034 };
8035 assert_eq!(
8036 s_zero.validate().unwrap_err(),
8037 SupervisorError::RestartWindowZero
8038 );
8039 }
8040
8041 #[test]
8042 fn validate_zero_window_runs_after_max_restarts_check() {
8043 // Pin the order: max_restarts == 0 fires before
8044 // restart_window == 0s, so an author with both wrong sees the
8045 // counter-axis diagnostic first (matches the order in the
8046 // struct and in the doc comment).
8047 let s = SupervisorSpec {
8048 max_restarts: 0,
8049 restart_window: Some(Duration::ZERO),
8050 children: vec![child("w", "^0.1", RestartPolicy::Permanent)],
8051 ..SupervisorSpec::default()
8052 };
8053 assert_eq!(s.validate().unwrap_err(), SupervisorError::ZeroMaxRestarts);
8054 }
8055
8056 #[test]
8057 fn round_trip_all_strategies() {
8058 for &strat in RestartStrategy::ALL {
8059 // Route the `SimpleOneForOne ↔ non-SimpleOneForOne` fixture-
8060 // shape partition through the [`gen_platform::IsVariant`]
8061 // derive-generated [`RestartStrategy::is_simple_one_for_one`]
8062 // predicate rather than the raw
8063 // `matches!(strat, RestartStrategy::SimpleOneForOne)`
8064 // open-coded pattern-match — same closed-set-typed-enum
8065 // arm-discriminator dispatch discipline the sibling
8066 // [`crate::upgrade::UpgradeInstruction::is_restart`] convergence
8067 // (915a934) extended onto its two paired positive / negated
8068 // `matches!` filter sites, and the sibling
8069 // [`crate::aplicacao::PlacementStrategy`] `IsVariant`-derived
8070 // predicate convergence (766ec63) extended onto the M3 mesh-
8071 // slot per-`:placement` distribution-strategy `matches!`
8072 // discriminator axis. See the sibling
8073 // `supervisor_spec_estrategia_returns_estrategia_verbatim_across_permutations`
8074 // fixture and the peer `manifest::tests::
8075 // caixa_estrategia_and_supervisor_view_reads_through_lifted_estrategia_accessor`
8076 // fixture — all three sites (the last unlifted
8077 // `matches!`-based arm-discriminator axis on the OTP-shape
8078 // supervisor sibling-restart-strategy closed-set typed enum,
8079 // acknowledged in 915a934's Prior-commits footnote as the
8080 // outstanding follow-up) now consult one typed dispatch on
8081 // the substrate primitive.
8082 let s = SupervisorSpec {
8083 estrategia: strat,
8084 children: if strat.is_simple_one_for_one() {
8085 vec![]
8086 } else {
8087 vec![child("w", "^0.1", RestartPolicy::Permanent)]
8088 },
8089 ..SupervisorSpec::default()
8090 };
8091 let json = serde_json::to_string(&s).unwrap();
8092 let back: SupervisorSpec = serde_json::from_str(&json).unwrap();
8093 assert_eq!(s, back);
8094 }
8095 }
8096
8097 #[test]
8098 fn round_trip_all_restart_policies() {
8099 for policy in [
8100 RestartPolicy::Permanent,
8101 RestartPolicy::Temporary,
8102 RestartPolicy::Transient,
8103 ] {
8104 let c = child("w", "^0.1", policy);
8105 let json = serde_json::to_string(&c).unwrap();
8106 let back: ChildSpec = serde_json::from_str(&json).unwrap();
8107 assert_eq!(c, back);
8108 }
8109 }
8110
8111 #[test]
8112 fn restart_strategy_is_simple_one_for_one_predicate_partitions_the_arm_set() {
8113 // The fail-before-pass-after pin on the `gen_platform::IsVariant`
8114 // derive's [`RestartStrategy::is_simple_one_for_one`] arm-
8115 // discriminator predicate: [`RestartStrategy::SimpleOneForOne`]
8116 // is the only variant that satisfies `.is_simple_one_for_one()`;
8117 // every static-children-bearing arm (`OneForOne` / `OneForAll`
8118 // / `RestForOne`) returns `false`. This pin makes the partition
8119 // invariant load-bearing at caixa-core test time so a future
8120 // derive regression (a hole that returns `false` for
8121 // `SimpleOneForOne` too, or a byte-collision that flips a second
8122 // variant to `true`) trips here rather than laundering the arm
8123 // at the three test-fixture builder sites (a hole flips the
8124 // `SimpleOneForOne` fixture to carry a non-empty children list
8125 // and the subsequent `SupervisorSpec::validate` would refuse the
8126 // fixture with [`SupervisorError::SimpleOneForOneWithStaticChildren`];
8127 // a collision flips a peer strategy's fixture to carry an empty
8128 // children list and the subsequent `validate` would refuse with
8129 // [`SupervisorError::NoChildren`] — either way, the pin fires
8130 // here, at the derive site, rather than at the fixture-refusal
8131 // site far away). Peer of the sibling
8132 // [`crate::upgrade::tests::upgrade_instruction_is_restart_predicate_partitions_the_arm_set`]
8133 // (915a934) pin on the M2 OTP-appup axis and the sibling
8134 // [`crate::kind::tests::caixa_kind_is_variant_predicates_partition_the_arm_set`]
8135 // pin on the M0 `:kind` axis.
8136 let cases: &[(RestartStrategy, bool)] = &[
8137 (RestartStrategy::OneForOne, false),
8138 (RestartStrategy::OneForAll, false),
8139 (RestartStrategy::RestForOne, false),
8140 (RestartStrategy::SimpleOneForOne, true),
8141 ];
8142 for (variant, expected) in cases {
8143 assert_eq!(
8144 variant.is_simple_one_for_one(),
8145 *expected,
8146 "RestartStrategy::{variant:?}.is_simple_one_for_one() must \
8147 return {expected} (partition invariant on the \
8148 IsVariant-derived arm-discriminator predicate — every \
8149 test-fixture site that partitions the `:children` slot \
8150 shape on `SimpleOneForOne ↔ non-SimpleOneForOne` keys \
8151 off this typed dispatch, so a derive regression must \
8152 surface here rather than at the fixture-refusal site)"
8153 );
8154 }
8155 }
8156
8157 #[test]
8158 fn restart_strategy_fixture_partition_routes_through_is_simple_one_for_one_predicate() {
8159 // Byte-identity pin on the `SimpleOneForOne ↔ non-SimpleOneForOne`
8160 // fixture-shape partition against the pre-lift
8161 // `matches!(strat, RestartStrategy::SimpleOneForOne)` open-coded
8162 // pattern-match every test-fixture builder site previously
8163 // coupled to inline. Asserts the two projections agree byte-for-
8164 // byte on every arm of the enum, so a future derive regression
8165 // that flipped either predicate's arm-set would surface here at
8166 // caixa-core test time rather than at the three fixture-builder
8167 // sites (`supervisor::tests::round_trip_all_strategies`,
8168 // `supervisor::tests::supervisor_spec_estrategia_returns_estrategia_verbatim_across_permutations`,
8169 // `manifest::tests::caixa_estrategia_and_supervisor_view_reads_through_lifted_estrategia_accessor`)
8170 // far from the derive site. Same peer-shape byte-identity pin
8171 // every sibling `IsVariant`-derive-routed convergence carries on
8172 // the substrate's closed-set typed-enum surface (peer of
8173 // [`crate::upgrade::tests::validate_restart_exclusive_routes_through_is_restart_predicate`]
8174 // on the M2 OTP-appup axis).
8175 for &strat in RestartStrategy::ALL {
8176 let via_predicate = strat.is_simple_one_for_one();
8177 let via_matches = matches!(strat, RestartStrategy::SimpleOneForOne);
8178 assert_eq!(
8179 via_predicate, via_matches,
8180 "RestartStrategy::{strat:?}: is_simple_one_for_one() must \
8181 byte-equal matches!(_, RestartStrategy::SimpleOneForOne) — \
8182 the pre-lift open-coded pattern and the \
8183 IsVariant-derived predicate are the same axis, \
8184 one typed dispatch"
8185 );
8186 }
8187 }
8188
8189 #[test]
8190 fn duration_codec_round_trip_canonical_units() {
8191 // Note the canonical-form rule: durations serialize to the
8192 // *largest* unit that divides cleanly, so 60s ↔ "1m" and not
8193 // "60s" — but the round-trip preserves the underlying Duration.
8194 let cases = [
8195 ("30s", Duration::from_secs(30)),
8196 ("5m", Duration::from_secs(300)),
8197 ("1h", Duration::from_secs(3600)),
8198 ("500ms", Duration::from_millis(500)),
8199 ];
8200 for (lit, dur) in cases {
8201 let s = SupervisorSpec {
8202 children: vec![child("w", "^0.1", RestartPolicy::Permanent)],
8203 restart_window: Some(dur),
8204 ..SupervisorSpec::default()
8205 };
8206 let json = serde_json::to_string(&s).unwrap();
8207 assert!(
8208 json.contains(&format!("\"{lit}\"")),
8209 "expected \"{lit}\" in {json}"
8210 );
8211 let back: SupervisorSpec = serde_json::from_str(&json).unwrap();
8212 assert_eq!(back.restart_window, Some(dur));
8213 }
8214 }
8215
8216 #[test]
8217 fn duration_canonicalizes_to_largest_unit() {
8218 // 60 seconds → "1m" (largest cleanly-divisible unit), but the
8219 // typed Duration still equals 60s on the way back.
8220 let s = SupervisorSpec {
8221 children: vec![child("w", "^0.1", RestartPolicy::Permanent)],
8222 restart_window: Some(Duration::from_secs(60)),
8223 ..SupervisorSpec::default()
8224 };
8225 let json = serde_json::to_string(&s).unwrap();
8226 assert!(json.contains("\"1m\""), "{json}");
8227 let back: SupervisorSpec = serde_json::from_str(&json).unwrap();
8228 assert_eq!(back.restart_window, Some(Duration::from_secs(60)));
8229 }
8230
8231 #[test]
8232 fn three_child_one_for_one_validates() {
8233 let s = SupervisorSpec {
8234 estrategia: RestartStrategy::OneForOne,
8235 max_restarts: 5,
8236 restart_window: Some(Duration::from_secs(60)),
8237 children: vec![
8238 child("worker", "^0.1", RestartPolicy::Permanent),
8239 child("cache", "^0.1", RestartPolicy::Transient),
8240 child("scratch", "^0.1", RestartPolicy::Temporary),
8241 ],
8242 };
8243 s.validate().unwrap();
8244 }
8245
8246 #[test]
8247 fn json_uses_pascal_case_for_strategy_and_policy() {
8248 // Variant names are PascalCase by default in serde, matching
8249 // tatara-lisp's enum convention (`:estrategia OneForOne`).
8250 let c = child("w", "^0.1", RestartPolicy::Permanent);
8251 let json = serde_json::to_string(&c).unwrap();
8252 assert!(json.contains("\"Permanent\""));
8253 assert!(!json.contains("\"permanent\""));
8254
8255 let s = SupervisorSpec {
8256 estrategia: RestartStrategy::OneForOne,
8257 children: vec![c],
8258 ..SupervisorSpec::default()
8259 };
8260 let json = serde_json::to_string(&s).unwrap();
8261 assert!(json.contains("\"estrategia\":\"OneForOne\""));
8262 }
8263
8264 // ── shared duration codec: integer-magnitude canonical-form gate ──
8265 //
8266 // The gate lifts the discipline `crate::limits::parse_duration`
8267 // (818dd38) carries on the peer `:limits :wall-clock` codec onto
8268 // the shared codec backing the remaining three typed-duration
8269 // slots: `:supervisor :restart-window`, `:politicas :timeout`, and
8270 // `:politicas :circuit-breaker :window`. Every magnitude `render`
8271 // emits is a non-negative integer with no decimal point and no
8272 // leading sign, so the codec's accepted set must match for
8273 // serialize/deserialize to round-trip without canonical-form
8274 // drift.
8275
8276 #[test]
8277 fn parse_accepts_integer_canonical_units() {
8278 // Pin the happy-path: every canonical author shape `render`
8279 // ever emits parses to the same `Duration` value, so the
8280 // codec's accepted set is at least a superset of its emitted
8281 // set on the canonical-unit axis.
8282 for (lit, dur) in [
8283 ("30s", Duration::from_secs(30)),
8284 ("500ms", Duration::from_millis(500)),
8285 ("2m", Duration::from_secs(120)),
8286 ("1h", Duration::from_secs(3600)),
8287 ("0s", Duration::ZERO),
8288 ] {
8289 assert_eq!(
8290 duration_codec::parse(lit).unwrap(),
8291 dur,
8292 "parse({lit:?}) should be {dur:?}"
8293 );
8294 }
8295 }
8296
8297 #[test]
8298 fn parse_accepts_bare_integer_as_seconds() {
8299 // The `"s" | ""` arm: a bare integer with no unit is read as
8300 // seconds. Pin this so the unit-empty form keeps parsing (it
8301 // renders to `"<n>s"` on serialize — that's a unit-choice
8302 // drift the integer-magnitude gate does NOT close, matching
8303 // the `parse_byte_size` `"1024"` → `"1KiB"` scope decision in
8304 // the peer `:limits :memory` codec).
8305 assert_eq!(
8306 duration_codec::parse("30").unwrap(),
8307 Duration::from_secs(30)
8308 );
8309 }
8310
8311 #[test]
8312 fn parse_rejects_fractional_seconds_with_canonical_form_diagnostic() {
8313 // `"1.5s"` parses as f64 to 1.5 → renders back as `"1500ms"`
8314 // on first serialize — DRIFT. The integer-magnitude gate names
8315 // the offending `"1.5"` verbatim and points at the canonical
8316 // remediation `"1500ms"`.
8317 let err = duration_codec::parse("1.5s").unwrap_err();
8318 assert!(err.contains("\"1.5\""), "missing magnitude in {err:?}");
8319 assert!(
8320 err.contains("not a non-negative integer"),
8321 "missing canonical-form reason in {err:?}"
8322 );
8323 assert!(
8324 err.contains("\"1500ms\""),
8325 "missing canonical-form remediation in {err:?}"
8326 );
8327 }
8328
8329 #[test]
8330 fn parse_rejects_decimal_shaped_integer_seconds() {
8331 // `"1.0s"` is the trickiest drift class: numerically `1.0s` is
8332 // `1s` exactly, so the round-trip looks correct — but the
8333 // emitted canonical form is `"1s"`, not `"1.0s"`. Gate the
8334 // decimal-shape-with-integer-value form so author intent is
8335 // never silently rewritten.
8336 let err = duration_codec::parse("1.0s").unwrap_err();
8337 assert!(err.contains("\"1.0\""), "missing magnitude in {err:?}");
8338 assert!(
8339 err.contains("not a non-negative integer"),
8340 "missing canonical-form reason in {err:?}"
8341 );
8342 }
8343
8344 #[test]
8345 fn parse_rejects_half_unit_minute() {
8346 // `"0.5m"` is the unit-fraction footgun — author writes a
8347 // human-readable half-minute, serde silently rewrites to
8348 // `"30s"` on next emit. The gate names the offending
8349 // magnitude `"0.5"` and points at the integer-in-smaller-unit
8350 // form.
8351 let err = duration_codec::parse("0.5m").unwrap_err();
8352 assert!(err.contains("\"0.5\""), "missing magnitude in {err:?}");
8353 assert!(
8354 err.contains("\"30s\""),
8355 "missing canonical-form remediation in {err:?}"
8356 );
8357 }
8358
8359 #[test]
8360 fn parse_rejects_leading_plus_sign() {
8361 // `u64::from_str` rejects `"+30"` but `f64::from_str` accepts
8362 // it as `30.0` — the prior parser used f64 so `"+30s"` parsed
8363 // cleanly to 30s and round-tripped to `"30s"` on next emit
8364 // (DRIFT). The digit-only gate closes the leading-sign class
8365 // first; the diagnostic names `"+30"` verbatim.
8366 let err = duration_codec::parse("+30s").unwrap_err();
8367 assert!(err.contains("\"+30\""), "missing magnitude in {err:?}");
8368 assert!(
8369 err.contains("not a non-negative integer"),
8370 "missing canonical-form reason in {err:?}"
8371 );
8372 }
8373
8374 #[test]
8375 fn parse_rejects_leading_minus_sign() {
8376 // The former `num < 0.0` arm: `"-30s"` parsed as f64 to -30,
8377 // rejected with `"negative duration in \"-30s\""`. Under the
8378 // integer-magnitude gate the diagnostic is unified — `-30` is
8379 // non-digit-only, f64-numeric, and surfaces with the canonical-
8380 // form reason (no leading `+` / `-` sign) naming the offending
8381 // `"-30"` verbatim. Same diagnostic shape as every other
8382 // rejected non-integer magnitude.
8383 let err = duration_codec::parse("-30s").unwrap_err();
8384 assert!(err.contains("\"-30\""), "missing magnitude in {err:?}");
8385 assert!(
8386 err.contains("not a non-negative integer"),
8387 "missing canonical-form reason in {err:?}"
8388 );
8389 }
8390
8391 #[test]
8392 fn parse_garbage_still_falls_through_to_bad_magnitude() {
8393 // Non-digit-only AND non-numeric (`"--1s"`, `"abc"`) falls
8394 // through to the narrower "bad duration magnitude" arm — the
8395 // canonical-form diagnostic is reserved for the parser-shape
8396 // footgun case, not the "not a number at all" case. Same
8397 // shape `parse_byte_size`'s `BadByteMagnitude` arm carries on
8398 // the peer `:limits :memory` codec.
8399 let err = duration_codec::parse("--1s").unwrap_err();
8400 assert!(
8401 err.contains("bad duration magnitude"),
8402 "expected bad-magnitude wording in {err:?}"
8403 );
8404 }
8405
8406 #[test]
8407 fn parse_digit_only_magnitude_carries_zero_f64_drift() {
8408 // The accepted set is now closed under `u64`-exact integer
8409 // arithmetic: `"500ms"` → `Duration::from_millis(500)` exactly,
8410 // `"3600s"` → `Duration::from_secs(3600)` exactly, `"1h"` →
8411 // `Duration::from_secs(3600)` exactly, no f64 mantissa drift
8412 // possible. Pin the integer-exact arms across the four unit
8413 // suffixes so a future refactor that reaches back for f64
8414 // (`from_secs_f64`, `mul_f64`) surfaces here.
8415 assert_eq!(
8416 duration_codec::parse("3600s").unwrap(),
8417 Duration::from_secs(3600)
8418 );
8419 assert_eq!(
8420 duration_codec::parse("60m").unwrap(),
8421 Duration::from_secs(3600)
8422 );
8423 assert_eq!(
8424 duration_codec::parse("1h").unwrap(),
8425 Duration::from_secs(3600)
8426 );
8427 assert_eq!(
8428 duration_codec::parse("999ms").unwrap(),
8429 Duration::from_millis(999)
8430 );
8431 }
8432
8433 #[test]
8434 fn restart_window_serde_rejects_fractional_seconds() {
8435 // The shared codec backs `SupervisorSpec::restart_window`
8436 // (`with = "duration_codec"`) — so the gate applies on serde
8437 // deserialize for the typed Supervisor slot. A
8438 // `{"restartWindow":"1.5s"}` payload that previously round-
8439 // tripped to a different canonical string on next serialize
8440 // is now refused at deserialize with the integer-magnitude
8441 // diagnostic.
8442 let payload = r#"{"estrategia":"OneForOne","maxRestarts":5,
8443 "restartWindow":"1.5s",
8444 "children":[{"caixa":"w","versao":"^0.1","restart":"Permanent"}]}"#;
8445 let err = serde_json::from_str::<SupervisorSpec>(payload).unwrap_err();
8446 let msg = err.to_string();
8447 assert!(
8448 msg.contains("not a non-negative integer"),
8449 "expected integer-magnitude diagnostic in {msg:?}"
8450 );
8451 assert!(msg.contains("\"1.5\""), "missing magnitude in {msg:?}");
8452 }
8453
8454 #[test]
8455 fn restart_window_serde_rejects_leading_plus() {
8456 // The `u64::from_str` leading-`+` permissiveness gap that
8457 // motivated the digit-only gate (the `f64`-side accepted
8458 // `"+30"`, the prior parser silently round-tripped to `"30s"`)
8459 // is now closed on the shared codec — surfaces as a structured
8460 // diagnostic at the serde layer for every typed-duration slot.
8461 let payload = r#"{"estrategia":"OneForOne","maxRestarts":5,
8462 "restartWindow":"+30s",
8463 "children":[{"caixa":"w","versao":"^0.1","restart":"Permanent"}]}"#;
8464 let err = serde_json::from_str::<SupervisorSpec>(payload).unwrap_err();
8465 let msg = err.to_string();
8466 assert!(msg.contains("\"+30\""), "missing magnitude in {msg:?}");
8467 assert!(
8468 msg.contains("not a non-negative integer"),
8469 "missing canonical-form reason in {msg:?}"
8470 );
8471 }
8472
8473 #[test]
8474 fn parse_rejects_leading_zero_magnitude() {
8475 // `"030s"` is digit-only, so the existing non-digit-only / sign
8476 // / fractional arm doesn't catch it — `u64::from_str("030")`
8477 // returns `Ok(30)`, so before this gate `"030s"` parsed to
8478 // `Duration::from_secs(30)` and round-tripped through `render`
8479 // to `"30s"` — a *different* canonical string on the next emit,
8480 // breaking the THEORY.md Part V render-determinism contract
8481 // exactly the way `"+30s"` did before the leading-`+` arm
8482 // landed. Peer with the `rate_limit_codec` leading-zero arm
8483 // (4f46830) on the same canonical-form-drift axis.
8484 let err = duration_codec::parse("030s").unwrap_err();
8485 assert!(
8486 err.contains("non-canonical leading zero"),
8487 "expected leading-zero diagnostic in {err:?}"
8488 );
8489 assert!(err.contains("\"030\""), "missing magnitude in {err:?}");
8490 assert!(
8491 err.contains("\"30s\""),
8492 "missing canonical-form remediation in {err:?}"
8493 );
8494 assert!(
8495 err.contains("THEORY.md"),
8496 "missing render-determinism citation in {err:?}"
8497 );
8498 }
8499
8500 #[test]
8501 fn parse_rejects_multi_digit_zero_magnitude() {
8502 // `"00s"` and `"00ms"` are the all-zero leading-zero footgun —
8503 // digit-only, parse losslessly to `Duration::ZERO`, but render
8504 // back to `"0s"` (the single-byte canonical form) on the next
8505 // emit. The leading-zero arm refuses the drift class at the
8506 // codec layer; the semantic-zero gate downstream
8507 // (`SupervisorError::ZeroRestartWindow`, etc.) would refuse
8508 // the single-byte canonical form `"0s"` separately on the
8509 // typed-validate layer.
8510 let err = duration_codec::parse("00s").unwrap_err();
8511 assert!(
8512 err.contains("non-canonical leading zero"),
8513 "expected leading-zero diagnostic in {err:?}"
8514 );
8515 assert!(err.contains("\"00\""), "missing magnitude in {err:?}");
8516 }
8517
8518 #[test]
8519 fn parse_rejects_leading_zero_per_hour_window() {
8520 // `"01h"` is the per-hour-window footgun — multi-byte magnitude
8521 // starting with `0`, parses losslessly to `Duration::from_secs(3600)`,
8522 // renders to `"1h"` (DRIFT). The arm is unit-agnostic: every
8523 // canonical unit suffix the codec accepts (`ms` / `s` / `m` /
8524 // `h` / bare-integer-as-seconds) inherits the same gate.
8525 let err = duration_codec::parse("01h").unwrap_err();
8526 assert!(
8527 err.contains("non-canonical leading zero"),
8528 "expected leading-zero diagnostic in {err:?}"
8529 );
8530 assert!(err.contains("\"01\""), "missing magnitude in {err:?}");
8531 }
8532
8533 #[test]
8534 fn parse_rejects_leading_zero_bare_integer_as_seconds() {
8535 // The `parse_accepts_bare_integer_as_seconds` happy-path
8536 // (`"30"` → 30s) inherits the leading-zero arm: `"030"` is
8537 // multi-byte starts-with-`0`, parses losslessly to
8538 // `Duration::from_secs(30)`, renders to `"30s"` (DRIFT). The
8539 // bare-integer surface accepts permissive unit-empty
8540 // shorthand but still must reject leading-zero padding.
8541 let err = duration_codec::parse("030").unwrap_err();
8542 assert!(
8543 err.contains("non-canonical leading zero"),
8544 "expected leading-zero diagnostic in {err:?}"
8545 );
8546 assert!(err.contains("\"030\""), "missing magnitude in {err:?}");
8547 }
8548
8549 #[test]
8550 fn parse_accepts_single_zero_magnitude_at_codec_layer() {
8551 // The codec-layer / typed-validate-layer boundary: `"0s"` /
8552 // `"0ms"` / `"0"` are the single-byte canonical-zero forms —
8553 // each round-trips losslessly through `render`
8554 // (`render(Duration::ZERO)` → `"0s"`), so the codec layer
8555 // accepts them. The downstream semantic-zero gates
8556 // (`SupervisorError::ZeroRestartWindow`,
8557 // `AplicacaoError::PolicyTimeoutZero`,
8558 // `AplicacaoError::PolicyCircuitBreakerWindowZero`) refuse
8559 // zero-magnitude authoring at the typed-validate layer above,
8560 // peer with the `rate_limit_codec` codec-layer / typed-
8561 // validate-layer partition for `"0/s"`.
8562 assert_eq!(duration_codec::parse("0s").unwrap(), Duration::ZERO);
8563 assert_eq!(duration_codec::parse("0ms").unwrap(), Duration::ZERO);
8564 assert_eq!(duration_codec::parse("0").unwrap(), Duration::ZERO);
8565 }
8566
8567 #[test]
8568 fn parse_accepts_canonical_magnitude_with_leading_one() {
8569 // The complementary boundary: a future tightening cannot
8570 // drift into rejecting valid canonical magnitudes that
8571 // happen to start with `1` (or any digit `[1-9]`). Pin
8572 // every canonical-unit suffix so the leading-zero arm
8573 // remains strictly narrower than the digit-only arm.
8574 assert_eq!(
8575 duration_codec::parse("100ms").unwrap(),
8576 Duration::from_millis(100)
8577 );
8578 assert_eq!(
8579 duration_codec::parse("100s").unwrap(),
8580 Duration::from_secs(100)
8581 );
8582 assert_eq!(
8583 duration_codec::parse("10m").unwrap(),
8584 Duration::from_secs(600)
8585 );
8586 assert_eq!(
8587 duration_codec::parse("10h").unwrap(),
8588 Duration::from_secs(36_000)
8589 );
8590 }
8591
8592 #[test]
8593 fn restart_window_serde_rejects_leading_zero() {
8594 // The shared codec backs `SupervisorSpec::restart_window`
8595 // (`with = "duration_codec"`) — so the leading-zero arm
8596 // applies on serde deserialize for the typed Supervisor slot.
8597 // A `{"restartWindow":"030s"}` payload that previously round-
8598 // tripped to a different canonical string on next serialize
8599 // is now refused at deserialize with the leading-zero
8600 // diagnostic. Peer with `restart_window_serde_rejects_leading_plus`
8601 // / `restart_window_serde_rejects_fractional_seconds` on the
8602 // same canonical-form-drift axis.
8603 let payload = r#"{"estrategia":"OneForOne","maxRestarts":5,
8604 "restartWindow":"030s",
8605 "children":[{"caixa":"w","versao":"^0.1","restart":"Permanent"}]}"#;
8606 let err = serde_json::from_str::<SupervisorSpec>(payload).unwrap_err();
8607 let msg = err.to_string();
8608 assert!(
8609 msg.contains("non-canonical leading zero"),
8610 "expected leading-zero diagnostic in {msg:?}"
8611 );
8612 assert!(msg.contains("\"030\""), "missing magnitude in {msg:?}");
8613 }
8614
8615 #[test]
8616 fn parse_rejects_leading_whitespace() {
8617 // `" 30s"` — the canonical paste-from-aligned-doc /
8618 // paste-from-YAML-quoted-plain-scalar footgun. Before this
8619 // gate the top-level `s.trim()` at parse entry silently ate
8620 // the leading space and parsed the value to
8621 // `Duration::from_secs(30)`, which then round-tripped through
8622 // `render` to `"30s"` (a *different* canonical string on the
8623 // next emit) — the exact canonical-form-drift class the
8624 // leading-`+` / leading-zero arms already close, extended
8625 // to the whitespace-byte class. Peer with the sibling
8626 // `rate_limit_codec` whitespace-rejection arm (1ad7755) on
8627 // the M3 `:politicas` axis.
8628 let err = duration_codec::parse(" 30s").unwrap_err();
8629 assert!(
8630 err.contains("contains whitespace byte"),
8631 "expected whitespace diagnostic in {err:?}"
8632 );
8633 assert!(err.contains("0x20"), "missing offending byte in {err:?}");
8634 assert!(
8635 err.contains("THEORY.md"),
8636 "missing render-determinism contract citation in {err:?}"
8637 );
8638 }
8639
8640 #[test]
8641 fn parse_rejects_trailing_whitespace() {
8642 // `"30s "` — the canonical shell-history / trailing-space
8643 // paste footgun. Before this gate the top-level `s.trim()`
8644 // silently ate the trailing space and parsed to
8645 // `Duration::from_secs(30)`, round-tripping to `"30s"` on the
8646 // next emit — same canonical-form drift as the leading-space
8647 // sibling, closed on the same whitespace-byte arm.
8648 let err = duration_codec::parse("30s ").unwrap_err();
8649 assert!(
8650 err.contains("contains whitespace byte"),
8651 "expected whitespace diagnostic in {err:?}"
8652 );
8653 assert!(err.contains("0x20"), "missing offending byte in {err:?}");
8654 }
8655
8656 #[test]
8657 fn parse_rejects_internal_whitespace_between_magnitude_and_unit() {
8658 // `"30 s"` — the canonical typographically-spaced author
8659 // shape (the same idiom every prose reference to a duration
8660 // renders as, mistakenly retained when the value is pasted
8661 // into a codec-shaped slot). Before this gate the per-part
8662 // `num_part.trim()` / `unit.trim()` calls silently ate the
8663 // whitespace between the magnitude and the unit and parsed
8664 // the value to `Duration::from_secs(30)`, round-tripping to
8665 // `"30s"` — the codec's *internal* whitespace-tolerance
8666 // vector, orthogonal to the leading / trailing surface but
8667 // the same canonical-form-drift class. Pins the arm as
8668 // strictly stronger than the pre-existing top-level
8669 // `s.trim()` behavior: it fires on whitespace anywhere in
8670 // the value, not just at the string boundary.
8671 let err = duration_codec::parse("30 s").unwrap_err();
8672 assert!(
8673 err.contains("contains whitespace byte"),
8674 "expected whitespace diagnostic in {err:?}"
8675 );
8676 assert!(err.contains("0x20"), "missing offending byte in {err:?}");
8677 }
8678
8679 #[test]
8680 fn parse_rejects_tab_byte() {
8681 // `"\t30s"` — the canonical paste-from-indented-doc /
8682 // paste-from-YAML-block-scalar footgun where a tab byte leads
8683 // the magnitude. Pins that the gate covers tab (`0x09`) as
8684 // well as space (`0x20`) — both are `u8::is_ascii_whitespace`
8685 // members and both would be silently swallowed by `s.trim()`
8686 // pre-gate. The `is_ascii_whitespace` coverage extends beyond
8687 // space alone to the full ASCII-whitespace set (space `0x20`,
8688 // tab `0x09`, LF `0x0A`, FF `0x0C`, CR `0x0D`); this test pins
8689 // the tab arm as a representative of the non-space members.
8690 let err = duration_codec::parse("\t30s").unwrap_err();
8691 assert!(
8692 err.contains("contains whitespace byte"),
8693 "expected whitespace diagnostic in {err:?}"
8694 );
8695 assert!(
8696 err.contains("0x09"),
8697 "missing offending tab byte in {err:?}"
8698 );
8699 }
8700
8701 #[test]
8702 fn restart_window_serde_rejects_whitespace() {
8703 // The shared codec backs `SupervisorSpec::restart_window`
8704 // (`with = "duration_codec"`) — so the whitespace arm
8705 // applies on serde deserialize for the typed Supervisor slot.
8706 // A `{"restartWindow":" 30s"}` payload that previously round-
8707 // tripped to a different canonical string on next serialize
8708 // is now refused at deserialize with the whitespace-byte
8709 // diagnostic. Peer with `restart_window_serde_rejects_leading_zero`
8710 // / `restart_window_serde_rejects_leading_plus` /
8711 // `restart_window_serde_rejects_fractional_seconds` on the
8712 // same canonical-form-drift axis.
8713 let payload = r#"{"estrategia":"OneForOne","maxRestarts":5,
8714 "restartWindow":" 30s",
8715 "children":[{"caixa":"w","versao":"^0.1","restart":"Permanent"}]}"#;
8716 let err = serde_json::from_str::<SupervisorSpec>(payload).unwrap_err();
8717 let msg = err.to_string();
8718 assert!(
8719 msg.contains("contains whitespace byte"),
8720 "expected whitespace diagnostic in {msg:?}"
8721 );
8722 assert!(msg.contains("0x20"), "missing offending byte in {msg:?}");
8723 }
8724
8725 // ── canonical-form: non-ASCII Unicode `White_Space` duration gate ─────
8726 //
8727 // Successor to the ASCII-whitespace arm (a7ae622) on the shared
8728 // duration codec — closes the strictly-complementary class the
8729 // byte-scan cannot see, through the lifted
8730 // [`crate::render::find_non_ascii_whitespace_char`] predicate.
8731 // Applies to `:supervisor :restart-window`, `:politicas :timeout`,
8732 // and `:politicas :circuit-breaker :window` simultaneously via
8733 // this shared codec.
8734
8735 #[test]
8736 fn duration_codec_parse_rejects_leading_nbsp() {
8737 // NBSP prefix — the strictly-complementary drift class the
8738 // ASCII byte-scan cannot see. `str::trim` strips it silently
8739 // and the value drifts to `"30s"` on next serialize.
8740 let err = duration_codec::parse("\u{00A0}30s").unwrap_err();
8741 assert!(
8742 err.contains("non-ASCII Unicode whitespace character"),
8743 "expected non-ASCII whitespace diagnostic in {err:?}"
8744 );
8745 assert!(err.contains("U+00A0"), "missing codepoint in {err:?}");
8746 }
8747
8748 #[test]
8749 fn duration_codec_parse_rejects_trailing_line_separator() {
8750 // LINE SEPARATOR (`\u{2028}`) trailing — paste-from-web-doc
8751 // footgun.
8752 let err = duration_codec::parse("30s\u{2028}").unwrap_err();
8753 assert!(
8754 err.contains("non-ASCII Unicode whitespace character"),
8755 "expected non-ASCII whitespace diagnostic in {err:?}"
8756 );
8757 assert!(err.contains("U+2028"), "missing codepoint in {err:?}");
8758 }
8759
8760 #[test]
8761 fn duration_codec_parse_accepts_ascii_only_forms_after_unicode_arm() {
8762 // Positive-control pin: every ASCII-only canonical form the
8763 // renderer emits stays accepted through the new arm.
8764 assert_eq!(
8765 duration_codec::parse("30s").unwrap(),
8766 Duration::from_secs(30)
8767 );
8768 assert_eq!(
8769 duration_codec::parse("500ms").unwrap(),
8770 Duration::from_millis(500)
8771 );
8772 assert_eq!(
8773 duration_codec::parse("1h").unwrap(),
8774 Duration::from_secs(3600)
8775 );
8776 }
8777
8778 #[test]
8779 fn restart_window_serde_rejects_non_ascii_whitespace() {
8780 // The shared codec backs `SupervisorSpec::restart_window` — so
8781 // the new non-ASCII Unicode whitespace arm applies on serde
8782 // deserialize for the typed Supervisor slot. A
8783 // `{"restartWindow":" 30s"}` payload that previously
8784 // survived the ASCII byte-scan (only ASCII whitespace was
8785 // refused) is now refused at deserialize with the
8786 // non-ASCII-whitespace-and-codepoint diagnostic.
8787 let payload = "{\"estrategia\":\"OneForOne\",\"maxRestarts\":5,\
8788 \"restartWindow\":\"\u{00A0}30s\",\
8789 \"children\":[{\"caixa\":\"w\",\"versao\":\"^0.1\",\"restart\":\"Permanent\"}]}";
8790 let err = serde_json::from_str::<SupervisorSpec>(payload).unwrap_err();
8791 let msg = err.to_string();
8792 assert!(
8793 msg.contains("non-ASCII Unicode whitespace character"),
8794 "expected non-ASCII whitespace diagnostic in {msg:?}"
8795 );
8796 assert!(msg.contains("U+00A0"), "missing codepoint in {msg:?}");
8797 }
8798
8799 // ── drift-detection: serde-derive-to-SUPERVISOR_KEY_* identity ────────
8800
8801 #[test]
8802 fn supervisor_spec_serde_keys_match_lifted_supervisor_key_consts() {
8803 // Load-bearing invariant: the four `SUPERVISOR_KEY_*` consts
8804 // (`SUPERVISOR_KEY_ESTRATEGIA` / `SUPERVISOR_KEY_MAX_RESTARTS` /
8805 // `SUPERVISOR_KEY_RESTART_WINDOW` / `SUPERVISOR_KEY_CHILDREN`)
8806 // name the exact camelCase JSON keys the
8807 // `#[serde(rename_all = "camelCase")]` attribute on
8808 // `SupervisorSpec` emits. Serialize a fully-populated spec (each
8809 // field carries `Some(_)` / non-empty) and pin that each canonical
8810 // byte-sequence appears verbatim in the JSON — a future accidental
8811 // `rename_all = "snake_case"` / `"kebab-case"` / verbatim-field-
8812 // name flip at the derive attribute (any of which would silently
8813 // break every downstream JSON consumer that reaches for one of the
8814 // four consts via `Value::get(...)`) surfaces here as a build-time
8815 // test failure at `supervisor.rs`, not as an apply-time
8816 // `.get(<stale-canonical-const>)` returning `None` far from the
8817 // derive-attr drift's commit. Peer with the sibling
8818 // `limits_spec_serde_keys_match_lifted_m2_limits_key_consts`
8819 // (d8b8b4f) pin on the M2 `:limits` axis — same discipline the
8820 // M2 typed-slot family established, extended here to close the
8821 // top-level Supervisor axis.
8822 let spec = SupervisorSpec {
8823 estrategia: RestartStrategy::OneForOne,
8824 max_restarts: 5,
8825 restart_window: Some(Duration::from_secs(60)),
8826 children: vec![ChildSpec {
8827 caixa: "w".into(),
8828 versao: "^0.1".into(),
8829 restart: RestartPolicy::Permanent,
8830 }],
8831 };
8832 let json = serde_json::to_string(&spec).unwrap();
8833 for key in [
8834 crate::render::SUPERVISOR_KEY_ESTRATEGIA,
8835 crate::render::SUPERVISOR_KEY_MAX_RESTARTS,
8836 crate::render::SUPERVISOR_KEY_RESTART_WINDOW,
8837 crate::render::SUPERVISOR_KEY_CHILDREN,
8838 ] {
8839 let quoted = format!("\"{key}\"");
8840 assert!(
8841 json.contains("ed),
8842 "serialized SupervisorSpec must carry the lifted \
8843 SUPERVISOR_KEY_* byte-sequence {quoted} verbatim in \
8844 the JSON emission (got: {json})",
8845 );
8846 }
8847 }
8848
8849 #[test]
8850 fn supervisor_key_consts_are_pairwise_distinct() {
8851 // Cross-axis drift-detection pin: a future collapse of two
8852 // canonical top-level byte-strings onto the same value (e.g. an
8853 // accidental copy-paste flip of `SUPERVISOR_KEY_CHILDREN` to
8854 // also read `"estrategia"`) would silently reroute every
8855 // downstream probe on one axis onto the sibling axis's overlay
8856 // entry and pass every propagation-probe test that expected only
8857 // the stale axis's value. Peer of the sibling four-way distinct
8858 // pin on the `M2_LIMITS_KEY_*` tetrad (d8b8b4f).
8859 let all = [
8860 crate::render::SUPERVISOR_KEY_ESTRATEGIA,
8861 crate::render::SUPERVISOR_KEY_MAX_RESTARTS,
8862 crate::render::SUPERVISOR_KEY_RESTART_WINDOW,
8863 crate::render::SUPERVISOR_KEY_CHILDREN,
8864 ];
8865 for (i, a) in all.iter().enumerate() {
8866 for b in all.iter().skip(i + 1) {
8867 assert_ne!(
8868 a, b,
8869 "SUPERVISOR_KEY_* consts must be pairwise-distinct \
8870 canonical byte-sequences — got `{a}` == `{b}`",
8871 );
8872 }
8873 }
8874 }
8875
8876 #[test]
8877 fn supervisor_key_consts_are_lower_camel_case_shape() {
8878 // Shape-pin: every `SUPERVISOR_KEY_*` const must be a
8879 // lowerCamelCase byte-sequence (no `snake_case` underscores, no
8880 // `kebab-case` hyphens, no leading colon, no `PascalCase` leading
8881 // capital, no whitespace / dots) — the canonical shape the
8882 // `#[serde(rename_all = "camelCase")]` derive produces on
8883 // `SupervisorSpec`. A future flip to a non-camelCase attribute
8884 // at the derive surfaces both here (this test fails on the
8885 // stale-constant shape) and at
8886 // `supervisor_spec_serde_keys_match_lifted_supervisor_key_consts`
8887 // (that test fails on the mismatch between const and derive).
8888 // Peer with `m2_limits_key_consts_are_lower_camel_case_shape`
8889 // (d8b8b4f) on the sibling M2 `:limits` axis.
8890 for key in [
8891 crate::render::SUPERVISOR_KEY_ESTRATEGIA,
8892 crate::render::SUPERVISOR_KEY_MAX_RESTARTS,
8893 crate::render::SUPERVISOR_KEY_RESTART_WINDOW,
8894 crate::render::SUPERVISOR_KEY_CHILDREN,
8895 ] {
8896 assert!(
8897 !key.is_empty(),
8898 "SUPERVISOR_KEY_* must be non-empty (got {key:?})"
8899 );
8900 let first = key.chars().next().unwrap();
8901 assert!(
8902 first.is_ascii_lowercase(),
8903 "SUPERVISOR_KEY_* must lead with an ASCII-lowercase byte \
8904 (got {key:?}, leads with {first:?})",
8905 );
8906 assert!(
8907 key.chars().all(|c| c.is_ascii_alphanumeric()),
8908 "SUPERVISOR_KEY_* must be ASCII-alphanumeric only \
8909 — no `_` / `-` / `:` / `.` / whitespace (got {key:?})",
8910 );
8911 }
8912 }
8913
8914 #[test]
8915 fn supervisor_key_consts_are_byte_distinct_from_supervisor_author_key_peers() {
8916 // Cross-axis drift pin: the four `SUPERVISOR_KEY_*` consts
8917 // (camelCase JSON keys, no leading colon) must never collide
8918 // byte-for-byte with the four peer `SUPERVISOR_AUTHOR_KEY_*`
8919 // consts (kebab-case author-facing labels with leading colon)
8920 // that sit next to them at `caixa_core::render`. Both families
8921 // cover the same four typed Supervisor slots on two distinct
8922 // axes (author-side kebab vs renderer-side camelCase);
8923 // collapsing either family onto the other's byte-shape would
8924 // silently reroute the render-side probe onto the author-facing
8925 // surface, or vice versa. Peer of the byte-distinctness
8926 // discipline the `M3_PLACEMENT_KEY_ESTRATEGIA` docstring names
8927 // against the peer `M3_AUTHOR_KEY_PLACEMENT`.
8928 let pairs = [
8929 (
8930 crate::render::SUPERVISOR_KEY_ESTRATEGIA,
8931 crate::render::SUPERVISOR_AUTHOR_KEY_ESTRATEGIA,
8932 ),
8933 (
8934 crate::render::SUPERVISOR_KEY_MAX_RESTARTS,
8935 crate::render::SUPERVISOR_AUTHOR_KEY_MAX_RESTARTS,
8936 ),
8937 (
8938 crate::render::SUPERVISOR_KEY_RESTART_WINDOW,
8939 crate::render::SUPERVISOR_AUTHOR_KEY_RESTART_WINDOW,
8940 ),
8941 (
8942 crate::render::SUPERVISOR_KEY_CHILDREN,
8943 crate::render::SUPERVISOR_AUTHOR_KEY_CHILDREN,
8944 ),
8945 ];
8946 for (json_key, author_key) in pairs {
8947 assert_ne!(
8948 json_key, author_key,
8949 "SUPERVISOR_KEY_* (JSON side) must differ byte-for-byte \
8950 from the peer SUPERVISOR_AUTHOR_KEY_* (author side); \
8951 got JSON `{json_key}` == author `{author_key}`",
8952 );
8953 }
8954 }
8955
8956 // ── drift-detection: serde-derive-to-SUPERVISOR_CHILD_KEY_* identity ──
8957
8958 #[test]
8959 fn child_spec_serde_keys_match_lifted_supervisor_child_key_consts() {
8960 // Load-bearing invariant: the three `SUPERVISOR_CHILD_KEY_*` consts
8961 // (`SUPERVISOR_CHILD_KEY_CAIXA` / `SUPERVISOR_CHILD_KEY_VERSAO` /
8962 // `SUPERVISOR_CHILD_KEY_RESTART`) name the exact camelCase JSON
8963 // keys the `#[serde(rename_all = "camelCase")]` attribute on
8964 // `ChildSpec` emits. Serialize a fully-populated `ChildSpec` and
8965 // pin that each canonical byte-sequence appears verbatim in the
8966 // JSON — a future accidental `rename_all = "snake_case"` /
8967 // `"kebab-case"` / verbatim-field-name flip at the derive
8968 // attribute (any of which would silently break every downstream
8969 // JSON consumer that reaches for one of the three consts via
8970 // `Value::get(...)`) surfaces here as a build-time test failure at
8971 // `supervisor.rs`, not as an apply-time
8972 // `.get(<stale-canonical-const>)` returning `None` far from the
8973 // derive-attr drift's commit. Peer with the enclosing
8974 // `supervisor_spec_serde_keys_match_lifted_supervisor_key_consts`
8975 // (40cc4e5) pin on the M2 supervision-tree top-level axis — same
8976 // discipline the SupervisorSpec top-level lift established,
8977 // extended here to the sibling per-`:children` entry `ChildSpec`
8978 // derive so the last M2 typed-struct sub-block
8979 // `#[serde(rename_all = "camelCase")]` axis on the Supervisor
8980 // surface without a lifted serde-key peer joins the substrate's
8981 // "one canonical byte-string per typed serialized-key axis"
8982 // discipline.
8983 let c = ChildSpec {
8984 caixa: "worker".into(),
8985 versao: "^0.1".into(),
8986 restart: RestartPolicy::Permanent,
8987 };
8988 let json = serde_json::to_string(&c).unwrap();
8989 for key in [
8990 crate::render::SUPERVISOR_CHILD_KEY_CAIXA,
8991 crate::render::SUPERVISOR_CHILD_KEY_VERSAO,
8992 crate::render::SUPERVISOR_CHILD_KEY_RESTART,
8993 ] {
8994 let quoted = format!("\"{key}\"");
8995 assert!(
8996 json.contains("ed),
8997 "serialized ChildSpec must carry the lifted \
8998 SUPERVISOR_CHILD_KEY_* byte-sequence {quoted} verbatim \
8999 in the JSON emission (got: {json})",
9000 );
9001 }
9002 }
9003
9004 #[test]
9005 fn supervisor_child_key_consts_are_pairwise_distinct() {
9006 // Cross-axis drift-detection pin: a future collapse of two
9007 // canonical `ChildSpec` per-entry byte-strings onto the same
9008 // value (e.g. an accidental copy-paste flip of
9009 // `SUPERVISOR_CHILD_KEY_RESTART` to also read `"caixa"`) would
9010 // silently reroute every downstream probe on one axis onto the
9011 // sibling axis's overlay entry and pass every propagation-probe
9012 // test that expected only the stale axis's value. Peer of the
9013 // sibling three-way distinct pin on the `CONTRATO_KEY_*` triad
9014 // (ca463a4) and the two-way distinct pin on the `MEMBRO_KEY_*`
9015 // pair (ce80ca0).
9016 let all = [
9017 crate::render::SUPERVISOR_CHILD_KEY_CAIXA,
9018 crate::render::SUPERVISOR_CHILD_KEY_VERSAO,
9019 crate::render::SUPERVISOR_CHILD_KEY_RESTART,
9020 ];
9021 for (i, a) in all.iter().enumerate() {
9022 for b in all.iter().skip(i + 1) {
9023 assert_ne!(
9024 a, b,
9025 "SUPERVISOR_CHILD_KEY_* consts must be pairwise-\
9026 distinct canonical byte-sequences — got `{a}` == `{b}`",
9027 );
9028 }
9029 }
9030 }
9031
9032 #[test]
9033 fn supervisor_child_key_consts_are_lower_camel_case_shape() {
9034 // Shape-pin: every `SUPERVISOR_CHILD_KEY_*` const must be a
9035 // lowerCamelCase byte-sequence (no `snake_case` underscores, no
9036 // `kebab-case` hyphens, no leading colon, no `PascalCase` leading
9037 // capital, no whitespace / dots) — the canonical shape the
9038 // `#[serde(rename_all = "camelCase")]` derive produces on
9039 // `ChildSpec`. A future flip to a non-camelCase attribute at the
9040 // derive surfaces both here (this test fails on the
9041 // stale-constant shape) and at
9042 // `child_spec_serde_keys_match_lifted_supervisor_child_key_consts`
9043 // (that test fails on the mismatch between const and derive).
9044 // Peer with `supervisor_key_consts_are_lower_camel_case_shape`
9045 // (40cc4e5) on the sibling `SupervisorSpec` top-level axis.
9046 for key in [
9047 crate::render::SUPERVISOR_CHILD_KEY_CAIXA,
9048 crate::render::SUPERVISOR_CHILD_KEY_VERSAO,
9049 crate::render::SUPERVISOR_CHILD_KEY_RESTART,
9050 ] {
9051 assert!(
9052 !key.is_empty(),
9053 "SUPERVISOR_CHILD_KEY_* must be non-empty (got {key:?})"
9054 );
9055 let first = key.chars().next().unwrap();
9056 assert!(
9057 first.is_ascii_lowercase(),
9058 "SUPERVISOR_CHILD_KEY_* must lead with an ASCII-lowercase \
9059 byte (got {key:?}, leads with {first:?})",
9060 );
9061 assert!(
9062 key.chars().all(|c| c.is_ascii_alphanumeric()),
9063 "SUPERVISOR_CHILD_KEY_* must be ASCII-alphanumeric only \
9064 — no `_` / `-` / `:` / `.` / whitespace (got {key:?})",
9065 );
9066 }
9067 }
9068
9069 // ── drift-detection: serde-derive-to-SUPERVISOR_ESTRATEGIA_* identity ────
9070
9071 #[test]
9072 fn restart_strategy_variants_serialize_to_lifted_scalar_values() {
9073 // The fail-before-pass-after pin: pre-lift there was no
9074 // single-source binding between the [`RestartStrategy`] variant
9075 // name the un-`rename`d `Serialize` derive emits under
9076 // [`crate::render::SUPERVISOR_KEY_ESTRATEGIA`] and the byte-string
9077 // every downstream cluster-side dispatcher (the future
9078 // wasm-operator's per-supervisor sibling-restart branch, the
9079 // future M4 `mesh.pleme.io/v1alpha1/Supervisor` CR materializer's
9080 // admission-time enum-arm bind, the `caixa-operator`'s
9081 // hierarchical reconciliation scheduler's per-strategy fan-out)
9082 // probes verbatim. A future `#[serde(rename_all = "kebab-case")]`
9083 // attribute on the enum — or a per-variant `#[serde(rename = "…")]`
9084 // override, or a variant rename in the source — would silently
9085 // rebrand the emitted scalar under one spelling while every
9086 // downstream dispatcher still probed the other, with the failure
9087 // surfacing at the operator's reconcile posture (subtrees coming
9088 // up under the `default()` `OneForOne` arm rather than the typed
9089 // slot's declared strategy — a bad child would then only take
9090 // itself down instead of the sibling set the author intended, so
9091 // shared-state children fall out of sync) far from the source
9092 // rebrand commit and with no field naming the drift. Pinning the
9093 // two paths (the `Serialize` derive's serialized string AND the
9094 // [`RestartStrategy::as_str`] helper) to the same four lifted
9095 // [`crate::render::SUPERVISOR_ESTRATEGIA_ONE_FOR_ONE`] /
9096 // [`crate::render::SUPERVISOR_ESTRATEGIA_ONE_FOR_ALL`] /
9097 // [`crate::render::SUPERVISOR_ESTRATEGIA_REST_FOR_ONE`] /
9098 // [`crate::render::SUPERVISOR_ESTRATEGIA_SIMPLE_ONE_FOR_ONE`]
9099 // byte-strings makes any future drift on either endpoint fail
9100 // here at caixa-core build time. Peer of the M3
9101 // `placement_strategy_variants_serialize_to_lifted_scalar_values`
9102 // (3f0e21c) on the sibling `PlacementStrategy` axis — same
9103 // three-path-convergence discipline, extended to close the
9104 // OTP-shaped per-supervisor sibling-restart axis.
9105 for (variant, expected) in [
9106 (
9107 RestartStrategy::OneForOne,
9108 crate::render::SUPERVISOR_ESTRATEGIA_ONE_FOR_ONE,
9109 ),
9110 (
9111 RestartStrategy::OneForAll,
9112 crate::render::SUPERVISOR_ESTRATEGIA_ONE_FOR_ALL,
9113 ),
9114 (
9115 RestartStrategy::RestForOne,
9116 crate::render::SUPERVISOR_ESTRATEGIA_REST_FOR_ONE,
9117 ),
9118 (
9119 RestartStrategy::SimpleOneForOne,
9120 crate::render::SUPERVISOR_ESTRATEGIA_SIMPLE_ONE_FOR_ONE,
9121 ),
9122 ] {
9123 let json = serde_json::to_string(&variant).unwrap();
9124 assert_eq!(
9125 json,
9126 format!("\"{expected}\""),
9127 "RestartStrategy::{variant:?} must serialize to {expected:?}"
9128 );
9129 assert_eq!(
9130 variant.as_str(),
9131 expected,
9132 "RestartStrategy::{variant:?}.as_str() must return the lifted \
9133 SUPERVISOR_ESTRATEGIA_* constant"
9134 );
9135 }
9136 }
9137
9138 #[test]
9139 fn supervisor_estrategia_consts_are_pairwise_distinct() {
9140 // Cross-arm drift-detection pin: a future collapse of two
9141 // canonical variant byte-strings onto the same value (e.g. an
9142 // accidental copy-paste flip of `SUPERVISOR_ESTRATEGIA_REST_FOR_ONE`
9143 // to also read `"OneForOne"`) would silently reroute every
9144 // downstream operator's per-strategy dispatch onto the sibling
9145 // arm's reconcile branch and pass every propagation-probe test
9146 // that expected only the stale arm's value — the mis-strategied
9147 // subtree would come up with the wrong sibling-restart posture
9148 // on every subsequent failure. Peer of the sibling four-way
9149 // distinct pin `supervisor_key_consts_are_pairwise_distinct`
9150 // (40cc4e5) on the top-level `SUPERVISOR_KEY_*` axis.
9151 let all = [
9152 crate::render::SUPERVISOR_ESTRATEGIA_ONE_FOR_ONE,
9153 crate::render::SUPERVISOR_ESTRATEGIA_ONE_FOR_ALL,
9154 crate::render::SUPERVISOR_ESTRATEGIA_REST_FOR_ONE,
9155 crate::render::SUPERVISOR_ESTRATEGIA_SIMPLE_ONE_FOR_ONE,
9156 ];
9157 for (i, a) in all.iter().enumerate() {
9158 for (j, b) in all.iter().enumerate() {
9159 if i != j {
9160 assert_ne!(
9161 a, b,
9162 "SUPERVISOR_ESTRATEGIA_* consts must be pairwise distinct \
9163 — got duplicate {a:?} at indices {i} and {j}",
9164 );
9165 }
9166 }
9167 }
9168 }
9169
9170 #[test]
9171 fn restart_strategy_display_routes_through_as_str_helper() {
9172 // The fail-before-pass-after pin on the first half of the
9173 // three-path convergence: pre-convergence the sibling
9174 // OTP-shape typed enum [`RestartStrategy`] carried a
9175 // [`std::fmt::Display`] surface via its
9176 // `#[discriminant(also_display)]` gen-platform derive route,
9177 // which arrived kebab-case as `"one-for-one"` /
9178 // `"one-for-all"` / `"rest-for-one"` /
9179 // `"simple-one-for-one"` while the wire format ran as
9180 // PascalCase `"OneForOne"` / `"OneForAll"` / `"RestForOne"` /
9181 // `"SimpleOneForOne"` through the un-`rename`d serde derive.
9182 // Every consumer reaching for a strategy byte-string past the
9183 // wire format had to pick between three paths
9184 // ([`RestartStrategy::as_str`], the `Serialize` derive's
9185 // serialized string, or `format!("{v}")` on the
9186 // discriminant-Display route), any two of which a future
9187 // variant rename or `#[serde(rename_all = "kebab-case")]`
9188 // attribute would silently desynchronize. Wiring
9189 // [`std::fmt::Display`] through [`RestartStrategy::as_str`]
9190 // closes the third path: every `format!("{v}")` call reaches
9191 // the same lifted [`crate::render::SUPERVISOR_ESTRATEGIA_*`]
9192 // const the wire format and the [`RestartStrategy::as_str`]
9193 // helper already route through, so a future variant rename
9194 // lands at exactly one place. Pin the routing here so a future
9195 // `impl std::fmt::Display for RestartStrategy`
9196 // reimplementation that hand-rolls the arms instead of
9197 // delegating to [`RestartStrategy::as_str`] fails at
9198 // caixa-core build time. Peer of the M3
9199 // `placement_strategy_display_routes_through_as_str_helper`
9200 // (cc8f749) which the M3 axis converged first.
9201 for &variant in RestartStrategy::ALL {
9202 assert_eq!(
9203 variant.to_string(),
9204 variant.as_str(),
9205 "RestartStrategy::{variant:?} Display must route through \
9206 RestartStrategy::as_str (single source of truth: the lifted \
9207 SUPERVISOR_ESTRATEGIA_* const the wire format also emits)"
9208 );
9209 }
9210 }
9211
9212 #[test]
9213 fn restart_strategy_display_matches_serialized_wire_byte_string() {
9214 // The fail-before-pass-after pin on the second half of the
9215 // three-path convergence: `Display` (user-facing text) agrees
9216 // byte-for-byte with the `Serialize` derive's wire format
9217 // (canonical camelCase-schema `SUPERVISOR_KEY_ESTRATEGIA`
9218 // scalar) on every variant. Pre-convergence the two paths
9219 // were structurally independent — a future
9220 // `#[serde(rename_all = "kebab-case")]` attribute on the
9221 // enum would silently rebrand the emitted wire scalar
9222 // (`one-for-one`, `one-for-all`, `rest-for-one`,
9223 // `simple-one-for-one`) while every consumer that
9224 // pretty-prints the strategy (the future wasm-operator's
9225 // per-supervisor sibling-restart-strategy diagnostic line,
9226 // the future `feira app graph` per-supervisor strategy line,
9227 // the future M4 `mesh.pleme.io/v1alpha1/Supervisor` CR
9228 // materializer's admission-webhook rejection body) would
9229 // still emit the PascalCase form the `as_str` / `Display`
9230 // route returns, with the mismatch surfacing at consumer
9231 // parse time / operator dispatch time far from the source
9232 // rebrand commit. Pin the two paths byte-for-byte here so any
9233 // future serde-attribute or variant-rename drift is a
9234 // caixa-core-build-time test failure at this call, not a
9235 // silent per-consumer dispatch miss. Peer of the M3
9236 // `placement_strategy_display_matches_serialized_wire_byte_string`
9237 // (cc8f749) which the M3 axis converged first.
9238 for &variant in RestartStrategy::ALL {
9239 let wire = serde_json::to_string(&variant).unwrap();
9240 let unquoted = wire
9241 .strip_prefix('"')
9242 .and_then(|s| s.strip_suffix('"'))
9243 .expect("serialized RestartStrategy is a JSON string");
9244 assert_eq!(
9245 variant.to_string(),
9246 unquoted,
9247 "RestartStrategy::{variant:?} Display byte-string must match the \
9248 Serialize derive's wire byte-string (three-path convergence: \
9249 Display + as_str + Serialize all resolve to the same \
9250 SUPERVISOR_ESTRATEGIA_* const)"
9251 );
9252 }
9253 }
9254
9255 #[test]
9256 fn restart_strategy_as_ref_str_routes_through_as_str_accessor() {
9257 // Fail-before-pass-after byte-parity pin on the lifted
9258 // `impl AsRef<str> for RestartStrategy` — asserts the
9259 // standard-library trait impl and the substrate-primitive
9260 // [`RestartStrategy::as_str`] `pub const fn` accessor resolve
9261 // to the same `&str` per instance across the four-arm
9262 // closed set, so any future silent detour that routes the
9263 // impl through a divergent projection (a per-arm inline
9264 // `match self { RestartStrategy::OneForOne => "OneForOne", … }`
9265 // re-inlining that opens a compile-time link to the un-lifted
9266 // arm-literal, a swap onto the kebab-case
9267 // [`gen_platform::Discriminant`] catalog identity that would
9268 // collide the wire axis with the dispatcher-catalog axis) trips
9269 // at caixa-core test time under `PartialEq` rather than at a
9270 // downstream `impl AsRef<str>`-bound consumer's silent split.
9271 // Sweeps every one of the four arms
9272 // [`RestartStrategy::ALL`] carries so no arm's projection is
9273 // covered only by the sibling wire-format `Serialize` derive
9274 // path. Peer of the sibling
9275 // [`crate::version::tests::caixa_version_as_ref_str_routes_through_as_str_accessor`]
9276 // (16d5c7e) `AsRef<str>`-byte-parity pin on the paired
9277 // top-level `:versao` typed newtype — the two pins together
9278 // cover the substrate primitive's `AsRef<str>` projection axis
9279 // on the paired newtype + closed-set-typed-enum surface.
9280 for &variant in RestartStrategy::ALL {
9281 assert_eq!(
9282 <RestartStrategy as AsRef<str>>::as_ref(&variant),
9283 variant.as_str(),
9284 "AsRef<str> impl on RestartStrategy::{variant:?} must \
9285 byte-equal RestartStrategy::as_str on the same instance \
9286 — divergence signals a silent detour off the substrate-\
9287 primitive accessor"
9288 );
9289 }
9290 }
9291
9292 #[test]
9293 fn restart_strategy_as_ref_str_routes_through_display_via_shared_accessor() {
9294 // Fail-before-pass-after byte-parity pin on the three-path
9295 // convergence discipline the M2 sibling-restart primitive now
9296 // carries on the `&str`-projection axis:
9297 // `<RestartStrategy as AsRef<str>>::as_ref(&s)` (the newly
9298 // lifted impl), `format!("{s}")` (the pre-existing
9299 // [`fmt::Display`] impl), and `s.as_str()` (the substrate-
9300 // primitive `pub const fn` accessor both trait impls delegate
9301 // through) must resolve to the same byte-string on every
9302 // instance across the four-arm closed set. Refuses any future
9303 // divergence between the two trait impls (a stray
9304 // [`fmt::Display::fmt`] rewrite that hand-rolls the arms
9305 // rather than delegating through the shared accessor; a
9306 // hypothetical `AsRef<str>` rewrite that inlines a per-arm
9307 // literal cascade) that would silently split the two
9308 // projection paths of the same closed-set typed enum. Mirrors
9309 // the sibling three-path-convergence discipline the peer
9310 // [`crate::CaixaVersion`] typed newtype carries on its
9311 // `AsRef<str>` / `Display` / `as_str` triple
9312 // (version.rs pin
9313 // `caixa_version_as_ref_str_routes_through_display_via_shared_accessor`,
9314 // 16d5c7e).
9315 for &variant in RestartStrategy::ALL {
9316 let via_as_ref: &str = <RestartStrategy as AsRef<str>>::as_ref(&variant);
9317 let via_display: String = format!("{variant}");
9318 let via_accessor: &str = variant.as_str();
9319 assert_eq!(via_as_ref, via_accessor);
9320 assert_eq!(via_display, via_accessor);
9321 assert_eq!(via_as_ref, via_display.as_str());
9322 }
9323 }
9324
9325 #[test]
9326 fn restart_strategy_all_enumerates_every_variant_exactly_once() {
9327 // Fail-before-pass-after pin on the [`RestartStrategy::ALL`]
9328 // exhaustive-iteration surface: every variant appears exactly
9329 // once, and the slice length matches the arm count of the
9330 // closed set. Every consumer that walks the accepted-strategy
9331 // set (a future `feira supervisor --estrategia …` CLI-side
9332 // arg-parse's "did you mean" hint, a future M4 admission-
9333 // webhook's rejection body naming the accepted-`:estrategia`
9334 // list, the [`RestartStrategy::from_wire`] reverse-projection
9335 // consumers that iterate the accept-set for diagnostic
9336 // rendering) reads through this slice, so a future arm addition
9337 // that grows the enum but forgets to grow [`Self::ALL`]
9338 // silently truncates every downstream consumer's accept-set at
9339 // the same pre-addition boundary — this pin fails at caixa-core
9340 // build time on the pairwise-distinct + arm-count invariants.
9341 //
9342 // Peer of the sibling [`crate::CaixaKind::ALL`] (6b1f4fb) /
9343 // [`crate::aplicacao::PlacementStrategy::ALL`] (18c7342) /
9344 // [`crate::aplicacao::RateLimitUnit::ALL`] (6bce03d) /
9345 // [`crate::dep::DepList::ALL`] (45ee563) exhaustive-iteration
9346 // pins on the peer closed-set typed-enum axes.
9347 let all: &[RestartStrategy] = RestartStrategy::ALL;
9348 assert_eq!(
9349 all.len(),
9350 4,
9351 "RestartStrategy::ALL must enumerate every variant of the \
9352 four-arm closed set (OneForOne, OneForAll, RestForOne, \
9353 SimpleOneForOne); got {all:?}"
9354 );
9355 for (i, a) in all.iter().enumerate() {
9356 for (j, b) in all.iter().enumerate() {
9357 if i != j {
9358 assert_ne!(
9359 a, b,
9360 "RestartStrategy::ALL must carry every variant exactly \
9361 once — got duplicate {a:?} at indices {i} and {j}"
9362 );
9363 }
9364 }
9365 }
9366 for variant in [
9367 RestartStrategy::OneForOne,
9368 RestartStrategy::OneForAll,
9369 RestartStrategy::RestForOne,
9370 RestartStrategy::SimpleOneForOne,
9371 ] {
9372 assert!(
9373 all.contains(&variant),
9374 "RestartStrategy::ALL must contain {variant:?} — a future arm \
9375 addition that grows the enum but forgets to grow the ALL slice \
9376 silently truncates every downstream consumer's accept-set at \
9377 the pre-addition boundary"
9378 );
9379 }
9380 }
9381
9382 #[test]
9383 fn restart_strategy_wire_names_covers_every_arm() {
9384 // Load-bearing pin on the substrate-canonical
9385 // [`RestartStrategy::WIRE_NAMES`] exhaustive accept-set roster
9386 // on the `PascalCase` wire byte-string axis: every variant of
9387 // the sibling [`RestartStrategy::ALL`] exhaustive-iteration
9388 // surface must project through [`RestartStrategy::as_str`] onto
9389 // an entry the [`RestartStrategy::WIRE_NAMES`] roster carries,
9390 // and the roster's length must byte-equal
9391 // `RestartStrategy::ALL.len()` so a silent skew between the
9392 // [`RestartStrategy::as_str`] match's arm-set and the roster's
9393 // arm-set trips here at caixa-core test time rather than at a
9394 // downstream M4 `mesh.pleme.io/v1alpha1/Supervisor` CR
9395 // admission-webhook rejection body's wire-form `:estrategia`
9396 // accepted-set enumeration miss / a `feira supervisor
9397 // --estrategia …` "did you mean" hint drift / a future
9398 // wasm-operator per-reconcile-step diagnostic log line's
9399 // accepted-wire-form enumeration miss. A future arm addition
9400 // (an OTP-`rest_for_all` arm the theory
9401 // [`ABSORPTION-ROADMAP`](https://github.com/pleme-io/theory/blob/main/ABSORPTION-ROADMAP.md)
9402 // might reach for once the four canonical OTP strategies stop
9403 // covering the substrate's discovered load-shape) extends
9404 // [`RestartStrategy::ALL`] as a single edit and this pin
9405 // sweeps the new arm by iteration; the paired
9406 // [`RestartStrategy::WIRE_NAMES`] roster must grow in lockstep
9407 // or this assertion trips. Every entry is further pinned to
9408 // open with an ASCII uppercase byte so a silent collapse of
9409 // the wire-form axis with the peer kebab-case
9410 // dispatcher-catalog axis (an entry byte-identical to a
9411 // sibling [`Self::discriminant`] kebab byte-string that would
9412 // let a wire-axis consumer accept the dispatcher-catalog
9413 // vocabulary) trips here rather than at a downstream K8s-CR
9414 // round-trip miss.
9415 //
9416 // Peer of the sibling
9417 // [`crate::kind::tests::caixa_kind_wire_names_covers_every_arm`]
9418 // (bd708bd) pin on the top-level typed-kind discriminator's
9419 // `PascalCase` wire byte-string axis, and of the sibling
9420 // [`crate::upgrade::tests::upgrade_instruction_wire_forms_covers_every_arm`]
9421 // (cc42c0e) /
9422 // [`crate::upgrade::tests::upgrade_instruction_lisp_forms_covers_every_arm`]
9423 // (1898d77) pins on the OTP-appup discriminator's two-axis
9424 // roster split — the same closed-set exhaustive-roster
9425 // coverage discipline extended here onto the first M2
9426 // OTP-shape sibling-restart closed-set typed enum.
9427 //
9428 // Fail-before-pass-after locally verified by mutating one arm
9429 // of the paired [`crate::render::SUPERVISOR_ESTRATEGIA_*`]
9430 // const family (e.g. dropping the trailing `e` from
9431 // `"OneForOne"` → `"OneForOn"`) — the length pin still passes
9432 // but the `contains` check fires on the mutated arm; and by
9433 // shortening the roster to three entries — the length pin
9434 // fires first.
9435 assert_eq!(
9436 RestartStrategy::WIRE_NAMES.len(),
9437 RestartStrategy::ALL.len(),
9438 "RestartStrategy::WIRE_NAMES.len() must byte-equal \
9439 RestartStrategy::ALL.len() — a mismatch means the roster \
9440 and the enum's arm-set have drifted; downstream consumers \
9441 that fan through both will silently disagree on the \
9442 accepted arm-set"
9443 );
9444 for &variant in RestartStrategy::ALL {
9445 let wire = variant.as_str();
9446 assert!(
9447 RestartStrategy::WIRE_NAMES.contains(&wire),
9448 "RestartStrategy::{variant:?}.as_str() = {wire:?} must \
9449 be a member of RestartStrategy::WIRE_NAMES — the \
9450 emitter and the roster have drifted out of lockstep"
9451 );
9452 }
9453 for tag in RestartStrategy::WIRE_NAMES {
9454 let first = tag.chars().next().unwrap_or_else(|| {
9455 panic!(
9456 "RestartStrategy::WIRE_NAMES entry {tag:?} must be \
9457 a non-empty PascalCase byte-string"
9458 )
9459 });
9460 assert!(
9461 first.is_ascii_uppercase(),
9462 "RestartStrategy::WIRE_NAMES entry {tag:?} must open \
9463 with an ASCII uppercase byte (PascalCase wire form) — \
9464 a lowercase entry would collide the wire-form axis \
9465 with the peer kebab-case dispatcher-catalog axis \
9466 [`RestartStrategy::discriminant`] serves"
9467 );
9468 }
9469 }
9470
9471 #[test]
9472 fn restart_strategy_from_wire_accepts_every_lifted_constant() {
9473 // Fail-before-pass-after pin on the forward accept-set of the
9474 // [`RestartStrategy::from_wire`] reverse projection: every
9475 // canonical [`crate::render::SUPERVISOR_ESTRATEGIA_*`]
9476 // constant the [`RestartStrategy::as_str`] emitter walks parses
9477 // back to its paired variant. Any future arm addition that
9478 // grows the emitter's `as_str` match but forgets to grow the
9479 // parser's `from_wire` match silently splits the two halves of
9480 // the round-trip — the wire byte-string one non-serde consumer
9481 // parses from the one the emitter wrote — with the failure
9482 // surfacing at parse time far from the rebrand commit. Pinning
9483 // the four-arm accept-set here catches the drift at caixa-core
9484 // build time.
9485 //
9486 // Peer of the sibling [`crate::CaixaKind::from_wire`] (2aa6d23)
9487 // + [`crate::aplicacao::PlacementStrategy::from_wire`] (18c7342)
9488 // accept-set pins on the peer closed-set typed-enum `str → Self`
9489 // axes.
9490 for (wire, expected) in [
9491 (
9492 crate::render::SUPERVISOR_ESTRATEGIA_ONE_FOR_ONE,
9493 RestartStrategy::OneForOne,
9494 ),
9495 (
9496 crate::render::SUPERVISOR_ESTRATEGIA_ONE_FOR_ALL,
9497 RestartStrategy::OneForAll,
9498 ),
9499 (
9500 crate::render::SUPERVISOR_ESTRATEGIA_REST_FOR_ONE,
9501 RestartStrategy::RestForOne,
9502 ),
9503 (
9504 crate::render::SUPERVISOR_ESTRATEGIA_SIMPLE_ONE_FOR_ONE,
9505 RestartStrategy::SimpleOneForOne,
9506 ),
9507 ] {
9508 let parsed = RestartStrategy::from_wire(wire).unwrap_or_else(|| {
9509 panic!(
9510 "RestartStrategy::from_wire({wire:?}) must accept every \
9511 SUPERVISOR_ESTRATEGIA_* constant — got None for the \
9512 lifted canonical byte-string that RestartStrategy::{expected:?} \
9513 serializes as under SUPERVISOR_KEY_ESTRATEGIA"
9514 )
9515 });
9516 assert_eq!(
9517 parsed, expected,
9518 "RestartStrategy::from_wire({wire:?}) must return \
9519 RestartStrategy::{expected:?}; got RestartStrategy::{parsed:?}"
9520 );
9521 }
9522 }
9523
9524 #[test]
9525 fn restart_strategy_from_wire_round_trips_through_as_str() {
9526 // Fail-before-pass-after pin on the closed round-trip between
9527 // the forward [`RestartStrategy::as_str`] emitter and the
9528 // reverse [`RestartStrategy::from_wire`] parser: for every
9529 // variant in [`RestartStrategy::ALL`], parsing the emitter's
9530 // output must return exactly the same variant. Any per-arm
9531 // divergence — a future arm added to `as_str` but not
9532 // `from_wire`, an accidental copy-paste flip in one but not
9533 // the other — silently splits the emit and parse halves and
9534 // the failure surfaces at consumer parse time far from the
9535 // drift site. The `ALL`-iterating shape means a future arm
9536 // addition picks up the coverage by construction.
9537 //
9538 // Peer of the sibling
9539 // [`crate::aplicacao::tests::placement_strategy_from_wire_round_trips_through_as_str`]
9540 // (18c7342) round-trip pin on
9541 // [`crate::aplicacao::PlacementStrategy::from_wire`] and
9542 // [`crate::kind::tests::caixa_kind_wire_round_trips_through_from_wire`]
9543 // (6b1f4fb) round-trip pin on [`crate::CaixaKind::from_wire`].
9544 for &variant in RestartStrategy::ALL {
9545 let wire = variant.as_str();
9546 let parsed = RestartStrategy::from_wire(wire).unwrap_or_else(|| {
9547 panic!(
9548 "RestartStrategy::from_wire(RestartStrategy::{variant:?}.as_str()) \
9549 must be Some({variant:?}) — the two halves of the round-trip \
9550 dispatch on the same lifted SUPERVISOR_ESTRATEGIA_* consts; \
9551 got None on wire byte-string {wire:?}"
9552 )
9553 });
9554 assert_eq!(
9555 parsed, variant,
9556 "RestartStrategy::from_wire(RestartStrategy::{variant:?}.as_str()) \
9557 must round-trip to the same variant; got {parsed:?}"
9558 );
9559 }
9560 }
9561
9562 #[test]
9563 fn restart_strategy_from_wire_rejects_unknown_byte_strings() {
9564 // Fail-before-pass-after pin on the closed-set refusal
9565 // discipline of [`RestartStrategy::from_wire`]: every
9566 // byte-string outside the four-arm accept-set returns `None`
9567 // rather than silently collapsing onto the [`Default`]
9568 // (`OneForOne`) arm or an arbitrary neighbor. The refusal set
9569 // exercised here sweeps the load-bearing drift shapes: the
9570 // empty string (a stripped serde-attribute drift), all-
9571 // whitespace strings (the canonical text-editor accidental
9572 // padding shape), the kebab-case dispatcher-catalog identities
9573 // (`"one-for-one"` / `"one-for-all"` / `"rest-for-one"` /
9574 // `"simple-one-for-one"` — the [`gen_platform::FromStrKind`]-
9575 // derived [`std::str::FromStr`] accept-set, which parses the
9576 // *other* axis of this enum's two-axis split and must not leak
9577 // into the `from_wire` PascalCase-wire accept-set), the
9578 // lowercased single-word forms (`"oneforone"`), the padded
9579 // canonical scalar (`" OneForOne "`), the trailing-newline
9580 // shapes (`"OneForOne\n"`), and neighboring-but-unknown arms
9581 // (`"AllForOne"` — the canonical typo direction).
9582 //
9583 // Peer of the sibling
9584 // [`crate::kind::tests::caixa_kind_from_wire_rejects_unknown_byte_strings`]
9585 // (2aa6d23) +
9586 // [`crate::aplicacao::tests::placement_strategy_from_wire_rejects_unknown_byte_strings`]
9587 // (18c7342) refusal pins on the peer closed-set typed-enum
9588 // axes.
9589 for bad in [
9590 "",
9591 " ",
9592 "\n",
9593 "\t",
9594 "one-for-one",
9595 "one-for-all",
9596 "rest-for-one",
9597 "simple-one-for-one",
9598 "oneforone",
9599 "OneForOnes",
9600 "one_for_one",
9601 "one for one",
9602 "ONEFORONE",
9603 "OneForOne ",
9604 " OneForOne",
9605 " SimpleOneForOne ",
9606 "OneForOne\n",
9607 "restforone",
9608 "REST_FOR_ONE",
9609 "AllForOne",
9610 "Simple",
9611 "?",
9612 ] {
9613 assert!(
9614 RestartStrategy::from_wire(bad).is_none(),
9615 "RestartStrategy::from_wire({bad:?}) must return None — the \
9616 parser's accept-set is exactly the four RestartStrategy::as_str \
9617 outputs (OneForOne, OneForAll, RestForOne, SimpleOneForOne), \
9618 and this byte-string is outside that closed set"
9619 );
9620 }
9621 }
9622
9623 #[test]
9624 fn restart_strategy_from_wire_matches_serialize_derive_wire_byte_string() {
9625 // Fail-before-pass-after pin on the fourth path of the four-path
9626 // convergence: `from_wire` (the reverse projection) inverts the
9627 // `Serialize` derive's wire byte-string on every variant.
9628 // Together with the pre-existing three-path convergence
9629 // (`Display` + `as_str` + `Serialize` all resolve to the same
9630 // lifted [`crate::render::SUPERVISOR_ESTRATEGIA_*`] const,
9631 // pinned by
9632 // [`restart_strategy_display_matches_serialized_wire_byte_string`])
9633 // this closes the round-trip: the wire byte-string the
9634 // `Serialize` derive emits parses back to the same variant
9635 // through `from_wire`, so any future serde-attribute or variant-
9636 // rename drift on the emit half now surfaces as a matched drift
9637 // on the parse half at caixa-core build time — the two halves
9638 // migrate as a unit through the lifted consts on any future
9639 // rename, and the round-trip cannot silently split.
9640 //
9641 // Peer of the sibling
9642 // [`crate::aplicacao::tests::placement_strategy_from_wire_matches_serialize_derive_wire_byte_string`]
9643 // (18c7342) wire-format pin on
9644 // [`crate::aplicacao::PlacementStrategy::from_wire`].
9645 for &variant in RestartStrategy::ALL {
9646 let wire = serde_json::to_string(&variant).unwrap();
9647 let unquoted = wire
9648 .strip_prefix('"')
9649 .and_then(|s| s.strip_suffix('"'))
9650 .expect("serialized RestartStrategy is a JSON string");
9651 let parsed = RestartStrategy::from_wire(unquoted).unwrap_or_else(|| {
9652 panic!(
9653 "RestartStrategy::from_wire({unquoted:?}) must accept the \
9654 Serialize derive's wire byte-string for \
9655 RestartStrategy::{variant:?} — the four-path convergence \
9656 (Display + as_str + Serialize + from_wire) resolves through \
9657 the same lifted SUPERVISOR_ESTRATEGIA_* const; got None"
9658 )
9659 });
9660 assert_eq!(
9661 parsed, variant,
9662 "RestartStrategy::from_wire of the Serialize derive's wire \
9663 byte-string for RestartStrategy::{variant:?} must round-trip \
9664 to the same variant; got {parsed:?}"
9665 );
9666 }
9667 }
9668
9669 #[test]
9670 fn restart_strategy_try_from_str_routes_through_from_wire_accessor() {
9671 // Fail-before-pass-after byte-parity pin on the newly lifted
9672 // `impl TryFrom<&str> for RestartStrategy` — asserts the standard-
9673 // library trait impl and the substrate-primitive
9674 // [`RestartStrategy::from_wire`] `Option<Self>` accessor resolve to
9675 // the same four-arm accept-set across every arm the exhaustive
9676 // [`RestartStrategy::ALL`] slice enumerates. Any future silent
9677 // detour that routes the trait impl through a divergent projection
9678 // (a per-arm inline `match s { "OneForOne" => Ok(Self::OneForOne),
9679 // … }` re-inlining that opens a compile-time link to the un-
9680 // lifted arm-literal, a hypothetical `#[serde(rename_all = "…")]`
9681 // attribute drift that silently splits the wire byte-string from
9682 // every consumer that reaches for this typed dispatch, an
9683 // accidental swap onto the kebab-case dispatcher-catalog axis the
9684 // pre-existing [`std::str::FromStr`] impl parses through and which
9685 // would collide the two-axis wire/catalog split the sibling
9686 // [`RestartStrategy::from_wire`] doc block makes load-bearing)
9687 // trips at caixa-core test time under `assert_eq!` rather than at
9688 // a downstream `impl TryFrom<&str>`-bound consumer's silent split.
9689 // Sweeps every one of the four arms [`RestartStrategy::ALL`]
9690 // carries so no arm's projection is covered only by the sibling
9691 // method-named `from_wire` path. Peer of the sibling
9692 // [`crate::kind::tests::caixa_kind_try_from_str_routes_through_from_wire_accessor`]
9693 // (3c83606),
9694 // [`crate::dialeto::tests::caixa_dialeto_try_from_str_routes_through_from_wire_accessor`]
9695 // (bf33136), and the M3
9696 // [`crate::aplicacao::tests::placement_strategy_try_from_str_routes_through_from_wire_accessor`]
9697 // (6fd00cd) — extends the trait-idiomatic reverse-projection axis
9698 // onto the first M2-OTP-shape closed-set typed enum on the caixa
9699 // surface.
9700 for &variant in RestartStrategy::ALL {
9701 let wire = variant.as_str();
9702 assert_eq!(
9703 <RestartStrategy as TryFrom<&str>>::try_from(wire),
9704 Ok(variant),
9705 "TryFrom<&str> impl on RestartStrategy must round-trip \
9706 RestartStrategy::{variant:?}.as_str() = {wire:?} back to \
9707 Ok(RestartStrategy::{variant:?}) — divergence from \
9708 RestartStrategy::from_wire signals a silent detour off \
9709 the substrate-primitive accessor"
9710 );
9711 assert_eq!(
9712 <RestartStrategy as TryFrom<&str>>::try_from(wire).ok(),
9713 RestartStrategy::from_wire(wire),
9714 "TryFrom<&str> ok()-projection on {wire:?} must byte-equal \
9715 RestartStrategy::from_wire on the same input"
9716 );
9717 }
9718 }
9719
9720 #[test]
9721 fn restart_strategy_try_from_str_rejects_unknown_byte_strings() {
9722 // Rejection witness on the `impl TryFrom<&str> for
9723 // RestartStrategy` — sweeps a candidate set of byte-strings
9724 // outside the four-arm PascalCase wire accept-set the sibling
9725 // [`RestartStrategy::as_str`] emits and asserts every one lands on
9726 // `Err(())`, so a future accidental widening of the trait impl's
9727 // accept-set (a stray additional
9728 // `_ if s.eq_ignore_ascii_case("OneForOne") => Ok(…)` case-fold
9729 // path, a silent inclusion of the kebab-case dispatcher-catalog
9730 // byte-string the pre-existing [`std::str::FromStr`] impl the
9731 // [`gen_platform::FromStrKind`] derive installs parses onto the
9732 // wire axis — which would collide the two-axis
9733 // wire/dispatcher-catalog split the sibling
9734 // [`RestartStrategy::from_wire`] doc block makes load-bearing —
9735 // an English-rebrand or plural-arm silent alias that would
9736 // widen the wire accept-set past the OTP-canonical four) trips at
9737 // caixa-core test time. The candidate set includes the empty
9738 // string, whitespace-only padding, the kebab-case dispatcher-
9739 // catalog byte-strings on the sibling axis (a caller who confuses
9740 // the two axes trips here rather than at a downstream consumer's
9741 // silent reject), a lowercase / uppercase / mixed-case fold of
9742 // each PascalCase arm (a caller who assumes case-fold acceptance
9743 // trips here), leading/trailing whitespace padding, the trailing-
9744 // newline shape, quote-wrapped candidates, and a residual set of
9745 // plausible-but-wrong English rebrand candidates. Peer of the
9746 // sibling
9747 // [`crate::kind::tests::caixa_kind_try_from_str_rejects_unknown_byte_strings`]
9748 // (3c83606) and
9749 // [`crate::aplicacao::tests::placement_strategy_try_from_str_rejects_unknown_byte_strings`]
9750 // (6fd00cd) rejection witnesses.
9751 let rejected: &[&str] = &[
9752 "",
9753 " ",
9754 "\n",
9755 "\t",
9756 "one-for-one",
9757 "one-for-all",
9758 "rest-for-one",
9759 "simple-one-for-one",
9760 "oneforone",
9761 "one_for_one",
9762 "OneForOnes",
9763 "ONEFORONE",
9764 "oneforall",
9765 "restforone",
9766 "simpleoneforone",
9767 "OneForOne ",
9768 " OneForOne",
9769 " OneForAll ",
9770 "OneForOne\n",
9771 "RestForOne\t",
9772 "OneForEach",
9773 "AllForOne",
9774 "one for one",
9775 "\"OneForOne\"",
9776 "?",
9777 ];
9778 for &input in rejected {
9779 assert_eq!(
9780 <RestartStrategy as TryFrom<&str>>::try_from(input),
9781 Err(()),
9782 "TryFrom<&str> impl on RestartStrategy must reject the \
9783 non-wire byte-string {input:?} — silent acceptance signals \
9784 an accept-set widening off the paired \
9785 RestartStrategy::from_wire resolver"
9786 );
9787 }
9788 }
9789
9790 #[test]
9791 fn restart_strategy_try_from_str_and_from_wire_partition_the_accept_set() {
9792 // Cross-axis partition pin: the paired `TryFrom<&str>` and
9793 // `from_wire` reverse projections must resolve identically on
9794 // *every* input, not just the ones [`RestartStrategy::ALL`]
9795 // enumerates. Sweeps a mixed candidate set spanning accepted
9796 // (four-arm PascalCase wire byte-strings) and rejected (kebab-case
9797 // dispatcher-catalog byte-strings, empty, whitespace-padded,
9798 // quoted, English-rebrand candidates) inputs and asserts the
9799 // trait's `Result::ok()` projection byte-equals the method-named
9800 // resolver's `Option<Self>` return-shape on each, locking the two
9801 // paths together by construction so any future detour (a stray
9802 // `try_from` special-case that widens or narrows the accept-set
9803 // outside the paired `from_wire` resolver, an accidental swap
9804 // onto the kebab-case [`std::str::FromStr`] impl the
9805 // [`gen_platform::FromStrKind`] derive installs on the sibling
9806 // dispatcher-catalog axis) trips at caixa-core test time. Peer of
9807 // the sibling
9808 // [`crate::kind::tests::caixa_kind_try_from_str_and_from_wire_partition_the_accept_set`]
9809 // pin — extends the round-trip discipline onto the M2-OTP-shape
9810 // sibling-restart axis.
9811 let candidates: &[&str] = &[
9812 "OneForOne",
9813 "OneForAll",
9814 "RestForOne",
9815 "SimpleOneForOne",
9816 "",
9817 "one-for-one",
9818 "one-for-all",
9819 "rest-for-one",
9820 "simple-one-for-one",
9821 "oneforone",
9822 "unknown",
9823 "OneForOne ",
9824 " OneForOne",
9825 "\"OneForOne\"",
9826 "OneForEach",
9827 "?",
9828 ];
9829 for &input in candidates {
9830 let via_trait: Option<RestartStrategy> =
9831 <RestartStrategy as TryFrom<&str>>::try_from(input).ok();
9832 let via_method: Option<RestartStrategy> = RestartStrategy::from_wire(input);
9833 assert_eq!(
9834 via_trait, via_method,
9835 "TryFrom<&str> and from_wire must resolve identically on \
9836 input {input:?} — divergence signals the two reverse-\
9837 projection paths have drifted onto different accept-sets"
9838 );
9839 }
9840 }
9841
9842 #[test]
9843 fn restart_strategy_from_into_static_str_routes_through_as_str_accessor() {
9844 // Fail-before-pass-after byte-parity pin on the newly lifted
9845 // `impl From<RestartStrategy> for &'static str` — asserts the
9846 // standard-library trait impl and the substrate-primitive
9847 // [`RestartStrategy::as_str`] `pub const fn` accessor resolve to
9848 // the same four-arm emit-set across every arm the exhaustive
9849 // [`RestartStrategy::ALL`] slice enumerates. Any future silent
9850 // detour that routes the trait impl through a divergent
9851 // projection (a per-arm inline `match strategy { OneForOne =>
9852 // "OneForOne", … }` re-inlining that opens a compile-time link to
9853 // the un-lifted arm-literal, an accidental swap onto the sibling
9854 // kebab-case [`Self::discriminant`] dispatcher-catalog axis that
9855 // would collide the two-axis wire/catalog split the sibling
9856 // [`RestartStrategy::from_wire`] doc block makes load-bearing) trips
9857 // at caixa-core test time under `assert_eq!` rather than at a
9858 // downstream `impl Into<&'static str>`-bound consumer's silent
9859 // split. Sweeps every one of the four arms
9860 // [`RestartStrategy::ALL`] carries so no arm's projection is
9861 // covered only by the sibling method-named `as_str` /
9862 // [`std::fmt::Display`] / [`AsRef<str>`] paths. Materializes the
9863 // `<&'static str as From<RestartStrategy>>::from` output in a
9864 // `const`-shape binding to make the `'static` lifetime promise a
9865 // build-time invariant — a future accidental downgrade of any of
9866 // the four arms' [`crate::render::SUPERVISOR_ESTRATEGIA_*`]
9867 // constants to a non-`&'static str` (a `String::leak()`-produced
9868 // return, a `Box::leak`-cast) trips at caixa-core build time
9869 // rather than at a downstream `'static`-bound consumer.
9870 const ONE_FOR_ONE: &str = RestartStrategy::OneForOne.as_str();
9871 const ONE_FOR_ALL: &str = RestartStrategy::OneForAll.as_str();
9872 const REST_FOR_ONE: &str = RestartStrategy::RestForOne.as_str();
9873 const SIMPLE_ONE_FOR_ONE: &str = RestartStrategy::SimpleOneForOne.as_str();
9874 for &variant in RestartStrategy::ALL {
9875 let via_trait: &'static str = <&'static str as From<RestartStrategy>>::from(variant);
9876 let via_method: &'static str = variant.as_str();
9877 assert_eq!(
9878 via_trait, via_method,
9879 "From<RestartStrategy> for &'static str impl must round-trip \
9880 RestartStrategy::{variant:?} to the same lifted \
9881 SUPERVISOR_ESTRATEGIA_* const RestartStrategy::as_str returns — \
9882 divergence signals a silent detour off the substrate-primitive \
9883 accessor"
9884 );
9885 let via_into: &'static str = variant.into();
9886 assert_eq!(
9887 via_into, via_method,
9888 "Into<&'static str>::into on RestartStrategy::{variant:?} must \
9889 byte-equal RestartStrategy::as_str on the same input — the \
9890 blanket-derived Into shape must resolve to the same as_str \
9891 dispatch as the explicit From impl"
9892 );
9893 }
9894 assert_eq!(
9895 [ONE_FOR_ONE, ONE_FOR_ALL, REST_FOR_ONE, SIMPLE_ONE_FOR_ONE],
9896 [
9897 crate::render::SUPERVISOR_ESTRATEGIA_ONE_FOR_ONE,
9898 crate::render::SUPERVISOR_ESTRATEGIA_ONE_FOR_ALL,
9899 crate::render::SUPERVISOR_ESTRATEGIA_REST_FOR_ONE,
9900 crate::render::SUPERVISOR_ESTRATEGIA_SIMPLE_ONE_FOR_ONE,
9901 ],
9902 "const-context RestartStrategy::as_str must resolve to the four \
9903 lifted SUPERVISOR_ESTRATEGIA_* consts — a future accidental \
9904 downgrade of any arm to a non-const or non-static byte-string \
9905 breaks the `&'static str`-lifetime promise the paired \
9906 From<RestartStrategy> for &'static str impl carries by \
9907 construction"
9908 );
9909 }
9910
9911 #[test]
9912 fn restart_strategy_from_into_static_str_and_as_str_partition_the_emit_set() {
9913 // Cross-axis partition pin: the paired trait-idiomatic
9914 // `From<RestartStrategy> for &'static str` forward projection and
9915 // the method-named [`RestartStrategy::as_str`] forward projection
9916 // must resolve identically on *every* arm, not just the ones
9917 // named in the primary byte-parity pin above. Sweeps every
9918 // [`RestartStrategy::ALL`] arm and asserts the trait's `From::from`
9919 // output byte-equals the method-named accessor's return-value on
9920 // each, locking the two forward-projection paths together by
9921 // construction so any future detour (a stray `From` special-case
9922 // that lands on a divergent per-arm literal outside the paired
9923 // `as_str` dispatch, a hypothetical rebrand touching one axis
9924 // without the other) trips at caixa-core test time. Peer of the
9925 // sibling reverse-projection partition pin
9926 // [`restart_strategy_try_from_str_and_from_wire_partition_the_accept_set`]
9927 // — extends the round-trip discipline onto the trait-idiomatic
9928 // *forward* axis, closing the two-way `Self ↔ &'static str`
9929 // round-trip on the trait-idiomatic pair
9930 // (`From<Self> for &'static str` + `TryFrom<&str> for Self`) as
9931 // well as the pre-existing method-named pair
9932 // (`as_str` + `from_wire`).
9933 for &variant in RestartStrategy::ALL {
9934 let via_trait: &'static str = <&'static str as From<RestartStrategy>>::from(variant);
9935 let via_method: &'static str = variant.as_str();
9936 assert_eq!(
9937 via_trait, via_method,
9938 "From<RestartStrategy> for &'static str and \
9939 RestartStrategy::as_str must resolve identically on \
9940 RestartStrategy::{variant:?} — divergence signals the \
9941 two forward-projection paths have drifted onto different \
9942 emit-sets"
9943 );
9944 }
9945 // Round-trip witness: every arm's forward `From` output re-parses
9946 // through the paired trait-idiomatic reverse `TryFrom<&str>` back
9947 // to the original variant. Closes the two-way `RestartStrategy ↔
9948 // &'static str` round-trip on the trait-idiomatic axis pair,
9949 // mirroring the pre-existing method-named `as_str` + `from_wire`
9950 // round-trip on the substrate-primitive axis pair.
9951 for &variant in RestartStrategy::ALL {
9952 let emitted: &'static str = variant.into();
9953 let re_parsed: Result<RestartStrategy, ()> =
9954 <RestartStrategy as TryFrom<&str>>::try_from(emitted);
9955 assert_eq!(
9956 re_parsed,
9957 Ok(variant),
9958 "trait-idiomatic axis pair must round-trip \
9959 RestartStrategy::{variant:?} through `.into::<&'static \
9960 str>()` and back through `TryFrom<&str>` — a break signals \
9961 the forward-emit and reverse-parse axes have drifted onto \
9962 different vocabularies"
9963 );
9964 }
9965 }
9966
9967 #[test]
9968 fn restart_strategy_from_borrowed_into_static_str_routes_through_as_str_accessor() {
9969 // Fail-before-pass-after byte-parity pin on the newly lifted
9970 // `impl From<&RestartStrategy> for &'static str` — asserts the
9971 // borrowed-input standard-library trait impl and the substrate-
9972 // primitive [`RestartStrategy::as_str`] `pub const fn` accessor
9973 // resolve to the same four-arm emit-set across every arm the
9974 // exhaustive [`RestartStrategy::ALL`] slice enumerates. Rust's
9975 // `From` trait does not auto-derive the borrowed-input sibling
9976 // from a paired owned-input impl (no `impl<T, U> From<&T> for U
9977 // where T: Copy, U: From<T>` blanket in `core`), so the
9978 // borrowed-input axis is a distinct trait-idiomatic surface
9979 // that a `.iter().map(Into::into)` shape over
9980 // [`RestartStrategy::ALL`] (whose iterator yields
9981 // `&RestartStrategy`, not `RestartStrategy`) reaches through
9982 // this impl and no other — the paired owned-input
9983 // [`From<RestartStrategy>`] impl requires an explicit
9984 // `.copied()` / dereference before the trait fires.
9985 // Materializes the `<&'static str as
9986 // From<&RestartStrategy>>::from` output in a `const`-shape
9987 // binding to make the `'static` lifetime promise a build-time
9988 // invariant.
9989 const ONE_FOR_ONE: &str = RestartStrategy::OneForOne.as_str();
9990 const ONE_FOR_ALL: &str = RestartStrategy::OneForAll.as_str();
9991 const REST_FOR_ONE: &str = RestartStrategy::RestForOne.as_str();
9992 const SIMPLE_ONE_FOR_ONE: &str = RestartStrategy::SimpleOneForOne.as_str();
9993 for variant in RestartStrategy::ALL {
9994 let via_trait: &'static str = <&'static str as From<&RestartStrategy>>::from(variant);
9995 let via_method: &'static str = variant.as_str();
9996 assert_eq!(
9997 via_trait, via_method,
9998 "From<&RestartStrategy> for &'static str impl must \
9999 round-trip &RestartStrategy::{variant:?} to the same \
10000 lifted SUPERVISOR_ESTRATEGIA_* const \
10001 RestartStrategy::as_str returns — divergence signals a \
10002 silent detour off the substrate-primitive accessor"
10003 );
10004 let via_into: &'static str = variant.into();
10005 assert_eq!(
10006 via_into, via_method,
10007 "Into<&'static str>::into on &RestartStrategy::{variant:?} \
10008 must byte-equal RestartStrategy::as_str on the same input — \
10009 the blanket-derived Into shape must resolve to the same \
10010 as_str dispatch as the explicit From impl"
10011 );
10012 }
10013 assert_eq!(
10014 [ONE_FOR_ONE, ONE_FOR_ALL, REST_FOR_ONE, SIMPLE_ONE_FOR_ONE],
10015 [
10016 crate::render::SUPERVISOR_ESTRATEGIA_ONE_FOR_ONE,
10017 crate::render::SUPERVISOR_ESTRATEGIA_ONE_FOR_ALL,
10018 crate::render::SUPERVISOR_ESTRATEGIA_REST_FOR_ONE,
10019 crate::render::SUPERVISOR_ESTRATEGIA_SIMPLE_ONE_FOR_ONE,
10020 ],
10021 "const-context RestartStrategy::as_str must resolve to the \
10022 four lifted SUPERVISOR_ESTRATEGIA_* consts — the borrowed-\
10023 input From<&RestartStrategy> for &'static str impl inherits \
10024 its `'static` lifetime promise from the same accessor the \
10025 owned-input sibling routes through"
10026 );
10027 }
10028
10029 #[test]
10030 fn restart_strategy_from_owned_and_borrowed_into_static_str_agree_on_every_arm() {
10031 // Cross-axis partition pin: the paired trait-idiomatic
10032 // owned-input `From<RestartStrategy> for &'static str` (523157d
10033 // campaign-shape) and borrowed-input `From<&RestartStrategy> for
10034 // &'static str` (this lift) forward projections must resolve
10035 // identically on every arm, locking the two input-shape paths
10036 // together so any future detour trips at caixa-core test time.
10037 // Then a witness that a `.iter().map(Into::into)` pipe over
10038 // [`RestartStrategy::ALL`] (whose iterator yields
10039 // `&RestartStrategy`) materializes the four-arm accept-set
10040 // through the borrowed-input axis alone — the exact shape a
10041 // future wasm-operator per-supervisor sibling-restart-strategy
10042 // diagnostic line, a future substrate-wide per-arm diagnostic
10043 // column, or a
10044 // `HashMap::<&'static str, RestartStrategy>::from_iter(
10045 // RestartStrategy::ALL.iter().map(|s| (s.into(), *s)))`-style
10046 // per-strategy lookup reaches through — closing the two-way
10047 // owned/borrowed input-shape symmetry on the forward-projection
10048 // trait-idiomatic axis. Peer of the sibling
10049 // [`crate::dep::tests::dep_list_from_owned_and_borrowed_into_static_str_agree_on_every_arm`]
10050 // (64aa742) /
10051 // [`crate::kind::tests::caixa_kind_from_owned_and_borrowed_into_static_str_agree_on_every_arm`]
10052 // (5ab993a) /
10053 // [`crate::dialeto::tests::caixa_dialeto_from_owned_and_borrowed_into_static_str_agree_on_every_arm`]
10054 // (807b0b5) partition pins on the sibling closed-set typed-enum
10055 // discriminator axes — extends the borrowed-input axis
10056 // discipline onto the first M2 OTP-shape sibling-restart
10057 // closed-set typed enum on the caixa surface. Also closes the
10058 // direct two-way `&Self → &'static str → Self` round-trip via
10059 // the paired [`TryFrom<&str>`] axis — unlike the peer
10060 // [`crate::CaixaKind`] axis pair (whose forward `From` emits
10061 // lowercase Portuguese diagnostic bytes while the reverse
10062 // `TryFrom` parses `PascalCase` wire bytes, forcing the round-
10063 // trip through an intermediate wire-vocab hop), the
10064 // [`RestartStrategy::as_str`] emit and
10065 // [`RestartStrategy::from_wire`] parse share the same
10066 // `PascalCase` vocabulary by construction, so the borrowed-
10067 // input forward axis and the reverse axis compose directly.
10068 for &variant in RestartStrategy::ALL {
10069 let owned: &'static str = <&'static str as From<RestartStrategy>>::from(variant);
10070 let borrowed: &'static str = <&'static str as From<&RestartStrategy>>::from(&variant);
10071 assert_eq!(
10072 owned, borrowed,
10073 "From<RestartStrategy> and From<&RestartStrategy> for \
10074 &'static str must resolve identically on \
10075 RestartStrategy::{variant:?} — divergence signals the \
10076 owned-input and borrowed-input forward-projection paths \
10077 have drifted onto different emit-sets"
10078 );
10079 }
10080 let via_iter: Vec<&'static str> = RestartStrategy::ALL.iter().map(Into::into).collect();
10081 let via_method: Vec<&'static str> =
10082 RestartStrategy::ALL.iter().map(|s| s.as_str()).collect();
10083 assert_eq!(
10084 via_iter, via_method,
10085 "`.iter().map(Into::into)` over RestartStrategy::ALL must \
10086 byte-equal `.iter().map(|s| s.as_str())` on every arm — the \
10087 borrowed-input `From<&RestartStrategy> for &'static str` \
10088 axis is what makes the `.iter().map(Into::into)` shape route \
10089 through the substrate-primitive `RestartStrategy::as_str` \
10090 accessor rather than through a per-call-site `.copied()` / \
10091 dereference detour"
10092 );
10093 for variant in RestartStrategy::ALL {
10094 let emitted: &'static str = variant.into();
10095 let re_parsed: Result<RestartStrategy, ()> =
10096 <RestartStrategy as TryFrom<&str>>::try_from(emitted);
10097 assert_eq!(
10098 re_parsed,
10099 Ok(*variant),
10100 "trait-idiomatic borrowed-input forward-projection + \
10101 reverse-projection axis pair must round-trip \
10102 &RestartStrategy::{variant:?} through `.into::<&'static \
10103 str>()` (via the borrowed-input axis) and back through \
10104 `TryFrom<&str>` — a break signals the borrowed-input \
10105 forward-emit and reverse-parse axes have drifted onto \
10106 different vocabularies"
10107 );
10108 }
10109 }
10110
10111 #[test]
10112 fn restart_strategy_from_into_owned_string_routes_through_as_str_accessor() {
10113 // Fail-before-pass-after byte-parity pin on the newly lifted
10114 // `impl From<RestartStrategy> for String` — asserts the
10115 // owned-`String`-returning standard-library trait impl and the
10116 // substrate-primitive [`RestartStrategy::as_str`] `pub const fn`
10117 // accessor resolve to the same four-arm emit-set across every
10118 // arm the exhaustive [`RestartStrategy::ALL`] slice enumerates.
10119 // Rust's standard library does not carry a blanket
10120 // `impl<T: AsRef<str>> From<T> for String` (nor an
10121 // `impl<T: fmt::Display> From<T> for String`), so the
10122 // owned-`String` forward-projection axis is a distinct
10123 // trait-idiomatic surface that a
10124 // `let key: String = strategy.into();`-shaped call site
10125 // reaches through this impl and no other — the paired sibling
10126 // `From<RestartStrategy> for &'static str` impl forces every
10127 // owned-`String` call site through an explicit
10128 // `.to_owned()` / `String::from` restatement.
10129 for &variant in RestartStrategy::ALL {
10130 let via_trait: String = <String as From<RestartStrategy>>::from(variant);
10131 let via_method: &'static str = variant.as_str();
10132 assert_eq!(
10133 via_trait.as_str(),
10134 via_method,
10135 "From<RestartStrategy> for String impl must round-trip \
10136 RestartStrategy::{variant:?} to the same lifted \
10137 SUPERVISOR_ESTRATEGIA_* const RestartStrategy::as_str \
10138 returns — divergence signals a silent detour off the \
10139 substrate-primitive accessor"
10140 );
10141 let via_into: String = variant.into();
10142 assert_eq!(
10143 via_into.as_str(),
10144 via_method,
10145 "Into<String>::into on RestartStrategy::{variant:?} must \
10146 byte-equal RestartStrategy::as_str on the same input — the \
10147 blanket-derived Into shape must resolve to the same as_str \
10148 dispatch as the explicit From impl"
10149 );
10150 }
10151 }
10152
10153 #[test]
10154 fn restart_strategy_from_into_owned_string_and_static_str_agree_on_every_arm() {
10155 // Cross-axis partition pin: the paired trait-idiomatic
10156 // owned-`String` `From<RestartStrategy> for String` (this lift)
10157 // and owned-`&'static str` `From<RestartStrategy> for &'static
10158 // str` (523157d) forward projections must resolve identically
10159 // on every arm, locking the two return-type-shape paths
10160 // together so any future detour trips at caixa-core test time.
10161 // Also byte-parity witness against the sibling
10162 // [`ToString::to_string`] surface routed through
10163 // [`std::fmt::Display`] — the three owned-heap-string paths
10164 // (`.into::<String>()`, `String::from`, `.to_string()`) must
10165 // resolve identically on every arm so a future consumer that
10166 // picks any of the three lands on the same lifted
10167 // SUPERVISOR_ESTRATEGIA_* const. Then a direct round-trip
10168 // witness through the paired trait-idiomatic reverse
10169 // [`TryFrom<&str>`] axis on the owned-`String`'s
10170 // [`String::as_str`] borrow that closes the two-way
10171 // `Self → String → Self` round-trip on the trait-idiomatic
10172 // owned-`String` forward + reverse axis pair.
10173 for &variant in RestartStrategy::ALL {
10174 let owned_string: String = <String as From<RestartStrategy>>::from(variant);
10175 let owned_static: &'static str = <&'static str as From<RestartStrategy>>::from(variant);
10176 assert_eq!(
10177 owned_string.as_str(),
10178 owned_static,
10179 "From<RestartStrategy> for String and From<RestartStrategy> \
10180 for &'static str must resolve identically on \
10181 RestartStrategy::{variant:?} — divergence signals the \
10182 owned-`String` and owned-`&'static str` forward-projection \
10183 return-type-shape paths have drifted onto different \
10184 emit-sets"
10185 );
10186 let via_to_string: String = variant.to_string();
10187 assert_eq!(
10188 owned_string, via_to_string,
10189 "From<RestartStrategy> for String must byte-equal \
10190 RestartStrategy::to_string on RestartStrategy::{variant:?} — \
10191 divergence signals the trait-idiomatic owned-`String` \
10192 forward-projection axis and the ToString-through-Display \
10193 axis have drifted onto different emit-sets"
10194 );
10195 }
10196 let via_iter: Vec<String> = RestartStrategy::ALL
10197 .iter()
10198 .copied()
10199 .map(String::from)
10200 .collect();
10201 let via_method: Vec<String> = RestartStrategy::ALL
10202 .iter()
10203 .map(|s| s.as_str().to_owned())
10204 .collect();
10205 assert_eq!(
10206 via_iter, via_method,
10207 "`.iter().copied().map(String::from)` over RestartStrategy::ALL \
10208 must byte-equal `.iter().map(|s| s.as_str().to_owned())` on \
10209 every arm — the owned-`String` `From<RestartStrategy> for \
10210 String` axis is what makes the `String::from` composition \
10211 route through the substrate-primitive `RestartStrategy::as_str` \
10212 accessor rather than through a per-call-site `.to_owned()` / \
10213 `String::from(strategy.as_str())` detour"
10214 );
10215 for &variant in RestartStrategy::ALL {
10216 let emitted: String = variant.into();
10217 let re_parsed: Result<RestartStrategy, ()> =
10218 <RestartStrategy as TryFrom<&str>>::try_from(emitted.as_str());
10219 assert_eq!(
10220 re_parsed,
10221 Ok(variant),
10222 "trait-idiomatic owned-`String` forward-projection + \
10223 reverse-projection axis pair must round-trip \
10224 RestartStrategy::{variant:?} through `.into::<String>()` \
10225 and back through `TryFrom<&str>` on the owned-`String`'s \
10226 String::as_str borrow — a break signals the owned-`String` \
10227 forward-emit and reverse-parse axes have drifted onto \
10228 different vocabularies"
10229 );
10230 }
10231 }
10232
10233 #[test]
10234 fn restart_strategy_from_into_borrowed_owned_string_routes_through_as_str_accessor() {
10235 // Fail-before-pass-after byte-parity pin on the newly lifted
10236 // `impl From<&RestartStrategy> for String` — asserts the
10237 // borrowed-input owned-`String`-returning standard-library trait
10238 // impl and the substrate-primitive [`RestartStrategy::as_str`]
10239 // `pub const fn` accessor resolve to the same four-arm emit-set
10240 // across every arm the exhaustive [`RestartStrategy::ALL`] slice
10241 // enumerates. Rust's standard library does not carry a blanket
10242 // `impl<T: AsRef<str>> From<&T> for String` (nor an
10243 // `impl<T: fmt::Display> From<&T> for String`), so the
10244 // borrowed-input owned-`String` forward-projection axis is a
10245 // distinct trait-idiomatic surface that a
10246 // `let key: String = (&strategy).into();`-shaped call site
10247 // reaches through this impl and no other — the paired sibling
10248 // `From<RestartStrategy> for String` impl forces every
10249 // borrowed-input call site through an explicit `Copy` deref
10250 // (`String::from(*strategy)`) or an `.as_str().to_owned()` /
10251 // `.to_string()` detour.
10252 for &variant in RestartStrategy::ALL {
10253 let via_trait: String = <String as From<&RestartStrategy>>::from(&variant);
10254 let via_method: &'static str = variant.as_str();
10255 assert_eq!(
10256 via_trait.as_str(),
10257 via_method,
10258 "From<&RestartStrategy> for String impl must round-trip \
10259 &RestartStrategy::{variant:?} to the same lifted \
10260 SUPERVISOR_ESTRATEGIA_* const RestartStrategy::as_str \
10261 returns — divergence signals a silent detour off the \
10262 substrate-primitive accessor"
10263 );
10264 let via_into: String = (&variant).into();
10265 assert_eq!(
10266 via_into.as_str(),
10267 via_method,
10268 "Into<String>::into on &RestartStrategy::{variant:?} must \
10269 byte-equal RestartStrategy::as_str on the same input — the \
10270 blanket-derived Into shape must resolve to the same as_str \
10271 dispatch as the explicit From impl"
10272 );
10273 }
10274 }
10275
10276 #[test]
10277 fn restart_strategy_from_into_borrowed_owned_string_agrees_with_paired_axes_on_every_arm() {
10278 // Cross-axis partition pin: the newly lifted trait-idiomatic
10279 // borrowed-input owned-`String` `From<&RestartStrategy> for
10280 // String` (this lift), the paired owned-input owned-`String`
10281 // `From<RestartStrategy> for String` (7baa18a), the paired
10282 // borrowed-input owned-`&'static str` `From<&RestartStrategy>
10283 // for &'static str` (e941836), and the paired owned-input
10284 // owned-`&'static str` `From<RestartStrategy> for &'static str`
10285 // (523157d) — every corner of the `{Self, &Self} × {&'static
10286 // str, String}` 2×2 trait-idiomatic projection family — must
10287 // resolve identically on every arm, locking the four
10288 // return-shape × input-shape paths together so any future
10289 // detour trips at caixa-core test time. Also byte-parity
10290 // witness against the sibling [`ToString::to_string`] surface
10291 // routed through [`std::fmt::Display`] and a direct round-trip
10292 // witness through the paired trait-idiomatic reverse
10293 // [`TryFrom<&str>`] axis on the owned-`String`'s
10294 // [`String::as_str`] borrow that closes the two-way
10295 // `&Self → String → Self` round-trip on the trait-idiomatic
10296 // borrowed-input owned-`String` forward + reverse axis pair.
10297 for &variant in RestartStrategy::ALL {
10298 let borrowed_string: String = <String as From<&RestartStrategy>>::from(&variant);
10299 let owned_string: String = <String as From<RestartStrategy>>::from(variant);
10300 let borrowed_static: &'static str =
10301 <&'static str as From<&RestartStrategy>>::from(&variant);
10302 let owned_static: &'static str = <&'static str as From<RestartStrategy>>::from(variant);
10303 assert_eq!(
10304 borrowed_string, owned_string,
10305 "From<&RestartStrategy> for String and From<RestartStrategy> \
10306 for String must resolve identically on \
10307 RestartStrategy::{variant:?} — divergence signals the \
10308 borrowed-input and owned-input owned-`String` \
10309 forward-projection input-shape paths have drifted onto \
10310 different emit-sets"
10311 );
10312 assert_eq!(
10313 borrowed_string.as_str(),
10314 borrowed_static,
10315 "From<&RestartStrategy> for String and From<&RestartStrategy> \
10316 for &'static str must resolve identically on \
10317 RestartStrategy::{variant:?} — divergence signals the \
10318 borrowed-input `&'static str` and owned-`String` \
10319 return-shape paths have drifted onto different emit-sets"
10320 );
10321 assert_eq!(
10322 borrowed_string.as_str(),
10323 owned_static,
10324 "From<&RestartStrategy> for String and From<RestartStrategy> \
10325 for &'static str must resolve identically on \
10326 RestartStrategy::{variant:?} — divergence signals a break \
10327 in the diagonal corner of the {{Self, &Self}} × \
10328 {{&'static str, String}} 2×2 trait-idiomatic \
10329 projection family"
10330 );
10331 let via_to_string: String = variant.to_string();
10332 assert_eq!(
10333 borrowed_string, via_to_string,
10334 "From<&RestartStrategy> for String must byte-equal \
10335 RestartStrategy::to_string on RestartStrategy::{variant:?} — \
10336 divergence signals the trait-idiomatic borrowed-input \
10337 owned-`String` forward-projection axis and the \
10338 ToString-through-Display axis have drifted onto different \
10339 emit-sets"
10340 );
10341 }
10342 let via_iter: Vec<String> = RestartStrategy::ALL.iter().map(String::from).collect();
10343 let via_method: Vec<String> = RestartStrategy::ALL
10344 .iter()
10345 .map(|s| s.as_str().to_owned())
10346 .collect();
10347 assert_eq!(
10348 via_iter, via_method,
10349 "`.iter().map(String::from)` over RestartStrategy::ALL — a \
10350 call site whose iteration axis holds `&RestartStrategy` by \
10351 construction — must byte-equal `.iter().map(|s| \
10352 s.as_str().to_owned())` on every arm — the borrowed-input \
10353 owned-`String` `From<&RestartStrategy> for String` axis is \
10354 what makes the `String::from` composition route through the \
10355 substrate-primitive `RestartStrategy::as_str` accessor \
10356 without a spurious `Copy` deref (which would only be \
10357 reachable through the owned-input `From<RestartStrategy> for \
10358 String` axis by first calling `.copied()` on the iterator)"
10359 );
10360 for &variant in RestartStrategy::ALL {
10361 let emitted: String = (&variant).into();
10362 let re_parsed: Result<RestartStrategy, ()> =
10363 <RestartStrategy as TryFrom<&str>>::try_from(emitted.as_str());
10364 assert_eq!(
10365 re_parsed,
10366 Ok(variant),
10367 "trait-idiomatic borrowed-input owned-`String` \
10368 forward-projection + reverse-projection axis pair must \
10369 round-trip &RestartStrategy::{variant:?} through \
10370 `.into::<String>()` on the borrowed-input surface and \
10371 back through `TryFrom<&str>` on the owned-`String`'s \
10372 String::as_str borrow — a break signals the \
10373 borrowed-input owned-`String` forward-emit and \
10374 reverse-parse axes have drifted onto different \
10375 vocabularies"
10376 );
10377 }
10378 }
10379
10380 #[test]
10381 fn restart_strategy_from_into_static_cow_str_routes_through_as_str_accessor() {
10382 // Fail-before-pass-after byte-parity pin on the newly lifted
10383 // `impl From<RestartStrategy> for std::borrow::Cow<'static, str>` —
10384 // asserts the standard-library trait impl and the substrate-
10385 // primitive [`super::RestartStrategy::as_str`] `pub const fn`
10386 // accessor resolve to the same four-arm emit-set across every
10387 // arm the exhaustive [`super::RestartStrategy::ALL`] slice
10388 // enumerates. Rust's standard library does not carry a blanket
10389 // `impl<T: AsRef<str>> From<T> for Cow<'static, str>` (nor an
10390 // `impl<T: fmt::Display> From<T> for Cow<'static, str>`), so
10391 // the `Cow<'static, str>` forward-projection axis is a
10392 // distinct trait-idiomatic surface that a
10393 // `let key: Cow<'static, str> = strategy.into();`-shaped call
10394 // site reaches through this impl and no other — the paired
10395 // sibling `From<RestartStrategy> for &'static str` and
10396 // `From<RestartStrategy> for String` impls force every
10397 // `Cow<'static, str>`-parameterized call site through a
10398 // `Cow::Borrowed(strategy.as_str())` /
10399 // `Cow::Owned(strategy.to_string())` composition whose type
10400 // bounds have no compile-time link back to the substrate
10401 // primitive.
10402 //
10403 // Also asserts the projection lands on the zero-alloc
10404 // [`std::borrow::Cow::Borrowed`] arm (not the
10405 // [`std::borrow::Cow::Owned`] arm) — the substrate-primitive
10406 // [`super::RestartStrategy::as_str`] accessor's `&'static str`
10407 // return lifetime by construction makes the borrowed arm the
10408 // type-correct projection with no runtime allocation. Any
10409 // future silent detour that routes the impl through the owned
10410 // arm (an accidental `Cow::Owned(strategy.to_string())` rewrite
10411 // that would allocate on every call site where the
10412 // `&'static str` return of [`super::RestartStrategy::as_str`]
10413 // makes the zero-alloc borrowed projection type-correct) trips
10414 // at caixa-core test time under the
10415 // [`std::borrow::Cow::Borrowed`] discriminator witness rather
10416 // than at a downstream `Cow<'static, str>`-bound consumer's
10417 // silent allocation.
10418 //
10419 // First peer on the substrate-wide trait-idiomatic
10420 // [`std::borrow::Cow<'static, str>`] forward-projection family
10421 // to extend the axis off the top-level [`super::CaixaKind`]
10422 // enum (99c1735 owned-input, d45c409 borrowed-input) onto the
10423 // first M2 OTP-shape closed-set fieldless typed enum on the
10424 // caixa surface.
10425 for &variant in RestartStrategy::ALL {
10426 let via_trait: std::borrow::Cow<'static, str> =
10427 <std::borrow::Cow<'static, str> as From<RestartStrategy>>::from(variant);
10428 let via_method: &'static str = variant.as_str();
10429 assert_eq!(
10430 via_trait.as_ref(),
10431 via_method,
10432 "From<RestartStrategy> for Cow<'static, str> impl must \
10433 round-trip RestartStrategy::{variant:?} to the same \
10434 lifted SUPERVISOR_ESTRATEGIA_* const \
10435 RestartStrategy::as_str returns — divergence signals a \
10436 silent detour off the substrate-primitive accessor"
10437 );
10438 assert!(
10439 matches!(via_trait, std::borrow::Cow::Borrowed(_)),
10440 "From<RestartStrategy> for Cow<'static, str> impl must \
10441 land on the zero-alloc Cow::Borrowed arm on \
10442 RestartStrategy::{variant:?} — a Cow::Owned outcome \
10443 signals the projection has silently allocated where \
10444 the substrate-primitive RestartStrategy::as_str \
10445 `&'static str` return makes the borrowed arm the \
10446 type-correct projection"
10447 );
10448 let via_into: std::borrow::Cow<'static, str> = variant.into();
10449 assert_eq!(
10450 via_into.as_ref(),
10451 via_method,
10452 "Into<Cow<'static, str>>::into on \
10453 RestartStrategy::{variant:?} must byte-equal \
10454 RestartStrategy::as_str on the same input — the \
10455 blanket-derived Into shape must resolve to the same \
10456 as_str dispatch as the explicit From impl"
10457 );
10458 assert!(
10459 matches!(via_into, std::borrow::Cow::Borrowed(_)),
10460 "Into<Cow<'static, str>>::into on \
10461 RestartStrategy::{variant:?} must land on the \
10462 zero-alloc Cow::Borrowed arm — the blanket-derived \
10463 Into shape must resolve to the same Cow::Borrowed \
10464 dispatch as the explicit From impl"
10465 );
10466 }
10467 }
10468
10469 #[test]
10470 fn restart_strategy_from_into_static_cow_str_agrees_with_paired_axes_on_every_arm() {
10471 // Cross-axis partition pin: the newly lifted trait-idiomatic
10472 // `From<RestartStrategy> for std::borrow::Cow<'static, str>`
10473 // (this lift), the paired owned-input `From<RestartStrategy>
10474 // for &'static str` (523157d), and the paired owned-input
10475 // `From<RestartStrategy> for String` (7baa18a) forward
10476 // projections must resolve identically on every arm, locking
10477 // the three return-shape paths together by construction so any
10478 // future detour trips at caixa-core test time. Also byte-parity
10479 // witness against the sibling [`ToString::to_string`] surface
10480 // routed through [`std::fmt::Display`] — every owned-heap-
10481 // string path (the `Cow::Owned` promotion of this axis's
10482 // `.into_owned()`, `From<RestartStrategy> for String`, and
10483 // `.to_string()`) resolves to the same lifted
10484 // [`crate::render::SUPERVISOR_ESTRATEGIA_*`] const per arm.
10485 //
10486 // Then a `.iter().copied().map(std::borrow::Cow::from)` pipe
10487 // witness over [`super::RestartStrategy::ALL`] that
10488 // materializes the four-arm accept-set through the
10489 // [`std::borrow::Cow<'static, str>`] axis alone — the exact
10490 // shape a future `axum::response::IntoResponse` per-strategy
10491 // rejection-body composer, a future M4 admission-webhook
10492 // per-strategy rejection-reason emitter whose typing rules out
10493 // the sibling [`AsRef<str>`] borrowed return, or a future
10494 // substrate-wide per-strategy diagnostic surface that binds
10495 // through a [`Cow<'static, str>`] boundary reaches through.
10496 // The pipe witness also pins the zero-alloc discipline: every
10497 // element in the collected vector satisfies the
10498 // [`std::borrow::Cow::Borrowed`] arm predicate, so a future
10499 // accidental silent-allocation regression on the pipe's
10500 // iteration axis is a caixa-core-test-time failure.
10501 for &variant in RestartStrategy::ALL {
10502 let via_cow: std::borrow::Cow<'static, str> =
10503 <std::borrow::Cow<'static, str> as From<RestartStrategy>>::from(variant);
10504 let via_static: &'static str = <&'static str as From<RestartStrategy>>::from(variant);
10505 let via_string: String = <String as From<RestartStrategy>>::from(variant);
10506 assert_eq!(
10507 via_cow.as_ref(),
10508 via_static,
10509 "From<RestartStrategy> for Cow<'static, str> and \
10510 From<RestartStrategy> for &'static str must resolve \
10511 identically on RestartStrategy::{variant:?} — \
10512 divergence signals the Cow<'static, str> and \
10513 &'static str return-shape paths have drifted onto \
10514 different emit-sets"
10515 );
10516 assert_eq!(
10517 via_cow.as_ref(),
10518 via_string.as_str(),
10519 "From<RestartStrategy> for Cow<'static, str> and \
10520 From<RestartStrategy> for String must resolve \
10521 identically on RestartStrategy::{variant:?} — \
10522 divergence signals the Cow<'static, str> and String \
10523 return-shape paths have drifted onto different \
10524 emit-sets"
10525 );
10526 let via_to_string: String = variant.to_string();
10527 assert_eq!(
10528 via_cow.as_ref(),
10529 via_to_string.as_str(),
10530 "From<RestartStrategy> for Cow<'static, str> must \
10531 byte-equal RestartStrategy::to_string on \
10532 RestartStrategy::{variant:?} — divergence signals the \
10533 trait-idiomatic Cow<'static, str> forward-projection \
10534 axis and the ToString-through-Display axis have \
10535 drifted onto different emit-sets"
10536 );
10537 }
10538 let via_iter: Vec<std::borrow::Cow<'static, str>> = RestartStrategy::ALL
10539 .iter()
10540 .copied()
10541 .map(std::borrow::Cow::from)
10542 .collect();
10543 let via_method: Vec<std::borrow::Cow<'static, str>> = RestartStrategy::ALL
10544 .iter()
10545 .map(|s| std::borrow::Cow::Borrowed(s.as_str()))
10546 .collect();
10547 assert_eq!(
10548 via_iter, via_method,
10549 "`.iter().copied().map(Cow::from)` over \
10550 RestartStrategy::ALL must byte-equal `.iter().map(|s| \
10551 Cow::Borrowed(s.as_str()))` on every arm — the \
10552 trait-idiomatic `From<RestartStrategy> for Cow<'static, \
10553 str>` axis is what makes the `Cow::from` composition \
10554 route through the substrate-primitive \
10555 `RestartStrategy::as_str` accessor with the zero-alloc \
10556 Cow::Borrowed arm by construction, rather than a \
10557 per-call-site `Cow::Owned(strategy.to_string())` \
10558 allocation"
10559 );
10560 for cow in &via_iter {
10561 assert!(
10562 matches!(cow, std::borrow::Cow::Borrowed(_)),
10563 "every element of the \
10564 .iter().copied().map(Cow::from) pipe over \
10565 RestartStrategy::ALL must land on the zero-alloc \
10566 Cow::Borrowed arm — a Cow::Owned outcome on any arm \
10567 signals the pipe's iteration axis has silently \
10568 allocated where the substrate-primitive \
10569 RestartStrategy::as_str `&'static str` return makes \
10570 the borrowed arm the type-correct projection"
10571 );
10572 }
10573 }
10574
10575 #[test]
10576 fn restart_strategy_from_borrowed_into_static_cow_str_routes_through_as_str_accessor() {
10577 // Fail-before-pass-after byte-parity pin on the newly lifted
10578 // `impl From<&RestartStrategy> for std::borrow::Cow<'static, str>` —
10579 // asserts the borrowed-input standard-library trait impl and
10580 // the substrate-primitive [`super::RestartStrategy::as_str`]
10581 // `pub const fn` accessor resolve to the same four-arm emit-
10582 // set across every arm the exhaustive
10583 // [`super::RestartStrategy::ALL`] slice enumerates. Rust's
10584 // standard library does not carry a blanket
10585 // `impl<T: AsRef<str>> From<&T> for Cow<'static, str>` (nor a
10586 // `Copy`-based `impl<T: Copy, U: From<T>> From<&T> for U`), so
10587 // the borrowed-input `Cow<'static, str>` forward-projection
10588 // axis is a distinct trait-idiomatic surface that a
10589 // `let key: Cow<'static, str> = (&strategy).into();`-shaped
10590 // call site or a
10591 // `RestartStrategy::ALL.iter().map(Cow::from)`-shaped pipe
10592 // reaches through this impl and no other — the paired owned-
10593 // input `From<RestartStrategy> for Cow<'static, str>` impl
10594 // (7dd28b3) forces every borrowed-input call site through an
10595 // explicit `Copy` deref (`Cow::from(*strategy)`) or a
10596 // `Cow::Borrowed(strategy.as_str())` open-code whose type
10597 // bounds have no compile-time link back to the substrate
10598 // primitive.
10599 //
10600 // Also asserts the projection lands on the zero-alloc
10601 // [`std::borrow::Cow::Borrowed`] arm (not the
10602 // [`std::borrow::Cow::Owned`] arm) — the substrate-primitive
10603 // [`super::RestartStrategy::as_str`] accessor's `&'static str`
10604 // return lifetime by construction makes the borrowed arm the
10605 // type-correct projection with no runtime allocation on the
10606 // borrowed-input surface just as on the paired owned-input
10607 // surface.
10608 //
10609 // Second peer on the substrate-wide trait-idiomatic
10610 // [`std::borrow::Cow<'static, str>`] forward-projection family
10611 // on this enum — closes the `{Self, &Self}` input-shape
10612 // corner of the [`Cow<'static, str>`] axis on the first M2
10613 // OTP-shape closed-set fieldless typed enum peer on the caixa
10614 // surface (`:supervisor :estrategia`), exactly as d45c409
10615 // closed it on the top-level [`super::CaixaKind`] one commit
10616 // after the owning half (99c1735) landed. Every future
10617 // closed-set fieldless typed enum peer on the substrate is a
10618 // future target of the campaign.
10619 for &variant in RestartStrategy::ALL {
10620 let via_trait: std::borrow::Cow<'static, str> =
10621 <std::borrow::Cow<'static, str> as From<&RestartStrategy>>::from(&variant);
10622 let via_method: &'static str = variant.as_str();
10623 assert_eq!(
10624 via_trait.as_ref(),
10625 via_method,
10626 "From<&RestartStrategy> for Cow<'static, str> impl must \
10627 round-trip &RestartStrategy::{variant:?} to the same \
10628 lifted SUPERVISOR_ESTRATEGIA_* const \
10629 RestartStrategy::as_str returns — divergence signals a \
10630 silent detour off the substrate-primitive accessor"
10631 );
10632 assert!(
10633 matches!(via_trait, std::borrow::Cow::Borrowed(_)),
10634 "From<&RestartStrategy> for Cow<'static, str> impl must \
10635 land on the zero-alloc Cow::Borrowed arm on \
10636 &RestartStrategy::{variant:?} — a Cow::Owned outcome \
10637 signals the projection has silently allocated where \
10638 the substrate-primitive RestartStrategy::as_str \
10639 `&'static str` return makes the borrowed arm the \
10640 type-correct projection"
10641 );
10642 let via_into: std::borrow::Cow<'static, str> = (&variant).into();
10643 assert_eq!(
10644 via_into.as_ref(),
10645 via_method,
10646 "Into<Cow<'static, str>>::into on \
10647 &RestartStrategy::{variant:?} must byte-equal \
10648 RestartStrategy::as_str on the same input — the \
10649 blanket-derived Into shape must resolve to the same \
10650 as_str dispatch as the explicit From impl"
10651 );
10652 assert!(
10653 matches!(via_into, std::borrow::Cow::Borrowed(_)),
10654 "Into<Cow<'static, str>>::into on \
10655 &RestartStrategy::{variant:?} must land on the \
10656 zero-alloc Cow::Borrowed arm — the blanket-derived \
10657 Into shape must resolve to the same Cow::Borrowed \
10658 dispatch as the explicit From impl"
10659 );
10660 }
10661 }
10662
10663 #[test]
10664 fn restart_strategy_from_borrowed_into_static_cow_str_agrees_with_paired_axes_on_every_arm() {
10665 // Cross-axis partition pin: the newly lifted trait-idiomatic
10666 // borrowed-input `From<&RestartStrategy> for
10667 // std::borrow::Cow<'static, str>` (this lift), the paired
10668 // owned-input `From<RestartStrategy> for
10669 // std::borrow::Cow<'static, str>` (7dd28b3), the paired
10670 // borrowed-input owned-`&'static str` `From<&RestartStrategy>
10671 // for &'static str`, and the paired borrowed-input owned-
10672 // `String` `From<&RestartStrategy> for String` must resolve
10673 // identically on every arm, locking the four
10674 // return-shape × input-shape paths together by construction so
10675 // any future detour trips at caixa-core test time. Also byte-
10676 // parity witness against the sibling [`ToString::to_string`]
10677 // surface routed through [`std::fmt::Display`] — every owned-
10678 // heap-string path (this axis's `.into_owned()` promotion, the
10679 // paired [`From<&RestartStrategy> for String`], and
10680 // `.to_string()`) resolves to the same lifted
10681 // [`crate::render::SUPERVISOR_ESTRATEGIA_*`] const per arm.
10682 //
10683 // Then a `.iter().map(std::borrow::Cow::from)` pipe witness
10684 // over [`super::RestartStrategy::ALL`] — whose iterator yields
10685 // `&RestartStrategy` by construction, so the borrowed-input
10686 // [`Cow<'static, str>`] axis is what routes the pipe through
10687 // the substrate-primitive [`super::RestartStrategy::as_str`]
10688 // accessor without a spurious [`Copy`] deref (which would only
10689 // be reachable through the owned-input
10690 // [`From<RestartStrategy> for Cow<'static, str>`] axis by
10691 // first calling `.copied()` on the iterator). The pipe witness
10692 // also pins the zero-alloc discipline: every element in the
10693 // collected vector satisfies the [`std::borrow::Cow::Borrowed`]
10694 // arm predicate, so a future accidental silent-allocation
10695 // regression on the pipe's iteration axis is a caixa-core-
10696 // test-time failure.
10697 for &strategy in RestartStrategy::ALL {
10698 let borrowed_cow: std::borrow::Cow<'static, str> =
10699 <std::borrow::Cow<'static, str> as From<&RestartStrategy>>::from(&strategy);
10700 let owned_cow: std::borrow::Cow<'static, str> =
10701 <std::borrow::Cow<'static, str> as From<RestartStrategy>>::from(strategy);
10702 let borrowed_static: &'static str =
10703 <&'static str as From<&RestartStrategy>>::from(&strategy);
10704 let borrowed_string: String = <String as From<&RestartStrategy>>::from(&strategy);
10705 assert_eq!(
10706 borrowed_cow, owned_cow,
10707 "From<&RestartStrategy> for Cow<'static, str> and \
10708 From<RestartStrategy> for Cow<'static, str> must \
10709 resolve identically on RestartStrategy::{strategy:?} — \
10710 divergence signals the borrowed-input and owned-input \
10711 Cow<'static, str> forward-projection input-shape \
10712 paths have drifted onto different emit-sets"
10713 );
10714 assert_eq!(
10715 borrowed_cow.as_ref(),
10716 borrowed_static,
10717 "From<&RestartStrategy> for Cow<'static, str> and \
10718 From<&RestartStrategy> for &'static str must resolve \
10719 identically on RestartStrategy::{strategy:?} — \
10720 divergence signals the borrowed-input Cow<'static, \
10721 str> and &'static str return-shape paths have drifted \
10722 onto different emit-sets"
10723 );
10724 assert_eq!(
10725 borrowed_cow.as_ref(),
10726 borrowed_string.as_str(),
10727 "From<&RestartStrategy> for Cow<'static, str> and \
10728 From<&RestartStrategy> for String must resolve \
10729 identically on RestartStrategy::{strategy:?} — \
10730 divergence signals the borrowed-input Cow<'static, \
10731 str> and owned-`String` return-shape paths have \
10732 drifted onto different emit-sets"
10733 );
10734 let via_to_string: String = strategy.to_string();
10735 assert_eq!(
10736 borrowed_cow.as_ref(),
10737 via_to_string.as_str(),
10738 "From<&RestartStrategy> for Cow<'static, str> must \
10739 byte-equal RestartStrategy::to_string on \
10740 RestartStrategy::{strategy:?} — divergence signals \
10741 the trait-idiomatic borrowed-input Cow<'static, str> \
10742 forward-projection axis and the ToString-through-\
10743 Display axis have drifted onto different emit-sets"
10744 );
10745 }
10746 let via_iter: Vec<std::borrow::Cow<'static, str>> = RestartStrategy::ALL
10747 .iter()
10748 .map(std::borrow::Cow::from)
10749 .collect();
10750 let via_method: Vec<std::borrow::Cow<'static, str>> = RestartStrategy::ALL
10751 .iter()
10752 .map(|s| std::borrow::Cow::Borrowed(s.as_str()))
10753 .collect();
10754 assert_eq!(
10755 via_iter, via_method,
10756 "`.iter().map(Cow::from)` over RestartStrategy::ALL — a \
10757 call site whose iteration axis holds `&RestartStrategy` \
10758 by construction — must byte-equal `.iter().map(|s| \
10759 Cow::Borrowed(s.as_str()))` on every arm — the borrowed-\
10760 input Cow<'static, str> `From<&RestartStrategy> for \
10761 Cow<'static, str>` axis is what makes the `Cow::from` \
10762 composition route through the substrate-primitive \
10763 `RestartStrategy::as_str` accessor with the zero-alloc \
10764 Cow::Borrowed arm by construction and without a spurious \
10765 `Copy` deref (which would only be reachable through the \
10766 owned-input `From<RestartStrategy> for Cow<'static, str>` \
10767 axis by first calling `.copied()` on the iterator)"
10768 );
10769 for cow in &via_iter {
10770 assert!(
10771 matches!(cow, std::borrow::Cow::Borrowed(_)),
10772 "every element of the .iter().map(Cow::from) pipe \
10773 over RestartStrategy::ALL must land on the zero-\
10774 alloc Cow::Borrowed arm — a Cow::Owned outcome on \
10775 any arm signals the pipe's iteration axis has \
10776 silently allocated where the substrate-primitive \
10777 RestartStrategy::as_str `&'static str` return makes \
10778 the borrowed arm the type-correct projection"
10779 );
10780 }
10781 }
10782
10783 #[test]
10784 fn restart_strategy_from_into_box_str_routes_through_as_str_accessor() {
10785 // Fail-before-pass-after byte-parity pin on the newly lifted
10786 // `impl From<RestartStrategy> for Box<str>` — asserts the
10787 // owned-input standard-library trait impl and the
10788 // substrate-primitive [`super::RestartStrategy::as_str`]
10789 // `pub const fn` accessor resolve to the same four-arm emit-
10790 // set across every arm the exhaustive
10791 // [`super::RestartStrategy::ALL`] slice enumerates. Opens the
10792 // substrate-wide `Box<str>` forward-projection campaign tier
10793 // on the first M2 OTP-shape closed-set fieldless typed enum
10794 // peer on the caixa surface (`:supervisor :estrategia`),
10795 // immediately after the paired `Cow<'static, str>` axis
10796 // (7dd28b3 / ee577fd) closed the
10797 // `{Self, &Self} × {&'static str, String, Cow<'static, str>}`
10798 // 2×3 corner on this enum. Rust's standard library carries
10799 // `impl From<&str> for Box<str>` and
10800 // `impl From<String> for Box<str>` but no blanket
10801 // `impl<T: AsRef<str>> From<T> for Box<str>`, so this axis is
10802 // a distinct trait-idiomatic surface that a
10803 // `let key: Box<str> = strategy.into();`-shaped call site
10804 // reaches through this impl and no other — a paired
10805 // `Box::from(strategy.as_str())` open-code has no compile-
10806 // time link back to the substrate primitive.
10807 for &variant in RestartStrategy::ALL {
10808 let via_trait: Box<str> = <Box<str> as From<RestartStrategy>>::from(variant);
10809 let via_method: &'static str = variant.as_str();
10810 assert_eq!(
10811 via_trait.as_ref(),
10812 via_method,
10813 "From<RestartStrategy> for Box<str> impl must round-\
10814 trip RestartStrategy::{variant:?} to the same lifted \
10815 SUPERVISOR_ESTRATEGIA_* const RestartStrategy::as_str \
10816 returns — divergence signals a silent detour off the \
10817 substrate-primitive accessor"
10818 );
10819 let via_into: Box<str> = variant.into();
10820 assert_eq!(
10821 via_into.as_ref(),
10822 via_method,
10823 "Into<Box<str>>::into on RestartStrategy::{variant:?} \
10824 must byte-equal RestartStrategy::as_str on the same \
10825 input — the blanket-derived Into shape must resolve \
10826 to the same as_str dispatch as the explicit From impl"
10827 );
10828 }
10829 }
10830
10831 #[test]
10832 fn restart_strategy_from_borrowed_into_box_str_routes_through_as_str_accessor() {
10833 // Fail-before-pass-after byte-parity pin on the newly lifted
10834 // `impl From<&RestartStrategy> for Box<str>` — asserts the
10835 // borrowed-input standard-library trait impl and the
10836 // substrate-primitive [`super::RestartStrategy::as_str`]
10837 // `pub const fn` accessor resolve to the same four-arm emit-
10838 // set across every arm the exhaustive
10839 // [`super::RestartStrategy::ALL`] slice enumerates. Rust's
10840 // standard library does not carry a blanket
10841 // `impl<T: AsRef<str>> From<&T> for Box<str>` (nor a
10842 // `Copy`-based `impl<T: Copy, U: From<T>> From<&T> for U`),
10843 // so the borrowed-input `Box<str>` forward-projection axis
10844 // is a distinct trait-idiomatic surface that a
10845 // `let key: Box<str> = (&strategy).into();`-shaped call site
10846 // or a `RestartStrategy::ALL.iter().map(Box::<str>::from)`-
10847 // shaped pipe reaches through this impl and no other — the
10848 // paired owned-input `From<RestartStrategy> for Box<str>`
10849 // impl (69ef45c) forces every borrowed-input call site
10850 // through an explicit `Copy` deref
10851 // (`Box::<str>::from((*strategy).as_str())`) or a
10852 // `Box::<str>::from(strategy.as_str())` open-code whose
10853 // type bounds have no compile-time link back to the
10854 // substrate primitive.
10855 //
10856 // Second peer on the substrate-wide trait-idiomatic
10857 // [`Box<str>`] forward-projection family on this enum —
10858 // closes the `{Self, &Self}` input-shape corner of the
10859 // [`Box<str>`] axis on the first M2 OTP-shape closed-set
10860 // fieldless typed enum peer on the caixa surface
10861 // (`:supervisor :estrategia`), exactly as ee577fd closed
10862 // the paired [`Cow<'static, str>`] axis one commit after
10863 // its owning half (7dd28b3) landed. Every future closed-
10864 // set fieldless typed enum peer on the substrate is a
10865 // future target of the campaign.
10866 //
10867 // Also byte-parity witness against the paired owned-input
10868 // [`From<RestartStrategy> for Box<str>`] and the sibling
10869 // borrowed-input [`From<&RestartStrategy> for &'static str`],
10870 // [`From<&RestartStrategy> for String`], and
10871 // [`From<&RestartStrategy> for Cow<'static, str>`]
10872 // return-shape axes — locking the four
10873 // return-shape × input-shape paths together by construction
10874 // so any future detour trips at caixa-core test time. Then a
10875 // `.iter().map(Box::<str>::from)` pipe witness over
10876 // [`super::RestartStrategy::ALL`] — whose iterator yields
10877 // `&RestartStrategy` by construction, so the borrowed-input
10878 // [`Box<str>`] axis is what routes the pipe through the
10879 // substrate-primitive [`super::RestartStrategy::as_str`]
10880 // accessor without a spurious [`Copy`] deref (which would
10881 // only be reachable through the owned-input
10882 // [`From<RestartStrategy> for Box<str>`] axis by first
10883 // calling `.copied()` on the iterator).
10884 for &variant in RestartStrategy::ALL {
10885 let via_trait: Box<str> = <Box<str> as From<&RestartStrategy>>::from(&variant);
10886 let via_method: &'static str = variant.as_str();
10887 assert_eq!(
10888 via_trait.as_ref(),
10889 via_method,
10890 "From<&RestartStrategy> for Box<str> impl must \
10891 round-trip &RestartStrategy::{variant:?} to the same \
10892 lifted SUPERVISOR_ESTRATEGIA_* const \
10893 RestartStrategy::as_str returns — divergence signals \
10894 a silent detour off the substrate-primitive accessor"
10895 );
10896 let via_into: Box<str> = (&variant).into();
10897 assert_eq!(
10898 via_into.as_ref(),
10899 via_method,
10900 "Into<Box<str>>::into on &RestartStrategy::{variant:?} \
10901 must byte-equal RestartStrategy::as_str on the same \
10902 input — the blanket-derived Into shape must resolve \
10903 to the same as_str dispatch as the explicit From impl"
10904 );
10905 let owned_box: Box<str> = <Box<str> as From<RestartStrategy>>::from(variant);
10906 assert_eq!(
10907 via_trait, owned_box,
10908 "From<&RestartStrategy> for Box<str> and \
10909 From<RestartStrategy> for Box<str> must resolve \
10910 identically on RestartStrategy::{variant:?} — \
10911 divergence signals the borrowed-input and owned-input \
10912 Box<str> forward-projection input-shape paths have \
10913 drifted onto different emit-sets"
10914 );
10915 let borrowed_static: &'static str =
10916 <&'static str as From<&RestartStrategy>>::from(&variant);
10917 assert_eq!(
10918 via_trait.as_ref(),
10919 borrowed_static,
10920 "From<&RestartStrategy> for Box<str> and \
10921 From<&RestartStrategy> for &'static str must resolve \
10922 identically on RestartStrategy::{variant:?} — \
10923 divergence signals the borrowed-input Box<str> and \
10924 &'static str return-shape paths have drifted onto \
10925 different emit-sets"
10926 );
10927 let borrowed_string: String = <String as From<&RestartStrategy>>::from(&variant);
10928 assert_eq!(
10929 via_trait.as_ref(),
10930 borrowed_string.as_str(),
10931 "From<&RestartStrategy> for Box<str> and \
10932 From<&RestartStrategy> for String must resolve \
10933 identically on RestartStrategy::{variant:?} — \
10934 divergence signals the borrowed-input Box<str> and \
10935 owned-`String` return-shape paths have drifted onto \
10936 different emit-sets"
10937 );
10938 let borrowed_cow: std::borrow::Cow<'static, str> =
10939 <std::borrow::Cow<'static, str> as From<&RestartStrategy>>::from(&variant);
10940 assert_eq!(
10941 via_trait.as_ref(),
10942 borrowed_cow.as_ref(),
10943 "From<&RestartStrategy> for Box<str> and \
10944 From<&RestartStrategy> for Cow<'static, str> must \
10945 resolve identically on RestartStrategy::{variant:?} — \
10946 divergence signals the borrowed-input Box<str> and \
10947 Cow<'static, str> return-shape paths have drifted \
10948 onto different emit-sets"
10949 );
10950 }
10951 let via_iter: Vec<Box<str>> = RestartStrategy::ALL.iter().map(Box::<str>::from).collect();
10952 let via_method: Vec<Box<str>> = RestartStrategy::ALL
10953 .iter()
10954 .map(|s| Box::<str>::from(s.as_str()))
10955 .collect();
10956 assert_eq!(
10957 via_iter, via_method,
10958 "`.iter().map(Box::<str>::from)` over \
10959 RestartStrategy::ALL — a call site whose iteration axis \
10960 holds `&RestartStrategy` by construction — must byte-\
10961 equal `.iter().map(|s| Box::<str>::from(s.as_str()))` \
10962 on every arm — the borrowed-input Box<str> \
10963 `From<&RestartStrategy> for Box<str>` axis is what \
10964 makes the `Box::<str>::from` composition route through \
10965 the substrate-primitive `RestartStrategy::as_str` \
10966 accessor without a spurious `Copy` deref (which would \
10967 only be reachable through the owned-input \
10968 `From<RestartStrategy> for Box<str>` axis by first \
10969 calling `.copied()` on the iterator)"
10970 );
10971 }
10972
10973 #[test]
10974 fn restart_strategy_from_into_arc_str_routes_through_as_str_accessor() {
10975 // Fail-before-pass-after byte-parity pin on the newly lifted
10976 // `impl From<RestartStrategy> for std::sync::Arc<str>` — asserts
10977 // the owned-input standard-library trait impl and the
10978 // substrate-primitive [`super::RestartStrategy::as_str`]
10979 // `pub const fn` accessor resolve to the same four-arm emit-
10980 // set across every arm the exhaustive
10981 // [`super::RestartStrategy::ALL`] slice enumerates. Opens the
10982 // substrate-wide [`std::sync::Arc<str>`] forward-projection
10983 // campaign tier on the first M2 OTP-shape closed-set fieldless
10984 // typed enum peer on the caixa surface
10985 // (`:supervisor :estrategia`), immediately after the paired
10986 // [`Box<str>`] axis (69ef45c / 59ae5dc) closed the
10987 // `{Self, &Self} × {&'static str, String, Cow<'static, str>,
10988 // Box<str>}` 2×4 corner on this enum. Rust's standard library
10989 // carries `impl From<&str> for std::sync::Arc<str>` and
10990 // `impl From<String> for std::sync::Arc<str>` but no blanket
10991 // `impl<T: AsRef<str>> From<T> for std::sync::Arc<str>` (nor
10992 // an `impl<T: fmt::Display> From<T> for std::sync::Arc<str>`),
10993 // so this axis is a distinct trait-idiomatic surface that a
10994 // `let key: std::sync::Arc<str> = strategy.into();`-shaped call
10995 // site reaches through this impl and no other — a paired
10996 // `std::sync::Arc::<str>::from(strategy.as_str())` open-code
10997 // has no compile-time link back to the substrate primitive,
10998 // and a two-step `std::sync::Arc::<str>::from(String::from(
10999 // strategy))` composition through the owned-`String` axis
11000 // allocates twice (once into the intermediate `String`, once
11001 // into the [`Arc<str>`] on the `From<String>` conversion)
11002 // where the single-step trait impl allocates once.
11003 //
11004 // Cross-axis byte-parity witness against the sibling owned-
11005 // input `{&'static str, String, Cow<'static, str>, Box<str>}`
11006 // return-shape axes — locking the five return-shape paths on
11007 // the owned-input surface together by construction so any
11008 // future detour off the substrate-primitive
11009 // [`super::RestartStrategy::as_str`] accessor trips at caixa-
11010 // core test time.
11011 for &variant in RestartStrategy::ALL {
11012 let via_trait: std::sync::Arc<str> =
11013 <std::sync::Arc<str> as From<RestartStrategy>>::from(variant);
11014 let via_method: &'static str = variant.as_str();
11015 assert_eq!(
11016 via_trait.as_ref(),
11017 via_method,
11018 "From<RestartStrategy> for std::sync::Arc<str> impl \
11019 must round-trip RestartStrategy::{variant:?} to the \
11020 same lifted SUPERVISOR_ESTRATEGIA_* const \
11021 RestartStrategy::as_str returns — divergence signals \
11022 a silent detour off the substrate-primitive accessor"
11023 );
11024 let via_into: std::sync::Arc<str> = variant.into();
11025 assert_eq!(
11026 via_into.as_ref(),
11027 via_method,
11028 "Into<std::sync::Arc<str>>::into on \
11029 RestartStrategy::{variant:?} must byte-equal \
11030 RestartStrategy::as_str on the same input — the \
11031 blanket-derived Into shape must resolve to the same \
11032 as_str dispatch as the explicit From impl"
11033 );
11034 let owned_static: &'static str = <&'static str as From<RestartStrategy>>::from(variant);
11035 assert_eq!(
11036 via_trait.as_ref(),
11037 owned_static,
11038 "From<RestartStrategy> for std::sync::Arc<str> and \
11039 From<RestartStrategy> for &'static str must resolve \
11040 identically on RestartStrategy::{variant:?} — \
11041 divergence signals the owned-input std::sync::Arc<str> \
11042 and &'static str return-shape paths have drifted onto \
11043 different emit-sets"
11044 );
11045 let owned_string: String = <String as From<RestartStrategy>>::from(variant);
11046 assert_eq!(
11047 via_trait.as_ref(),
11048 owned_string.as_str(),
11049 "From<RestartStrategy> for std::sync::Arc<str> and \
11050 From<RestartStrategy> for String must resolve \
11051 identically on RestartStrategy::{variant:?} — \
11052 divergence signals the owned-input std::sync::Arc<str> \
11053 and owned-`String` return-shape paths have drifted \
11054 onto different emit-sets"
11055 );
11056 let owned_cow: std::borrow::Cow<'static, str> =
11057 <std::borrow::Cow<'static, str> as From<RestartStrategy>>::from(variant);
11058 assert_eq!(
11059 via_trait.as_ref(),
11060 owned_cow.as_ref(),
11061 "From<RestartStrategy> for std::sync::Arc<str> and \
11062 From<RestartStrategy> for Cow<'static, str> must \
11063 resolve identically on RestartStrategy::{variant:?} — \
11064 divergence signals the owned-input std::sync::Arc<str> \
11065 and Cow<'static, str> return-shape paths have drifted \
11066 onto different emit-sets"
11067 );
11068 let owned_box: Box<str> = <Box<str> as From<RestartStrategy>>::from(variant);
11069 assert_eq!(
11070 via_trait.as_ref(),
11071 owned_box.as_ref(),
11072 "From<RestartStrategy> for std::sync::Arc<str> and \
11073 From<RestartStrategy> for Box<str> must resolve \
11074 identically on RestartStrategy::{variant:?} — \
11075 divergence signals the owned-input std::sync::Arc<str> \
11076 and Box<str> return-shape paths have drifted onto \
11077 different emit-sets"
11078 );
11079 }
11080 }
11081
11082 #[test]
11083 fn restart_strategy_from_borrowed_into_arc_str_routes_through_as_str_accessor() {
11084 // Fail-before-pass-after byte-parity pin on the newly lifted
11085 // `impl From<&RestartStrategy> for std::sync::Arc<str>` —
11086 // asserts the borrowed-input standard-library trait impl and
11087 // the substrate-primitive [`super::RestartStrategy::as_str`]
11088 // `pub const fn` accessor resolve to the same four-arm emit-
11089 // set across every arm the exhaustive
11090 // [`super::RestartStrategy::ALL`] slice enumerates. Rust's
11091 // standard library does not carry a blanket
11092 // `impl<T: AsRef<str>> From<&T> for std::sync::Arc<str>` (nor
11093 // a `Copy`-based `impl<T: Copy, U: From<T>> From<&T> for U`),
11094 // so the borrowed-input [`std::sync::Arc<str>`] forward-
11095 // projection axis is a distinct trait-idiomatic surface that a
11096 // `let key: std::sync::Arc<str> = (&strategy).into();`-shaped
11097 // call site or a
11098 // `RestartStrategy::ALL.iter().map(std::sync::Arc::<str>::from)`-
11099 // shaped pipe reaches through this impl and no other — the
11100 // paired owned-input
11101 // `From<RestartStrategy> for std::sync::Arc<str>` impl
11102 // (bca2ec8) forces every borrowed-input call site through an
11103 // explicit `Copy` deref
11104 // (`std::sync::Arc::<str>::from((*strategy).as_str())`) or a
11105 // `std::sync::Arc::<str>::from(strategy.as_str())` open-code
11106 // whose type bounds have no compile-time link back to the
11107 // substrate primitive.
11108 //
11109 // Second peer on the substrate-wide trait-idiomatic
11110 // [`std::sync::Arc<str>`] forward-projection family on this
11111 // enum — closes the `{Self, &Self}` input-shape corner of
11112 // the [`std::sync::Arc<str>`] axis on the first M2 OTP-shape
11113 // closed-set fieldless typed enum peer on the caixa surface
11114 // (`:supervisor :estrategia`), exactly as 59ae5dc closed the
11115 // paired [`Box<str>`] axis one commit after its owning half
11116 // (69ef45c) landed. Every future closed-set fieldless typed
11117 // enum peer on the substrate is a future target of the
11118 // campaign.
11119 //
11120 // Also byte-parity witness against the paired owned-input
11121 // [`From<RestartStrategy> for std::sync::Arc<str>`] and the
11122 // sibling borrowed-input
11123 // [`From<&RestartStrategy> for &'static str`],
11124 // [`From<&RestartStrategy> for String`],
11125 // [`From<&RestartStrategy> for Cow<'static, str>`], and
11126 // [`From<&RestartStrategy> for Box<str>`] return-shape axes —
11127 // locking the five return-shape × input-shape paths together
11128 // by construction so any future detour trips at caixa-core
11129 // test time. Then a
11130 // `.iter().map(std::sync::Arc::<str>::from)` pipe witness over
11131 // [`super::RestartStrategy::ALL`] — whose iterator yields
11132 // `&RestartStrategy` by construction, so the borrowed-input
11133 // [`std::sync::Arc<str>`] axis is what routes the pipe
11134 // through the substrate-primitive
11135 // [`super::RestartStrategy::as_str`] accessor without a
11136 // spurious [`Copy`] deref (which would only be reachable
11137 // through the owned-input
11138 // [`From<RestartStrategy> for std::sync::Arc<str>`] axis by
11139 // first calling `.copied()` on the iterator).
11140 for &variant in RestartStrategy::ALL {
11141 let via_trait: std::sync::Arc<str> =
11142 <std::sync::Arc<str> as From<&RestartStrategy>>::from(&variant);
11143 let via_method: &'static str = variant.as_str();
11144 assert_eq!(
11145 via_trait.as_ref(),
11146 via_method,
11147 "From<&RestartStrategy> for std::sync::Arc<str> impl \
11148 must round-trip &RestartStrategy::{variant:?} to the \
11149 same lifted SUPERVISOR_ESTRATEGIA_* const \
11150 RestartStrategy::as_str returns — divergence signals \
11151 a silent detour off the substrate-primitive accessor"
11152 );
11153 let via_into: std::sync::Arc<str> = (&variant).into();
11154 assert_eq!(
11155 via_into.as_ref(),
11156 via_method,
11157 "Into<std::sync::Arc<str>>::into on \
11158 &RestartStrategy::{variant:?} must byte-equal \
11159 RestartStrategy::as_str on the same input — the \
11160 blanket-derived Into shape must resolve to the same \
11161 as_str dispatch as the explicit From impl"
11162 );
11163 let owned_arc: std::sync::Arc<str> =
11164 <std::sync::Arc<str> as From<RestartStrategy>>::from(variant);
11165 assert_eq!(
11166 via_trait, owned_arc,
11167 "From<&RestartStrategy> for std::sync::Arc<str> and \
11168 From<RestartStrategy> for std::sync::Arc<str> must \
11169 resolve identically on RestartStrategy::{variant:?} — \
11170 divergence signals the borrowed-input and owned-input \
11171 std::sync::Arc<str> forward-projection input-shape \
11172 paths have drifted onto different emit-sets"
11173 );
11174 let borrowed_static: &'static str =
11175 <&'static str as From<&RestartStrategy>>::from(&variant);
11176 assert_eq!(
11177 via_trait.as_ref(),
11178 borrowed_static,
11179 "From<&RestartStrategy> for std::sync::Arc<str> and \
11180 From<&RestartStrategy> for &'static str must resolve \
11181 identically on RestartStrategy::{variant:?} — \
11182 divergence signals the borrowed-input \
11183 std::sync::Arc<str> and &'static str return-shape \
11184 paths have drifted onto different emit-sets"
11185 );
11186 let borrowed_string: String = <String as From<&RestartStrategy>>::from(&variant);
11187 assert_eq!(
11188 via_trait.as_ref(),
11189 borrowed_string.as_str(),
11190 "From<&RestartStrategy> for std::sync::Arc<str> and \
11191 From<&RestartStrategy> for String must resolve \
11192 identically on RestartStrategy::{variant:?} — \
11193 divergence signals the borrowed-input \
11194 std::sync::Arc<str> and owned-`String` return-shape \
11195 paths have drifted onto different emit-sets"
11196 );
11197 let borrowed_cow: std::borrow::Cow<'static, str> =
11198 <std::borrow::Cow<'static, str> as From<&RestartStrategy>>::from(&variant);
11199 assert_eq!(
11200 via_trait.as_ref(),
11201 borrowed_cow.as_ref(),
11202 "From<&RestartStrategy> for std::sync::Arc<str> and \
11203 From<&RestartStrategy> for Cow<'static, str> must \
11204 resolve identically on RestartStrategy::{variant:?} — \
11205 divergence signals the borrowed-input \
11206 std::sync::Arc<str> and Cow<'static, str> return-shape \
11207 paths have drifted onto different emit-sets"
11208 );
11209 let borrowed_box: Box<str> = <Box<str> as From<&RestartStrategy>>::from(&variant);
11210 assert_eq!(
11211 via_trait.as_ref(),
11212 borrowed_box.as_ref(),
11213 "From<&RestartStrategy> for std::sync::Arc<str> and \
11214 From<&RestartStrategy> for Box<str> must resolve \
11215 identically on RestartStrategy::{variant:?} — \
11216 divergence signals the borrowed-input \
11217 std::sync::Arc<str> and Box<str> return-shape paths \
11218 have drifted onto different emit-sets"
11219 );
11220 }
11221 let via_iter: Vec<std::sync::Arc<str>> = RestartStrategy::ALL
11222 .iter()
11223 .map(std::sync::Arc::<str>::from)
11224 .collect();
11225 let via_method: Vec<std::sync::Arc<str>> = RestartStrategy::ALL
11226 .iter()
11227 .map(|s| std::sync::Arc::<str>::from(s.as_str()))
11228 .collect();
11229 assert_eq!(
11230 via_iter, via_method,
11231 "`.iter().map(std::sync::Arc::<str>::from)` over \
11232 RestartStrategy::ALL — a call site whose iteration axis \
11233 holds `&RestartStrategy` by construction — must byte-\
11234 equal `.iter().map(|s| std::sync::Arc::<str>::from(s.as_str()))` \
11235 on every arm — the borrowed-input std::sync::Arc<str> \
11236 `From<&RestartStrategy> for std::sync::Arc<str>` axis is \
11237 what makes the `std::sync::Arc::<str>::from` composition \
11238 route through the substrate-primitive \
11239 `RestartStrategy::as_str` accessor without a spurious \
11240 `Copy` deref (which would only be reachable through the \
11241 owned-input `From<RestartStrategy> for std::sync::Arc<str>` \
11242 axis by first calling `.copied()` on the iterator)"
11243 );
11244 }
11245
11246 #[test]
11247 fn restart_strategy_from_into_rc_str_routes_through_as_str_accessor() {
11248 // Fail-before-pass-after byte-parity pin on the newly lifted
11249 // `impl From<RestartStrategy> for std::rc::Rc<str>` — asserts
11250 // the owned-input standard-library trait impl and the
11251 // substrate-primitive [`super::RestartStrategy::as_str`]
11252 // `pub const fn` accessor resolve to the same four-arm emit-
11253 // set across every arm the exhaustive
11254 // [`super::RestartStrategy::ALL`] slice enumerates, and cross-
11255 // witnesses against every sibling owned-input `{&'static str,
11256 // String, Cow<'static, str>, Box<str>, std::sync::Arc<str>}`
11257 // return-shape axis so the six return-shape paths on the
11258 // owned-input surface lock together by construction. Extends
11259 // the substrate-wide [`std::rc::Rc<str>`] forward-projection
11260 // campaign onto the first M2 OTP-shape closed-set fieldless
11261 // typed enum peer on the caixa surface
11262 // (`:supervisor :estrategia`).
11263 for &variant in RestartStrategy::ALL {
11264 let via_trait: std::rc::Rc<str> =
11265 <std::rc::Rc<str> as From<RestartStrategy>>::from(variant);
11266 let via_method: &'static str = variant.as_str();
11267 assert_eq!(
11268 via_trait.as_ref(),
11269 via_method,
11270 "From<RestartStrategy> for std::rc::Rc<str> impl must \
11271 round-trip RestartStrategy::{variant:?} to the same \
11272 lifted SUPERVISOR_ESTRATEGIA_* const \
11273 RestartStrategy::as_str returns — divergence signals \
11274 a silent detour off the substrate-primitive accessor"
11275 );
11276 let via_into: std::rc::Rc<str> = variant.into();
11277 assert_eq!(
11278 via_into.as_ref(),
11279 via_method,
11280 "Into<std::rc::Rc<str>>::into on \
11281 RestartStrategy::{variant:?} must byte-equal \
11282 RestartStrategy::as_str on the same input — the \
11283 blanket-derived Into shape must resolve to the same \
11284 as_str dispatch as the explicit From impl"
11285 );
11286 let owned_static: &'static str = <&'static str as From<RestartStrategy>>::from(variant);
11287 assert_eq!(
11288 via_trait.as_ref(),
11289 owned_static,
11290 "From<RestartStrategy> for std::rc::Rc<str> and \
11291 From<RestartStrategy> for &'static str must resolve \
11292 identically on RestartStrategy::{variant:?}"
11293 );
11294 let owned_string: String = <String as From<RestartStrategy>>::from(variant);
11295 assert_eq!(
11296 via_trait.as_ref(),
11297 owned_string.as_str(),
11298 "From<RestartStrategy> for std::rc::Rc<str> and \
11299 From<RestartStrategy> for String must resolve \
11300 identically on RestartStrategy::{variant:?}"
11301 );
11302 let owned_cow: std::borrow::Cow<'static, str> =
11303 <std::borrow::Cow<'static, str> as From<RestartStrategy>>::from(variant);
11304 assert_eq!(
11305 via_trait.as_ref(),
11306 owned_cow.as_ref(),
11307 "From<RestartStrategy> for std::rc::Rc<str> and \
11308 From<RestartStrategy> for Cow<'static, str> must \
11309 resolve identically on RestartStrategy::{variant:?}"
11310 );
11311 let owned_box: Box<str> = <Box<str> as From<RestartStrategy>>::from(variant);
11312 assert_eq!(
11313 via_trait.as_ref(),
11314 owned_box.as_ref(),
11315 "From<RestartStrategy> for std::rc::Rc<str> and \
11316 From<RestartStrategy> for Box<str> must resolve \
11317 identically on RestartStrategy::{variant:?}"
11318 );
11319 let owned_arc: std::sync::Arc<str> =
11320 <std::sync::Arc<str> as From<RestartStrategy>>::from(variant);
11321 assert_eq!(
11322 via_trait.as_ref(),
11323 owned_arc.as_ref(),
11324 "From<RestartStrategy> for std::rc::Rc<str> and \
11325 From<RestartStrategy> for std::sync::Arc<str> must \
11326 resolve identically on RestartStrategy::{variant:?}"
11327 );
11328 }
11329 }
11330
11331 #[test]
11332 fn restart_strategy_from_borrowed_into_rc_str_routes_through_as_str_accessor() {
11333 // Fail-before-pass-after byte-parity pin on the newly lifted
11334 // `impl From<&RestartStrategy> for std::rc::Rc<str>` — asserts
11335 // the borrowed-input standard-library trait impl and the
11336 // substrate-primitive [`super::RestartStrategy::as_str`]
11337 // `pub const fn` accessor resolve to the same four-arm emit-
11338 // set across every arm the exhaustive
11339 // [`super::RestartStrategy::ALL`] slice enumerates. Closes the
11340 // `{Self, &Self}` input-shape corner of the
11341 // [`std::rc::Rc<str>`] axis on this enum, cross-witnesses
11342 // against the paired owned-input axis and every sibling
11343 // borrowed-input return-shape axis, and locks the
11344 // `.iter().map(std::rc::Rc::<str>::from)` pipe over
11345 // [`super::RestartStrategy::ALL`] to the substrate-primitive
11346 // accessor without a spurious [`Copy`] deref (which would only
11347 // be reachable through the owned-input axis by first calling
11348 // `.copied()` on the iterator).
11349 for &variant in RestartStrategy::ALL {
11350 let via_trait: std::rc::Rc<str> =
11351 <std::rc::Rc<str> as From<&RestartStrategy>>::from(&variant);
11352 let via_method: &'static str = variant.as_str();
11353 assert_eq!(
11354 via_trait.as_ref(),
11355 via_method,
11356 "From<&RestartStrategy> for std::rc::Rc<str> impl must \
11357 round-trip &RestartStrategy::{variant:?} to the same \
11358 lifted SUPERVISOR_ESTRATEGIA_* const \
11359 RestartStrategy::as_str returns"
11360 );
11361 let via_into: std::rc::Rc<str> = (&variant).into();
11362 assert_eq!(
11363 via_into.as_ref(),
11364 via_method,
11365 "Into<std::rc::Rc<str>>::into on \
11366 &RestartStrategy::{variant:?} must byte-equal \
11367 RestartStrategy::as_str on the same input"
11368 );
11369 let owned_rc: std::rc::Rc<str> =
11370 <std::rc::Rc<str> as From<RestartStrategy>>::from(variant);
11371 assert_eq!(
11372 via_trait, owned_rc,
11373 "From<&RestartStrategy> for std::rc::Rc<str> and \
11374 From<RestartStrategy> for std::rc::Rc<str> must \
11375 resolve identically on RestartStrategy::{variant:?}"
11376 );
11377 let borrowed_static: &'static str =
11378 <&'static str as From<&RestartStrategy>>::from(&variant);
11379 assert_eq!(
11380 via_trait.as_ref(),
11381 borrowed_static,
11382 "From<&RestartStrategy> for std::rc::Rc<str> and \
11383 From<&RestartStrategy> for &'static str must resolve \
11384 identically on RestartStrategy::{variant:?}"
11385 );
11386 let borrowed_string: String = <String as From<&RestartStrategy>>::from(&variant);
11387 assert_eq!(
11388 via_trait.as_ref(),
11389 borrowed_string.as_str(),
11390 "From<&RestartStrategy> for std::rc::Rc<str> and \
11391 From<&RestartStrategy> for String must resolve \
11392 identically on RestartStrategy::{variant:?}"
11393 );
11394 let borrowed_cow: std::borrow::Cow<'static, str> =
11395 <std::borrow::Cow<'static, str> as From<&RestartStrategy>>::from(&variant);
11396 assert_eq!(
11397 via_trait.as_ref(),
11398 borrowed_cow.as_ref(),
11399 "From<&RestartStrategy> for std::rc::Rc<str> and \
11400 From<&RestartStrategy> for Cow<'static, str> must \
11401 resolve identically on RestartStrategy::{variant:?}"
11402 );
11403 let borrowed_box: Box<str> = <Box<str> as From<&RestartStrategy>>::from(&variant);
11404 assert_eq!(
11405 via_trait.as_ref(),
11406 borrowed_box.as_ref(),
11407 "From<&RestartStrategy> for std::rc::Rc<str> and \
11408 From<&RestartStrategy> for Box<str> must resolve \
11409 identically on RestartStrategy::{variant:?}"
11410 );
11411 let borrowed_arc: std::sync::Arc<str> =
11412 <std::sync::Arc<str> as From<&RestartStrategy>>::from(&variant);
11413 assert_eq!(
11414 via_trait.as_ref(),
11415 borrowed_arc.as_ref(),
11416 "From<&RestartStrategy> for std::rc::Rc<str> and \
11417 From<&RestartStrategy> for std::sync::Arc<str> must \
11418 resolve identically on RestartStrategy::{variant:?}"
11419 );
11420 }
11421 let via_iter: Vec<std::rc::Rc<str>> = RestartStrategy::ALL
11422 .iter()
11423 .map(std::rc::Rc::<str>::from)
11424 .collect();
11425 let via_method: Vec<std::rc::Rc<str>> = RestartStrategy::ALL
11426 .iter()
11427 .map(|s| std::rc::Rc::<str>::from(s.as_str()))
11428 .collect();
11429 assert_eq!(
11430 via_iter, via_method,
11431 "`.iter().map(std::rc::Rc::<str>::from)` over \
11432 RestartStrategy::ALL — a call site whose iteration axis \
11433 holds `&RestartStrategy` by construction — must byte-\
11434 equal `.iter().map(|s| std::rc::Rc::<str>::from(s.as_str()))` \
11435 on every arm — the borrowed-input std::rc::Rc<str> \
11436 `From<&RestartStrategy> for std::rc::Rc<str>` axis is \
11437 what makes the `std::rc::Rc::<str>::from` composition \
11438 route through the substrate-primitive \
11439 `RestartStrategy::as_str` accessor without a spurious \
11440 `Copy` deref (which would only be reachable through the \
11441 owned-input `From<RestartStrategy> for std::rc::Rc<str>` \
11442 axis by first calling `.copied()` on the iterator)"
11443 );
11444 }
11445
11446 #[test]
11447 #[allow(
11448 clippy::too_many_lines,
11449 reason = "cross-axis partition pin folds the substrate-primitive \
11450 as_str accessor's `.as_bytes()` byte-tail plus the \
11451 paired str-view (AsRef<str>, Display, as_str) and \
11452 reverse-projection ({&'static str, String, Cow<'static, \
11453 str>, Box<str>, std::sync::Arc<str>}) return-shape \
11454 axes' `.as_bytes()` byte-tails plus a <T: AsRef<[u8]>>\
11455 -bound-consumer witness plus a blake3::Hasher::update-\
11456 shape byte-input surface witness into one exhaustive \
11457 round-trip over RestartStrategy::ALL — the accepted \
11458 line-count cost of opening the byte-view axis keyed \
11459 to the substrate-primitive as_str accessor at the \
11460 same test-site"
11461 )]
11462 #[allow(
11463 clippy::needless_borrows_for_generic_args,
11464 reason = "the borrowed-input surface (&variant) is exercised \
11465 deliberately: the `<T: AsRef<[u8]>>`-bound consumer \
11466 and the `blake3::Hasher::update`-shape byte-input \
11467 surface both accept either owned or borrowed input \
11468 through the standard-library blanket \
11469 `impl<T: ?Sized + AsRef<[u8]>> AsRef<[u8]> for &T`, \
11470 and this pin round-trips both input shapes to lock \
11471 the borrowed-input path load-bearing against a \
11472 future silent regression"
11473 )]
11474 fn restart_strategy_as_ref_bytes_routes_through_as_str_accessor() {
11475 // `<T: AsRef<[u8]>>`-bound generic-consumer witness: a byte-input
11476 // function that binds its argument through the standard-library
11477 // [`AsRef<[u8]>`] trait bound accepts a [`super::RestartStrategy`]
11478 // directly, without the caller open-coding the two-hop
11479 // `estrategia.as_str().as_bytes()` composition. Lifted to the top
11480 // of the function per `clippy::items_after_statements`.
11481 fn generic_bytes_sink<T: AsRef<[u8]>>(t: T) -> Vec<u8> {
11482 t.as_ref().to_vec()
11483 }
11484 // `blake3::Hasher::update`-shape byte-input surface mock: mirrors
11485 // `blake3::Hasher::update` / `ring::digest::Context::update` /
11486 // `sha2::Sha256::update`'s `impl AsRef<[u8]>`-bound `update`
11487 // signature so a per-supervisor BLAKE3 content-address closure
11488 // that composes `hasher.update(estrategia)` on the
11489 // [`crate::Lacre`] closure builder reaches the substrate-primitive
11490 // `as_str` accessor through the [`super::RestartStrategy`]
11491 // `AsRef<[u8]>` axis and no other. Lifted to the top of the
11492 // function per `clippy::items_after_statements`.
11493 struct MockHasher(Vec<u8>);
11494 impl MockHasher {
11495 fn new() -> Self {
11496 Self(Vec::new())
11497 }
11498 fn update(&mut self, bytes: impl AsRef<[u8]>) -> &mut Self {
11499 self.0.extend_from_slice(bytes.as_ref());
11500 self
11501 }
11502 fn finalize(self) -> Vec<u8> {
11503 self.0
11504 }
11505 }
11506
11507 // Fail-before-pass-after byte-parity pin on the newly lifted
11508 // `impl AsRef<[u8]> for RestartStrategy` — asserts the trait-
11509 // idiomatic byte-view standard-library impl and the substrate-
11510 // primitive [`super::RestartStrategy::as_str`] `pub const fn`
11511 // accessor's `.as_bytes()` byte-tail resolve to the same four-arm
11512 // `PascalCase` wire byte-string emit-set across every arm the
11513 // exhaustive [`super::RestartStrategy::ALL`] slice enumerates.
11514 // Opens the trait-idiomatic byte-view axis onto the first M2
11515 // OTP-shape closed-set fieldless typed enum peer on the caixa
11516 // surface (`:supervisor :estrategia`), extending the substrate-
11517 // wide byte-view campaign the sibling
11518 // [`super::crate::CaixaKind`] first-mover (69d8d86) opened.
11519 //
11520 // Rust's standard library carries `impl AsRef<[u8]> for str` and
11521 // `impl AsRef<[u8]> for String`, so a two-hop composition
11522 // `estrategia.as_str().as_bytes()` (or the equally two-hop
11523 // `AsRef::<str>::as_ref(&estrategia).as_bytes()`) is reachable
11524 // through the pre-existing str-view axis alone. But that two-hop
11525 // shape has no compile-time link back to the byte-projection
11526 // axis, forces every downstream `<T: AsRef<[u8]>>`-bound
11527 // consumer to open-code the two-hop composition at every call
11528 // site, and admits a silent split whenever a future call site
11529 // takes a sibling reverse-projection axis whose `.as_bytes()`
11530 // byte-tail carries no compile-time byte-view surface. This
11531 // impl closes the byte-view axis at the substrate-primitive
11532 // [`super::RestartStrategy::as_str`] accessor so every future
11533 // `<T: AsRef<[u8]>>`-bound consumer reaches the same lifted
11534 // [`super::crate::render::SUPERVISOR_ESTRATEGIA_*`] const roster
11535 // the paired str-view axes already return through — through one
11536 // trait dispatch.
11537 for &variant in RestartStrategy::ALL {
11538 let via_trait: &[u8] = <RestartStrategy as AsRef<[u8]>>::as_ref(&variant);
11539 let via_method_bytes: &[u8] = variant.as_str().as_bytes();
11540 assert_eq!(
11541 via_trait, via_method_bytes,
11542 "AsRef<[u8]> for RestartStrategy impl must byte-equal \
11543 RestartStrategy::as_str().as_bytes() on \
11544 RestartStrategy::{variant:?} — divergence signals a \
11545 silent detour off the substrate-primitive accessor"
11546 );
11547 // Cross-axis witness against the paired str-view axes'
11548 // `.as_bytes()` byte-tails: [`AsRef<str>`] /
11549 // [`std::fmt::Display`] / [`super::RestartStrategy::as_str`]
11550 // all resolve to the same lifted
11551 // [`super::crate::render::SUPERVISOR_ESTRATEGIA_*`] const
11552 // roster, and the byte-view axis must byte-equal each of
11553 // their `.as_bytes()` byte-tails by construction — locking
11554 // the str-view and byte-view axes together at the
11555 // substrate-primitive accessor.
11556 let str_view_ref: &str = <RestartStrategy as AsRef<str>>::as_ref(&variant);
11557 assert_eq!(
11558 via_trait,
11559 str_view_ref.as_bytes(),
11560 "AsRef<[u8]> for RestartStrategy and AsRef<str> for \
11561 RestartStrategy must resolve to byte-equal byte-tails \
11562 on RestartStrategy::{variant:?} — divergence signals \
11563 the byte-view and str-view axes have drifted off the \
11564 same substrate-primitive as_str accessor"
11565 );
11566 let display_bytes = variant.to_string();
11567 assert_eq!(
11568 via_trait,
11569 display_bytes.as_bytes(),
11570 "AsRef<[u8]> for RestartStrategy and \
11571 <RestartStrategy as std::fmt::Display>::to_string must \
11572 resolve to byte-equal byte-tails on \
11573 RestartStrategy::{variant:?} — divergence signals the \
11574 byte-view axis and the Display formatter axis have \
11575 drifted off the same substrate-primitive as_str \
11576 accessor"
11577 );
11578 // Cross-axis witness against the paired reverse-projection
11579 // axes' `.as_bytes()` byte-tails: every one of `{&'static
11580 // str, String, Cow<'static, str>, Box<str>,
11581 // std::sync::Arc<str>}` allocates (or borrows) the same
11582 // `PascalCase` wire byte-string the substrate-primitive
11583 // accessor emits, so the byte-view axis must byte-equal
11584 // each of their `.as_bytes()` byte-tails by construction.
11585 let owned_static: &'static str = <&'static str as From<RestartStrategy>>::from(variant);
11586 assert_eq!(
11587 via_trait,
11588 owned_static.as_bytes(),
11589 "AsRef<[u8]> for RestartStrategy and From<RestartStrategy> \
11590 for &'static str must resolve to byte-equal byte-tails \
11591 on RestartStrategy::{variant:?}"
11592 );
11593 let owned_string: String = <String as From<RestartStrategy>>::from(variant);
11594 assert_eq!(
11595 via_trait,
11596 owned_string.as_bytes(),
11597 "AsRef<[u8]> for RestartStrategy and From<RestartStrategy> \
11598 for String must resolve to byte-equal byte-tails on \
11599 RestartStrategy::{variant:?}"
11600 );
11601 let owned_cow: std::borrow::Cow<'static, str> =
11602 <std::borrow::Cow<'static, str> as From<RestartStrategy>>::from(variant);
11603 assert_eq!(
11604 via_trait,
11605 owned_cow.as_bytes(),
11606 "AsRef<[u8]> for RestartStrategy and From<RestartStrategy> \
11607 for Cow<'static, str> must resolve to byte-equal byte-\
11608 tails on RestartStrategy::{variant:?}"
11609 );
11610 let owned_box: Box<str> = <Box<str> as From<RestartStrategy>>::from(variant);
11611 assert_eq!(
11612 via_trait,
11613 owned_box.as_bytes(),
11614 "AsRef<[u8]> for RestartStrategy and From<RestartStrategy> \
11615 for Box<str> must resolve to byte-equal byte-tails on \
11616 RestartStrategy::{variant:?}"
11617 );
11618 let owned_arc: std::sync::Arc<str> =
11619 <std::sync::Arc<str> as From<RestartStrategy>>::from(variant);
11620 assert_eq!(
11621 via_trait,
11622 owned_arc.as_bytes(),
11623 "AsRef<[u8]> for RestartStrategy and From<RestartStrategy> \
11624 for std::sync::Arc<str> must resolve to byte-equal byte-\
11625 tails on RestartStrategy::{variant:?}"
11626 );
11627 }
11628 // `<T: AsRef<[u8]>>`-bound-consumer witness: the generic byte-
11629 // input function `generic_bytes_sink` (lifted above per
11630 // `clippy::items_after_statements`) accepts a
11631 // [`super::RestartStrategy`] directly through the trait bound,
11632 // without the caller open-coding the two-hop
11633 // `estrategia.as_str().as_bytes()` composition. This is the
11634 // shape that reaches the caixa-lacre BLAKE3 content-address
11635 // closure's `blake3::Hasher::update(impl AsRef<[u8]>)` byte-
11636 // input surface through this impl and no other.
11637 for &variant in RestartStrategy::ALL {
11638 let via_generic = generic_bytes_sink(variant);
11639 let via_borrowed_generic = generic_bytes_sink(&variant);
11640 let via_method_bytes = variant.as_str().as_bytes().to_vec();
11641 assert_eq!(
11642 via_generic, via_method_bytes,
11643 "generic `<T: AsRef<[u8]>>`-bound consumer on \
11644 RestartStrategy::{variant:?} must yield the same byte-\
11645 tail RestartStrategy::as_str().as_bytes() returns — \
11646 divergence signals the byte-view axis fails to bridge \
11647 a generic byte-input trait bound to the substrate-\
11648 primitive accessor"
11649 );
11650 assert_eq!(
11651 via_borrowed_generic, via_method_bytes,
11652 "generic `<T: AsRef<[u8]>>`-bound consumer on \
11653 &RestartStrategy::{variant:?} must yield the same byte-\
11654 tail RestartStrategy::as_str().as_bytes() returns — \
11655 the borrowed-input surface must resolve to the same \
11656 as_str dispatch"
11657 );
11658 }
11659 // `blake3::Hasher::update`-shape byte-input surface witness on
11660 // the caixa-lacre compounding target: the `MockHasher` (lifted
11661 // above per `clippy::items_after_statements`) mirrors
11662 // `blake3::Hasher::update` / `ring::digest::Context::update` /
11663 // `sha2::Sha256::update`'s `impl AsRef<[u8]>`-bound update
11664 // signature and accepts a [`super::RestartStrategy`] directly,
11665 // routing its byte-tail through the substrate-primitive
11666 // `as_str` accessor — the shape a future per-supervisor BLAKE3
11667 // content-address closure composes to fold an `:estrategia`
11668 // discriminator byte-tag into the [`crate::Lacre`] closure
11669 // body.
11670 for &variant in RestartStrategy::ALL {
11671 let mut owned_hasher = MockHasher::new();
11672 owned_hasher.update(variant);
11673 let owned_folded = owned_hasher.finalize();
11674 assert_eq!(
11675 owned_folded,
11676 variant.as_str().as_bytes(),
11677 "`hasher.update(estrategia)`-shape composition on \
11678 RestartStrategy::{variant:?} must fold the same byte-\
11679 tail RestartStrategy::as_str().as_bytes() returns — \
11680 the shape a future per-supervisor BLAKE3 content-\
11681 address closure composes to fold an `:estrategia` \
11682 discriminator byte-tag into the Lacre closure body"
11683 );
11684 let mut borrowed_hasher = MockHasher::new();
11685 borrowed_hasher.update(&variant);
11686 let borrowed_folded = borrowed_hasher.finalize();
11687 assert_eq!(
11688 borrowed_folded,
11689 variant.as_str().as_bytes(),
11690 "`hasher.update(&estrategia)`-shape composition on \
11691 &RestartStrategy::{variant:?} must fold the same byte-\
11692 tail RestartStrategy::as_str().as_bytes() returns — \
11693 the borrowed-input surface must resolve to the same \
11694 as_str dispatch"
11695 );
11696 }
11697 }
11698
11699 #[test]
11700 #[expect(
11701 clippy::too_many_lines,
11702 reason = "the byte-owned reverse-projection axis is extended \
11703 here onto the first M2-OTP-shape closed-set fieldless \
11704 typed-enum peer, so the pin binds the new impl against \
11705 every paired byte-view and str-owned axis on the same \
11706 enum plus a generic <T: Into<Vec<u8>>>-bound consumer \
11707 witness and a std::io::Write::write_all-shape owned-\
11708 byte-sink surface witness on both owned and borrowed \
11709 input shapes to lock the whole family against a future \
11710 silent regression"
11711 )]
11712 fn restart_strategy_from_into_owned_vec_bytes_routes_through_as_str_accessor() {
11713 // `<T: Into<Vec<u8>>>`-bound-consumer witness helper: a generic
11714 // owned-byte-input function accepts a [`super::RestartStrategy`]
11715 // directly through the trait bound, without the caller open-
11716 // coding the three-hop `strategy.as_str().as_bytes().to_vec()`
11717 // composition. Lifted to the top of the function per
11718 // `clippy::items_after_statements`.
11719 fn generic_owned_bytes_sink<T: Into<Vec<u8>>>(t: T) -> Vec<u8> {
11720 t.into()
11721 }
11722 // `std::io::Write::write_all`-shape owned-byte-sink surface
11723 // mock: mirrors `std::io::Write::write_all` /
11724 // `bytes::BytesMut::extend_from_slice` / any per-arm audit-log
11725 // byte-sink that consumes a `Vec<u8>` payload via
11726 // `Into<Vec<u8>>`, so a future per-supervisor per-`:estrategia`
11727 // audit-log emit reaches the substrate-primitive `as_str`
11728 // accessor through the byte-owned reverse-projection axis and
11729 // no other. Lifted to the top of the function per
11730 // `clippy::items_after_statements`.
11731 struct MockOwnedByteSink(Vec<u8>);
11732 impl MockOwnedByteSink {
11733 fn new() -> Self {
11734 Self(Vec::new())
11735 }
11736 fn write_all(&mut self, bytes: impl Into<Vec<u8>>) -> &mut Self {
11737 self.0.extend_from_slice(&bytes.into());
11738 self
11739 }
11740 fn finalize(self) -> Vec<u8> {
11741 self.0
11742 }
11743 }
11744
11745 // Fail-before-pass-after byte-parity pin on the newly lifted
11746 // `impl From<RestartStrategy> for Vec<u8>` and
11747 // `impl From<&RestartStrategy> for Vec<u8>` — asserts the trait-
11748 // idiomatic byte-owned reverse-projection standard-library
11749 // impls and the substrate-primitive
11750 // [`super::RestartStrategy::as_str`] `pub const fn` accessor's
11751 // `.as_bytes().to_vec()` byte-tail resolve to the same four-arm
11752 // PascalCase wire byte-string emit-set across every arm the
11753 // exhaustive [`super::RestartStrategy::ALL`] slice enumerates.
11754 // Extends the substrate-wide trait-idiomatic byte-owned
11755 // reverse-projection axis onto the first M2-OTP-shape closed-
11756 // set fieldless typed-enum peer on the caixa surface
11757 // (`:supervisor :estrategia`), matching the trajectory the
11758 // first-mover [`super::crate::CaixaKind`] lift (b245fd6), the
11759 // second-mover [`super::crate::dialeto::CaixaDialeto`] lift
11760 // (4cceaf5), and the third-mover
11761 // [`super::crate::dep::DepList`] lift (e974ca2) established
11762 // across the caixa-core-internal tier.
11763 for &variant in RestartStrategy::ALL {
11764 let via_owned_from: Vec<u8> = <Vec<u8> as From<RestartStrategy>>::from(variant);
11765 let via_borrowed_from: Vec<u8> = <Vec<u8> as From<&RestartStrategy>>::from(&variant);
11766 let via_method_bytes: Vec<u8> = variant.as_str().as_bytes().to_vec();
11767 assert_eq!(
11768 via_owned_from, via_method_bytes,
11769 "From<RestartStrategy> for Vec<u8> impl must byte-equal \
11770 RestartStrategy::as_str().as_bytes().to_vec() on \
11771 RestartStrategy::{variant:?} — divergence signals a \
11772 silent detour off the substrate-primitive accessor"
11773 );
11774 assert_eq!(
11775 via_borrowed_from, via_method_bytes,
11776 "From<&RestartStrategy> for Vec<u8> impl must byte-\
11777 equal RestartStrategy::as_str().as_bytes().to_vec() \
11778 on RestartStrategy::{variant:?} — divergence signals \
11779 a silent detour off the substrate-primitive accessor"
11780 );
11781 assert_eq!(
11782 via_owned_from, via_borrowed_from,
11783 "From<RestartStrategy> for Vec<u8> and \
11784 From<&RestartStrategy> for Vec<u8> must byte-equal \
11785 each other on RestartStrategy::{variant:?} — \
11786 divergence signals the owned-input and borrowed-input \
11787 paths have drifted off the same substrate-primitive \
11788 as_str accessor"
11789 );
11790 // Cross-axis witness against the paired [`AsRef<[u8]>`]
11791 // borrowed byte-view axis (cd4c4e0): the byte-owned
11792 // reverse-projection axis must byte-equal the paired
11793 // borrowed byte-view axis by construction — locking the
11794 // byte-view and byte-owned axes together at the substrate-
11795 // primitive accessor.
11796 let borrowed_bytes: &[u8] = <RestartStrategy as AsRef<[u8]>>::as_ref(&variant);
11797 assert_eq!(
11798 via_owned_from,
11799 borrowed_bytes.to_vec(),
11800 "From<RestartStrategy> for Vec<u8> and AsRef<[u8]> \
11801 for RestartStrategy must resolve to byte-equal byte-\
11802 tails on RestartStrategy::{variant:?} — divergence \
11803 signals the byte-owned and byte-view axes have \
11804 drifted off the same substrate-primitive as_str \
11805 accessor"
11806 );
11807 // Cross-axis witness against the str-owned reverse-
11808 // projection family's `.into_bytes()` / `.as_bytes().to_vec()`
11809 // byte-tails: every one of `{String, Cow<'static, str>,
11810 // Box<str>, std::sync::Arc<str>, std::rc::Rc<str>}`
11811 // allocates (or borrows) the same PascalCase wire byte-
11812 // string the substrate-primitive accessor emits, so the
11813 // byte-owned axis must byte-equal each of their owned
11814 // byte-tails by construction.
11815 let owned_string: String = <String as From<RestartStrategy>>::from(variant);
11816 assert_eq!(
11817 via_owned_from,
11818 owned_string.into_bytes(),
11819 "From<RestartStrategy> for Vec<u8> and \
11820 String::from(strategy).into_bytes() must resolve to \
11821 byte-equal byte-tails on RestartStrategy::{variant:?}"
11822 );
11823 let owned_cow: std::borrow::Cow<'static, str> =
11824 <std::borrow::Cow<'static, str> as From<RestartStrategy>>::from(variant);
11825 assert_eq!(
11826 via_owned_from,
11827 owned_cow.as_bytes().to_vec(),
11828 "From<RestartStrategy> for Vec<u8> and \
11829 From<RestartStrategy> for Cow<'static, str> must \
11830 resolve to byte-equal byte-tails on \
11831 RestartStrategy::{variant:?}"
11832 );
11833 let owned_box: Box<str> = <Box<str> as From<RestartStrategy>>::from(variant);
11834 assert_eq!(
11835 via_owned_from,
11836 owned_box.as_bytes().to_vec(),
11837 "From<RestartStrategy> for Vec<u8> and \
11838 From<RestartStrategy> for Box<str> must resolve to \
11839 byte-equal byte-tails on RestartStrategy::{variant:?}"
11840 );
11841 let owned_arc: std::sync::Arc<str> =
11842 <std::sync::Arc<str> as From<RestartStrategy>>::from(variant);
11843 assert_eq!(
11844 via_owned_from,
11845 owned_arc.as_bytes().to_vec(),
11846 "From<RestartStrategy> for Vec<u8> and \
11847 From<RestartStrategy> for std::sync::Arc<str> must \
11848 resolve to byte-equal byte-tails on \
11849 RestartStrategy::{variant:?}"
11850 );
11851 }
11852 // `<T: Into<Vec<u8>>>`-bound-consumer witness on both owned
11853 // and borrowed input shapes: the generic owned-byte-input
11854 // function `generic_owned_bytes_sink` (lifted above per
11855 // `clippy::items_after_statements`) accepts a
11856 // [`super::RestartStrategy`] and a `&RestartStrategy`
11857 // directly through the trait bound, without the caller open-
11858 // coding the three-hop `strategy.as_str().as_bytes().to_vec()`
11859 // composition.
11860 for &variant in RestartStrategy::ALL {
11861 let via_generic_owned = generic_owned_bytes_sink(variant);
11862 // Bind the borrowed-input path through an explicit
11863 // `&RestartStrategy` local so the generic-consumer witness
11864 // routes through `From<&RestartStrategy> for Vec<u8>` (T
11865 // binds to `&RestartStrategy`) rather than clippy-collapsing
11866 // the borrow onto the owned-input peer.
11867 let variant_ref: &RestartStrategy = &variant;
11868 let via_generic_borrowed = generic_owned_bytes_sink(variant_ref);
11869 let via_method_bytes = variant.as_str().as_bytes().to_vec();
11870 assert_eq!(
11871 via_generic_owned, via_method_bytes,
11872 "generic `<T: Into<Vec<u8>>>`-bound consumer on \
11873 RestartStrategy::{variant:?} must yield the same byte-\
11874 tail RestartStrategy::as_str().as_bytes() returns — \
11875 divergence signals the byte-owned axis fails to bridge \
11876 a generic owned-byte-input trait bound to the \
11877 substrate-primitive accessor"
11878 );
11879 assert_eq!(
11880 via_generic_borrowed, via_method_bytes,
11881 "generic `<T: Into<Vec<u8>>>`-bound consumer on \
11882 &RestartStrategy::{variant:?} must yield the same byte-\
11883 tail RestartStrategy::as_str().as_bytes() returns — \
11884 the borrowed-input surface must resolve to the same \
11885 as_str dispatch"
11886 );
11887 }
11888 // `std::io::Write::write_all`-shape owned-byte-sink surface
11889 // witness: the `MockOwnedByteSink` (lifted above per
11890 // `clippy::items_after_statements`) mirrors
11891 // `std::io::Write::write_all` /
11892 // `bytes::BytesMut::extend_from_slice`'s `impl Into<Vec<u8>>`-
11893 // bound owned-byte input signature and accepts a
11894 // [`super::RestartStrategy`] directly on both owned and
11895 // borrowed input shapes, routing its byte-tail through the
11896 // substrate-primitive `as_str` accessor — the shape a future
11897 // per-supervisor per-`:estrategia` audit-log emit composes to
11898 // fold an `:estrategia` discriminator byte-tag into a
11899 // downstream owned-byte-sink surface.
11900 for &variant in RestartStrategy::ALL {
11901 let mut owned_sink = MockOwnedByteSink::new();
11902 owned_sink.write_all(variant);
11903 let owned_folded = owned_sink.finalize();
11904 assert_eq!(
11905 owned_folded,
11906 variant.as_str().as_bytes(),
11907 "`sink.write_all(strategy)`-shape composition on \
11908 RestartStrategy::{variant:?} must fold the same byte-\
11909 tail RestartStrategy::as_str().as_bytes() returns"
11910 );
11911 let mut borrowed_sink = MockOwnedByteSink::new();
11912 let variant_ref: &RestartStrategy = &variant;
11913 borrowed_sink.write_all(variant_ref);
11914 let borrowed_folded = borrowed_sink.finalize();
11915 assert_eq!(
11916 borrowed_folded,
11917 variant.as_str().as_bytes(),
11918 "`sink.write_all(&strategy)`-shape composition on \
11919 &RestartStrategy::{variant:?} must fold the same byte-\
11920 tail RestartStrategy::as_str().as_bytes() returns — \
11921 the borrowed-input surface must resolve to the same \
11922 as_str dispatch"
11923 );
11924 }
11925 }
11926
11927 #[test]
11928 fn restart_policy_try_from_str_routes_through_from_wire_accessor() {
11929 // Fail-before-pass-after byte-parity pin on the newly lifted
11930 // `impl TryFrom<&str> for RestartPolicy` — asserts the standard-
11931 // library trait impl and the substrate-primitive
11932 // [`RestartPolicy::from_wire`] `Option<Self>` accessor resolve to
11933 // the same three-arm accept-set across every arm the exhaustive
11934 // [`RestartPolicy::ALL`] slice enumerates. Any future silent
11935 // detour that routes the trait impl through a divergent
11936 // projection (a per-arm inline `match s { "Permanent" =>
11937 // Ok(Self::Permanent), … }` re-inlining that opens a compile-time
11938 // link to the un-lifted arm-literal, a hypothetical
11939 // `#[serde(rename_all = "…")]` attribute drift that silently
11940 // splits the wire byte-string from every consumer that reaches
11941 // for this typed dispatch, an accidental swap onto the kebab-case
11942 // dispatcher-catalog axis the pre-existing [`std::str::FromStr`]
11943 // impl parses through and which would collide the two-axis
11944 // wire/catalog split the sibling [`RestartPolicy::from_wire`]
11945 // doc block makes load-bearing) trips at caixa-core test time
11946 // under `assert_eq!` rather than at a downstream
11947 // `impl TryFrom<&str>`-bound consumer's silent split. Sweeps
11948 // every one of the three arms [`RestartPolicy::ALL`] carries so
11949 // no arm's projection is covered only by the sibling method-
11950 // named `from_wire` path. Peer of the sibling
11951 // [`restart_strategy_try_from_str_routes_through_from_wire_accessor`]
11952 // (5b828ed) — extends the trait-idiomatic reverse-projection
11953 // axis onto the third and final M2-OTP-shape closed-set typed
11954 // enum on the caixa surface (the paired per-child restart-
11955 // decision-policy sibling on the same M2 `:supervisor` slot).
11956 for &variant in RestartPolicy::ALL {
11957 let wire = variant.as_str();
11958 assert_eq!(
11959 <RestartPolicy as TryFrom<&str>>::try_from(wire),
11960 Ok(variant),
11961 "TryFrom<&str> impl on RestartPolicy must round-trip \
11962 RestartPolicy::{variant:?}.as_str() = {wire:?} back to \
11963 Ok(RestartPolicy::{variant:?}) — divergence from \
11964 RestartPolicy::from_wire signals a silent detour off \
11965 the substrate-primitive accessor"
11966 );
11967 assert_eq!(
11968 <RestartPolicy as TryFrom<&str>>::try_from(wire).ok(),
11969 RestartPolicy::from_wire(wire),
11970 "TryFrom<&str> ok()-projection on {wire:?} must byte-\
11971 equal RestartPolicy::from_wire on the same input"
11972 );
11973 }
11974 }
11975
11976 #[test]
11977 fn restart_policy_try_from_str_rejects_unknown_byte_strings() {
11978 // Rejection witness on the `impl TryFrom<&str> for
11979 // RestartPolicy` — sweeps a candidate set of byte-strings
11980 // outside the three-arm PascalCase wire accept-set the sibling
11981 // [`RestartPolicy::as_str`] emits and asserts every one lands on
11982 // `Err(())`, so a future accidental widening of the trait impl's
11983 // accept-set (a stray additional
11984 // `_ if s.eq_ignore_ascii_case("Permanent") => Ok(…)` case-fold
11985 // path, a silent inclusion of the kebab-case dispatcher-catalog
11986 // byte-string the pre-existing [`std::str::FromStr`] impl the
11987 // [`gen_platform::FromStrKind`] derive installs parses onto the
11988 // wire axis — which would collide the two-axis
11989 // wire/dispatcher-catalog split the sibling
11990 // [`RestartPolicy::from_wire`] doc block makes load-bearing —
11991 // an English-rebrand or plural-arm silent alias that would widen
11992 // the wire accept-set past the OTP-canonical three) trips at
11993 // caixa-core test time. The candidate set includes the empty
11994 // string, whitespace-only padding, the kebab-case dispatcher-
11995 // catalog byte-strings on the sibling axis (a caller who
11996 // confuses the two axes trips here rather than at a downstream
11997 // consumer's silent reject), a lowercase / uppercase / mixed-case
11998 // fold of each PascalCase arm (a caller who assumes case-fold
11999 // acceptance trips here), leading/trailing whitespace padding,
12000 // the trailing-newline shape, quote-wrapped candidates, and a
12001 // residual set of plausible-but-wrong English rebrand
12002 // candidates. Peer of the sibling
12003 // [`restart_strategy_try_from_str_rejects_unknown_byte_strings`]
12004 // (5b828ed) rejection witness.
12005 let rejected: &[&str] = &[
12006 "",
12007 " ",
12008 "\n",
12009 "\t",
12010 "permanent",
12011 "temporary",
12012 "transient",
12013 "PERMANENT",
12014 "TEMPORARY",
12015 "TRANSIENT",
12016 "Permanents",
12017 "Permanent ",
12018 " Permanent",
12019 " Temporary ",
12020 "Permanent\n",
12021 "Transient\t",
12022 "\"Permanent\"",
12023 "Ephemeral",
12024 "Always",
12025 "Never",
12026 "OnAbnormalExit",
12027 "intrinsic",
12028 "?",
12029 ];
12030 for &input in rejected {
12031 assert_eq!(
12032 <RestartPolicy as TryFrom<&str>>::try_from(input),
12033 Err(()),
12034 "TryFrom<&str> impl on RestartPolicy must reject the \
12035 non-wire byte-string {input:?} — silent acceptance \
12036 signals an accept-set widening off the paired \
12037 RestartPolicy::from_wire resolver"
12038 );
12039 }
12040 }
12041
12042 #[test]
12043 fn restart_policy_try_from_str_and_from_wire_partition_the_accept_set() {
12044 // Cross-axis partition pin: the paired `TryFrom<&str>` and
12045 // `from_wire` reverse projections must resolve identically on
12046 // *every* input, not just the ones [`RestartPolicy::ALL`]
12047 // enumerates. Sweeps a mixed candidate set spanning accepted
12048 // (three-arm PascalCase wire byte-strings) and rejected (kebab-
12049 // case dispatcher-catalog byte-strings, empty, whitespace-
12050 // padded, quoted, English-rebrand candidates) inputs and asserts
12051 // the trait's `Result::ok()` projection byte-equals the method-
12052 // named resolver's `Option<Self>` return-shape on each, locking
12053 // the two paths together by construction so any future detour
12054 // (a stray `try_from` special-case that widens or narrows the
12055 // accept-set outside the paired `from_wire` resolver, an
12056 // accidental swap onto the kebab-case [`std::str::FromStr`]
12057 // impl the [`gen_platform::FromStrKind`] derive installs on the
12058 // sibling dispatcher-catalog axis) trips at caixa-core test
12059 // time. Peer of the sibling
12060 // [`restart_strategy_try_from_str_and_from_wire_partition_the_accept_set`]
12061 // pin — extends the round-trip discipline onto the M2-OTP-shape
12062 // per-child restart-policy axis.
12063 let candidates: &[&str] = &[
12064 "Permanent",
12065 "Temporary",
12066 "Transient",
12067 "",
12068 "permanent",
12069 "temporary",
12070 "transient",
12071 "PERMANENT",
12072 "unknown",
12073 "Permanent ",
12074 " Permanent",
12075 "\"Permanent\"",
12076 "Ephemeral",
12077 "OnAbnormalExit",
12078 "?",
12079 ];
12080 for &input in candidates {
12081 let via_trait: Option<RestartPolicy> =
12082 <RestartPolicy as TryFrom<&str>>::try_from(input).ok();
12083 let via_method: Option<RestartPolicy> = RestartPolicy::from_wire(input);
12084 assert_eq!(
12085 via_trait, via_method,
12086 "TryFrom<&str> and from_wire must resolve identically on \
12087 input {input:?} — divergence signals the two reverse-\
12088 projection paths have drifted onto different accept-sets"
12089 );
12090 }
12091 }
12092
12093 #[test]
12094 fn restart_policy_from_into_static_str_routes_through_as_str_accessor() {
12095 // Fail-before-pass-after byte-parity pin on the newly lifted
12096 // `impl From<RestartPolicy> for &'static str` — asserts the
12097 // standard-library trait impl and the substrate-primitive
12098 // [`RestartPolicy::as_str`] `pub const fn` accessor resolve to
12099 // the same three-arm emit-set across every arm the exhaustive
12100 // [`RestartPolicy::ALL`] slice enumerates. Any future silent
12101 // detour that routes the trait impl through a divergent
12102 // projection (a per-arm inline `match policy { Permanent =>
12103 // "Permanent", … }` re-inlining that opens a compile-time link
12104 // to the un-lifted arm-literal, an accidental swap onto the
12105 // sibling kebab-case [`Self::discriminant`] dispatcher-catalog
12106 // axis that would collide the two-axis wire/catalog split the
12107 // sibling [`RestartPolicy::from_wire`] doc block makes
12108 // load-bearing) trips at caixa-core test time under
12109 // `assert_eq!` rather than at a downstream
12110 // `impl Into<&'static str>`-bound consumer's silent split.
12111 // Sweeps every one of the three arms [`RestartPolicy::ALL`]
12112 // carries so no arm's projection is covered only by the sibling
12113 // method-named `as_str` / [`std::fmt::Display`] / [`AsRef<str>`]
12114 // paths. Materializes the `<&'static str as
12115 // From<RestartPolicy>>::from` output in a `const`-shape binding
12116 // to make the `'static` lifetime promise a build-time invariant
12117 // — a future accidental downgrade of any of the three arms'
12118 // [`crate::render::SUPERVISOR_CHILD_RESTART_*`] constants to a
12119 // non-`&'static str` (a `String::leak()`-produced return, a
12120 // `Box::leak`-cast) trips at caixa-core build time rather than
12121 // at a downstream `'static`-bound consumer. Peer of the sibling
12122 // [`restart_strategy_from_into_static_str_routes_through_as_str_accessor`]
12123 // (523157d) — extends the trait-idiomatic forward-projection
12124 // axis onto the second (and second-of-two-in-M2) closed-set
12125 // typed enum on the caixa surface (the paired per-child
12126 // restart-decision-policy sibling on the same M2 `:supervisor`
12127 // slot).
12128 const PERMANENT: &str = RestartPolicy::Permanent.as_str();
12129 const TEMPORARY: &str = RestartPolicy::Temporary.as_str();
12130 const TRANSIENT: &str = RestartPolicy::Transient.as_str();
12131 for &variant in RestartPolicy::ALL {
12132 let via_trait: &'static str = <&'static str as From<RestartPolicy>>::from(variant);
12133 let via_method: &'static str = variant.as_str();
12134 assert_eq!(
12135 via_trait, via_method,
12136 "From<RestartPolicy> for &'static str impl must round-trip \
12137 RestartPolicy::{variant:?} to the same lifted \
12138 SUPERVISOR_CHILD_RESTART_* const RestartPolicy::as_str returns — \
12139 divergence signals a silent detour off the substrate-primitive \
12140 accessor"
12141 );
12142 let via_into: &'static str = variant.into();
12143 assert_eq!(
12144 via_into, via_method,
12145 "Into<&'static str>::into on RestartPolicy::{variant:?} must \
12146 byte-equal RestartPolicy::as_str on the same input — the \
12147 blanket-derived Into shape must resolve to the same as_str \
12148 dispatch as the explicit From impl"
12149 );
12150 }
12151 assert_eq!(
12152 [PERMANENT, TEMPORARY, TRANSIENT],
12153 [
12154 crate::render::SUPERVISOR_CHILD_RESTART_PERMANENT,
12155 crate::render::SUPERVISOR_CHILD_RESTART_TEMPORARY,
12156 crate::render::SUPERVISOR_CHILD_RESTART_TRANSIENT,
12157 ],
12158 "const-context RestartPolicy::as_str must resolve to the three \
12159 lifted SUPERVISOR_CHILD_RESTART_* consts — a future accidental \
12160 downgrade of any arm to a non-const or non-static byte-string \
12161 breaks the `&'static str`-lifetime promise the paired \
12162 From<RestartPolicy> for &'static str impl carries by \
12163 construction"
12164 );
12165 }
12166
12167 #[test]
12168 fn restart_policy_from_into_static_str_and_as_str_partition_the_emit_set() {
12169 // Cross-axis partition pin: the paired trait-idiomatic
12170 // `From<RestartPolicy> for &'static str` forward projection and
12171 // the method-named [`RestartPolicy::as_str`] forward projection
12172 // must resolve identically on *every* arm, not just the ones
12173 // named in the primary byte-parity pin above. Sweeps every
12174 // [`RestartPolicy::ALL`] arm and asserts the trait's `From::from`
12175 // output byte-equals the method-named accessor's return-value on
12176 // each, locking the two forward-projection paths together by
12177 // construction so any future detour (a stray `From` special-case
12178 // that lands on a divergent per-arm literal outside the paired
12179 // `as_str` dispatch, a hypothetical rebrand touching one axis
12180 // without the other) trips at caixa-core test time. Peer of the
12181 // sibling forward-projection partition pin
12182 // [`restart_strategy_from_into_static_str_and_as_str_partition_the_emit_set`]
12183 // (523157d) — extends the round-trip discipline onto the
12184 // second-of-two M2-OTP-shape closed-set typed enum on the caixa
12185 // surface, closing the two-way `Self ↔ &'static str` round-trip
12186 // on the trait-idiomatic pair (`From<Self> for &'static str` +
12187 // `TryFrom<&str> for Self`) as well as the pre-existing method-
12188 // named pair (`as_str` + `from_wire`).
12189 for &variant in RestartPolicy::ALL {
12190 let via_trait: &'static str = <&'static str as From<RestartPolicy>>::from(variant);
12191 let via_method: &'static str = variant.as_str();
12192 assert_eq!(
12193 via_trait, via_method,
12194 "From<RestartPolicy> for &'static str and \
12195 RestartPolicy::as_str must resolve identically on \
12196 RestartPolicy::{variant:?} — divergence signals the \
12197 two forward-projection paths have drifted onto different \
12198 emit-sets"
12199 );
12200 }
12201 // Round-trip witness: every arm's forward `From` output re-parses
12202 // through the paired trait-idiomatic reverse `TryFrom<&str>` back
12203 // to the original variant. Closes the two-way `RestartPolicy ↔
12204 // &'static str` round-trip on the trait-idiomatic axis pair,
12205 // mirroring the pre-existing method-named `as_str` + `from_wire`
12206 // round-trip on the substrate-primitive axis pair.
12207 for &variant in RestartPolicy::ALL {
12208 let emitted: &'static str = variant.into();
12209 let re_parsed: Result<RestartPolicy, ()> =
12210 <RestartPolicy as TryFrom<&str>>::try_from(emitted);
12211 assert_eq!(
12212 re_parsed,
12213 Ok(variant),
12214 "trait-idiomatic axis pair must round-trip \
12215 RestartPolicy::{variant:?} through `.into::<&'static \
12216 str>()` and back through `TryFrom<&str>` — a break signals \
12217 the forward-emit and reverse-parse axes have drifted onto \
12218 different vocabularies"
12219 );
12220 }
12221 }
12222
12223 #[test]
12224 fn restart_policy_from_borrowed_into_static_str_routes_through_as_str_accessor() {
12225 // Fail-before-pass-after byte-parity pin on the newly lifted
12226 // `impl From<&RestartPolicy> for &'static str` — asserts the
12227 // borrowed-input standard-library trait impl and the substrate-
12228 // primitive [`RestartPolicy::as_str`] `pub const fn` accessor
12229 // resolve to the same three-arm emit-set across every arm the
12230 // exhaustive [`RestartPolicy::ALL`] slice enumerates. Rust's
12231 // `From` trait does not auto-derive the borrowed-input sibling
12232 // from a paired owned-input impl (no `impl<T, U> From<&T> for U
12233 // where T: Copy, U: From<T>` blanket in `core`), so the
12234 // borrowed-input axis is a distinct trait-idiomatic surface
12235 // that a `.iter().map(Into::into)` shape over
12236 // [`RestartPolicy::ALL`] (whose iterator yields
12237 // `&RestartPolicy`, not `RestartPolicy`) reaches through this
12238 // impl and no other — the paired owned-input
12239 // [`From<RestartPolicy>`] impl requires an explicit `.copied()`
12240 // / dereference before the trait fires. Materializes the
12241 // `<&'static str as From<&RestartPolicy>>::from` output in a
12242 // `const`-shape binding to make the `'static` lifetime promise
12243 // a build-time invariant.
12244 const PERMANENT: &str = RestartPolicy::Permanent.as_str();
12245 const TEMPORARY: &str = RestartPolicy::Temporary.as_str();
12246 const TRANSIENT: &str = RestartPolicy::Transient.as_str();
12247 for variant in RestartPolicy::ALL {
12248 let via_trait: &'static str = <&'static str as From<&RestartPolicy>>::from(variant);
12249 let via_method: &'static str = variant.as_str();
12250 assert_eq!(
12251 via_trait, via_method,
12252 "From<&RestartPolicy> for &'static str impl must round-trip \
12253 &RestartPolicy::{variant:?} to the same lifted \
12254 SUPERVISOR_CHILD_RESTART_* const RestartPolicy::as_str \
12255 returns — divergence signals a silent detour off the \
12256 substrate-primitive accessor"
12257 );
12258 let via_into: &'static str = variant.into();
12259 assert_eq!(
12260 via_into, via_method,
12261 "Into<&'static str>::into on &RestartPolicy::{variant:?} \
12262 must byte-equal RestartPolicy::as_str on the same input — \
12263 the blanket-derived Into shape must resolve to the same \
12264 as_str dispatch as the explicit From impl"
12265 );
12266 }
12267 assert_eq!(
12268 [PERMANENT, TEMPORARY, TRANSIENT],
12269 [
12270 crate::render::SUPERVISOR_CHILD_RESTART_PERMANENT,
12271 crate::render::SUPERVISOR_CHILD_RESTART_TEMPORARY,
12272 crate::render::SUPERVISOR_CHILD_RESTART_TRANSIENT,
12273 ],
12274 "const-context RestartPolicy::as_str must resolve to the three \
12275 lifted SUPERVISOR_CHILD_RESTART_* consts — the borrowed-input \
12276 From<&RestartPolicy> for &'static str impl inherits its \
12277 `'static` lifetime promise from the same accessor the \
12278 owned-input sibling routes through"
12279 );
12280 }
12281
12282 #[test]
12283 fn restart_policy_from_owned_and_borrowed_into_static_str_agree_on_every_arm() {
12284 // Cross-axis partition pin: the paired trait-idiomatic
12285 // owned-input `From<RestartPolicy> for &'static str` (9fb37d0
12286 // campaign-shape) and borrowed-input `From<&RestartPolicy> for
12287 // &'static str` (this lift) forward projections must resolve
12288 // identically on every arm, locking the two input-shape paths
12289 // together so any future detour trips at caixa-core test time.
12290 // Then a witness that a `.iter().map(Into::into)` pipe over
12291 // [`RestartPolicy::ALL`] (whose iterator yields
12292 // `&RestartPolicy`) materializes the three-arm accept-set
12293 // through the borrowed-input axis alone — the exact shape a
12294 // future wasm-operator per-child post-exit restart-decision
12295 // diagnostic line, a future substrate-wide per-arm diagnostic
12296 // column, or a
12297 // `HashMap::<&'static str, RestartPolicy>::from_iter(
12298 // RestartPolicy::ALL.iter().map(|p| (p.into(), *p)))`-style
12299 // per-policy lookup reaches through — closing the two-way
12300 // owned/borrowed input-shape symmetry on the forward-projection
12301 // trait-idiomatic axis. Peer of the sibling
12302 // [`crate::dep::tests::dep_list_from_owned_and_borrowed_into_static_str_agree_on_every_arm`]
12303 // (64aa742) /
12304 // [`crate::kind::tests::caixa_kind_from_owned_and_borrowed_into_static_str_agree_on_every_arm`]
12305 // (5ab993a) /
12306 // [`crate::dialeto::tests::caixa_dialeto_from_owned_and_borrowed_into_static_str_agree_on_every_arm`]
12307 // (807b0b5) /
12308 // [`restart_strategy_from_owned_and_borrowed_into_static_str_agree_on_every_arm`]
12309 // (e941836) partition pins on the sibling closed-set typed-enum
12310 // discriminator axes — extends the borrowed-input axis
12311 // discipline onto the second-of-two M2 OTP-shape closed-set
12312 // typed enum on the caixa surface (per-child restart-decision
12313 // policy). Also closes the direct two-way `&Self → &'static
12314 // str → Self` round-trip via the paired [`TryFrom<&str>`] axis
12315 // — unlike the peer [`crate::CaixaKind`] axis pair (whose
12316 // forward `From` emits lowercase Portuguese diagnostic bytes
12317 // while the reverse `TryFrom` parses `PascalCase` wire bytes,
12318 // forcing the round-trip through an intermediate wire-vocab
12319 // hop), the [`RestartPolicy::as_str`] emit and
12320 // [`RestartPolicy::from_wire`] parse share the same
12321 // `PascalCase` vocabulary by construction, so the borrowed-
12322 // input forward axis and the reverse axis compose directly.
12323 for &variant in RestartPolicy::ALL {
12324 let owned: &'static str = <&'static str as From<RestartPolicy>>::from(variant);
12325 let borrowed: &'static str = <&'static str as From<&RestartPolicy>>::from(&variant);
12326 assert_eq!(
12327 owned, borrowed,
12328 "From<RestartPolicy> and From<&RestartPolicy> for \
12329 &'static str must resolve identically on \
12330 RestartPolicy::{variant:?} — divergence signals the \
12331 owned-input and borrowed-input forward-projection paths \
12332 have drifted onto different emit-sets"
12333 );
12334 }
12335 let via_iter: Vec<&'static str> = RestartPolicy::ALL.iter().map(Into::into).collect();
12336 let via_method: Vec<&'static str> = RestartPolicy::ALL.iter().map(|p| p.as_str()).collect();
12337 assert_eq!(
12338 via_iter, via_method,
12339 "`.iter().map(Into::into)` over RestartPolicy::ALL must \
12340 byte-equal `.iter().map(|p| p.as_str())` on every arm — the \
12341 borrowed-input `From<&RestartPolicy> for &'static str` axis \
12342 is what makes the `.iter().map(Into::into)` shape route \
12343 through the substrate-primitive `RestartPolicy::as_str` \
12344 accessor rather than through a per-call-site `.copied()` / \
12345 dereference detour"
12346 );
12347 for variant in RestartPolicy::ALL {
12348 let emitted: &'static str = variant.into();
12349 let re_parsed: Result<RestartPolicy, ()> =
12350 <RestartPolicy as TryFrom<&str>>::try_from(emitted);
12351 assert_eq!(
12352 re_parsed,
12353 Ok(*variant),
12354 "trait-idiomatic borrowed-input forward-projection + \
12355 reverse-projection axis pair must round-trip \
12356 &RestartPolicy::{variant:?} through `.into::<&'static \
12357 str>()` (via the borrowed-input axis) and back through \
12358 `TryFrom<&str>` — a break signals the borrowed-input \
12359 forward-emit and reverse-parse axes have drifted onto \
12360 different vocabularies"
12361 );
12362 }
12363 }
12364
12365 #[test]
12366 fn restart_policy_from_into_owned_string_routes_through_as_str_accessor() {
12367 // Fail-before-pass-after byte-parity pin on the newly lifted
12368 // `impl From<RestartPolicy> for String` — asserts the
12369 // owned-`String`-returning standard-library trait impl and the
12370 // substrate-primitive [`RestartPolicy::as_str`] `pub const fn`
12371 // accessor resolve to the same three-arm emit-set across every
12372 // arm the exhaustive [`RestartPolicy::ALL`] slice enumerates.
12373 // Rust's standard library does not carry a blanket
12374 // `impl<T: AsRef<str>> From<T> for String` (nor an
12375 // `impl<T: fmt::Display> From<T> for String`), so the
12376 // owned-`String` forward-projection axis is a distinct
12377 // trait-idiomatic surface that a `let key: String =
12378 // policy.into();`-shaped call site reaches through this impl
12379 // and no other — the paired sibling `From<RestartPolicy> for
12380 // &'static str` impl forces every owned-`String` call site
12381 // through an explicit `.to_owned()` / `String::from`
12382 // restatement. Peer of the first-mover
12383 // [`restart_strategy_from_into_owned_string_routes_through_as_str_accessor`]
12384 // (7baa18a) — extends the trait-idiomatic owned-`String`
12385 // forward-projection axis onto the second-of-two M2 OTP-shape
12386 // closed-set typed enums on the caixa surface (per-child
12387 // restart-decision-policy sibling on the same M2 `:supervisor`
12388 // slot).
12389 for &variant in RestartPolicy::ALL {
12390 let via_trait: String = <String as From<RestartPolicy>>::from(variant);
12391 let via_method: &'static str = variant.as_str();
12392 assert_eq!(
12393 via_trait.as_str(),
12394 via_method,
12395 "From<RestartPolicy> for String impl must round-trip \
12396 RestartPolicy::{variant:?} to the same lifted \
12397 SUPERVISOR_CHILD_RESTART_* const RestartPolicy::as_str \
12398 returns — divergence signals a silent detour off the \
12399 substrate-primitive accessor"
12400 );
12401 let via_into: String = variant.into();
12402 assert_eq!(
12403 via_into.as_str(),
12404 via_method,
12405 "Into<String>::into on RestartPolicy::{variant:?} must \
12406 byte-equal RestartPolicy::as_str on the same input — the \
12407 blanket-derived Into shape must resolve to the same as_str \
12408 dispatch as the explicit From impl"
12409 );
12410 }
12411 }
12412
12413 #[test]
12414 fn restart_policy_from_into_owned_string_and_static_str_agree_on_every_arm() {
12415 // Cross-axis partition pin: the paired trait-idiomatic
12416 // owned-`String` `From<RestartPolicy> for String` (this lift)
12417 // and owned-`&'static str` `From<RestartPolicy> for &'static
12418 // str` (9fb37d0) forward projections must resolve identically
12419 // on every arm, locking the two return-type-shape paths
12420 // together so any future detour trips at caixa-core test time.
12421 // Also byte-parity witness against the sibling
12422 // [`ToString::to_string`] surface routed through
12423 // [`std::fmt::Display`] — the three owned-heap-string paths
12424 // (`.into::<String>()`, `String::from`, `.to_string()`) must
12425 // resolve identically on every arm so a future consumer that
12426 // picks any of the three lands on the same lifted
12427 // SUPERVISOR_CHILD_RESTART_* const. Then a `.iter().copied()
12428 // .map(String::from)` pipe witness over [`RestartPolicy::ALL`]
12429 // that materializes the three-arm accept-set through the
12430 // owned-`String` axis alone — the exact shape a future
12431 // wasm-operator per-child post-exit restart-decision
12432 // diagnostic line composer or a
12433 // `HashMap::<String, RestartPolicy>::from_iter(
12434 // RestartPolicy::ALL.iter().copied().map(|p| (p.into(), p)))`-style
12435 // owned-key per-policy lookup reaches through — closing the
12436 // owned-`String` forward-projection axis's iterator-pipe
12437 // shape. Then a direct round-trip witness through the paired
12438 // trait-idiomatic reverse [`TryFrom<&str>`] axis on the
12439 // owned-`String`'s [`String::as_str`] borrow that closes the
12440 // two-way `Self → String → Self` round-trip on the trait-
12441 // idiomatic owned-`String` forward + reverse axis pair —
12442 // unlike the peer [`crate::CaixaKind`] axis pair (whose
12443 // forward `From` emits lowercase Portuguese diagnostic bytes
12444 // while the reverse `TryFrom` parses `PascalCase` wire bytes,
12445 // forcing the round-trip through an intermediate wire-vocab
12446 // hop), the [`RestartPolicy::as_str`] emit and
12447 // [`RestartPolicy::from_wire`] parse share the same
12448 // `PascalCase` vocabulary by construction, so the owned-
12449 // `String` forward axis and the reverse axis compose directly.
12450 for &variant in RestartPolicy::ALL {
12451 let owned_string: String = <String as From<RestartPolicy>>::from(variant);
12452 let owned_static: &'static str = <&'static str as From<RestartPolicy>>::from(variant);
12453 assert_eq!(
12454 owned_string.as_str(),
12455 owned_static,
12456 "From<RestartPolicy> for String and From<RestartPolicy> \
12457 for &'static str must resolve identically on \
12458 RestartPolicy::{variant:?} — divergence signals the \
12459 owned-`String` and owned-`&'static str` forward-projection \
12460 return-type-shape paths have drifted onto different \
12461 emit-sets"
12462 );
12463 let via_to_string: String = variant.to_string();
12464 assert_eq!(
12465 owned_string, via_to_string,
12466 "From<RestartPolicy> for String must byte-equal \
12467 RestartPolicy::to_string on RestartPolicy::{variant:?} — \
12468 divergence signals the trait-idiomatic owned-`String` \
12469 forward-projection axis and the ToString-through-Display \
12470 axis have drifted onto different emit-sets"
12471 );
12472 }
12473 let via_iter: Vec<String> = RestartPolicy::ALL
12474 .iter()
12475 .copied()
12476 .map(String::from)
12477 .collect();
12478 let via_method: Vec<String> = RestartPolicy::ALL
12479 .iter()
12480 .map(|p| p.as_str().to_owned())
12481 .collect();
12482 assert_eq!(
12483 via_iter, via_method,
12484 "`.iter().copied().map(String::from)` over RestartPolicy::ALL \
12485 must byte-equal `.iter().map(|p| p.as_str().to_owned())` on \
12486 every arm — the owned-`String` `From<RestartPolicy> for \
12487 String` axis is what makes the `String::from` composition \
12488 route through the substrate-primitive `RestartPolicy::as_str` \
12489 accessor rather than through a per-call-site `.to_owned()` / \
12490 `String::from(policy.as_str())` detour"
12491 );
12492 for &variant in RestartPolicy::ALL {
12493 let emitted: String = variant.into();
12494 let re_parsed: Result<RestartPolicy, ()> =
12495 <RestartPolicy as TryFrom<&str>>::try_from(emitted.as_str());
12496 assert_eq!(
12497 re_parsed,
12498 Ok(variant),
12499 "trait-idiomatic owned-`String` forward-projection + \
12500 reverse-projection axis pair must round-trip \
12501 RestartPolicy::{variant:?} through `.into::<String>()` \
12502 and back through `TryFrom<&str>` on the owned-`String`'s \
12503 String::as_str borrow — a break signals the owned-`String` \
12504 forward-emit and reverse-parse axes have drifted onto \
12505 different vocabularies"
12506 );
12507 }
12508 }
12509
12510 #[test]
12511 fn restart_policy_from_into_borrowed_owned_string_routes_through_as_str_accessor() {
12512 // Fail-before-pass-after byte-parity pin on the newly lifted
12513 // `impl From<&RestartPolicy> for String` — asserts the
12514 // borrowed-input owned-`String`-returning standard-library
12515 // trait impl and the substrate-primitive
12516 // [`RestartPolicy::as_str`] `pub const fn` accessor resolve to
12517 // the same three-arm emit-set across every arm the exhaustive
12518 // [`RestartPolicy::ALL`] slice enumerates. Rust's standard
12519 // library does not carry a blanket `impl<T: AsRef<str>>
12520 // From<&T> for String` (nor an `impl<T: fmt::Display> From<&T>
12521 // for String`), so the borrowed-input owned-`String` forward-
12522 // projection axis is a distinct trait-idiomatic surface that a
12523 // `let key: String = (&policy).into();`-shaped call site
12524 // reaches through this impl and no other — the paired sibling
12525 // `From<RestartPolicy> for String` impl forces every borrowed-
12526 // input call site through an explicit `Copy` deref
12527 // (`String::from(*policy)`) or an `.as_str().to_owned()` /
12528 // `.to_string()` detour. Peer of the first-mover
12529 // [`restart_strategy_from_into_borrowed_owned_string_routes_through_as_str_accessor`]
12530 // (579385f) — extends the trait-idiomatic borrowed-input
12531 // owned-`String` forward-projection axis onto the second-of-
12532 // two M2 OTP-shape closed-set typed enums on the caixa surface
12533 // (per-child restart-decision-policy sibling on the same M2
12534 // `:supervisor` slot).
12535 for &variant in RestartPolicy::ALL {
12536 let via_trait: String = <String as From<&RestartPolicy>>::from(&variant);
12537 let via_method: &'static str = variant.as_str();
12538 assert_eq!(
12539 via_trait.as_str(),
12540 via_method,
12541 "From<&RestartPolicy> for String impl must round-trip \
12542 &RestartPolicy::{variant:?} to the same lifted \
12543 SUPERVISOR_CHILD_RESTART_* const RestartPolicy::as_str \
12544 returns — divergence signals a silent detour off the \
12545 substrate-primitive accessor"
12546 );
12547 let via_into: String = (&variant).into();
12548 assert_eq!(
12549 via_into.as_str(),
12550 via_method,
12551 "Into<String>::into on &RestartPolicy::{variant:?} must \
12552 byte-equal RestartPolicy::as_str on the same input — \
12553 the blanket-derived Into shape must resolve to the \
12554 same as_str dispatch as the explicit From impl"
12555 );
12556 }
12557 }
12558
12559 #[test]
12560 fn restart_policy_from_into_borrowed_owned_string_agrees_with_paired_axes_on_every_arm() {
12561 // Cross-axis partition pin: the newly lifted trait-idiomatic
12562 // borrowed-input owned-`String` `From<&RestartPolicy> for
12563 // String` (this lift), the paired owned-input owned-`String`
12564 // `From<RestartPolicy> for String` (7851725), the paired
12565 // borrowed-input owned-`&'static str` `From<&RestartPolicy>
12566 // for &'static str` (842c7f3), and the paired owned-input
12567 // owned-`&'static str` `From<RestartPolicy> for &'static str`
12568 // (9fb37d0) — every corner of the `{Self, &Self} × {&'static
12569 // str, String}` 2×2 trait-idiomatic projection family — must
12570 // resolve identically on every arm, locking the four
12571 // return-shape × input-shape paths together so any future
12572 // detour trips at caixa-core test time. Also byte-parity
12573 // witness against the sibling [`ToString::to_string`] surface
12574 // routed through [`std::fmt::Display`] and a direct round-trip
12575 // witness through the paired trait-idiomatic reverse
12576 // [`TryFrom<&str>`] axis on the owned-`String`'s
12577 // [`String::as_str`] borrow that closes the two-way
12578 // `&Self → String → Self` round-trip on the trait-idiomatic
12579 // borrowed-input owned-`String` forward + reverse axis pair.
12580 // Peer of the first-mover
12581 // [`restart_strategy_from_into_borrowed_owned_string_agrees_with_paired_axes_on_every_arm`]
12582 // (579385f) — closes the whole `{Self, &Self} × {&'static str,
12583 // String}` 2×2 projection corner on both M2 OTP-shape sibling
12584 // peers.
12585 for &variant in RestartPolicy::ALL {
12586 let borrowed_string: String = <String as From<&RestartPolicy>>::from(&variant);
12587 let owned_string: String = <String as From<RestartPolicy>>::from(variant);
12588 let borrowed_static: &'static str =
12589 <&'static str as From<&RestartPolicy>>::from(&variant);
12590 let owned_static: &'static str = <&'static str as From<RestartPolicy>>::from(variant);
12591 assert_eq!(
12592 borrowed_string, owned_string,
12593 "From<&RestartPolicy> for String and From<RestartPolicy> \
12594 for String must resolve identically on \
12595 RestartPolicy::{variant:?} — divergence signals the \
12596 borrowed-input and owned-input owned-`String` \
12597 forward-projection input-shape paths have drifted onto \
12598 different emit-sets"
12599 );
12600 assert_eq!(
12601 borrowed_string.as_str(),
12602 borrowed_static,
12603 "From<&RestartPolicy> for String and From<&RestartPolicy> \
12604 for &'static str must resolve identically on \
12605 RestartPolicy::{variant:?} — divergence signals the \
12606 borrowed-input `&'static str` and owned-`String` \
12607 return-shape paths have drifted onto different \
12608 emit-sets"
12609 );
12610 assert_eq!(
12611 borrowed_string.as_str(),
12612 owned_static,
12613 "From<&RestartPolicy> for String and From<RestartPolicy> \
12614 for &'static str must resolve identically on \
12615 RestartPolicy::{variant:?} — divergence signals a \
12616 break in the diagonal corner of the {{Self, &Self}} × \
12617 {{&'static str, String}} 2×2 trait-idiomatic \
12618 projection family"
12619 );
12620 let via_to_string: String = variant.to_string();
12621 assert_eq!(
12622 borrowed_string, via_to_string,
12623 "From<&RestartPolicy> for String must byte-equal \
12624 RestartPolicy::to_string on RestartPolicy::{variant:?} \
12625 — divergence signals the trait-idiomatic borrowed-input \
12626 owned-`String` forward-projection axis and the \
12627 ToString-through-Display axis have drifted onto \
12628 different emit-sets"
12629 );
12630 }
12631 let via_iter: Vec<String> = RestartPolicy::ALL.iter().map(String::from).collect();
12632 let via_method: Vec<String> = RestartPolicy::ALL
12633 .iter()
12634 .map(|p| p.as_str().to_owned())
12635 .collect();
12636 assert_eq!(
12637 via_iter, via_method,
12638 "`.iter().map(String::from)` over RestartPolicy::ALL — a \
12639 call site whose iteration axis holds `&RestartPolicy` by \
12640 construction — must byte-equal `.iter().map(|p| \
12641 p.as_str().to_owned())` on every arm — the borrowed-input \
12642 owned-`String` `From<&RestartPolicy> for String` axis is \
12643 what makes the `String::from` composition route through \
12644 the substrate-primitive `RestartPolicy::as_str` accessor \
12645 without a spurious `Copy` deref (which would only be \
12646 reachable through the owned-input `From<RestartPolicy> \
12647 for String` axis by first calling `.copied()` on the \
12648 iterator)"
12649 );
12650 for &variant in RestartPolicy::ALL {
12651 let emitted: String = (&variant).into();
12652 let re_parsed: Result<RestartPolicy, ()> =
12653 <RestartPolicy as TryFrom<&str>>::try_from(emitted.as_str());
12654 assert_eq!(
12655 re_parsed,
12656 Ok(variant),
12657 "trait-idiomatic borrowed-input owned-`String` \
12658 forward-projection + reverse-projection axis pair must \
12659 round-trip &RestartPolicy::{variant:?} through \
12660 `.into::<String>()` on the borrowed-input surface and \
12661 back through `TryFrom<&str>` on the owned-`String`'s \
12662 String::as_str borrow — a break signals the \
12663 borrowed-input owned-`String` forward-emit and \
12664 reverse-parse axes have drifted onto different \
12665 vocabularies"
12666 );
12667 }
12668 }
12669
12670 #[test]
12671 fn restart_policy_from_into_static_cow_str_routes_through_as_str_accessor() {
12672 // Fail-before-pass-after byte-parity pin on the newly lifted
12673 // `impl From<RestartPolicy> for std::borrow::Cow<'static, str>` —
12674 // asserts the standard-library trait impl and the substrate-
12675 // primitive [`super::RestartPolicy::as_str`] `pub const fn`
12676 // accessor resolve to the same three-arm emit-set across every
12677 // arm the exhaustive [`super::RestartPolicy::ALL`] slice
12678 // enumerates. Rust's standard library does not carry a blanket
12679 // `impl<T: AsRef<str>> From<T> for Cow<'static, str>` (nor an
12680 // `impl<T: fmt::Display> From<T> for Cow<'static, str>`), so
12681 // the `Cow<'static, str>` forward-projection axis is a
12682 // distinct trait-idiomatic surface that a
12683 // `let key: Cow<'static, str> = policy.into();`-shaped call
12684 // site reaches through this impl and no other — the paired
12685 // sibling `From<RestartPolicy> for &'static str` and
12686 // `From<RestartPolicy> for String` impls force every
12687 // `Cow<'static, str>`-parameterized call site through a
12688 // `Cow::Borrowed(policy.as_str())` /
12689 // `Cow::Owned(policy.to_string())` composition whose type
12690 // bounds have no compile-time link back to the substrate
12691 // primitive.
12692 //
12693 // Also asserts the projection lands on the zero-alloc
12694 // [`std::borrow::Cow::Borrowed`] arm (not the
12695 // [`std::borrow::Cow::Owned`] arm) — the substrate-primitive
12696 // [`super::RestartPolicy::as_str`] accessor's `&'static str`
12697 // return lifetime by construction makes the borrowed arm the
12698 // type-correct projection with no runtime allocation. Any
12699 // future silent detour that routes the impl through the owned
12700 // arm (an accidental `Cow::Owned(policy.to_string())` rewrite
12701 // that would allocate on every call site where the
12702 // `&'static str` return of [`super::RestartPolicy::as_str`]
12703 // makes the zero-alloc borrowed projection type-correct) trips
12704 // at caixa-core test time under the
12705 // [`std::borrow::Cow::Borrowed`] discriminator witness rather
12706 // than at a downstream `Cow<'static, str>`-bound consumer's
12707 // silent allocation.
12708 //
12709 // Second peer on the substrate-wide trait-idiomatic
12710 // [`std::borrow::Cow<'static, str>`] forward-projection family
12711 // to extend the axis off the top-level [`super::CaixaKind`]
12712 // enum (99c1735 owned-input, d45c409 borrowed-input) onto the
12713 // second (and second-of-two-in-M2) M2 OTP-shape closed-set
12714 // fieldless typed enum peer on the caixa surface — closes the
12715 // M2 OTP-shape tier of the campaign on the owned-input axis
12716 // (both sibling peers, `RestartStrategy` and `RestartPolicy`,
12717 // now carry the owned-input Cow<'static, str> forward
12718 // projection).
12719 for &variant in RestartPolicy::ALL {
12720 let via_trait: std::borrow::Cow<'static, str> =
12721 <std::borrow::Cow<'static, str> as From<RestartPolicy>>::from(variant);
12722 let via_method: &'static str = variant.as_str();
12723 assert_eq!(
12724 via_trait.as_ref(),
12725 via_method,
12726 "From<RestartPolicy> for Cow<'static, str> impl must \
12727 round-trip RestartPolicy::{variant:?} to the same \
12728 lifted SUPERVISOR_CHILD_RESTART_* const \
12729 RestartPolicy::as_str returns — divergence signals a \
12730 silent detour off the substrate-primitive accessor"
12731 );
12732 assert!(
12733 matches!(via_trait, std::borrow::Cow::Borrowed(_)),
12734 "From<RestartPolicy> for Cow<'static, str> impl must \
12735 land on the zero-alloc Cow::Borrowed arm on \
12736 RestartPolicy::{variant:?} — a Cow::Owned outcome \
12737 signals the projection has silently allocated where \
12738 the substrate-primitive RestartPolicy::as_str \
12739 `&'static str` return makes the borrowed arm the \
12740 type-correct projection"
12741 );
12742 let via_into: std::borrow::Cow<'static, str> = variant.into();
12743 assert_eq!(
12744 via_into.as_ref(),
12745 via_method,
12746 "Into<Cow<'static, str>>::into on \
12747 RestartPolicy::{variant:?} must byte-equal \
12748 RestartPolicy::as_str on the same input — the \
12749 blanket-derived Into shape must resolve to the same \
12750 as_str dispatch as the explicit From impl"
12751 );
12752 assert!(
12753 matches!(via_into, std::borrow::Cow::Borrowed(_)),
12754 "Into<Cow<'static, str>>::into on \
12755 RestartPolicy::{variant:?} must land on the \
12756 zero-alloc Cow::Borrowed arm — the blanket-derived \
12757 Into shape must resolve to the same Cow::Borrowed \
12758 dispatch as the explicit From impl"
12759 );
12760 }
12761 }
12762
12763 #[test]
12764 fn restart_policy_from_into_static_cow_str_agrees_with_paired_axes_on_every_arm() {
12765 // Cross-axis partition pin: the newly lifted trait-idiomatic
12766 // `From<RestartPolicy> for std::borrow::Cow<'static, str>`
12767 // (this lift), the paired owned-input `From<RestartPolicy>
12768 // for &'static str` (9fb37d0), and the paired owned-input
12769 // `From<RestartPolicy> for String` (7851725) forward
12770 // projections must resolve identically on every arm, locking
12771 // the three return-shape paths together by construction so any
12772 // future detour trips at caixa-core test time. Also byte-parity
12773 // witness against the sibling [`ToString::to_string`] surface
12774 // routed through [`std::fmt::Display`] — every owned-heap-
12775 // string path (the `Cow::Owned` promotion of this axis's
12776 // `.into_owned()`, `From<RestartPolicy> for String`, and
12777 // `.to_string()`) resolves to the same lifted
12778 // [`crate::render::SUPERVISOR_CHILD_RESTART_*`] const per arm.
12779 //
12780 // Then a `.iter().copied().map(std::borrow::Cow::from)` pipe
12781 // witness over [`super::RestartPolicy::ALL`] that
12782 // materializes the three-arm accept-set through the
12783 // [`std::borrow::Cow<'static, str>`] axis alone — the exact
12784 // shape a future `axum::response::IntoResponse` per-policy
12785 // rejection-body composer, a future M4 admission-webhook
12786 // per-policy rejection-reason emitter whose typing rules out
12787 // the sibling [`AsRef<str>`] borrowed return, or a future
12788 // substrate-wide per-policy diagnostic surface that binds
12789 // through a [`Cow<'static, str>`] boundary reaches through.
12790 // The pipe witness also pins the zero-alloc discipline: every
12791 // element in the collected vector satisfies the
12792 // [`std::borrow::Cow::Borrowed`] arm predicate, so a future
12793 // accidental silent-allocation regression on the pipe's
12794 // iteration axis is a caixa-core-test-time failure. Peer of
12795 // the first-mover
12796 // [`restart_strategy_from_into_static_cow_str_agrees_with_paired_axes_on_every_arm`]
12797 // (7dd28b3) on the sibling M2 OTP-shape sibling-restart axis
12798 // — closes the whole owned-input `Cow<'static, str>` +
12799 // paired `{&'static str, String}` cross-axis-parity corner on
12800 // both M2 OTP-shape sibling peers.
12801 for &variant in RestartPolicy::ALL {
12802 let via_cow: std::borrow::Cow<'static, str> =
12803 <std::borrow::Cow<'static, str> as From<RestartPolicy>>::from(variant);
12804 let via_static: &'static str = <&'static str as From<RestartPolicy>>::from(variant);
12805 let via_string: String = <String as From<RestartPolicy>>::from(variant);
12806 assert_eq!(
12807 via_cow.as_ref(),
12808 via_static,
12809 "From<RestartPolicy> for Cow<'static, str> and \
12810 From<RestartPolicy> for &'static str must resolve \
12811 identically on RestartPolicy::{variant:?} — \
12812 divergence signals the Cow<'static, str> and \
12813 &'static str return-shape paths have drifted onto \
12814 different emit-sets"
12815 );
12816 assert_eq!(
12817 via_cow.as_ref(),
12818 via_string.as_str(),
12819 "From<RestartPolicy> for Cow<'static, str> and \
12820 From<RestartPolicy> for String must resolve \
12821 identically on RestartPolicy::{variant:?} — \
12822 divergence signals the Cow<'static, str> and String \
12823 return-shape paths have drifted onto different \
12824 emit-sets"
12825 );
12826 let via_to_string: String = variant.to_string();
12827 assert_eq!(
12828 via_cow.as_ref(),
12829 via_to_string.as_str(),
12830 "From<RestartPolicy> for Cow<'static, str> must \
12831 byte-equal RestartPolicy::to_string on \
12832 RestartPolicy::{variant:?} — divergence signals the \
12833 trait-idiomatic Cow<'static, str> forward-projection \
12834 axis and the ToString-through-Display axis have \
12835 drifted onto different emit-sets"
12836 );
12837 }
12838 let via_iter: Vec<std::borrow::Cow<'static, str>> = RestartPolicy::ALL
12839 .iter()
12840 .copied()
12841 .map(std::borrow::Cow::from)
12842 .collect();
12843 let via_method: Vec<std::borrow::Cow<'static, str>> = RestartPolicy::ALL
12844 .iter()
12845 .map(|p| std::borrow::Cow::Borrowed(p.as_str()))
12846 .collect();
12847 assert_eq!(
12848 via_iter, via_method,
12849 "`.iter().copied().map(Cow::from)` over \
12850 RestartPolicy::ALL must byte-equal `.iter().map(|p| \
12851 Cow::Borrowed(p.as_str()))` on every arm — the \
12852 trait-idiomatic `From<RestartPolicy> for Cow<'static, \
12853 str>` axis is what makes the `Cow::from` composition \
12854 route through the substrate-primitive \
12855 `RestartPolicy::as_str` accessor with the zero-alloc \
12856 Cow::Borrowed arm by construction, rather than a \
12857 per-call-site `Cow::Owned(policy.to_string())` \
12858 allocation"
12859 );
12860 for cow in &via_iter {
12861 assert!(
12862 matches!(cow, std::borrow::Cow::Borrowed(_)),
12863 "every element of the \
12864 .iter().copied().map(Cow::from) pipe over \
12865 RestartPolicy::ALL must land on the zero-alloc \
12866 Cow::Borrowed arm — a Cow::Owned outcome on any arm \
12867 signals the pipe's iteration axis has silently \
12868 allocated where the substrate-primitive \
12869 RestartPolicy::as_str `&'static str` return makes \
12870 the borrowed arm the type-correct projection"
12871 );
12872 }
12873 }
12874
12875 #[test]
12876 fn restart_policy_from_borrowed_into_static_cow_str_routes_through_as_str_accessor() {
12877 // Fail-before-pass-after byte-parity pin on the newly lifted
12878 // `impl From<&RestartPolicy> for std::borrow::Cow<'static, str>` —
12879 // asserts the borrowed-input standard-library trait impl and
12880 // the substrate-primitive [`super::RestartPolicy::as_str`]
12881 // `pub const fn` accessor resolve to the same three-arm emit-
12882 // set across every arm the exhaustive
12883 // [`super::RestartPolicy::ALL`] slice enumerates. Rust's
12884 // standard library does not carry a blanket
12885 // `impl<T: AsRef<str>> From<&T> for Cow<'static, str>` (nor a
12886 // `Copy`-based `impl<T: Copy, U: From<T>> From<&T> for U`), so
12887 // the borrowed-input `Cow<'static, str>` forward-projection
12888 // axis is a distinct trait-idiomatic surface that a
12889 // `let key: Cow<'static, str> = (&policy).into();`-shaped
12890 // call site or a
12891 // `RestartPolicy::ALL.iter().map(Cow::from)`-shaped pipe
12892 // reaches through this impl and no other — the paired owned-
12893 // input `From<RestartPolicy> for Cow<'static, str>` impl
12894 // (0612398) forces every borrowed-input call site through an
12895 // explicit `Copy` deref (`Cow::from(*policy)`) or a
12896 // `Cow::Borrowed(policy.as_str())` open-code whose type
12897 // bounds have no compile-time link back to the substrate
12898 // primitive.
12899 //
12900 // Also asserts the projection lands on the zero-alloc
12901 // [`std::borrow::Cow::Borrowed`] arm (not the
12902 // [`std::borrow::Cow::Owned`] arm) — the substrate-primitive
12903 // [`super::RestartPolicy::as_str`] accessor's `&'static str`
12904 // return lifetime by construction makes the borrowed arm the
12905 // type-correct projection with no runtime allocation on the
12906 // borrowed-input surface just as on the paired owned-input
12907 // surface.
12908 //
12909 // Closes the `{Self, &Self}` input-shape corner on the M2
12910 // OTP-shape per-child-restart [`Cow<'static, str>`] axis on
12911 // the second-of-two-in-M2 closed-set fieldless typed enum peer
12912 // on the caixa surface (`:supervisor :children :restart`),
12913 // exactly as d45c409 closed it on the top-level
12914 // [`super::CaixaKind`] one commit after the owning half
12915 // (99c1735) landed and as 9b3e4b3 closed it on the sibling
12916 // M2 OTP-shape [`super::RestartStrategy`] one commit after
12917 // (7dd28b3) landed. This lift closes the whole M2 OTP-shape
12918 // tier of the substrate-wide Cow<'static, str> forward-
12919 // projection campaign on both input-shape corners
12920 // ({Self, &Self}) of both M2 OTP-shape sibling peers.
12921 for &variant in RestartPolicy::ALL {
12922 let via_trait: std::borrow::Cow<'static, str> =
12923 <std::borrow::Cow<'static, str> as From<&RestartPolicy>>::from(&variant);
12924 let via_method: &'static str = variant.as_str();
12925 assert_eq!(
12926 via_trait.as_ref(),
12927 via_method,
12928 "From<&RestartPolicy> for Cow<'static, str> impl must \
12929 round-trip &RestartPolicy::{variant:?} to the same \
12930 lifted SUPERVISOR_CHILD_RESTART_* const \
12931 RestartPolicy::as_str returns — divergence signals a \
12932 silent detour off the substrate-primitive accessor"
12933 );
12934 assert!(
12935 matches!(via_trait, std::borrow::Cow::Borrowed(_)),
12936 "From<&RestartPolicy> for Cow<'static, str> impl must \
12937 land on the zero-alloc Cow::Borrowed arm on \
12938 &RestartPolicy::{variant:?} — a Cow::Owned outcome \
12939 signals the projection has silently allocated where \
12940 the substrate-primitive RestartPolicy::as_str \
12941 `&'static str` return makes the borrowed arm the \
12942 type-correct projection"
12943 );
12944 let via_into: std::borrow::Cow<'static, str> = (&variant).into();
12945 assert_eq!(
12946 via_into.as_ref(),
12947 via_method,
12948 "Into<Cow<'static, str>>::into on \
12949 &RestartPolicy::{variant:?} must byte-equal \
12950 RestartPolicy::as_str on the same input — the \
12951 blanket-derived Into shape must resolve to the same \
12952 as_str dispatch as the explicit From impl"
12953 );
12954 assert!(
12955 matches!(via_into, std::borrow::Cow::Borrowed(_)),
12956 "Into<Cow<'static, str>>::into on \
12957 &RestartPolicy::{variant:?} must land on the \
12958 zero-alloc Cow::Borrowed arm — the blanket-derived \
12959 Into shape must resolve to the same Cow::Borrowed \
12960 dispatch as the explicit From impl"
12961 );
12962 }
12963 }
12964
12965 #[test]
12966 fn restart_policy_from_borrowed_into_static_cow_str_agrees_with_paired_axes_on_every_arm() {
12967 // Cross-axis partition pin: the newly lifted trait-idiomatic
12968 // borrowed-input `From<&RestartPolicy> for
12969 // std::borrow::Cow<'static, str>` (this lift), the paired
12970 // owned-input `From<RestartPolicy> for
12971 // std::borrow::Cow<'static, str>` (0612398), the paired
12972 // borrowed-input owned-`&'static str` `From<&RestartPolicy>
12973 // for &'static str`, and the paired borrowed-input owned-
12974 // `String` `From<&RestartPolicy> for String` must resolve
12975 // identically on every arm, locking the four
12976 // return-shape × input-shape paths together by construction so
12977 // any future detour trips at caixa-core test time. Also byte-
12978 // parity witness against the sibling [`ToString::to_string`]
12979 // surface routed through [`std::fmt::Display`] — every owned-
12980 // heap-string path (this axis's `.into_owned()` promotion, the
12981 // paired [`From<&RestartPolicy> for String`], and
12982 // `.to_string()`) resolves to the same lifted
12983 // [`crate::render::SUPERVISOR_CHILD_RESTART_*`] const per arm.
12984 //
12985 // Then a `.iter().map(std::borrow::Cow::from)` pipe witness
12986 // over [`super::RestartPolicy::ALL`] — whose iterator yields
12987 // `&RestartPolicy` by construction, so the borrowed-input
12988 // [`Cow<'static, str>`] axis is what routes the pipe through
12989 // the substrate-primitive [`super::RestartPolicy::as_str`]
12990 // accessor without a spurious [`Copy`] deref (which would only
12991 // be reachable through the owned-input
12992 // [`From<RestartPolicy> for Cow<'static, str>`] axis by first
12993 // calling `.copied()` on the iterator). The pipe witness also
12994 // pins the zero-alloc discipline: every element in the
12995 // collected vector satisfies the [`std::borrow::Cow::Borrowed`]
12996 // arm predicate, so a future accidental silent-allocation
12997 // regression on the pipe's iteration axis is a caixa-core-
12998 // test-time failure. Peer of the sibling
12999 // [`restart_strategy_from_borrowed_into_static_cow_str_agrees_with_paired_axes_on_every_arm`]
13000 // (9b3e4b3) on the M2 OTP-shape sibling-restart axis — closes
13001 // the whole borrowed-input `Cow<'static, str>` +
13002 // paired `{&'static str, String}` cross-axis-parity corner on
13003 // both M2 OTP-shape sibling peers.
13004 for &policy in RestartPolicy::ALL {
13005 let borrowed_cow: std::borrow::Cow<'static, str> =
13006 <std::borrow::Cow<'static, str> as From<&RestartPolicy>>::from(&policy);
13007 let owned_cow: std::borrow::Cow<'static, str> =
13008 <std::borrow::Cow<'static, str> as From<RestartPolicy>>::from(policy);
13009 let borrowed_static: &'static str =
13010 <&'static str as From<&RestartPolicy>>::from(&policy);
13011 let borrowed_string: String = <String as From<&RestartPolicy>>::from(&policy);
13012 assert_eq!(
13013 borrowed_cow, owned_cow,
13014 "From<&RestartPolicy> for Cow<'static, str> and \
13015 From<RestartPolicy> for Cow<'static, str> must \
13016 resolve identically on RestartPolicy::{policy:?} — \
13017 divergence signals the borrowed-input and owned-input \
13018 Cow<'static, str> forward-projection input-shape \
13019 paths have drifted onto different emit-sets"
13020 );
13021 assert_eq!(
13022 borrowed_cow.as_ref(),
13023 borrowed_static,
13024 "From<&RestartPolicy> for Cow<'static, str> and \
13025 From<&RestartPolicy> for &'static str must resolve \
13026 identically on RestartPolicy::{policy:?} — \
13027 divergence signals the borrowed-input Cow<'static, \
13028 str> and &'static str return-shape paths have drifted \
13029 onto different emit-sets"
13030 );
13031 assert_eq!(
13032 borrowed_cow.as_ref(),
13033 borrowed_string.as_str(),
13034 "From<&RestartPolicy> for Cow<'static, str> and \
13035 From<&RestartPolicy> for String must resolve \
13036 identically on RestartPolicy::{policy:?} — \
13037 divergence signals the borrowed-input Cow<'static, \
13038 str> and owned-`String` return-shape paths have \
13039 drifted onto different emit-sets"
13040 );
13041 let via_to_string: String = policy.to_string();
13042 assert_eq!(
13043 borrowed_cow.as_ref(),
13044 via_to_string.as_str(),
13045 "From<&RestartPolicy> for Cow<'static, str> must \
13046 byte-equal RestartPolicy::to_string on \
13047 RestartPolicy::{policy:?} — divergence signals \
13048 the trait-idiomatic borrowed-input Cow<'static, str> \
13049 forward-projection axis and the ToString-through-\
13050 Display axis have drifted onto different emit-sets"
13051 );
13052 }
13053 let via_iter: Vec<std::borrow::Cow<'static, str>> = RestartPolicy::ALL
13054 .iter()
13055 .map(std::borrow::Cow::from)
13056 .collect();
13057 let via_method: Vec<std::borrow::Cow<'static, str>> = RestartPolicy::ALL
13058 .iter()
13059 .map(|p| std::borrow::Cow::Borrowed(p.as_str()))
13060 .collect();
13061 assert_eq!(
13062 via_iter, via_method,
13063 "`.iter().map(Cow::from)` over RestartPolicy::ALL — a \
13064 call site whose iteration axis holds `&RestartPolicy` \
13065 by construction — must byte-equal `.iter().map(|p| \
13066 Cow::Borrowed(p.as_str()))` on every arm — the borrowed-\
13067 input Cow<'static, str> `From<&RestartPolicy> for \
13068 Cow<'static, str>` axis is what makes the `Cow::from` \
13069 composition route through the substrate-primitive \
13070 `RestartPolicy::as_str` accessor with the zero-alloc \
13071 Cow::Borrowed arm by construction and without a spurious \
13072 `Copy` deref (which would only be reachable through the \
13073 owned-input `From<RestartPolicy> for Cow<'static, str>` \
13074 axis by first calling `.copied()` on the iterator)"
13075 );
13076 for cow in &via_iter {
13077 assert!(
13078 matches!(cow, std::borrow::Cow::Borrowed(_)),
13079 "every element of the .iter().map(Cow::from) pipe \
13080 over RestartPolicy::ALL must land on the zero-\
13081 alloc Cow::Borrowed arm — a Cow::Owned outcome on \
13082 any arm signals the pipe's iteration axis has \
13083 silently allocated where the substrate-primitive \
13084 RestartPolicy::as_str `&'static str` return makes \
13085 the borrowed arm the type-correct projection"
13086 );
13087 }
13088 }
13089
13090 #[test]
13091 fn restart_policy_from_into_box_str_routes_through_as_str_accessor() {
13092 // Fail-before-pass-after byte-parity pin on the newly lifted
13093 // `impl From<RestartPolicy> for Box<str>` — asserts the
13094 // owned-input standard-library trait impl and the
13095 // substrate-primitive [`super::RestartPolicy::as_str`]
13096 // `pub const fn` accessor resolve to the same three-arm emit-
13097 // set across every arm the exhaustive
13098 // [`super::RestartPolicy::ALL`] slice enumerates. Extends the
13099 // substrate-wide `Box<str>` forward-projection campaign tier
13100 // opened one commit prior (69ef45c) on the paired sibling-
13101 // restart [`RestartStrategy`] onto the second (and third-and-
13102 // final) M2 OTP-shape closed-set fieldless typed enum peer on
13103 // the caixa surface (`:children :restart`), immediately after
13104 // the paired `Cow<'static, str>` axis (0612398 / b4dc55c)
13105 // closed the
13106 // `{Self, &Self} × {&'static str, String, Cow<'static, str>}`
13107 // 2×3 corner on this enum. Rust's standard library carries
13108 // `impl From<&str> for Box<str>` and
13109 // `impl From<String> for Box<str>` but no blanket
13110 // `impl<T: AsRef<str>> From<T> for Box<str>`, so this axis is
13111 // a distinct trait-idiomatic surface that a
13112 // `let key: Box<str> = policy.into();`-shaped call site
13113 // reaches through this impl and no other — a paired
13114 // `Box::from(policy.as_str())` open-code has no compile-time
13115 // link back to the substrate primitive. Peer of the sibling
13116 // [`restart_strategy_from_into_box_str_routes_through_as_str_accessor`]
13117 // (69ef45c) — extends the trait-idiomatic owned-input
13118 // [`Box<str>`] forward-projection axis onto the third and
13119 // final M2-OTP-shape closed-set typed enum on the caixa
13120 // surface.
13121 for &variant in RestartPolicy::ALL {
13122 let via_trait: Box<str> = <Box<str> as From<RestartPolicy>>::from(variant);
13123 let via_method: &'static str = variant.as_str();
13124 assert_eq!(
13125 via_trait.as_ref(),
13126 via_method,
13127 "From<RestartPolicy> for Box<str> impl must round-\
13128 trip RestartPolicy::{variant:?} to the same lifted \
13129 SUPERVISOR_CHILD_RESTART_* const RestartPolicy::as_str \
13130 returns — divergence signals a silent detour off the \
13131 substrate-primitive accessor"
13132 );
13133 let via_into: Box<str> = variant.into();
13134 assert_eq!(
13135 via_into.as_ref(),
13136 via_method,
13137 "Into<Box<str>>::into on RestartPolicy::{variant:?} \
13138 must byte-equal RestartPolicy::as_str on the same \
13139 input — the blanket-derived Into shape must resolve \
13140 to the same as_str dispatch as the explicit From impl"
13141 );
13142 }
13143 }
13144
13145 #[test]
13146 fn restart_policy_from_borrowed_into_box_str_routes_through_as_str_accessor() {
13147 // Fail-before-pass-after byte-parity pin on the newly lifted
13148 // `impl From<&RestartPolicy> for Box<str>` — asserts the
13149 // borrowed-input standard-library trait impl and the
13150 // substrate-primitive [`super::RestartPolicy::as_str`]
13151 // `pub const fn` accessor resolve to the same three-arm emit-
13152 // set across every arm the exhaustive
13153 // [`super::RestartPolicy::ALL`] slice enumerates. Rust's
13154 // standard library does not carry a blanket
13155 // `impl<T: AsRef<str>> From<&T> for Box<str>` (nor a
13156 // `Copy`-based `impl<T: Copy, U: From<T>> From<&T> for U`),
13157 // so the borrowed-input `Box<str>` forward-projection axis
13158 // is a distinct trait-idiomatic surface that a
13159 // `let key: Box<str> = (&policy).into();`-shaped call site
13160 // or a `RestartPolicy::ALL.iter().map(Box::<str>::from)`-
13161 // shaped pipe reaches through this impl and no other — the
13162 // paired owned-input `From<RestartPolicy> for Box<str>`
13163 // impl (0a1b313) forces every borrowed-input call site
13164 // through an explicit `Copy` deref
13165 // (`Box::<str>::from((*policy).as_str())`) or a
13166 // `Box::<str>::from(policy.as_str())` open-code whose
13167 // type bounds have no compile-time link back to the
13168 // substrate primitive.
13169 //
13170 // Fourth (and closing) peer on the substrate-wide trait-
13171 // idiomatic [`Box<str>`] forward-projection family on the
13172 // M2 OTP-shape tier — closes the `{Self, &Self}` input-
13173 // shape corner of the [`Box<str>`] axis on the second (and
13174 // third-and-final) M2 OTP-shape closed-set fieldless typed
13175 // enum peer on the caixa surface (`:children :restart`),
13176 // exactly as b4dc55c closed the paired [`Cow<'static, str>`]
13177 // axis one commit after its owning half (0612398) landed
13178 // on this enum. Every remaining closed-set fieldless typed
13179 // enum peer on the M3 mesh-shape / outside-M3 caixa-core /
13180 // render-side / outside-caixa-core tiers is a future
13181 // target of the campaign.
13182 //
13183 // Also byte-parity witness against the paired owned-input
13184 // [`From<RestartPolicy> for Box<str>`] and the sibling
13185 // borrowed-input [`From<&RestartPolicy> for &'static str`],
13186 // [`From<&RestartPolicy> for String`], and
13187 // [`From<&RestartPolicy> for Cow<'static, str>`]
13188 // return-shape axes — locking the four
13189 // return-shape × input-shape paths together by construction
13190 // so any future detour trips at caixa-core test time. Then a
13191 // `.iter().map(Box::<str>::from)` pipe witness over
13192 // [`super::RestartPolicy::ALL`] — whose iterator yields
13193 // `&RestartPolicy` by construction, so the borrowed-input
13194 // [`Box<str>`] axis is what routes the pipe through the
13195 // substrate-primitive [`super::RestartPolicy::as_str`]
13196 // accessor without a spurious [`Copy`] deref (which would
13197 // only be reachable through the owned-input
13198 // [`From<RestartPolicy> for Box<str>`] axis by first
13199 // calling `.copied()` on the iterator).
13200 for &variant in RestartPolicy::ALL {
13201 let via_trait: Box<str> = <Box<str> as From<&RestartPolicy>>::from(&variant);
13202 let via_method: &'static str = variant.as_str();
13203 assert_eq!(
13204 via_trait.as_ref(),
13205 via_method,
13206 "From<&RestartPolicy> for Box<str> impl must round-\
13207 trip &RestartPolicy::{variant:?} to the same lifted \
13208 SUPERVISOR_CHILD_RESTART_* const RestartPolicy::as_str \
13209 returns — divergence signals a silent detour off the \
13210 substrate-primitive accessor"
13211 );
13212 let via_into: Box<str> = (&variant).into();
13213 assert_eq!(
13214 via_into.as_ref(),
13215 via_method,
13216 "Into<Box<str>>::into on &RestartPolicy::{variant:?} \
13217 must byte-equal RestartPolicy::as_str on the same \
13218 input — the blanket-derived Into shape must resolve \
13219 to the same as_str dispatch as the explicit From impl"
13220 );
13221 let owned_box: Box<str> = <Box<str> as From<RestartPolicy>>::from(variant);
13222 assert_eq!(
13223 via_trait, owned_box,
13224 "From<&RestartPolicy> for Box<str> and \
13225 From<RestartPolicy> for Box<str> must resolve \
13226 identically on RestartPolicy::{variant:?} — \
13227 divergence signals the borrowed-input and owned-input \
13228 Box<str> forward-projection input-shape paths have \
13229 drifted onto different emit-sets"
13230 );
13231 let borrowed_static: &'static str =
13232 <&'static str as From<&RestartPolicy>>::from(&variant);
13233 assert_eq!(
13234 via_trait.as_ref(),
13235 borrowed_static,
13236 "From<&RestartPolicy> for Box<str> and \
13237 From<&RestartPolicy> for &'static str must resolve \
13238 identically on RestartPolicy::{variant:?} — \
13239 divergence signals the borrowed-input Box<str> and \
13240 &'static str return-shape paths have drifted onto \
13241 different emit-sets"
13242 );
13243 let borrowed_string: String = <String as From<&RestartPolicy>>::from(&variant);
13244 assert_eq!(
13245 via_trait.as_ref(),
13246 borrowed_string.as_str(),
13247 "From<&RestartPolicy> for Box<str> and \
13248 From<&RestartPolicy> for String must resolve \
13249 identically on RestartPolicy::{variant:?} — \
13250 divergence signals the borrowed-input Box<str> and \
13251 owned-`String` return-shape paths have drifted onto \
13252 different emit-sets"
13253 );
13254 let borrowed_cow: std::borrow::Cow<'static, str> =
13255 <std::borrow::Cow<'static, str> as From<&RestartPolicy>>::from(&variant);
13256 assert_eq!(
13257 via_trait.as_ref(),
13258 borrowed_cow.as_ref(),
13259 "From<&RestartPolicy> for Box<str> and \
13260 From<&RestartPolicy> for Cow<'static, str> must \
13261 resolve identically on RestartPolicy::{variant:?} — \
13262 divergence signals the borrowed-input Box<str> and \
13263 Cow<'static, str> return-shape paths have drifted \
13264 onto different emit-sets"
13265 );
13266 }
13267 let via_iter: Vec<Box<str>> = RestartPolicy::ALL.iter().map(Box::<str>::from).collect();
13268 let via_method: Vec<Box<str>> = RestartPolicy::ALL
13269 .iter()
13270 .map(|p| Box::<str>::from(p.as_str()))
13271 .collect();
13272 assert_eq!(
13273 via_iter, via_method,
13274 "`.iter().map(Box::<str>::from)` over \
13275 RestartPolicy::ALL — a call site whose iteration axis \
13276 holds `&RestartPolicy` by construction — must byte-\
13277 equal `.iter().map(|p| Box::<str>::from(p.as_str()))` \
13278 on every arm — the borrowed-input Box<str> \
13279 `From<&RestartPolicy> for Box<str>` axis is what \
13280 makes the `Box::<str>::from` composition route through \
13281 the substrate-primitive `RestartPolicy::as_str` \
13282 accessor without a spurious `Copy` deref (which would \
13283 only be reachable through the owned-input \
13284 `From<RestartPolicy> for Box<str>` axis by first \
13285 calling `.copied()` on the iterator)"
13286 );
13287 }
13288
13289 #[test]
13290 fn restart_policy_from_into_arc_str_routes_through_as_str_accessor() {
13291 // Fail-before-pass-after byte-parity pin on the newly lifted
13292 // `impl From<RestartPolicy> for std::sync::Arc<str>` — asserts
13293 // the owned-input standard-library trait impl and the
13294 // substrate-primitive [`super::RestartPolicy::as_str`]
13295 // `pub const fn` accessor resolve to the same three-arm emit-
13296 // set across every arm the exhaustive
13297 // [`super::RestartPolicy::ALL`] slice enumerates. Extends the
13298 // substrate-wide [`std::sync::Arc<str>`] forward-projection
13299 // campaign tier opened one projection tier prior (bca2ec8) on
13300 // the paired sibling-restart [`RestartStrategy`] owned-input
13301 // first-mover onto the second (and third-and-final) M2 OTP-
13302 // shape closed-set fieldless typed enum peer on the caixa
13303 // surface (`:children :restart`), immediately after the paired
13304 // [`Box<str>`] axis (0a1b313 / cb1d068) closed the
13305 // `{Self, &Self} × {&'static str, String, Cow<'static, str>,
13306 // Box<str>}` 2×4 corner on this enum. Rust's standard library
13307 // carries `impl From<&str> for std::sync::Arc<str>` and
13308 // `impl From<String> for std::sync::Arc<str>` but no blanket
13309 // `impl<T: AsRef<str>> From<T> for std::sync::Arc<str>` (nor
13310 // an `impl<T: fmt::Display> From<T> for std::sync::Arc<str>`),
13311 // so this axis is a distinct trait-idiomatic surface that a
13312 // `let key: std::sync::Arc<str> = policy.into();`-shaped call
13313 // site reaches through this impl and no other — a paired
13314 // `std::sync::Arc::<str>::from(policy.as_str())` open-code
13315 // has no compile-time link back to the substrate primitive,
13316 // and a two-step `std::sync::Arc::<str>::from(String::from(
13317 // policy))` composition through the owned-`String` axis
13318 // allocates twice (once into the intermediate `String`, once
13319 // into the [`Arc<str>`] on the `From<String>` conversion)
13320 // where the single-step trait impl allocates once.
13321 //
13322 // Cross-axis byte-parity witness against the sibling owned-
13323 // input `{&'static str, String, Cow<'static, str>, Box<str>}`
13324 // return-shape axes — locking the five return-shape paths on
13325 // the owned-input surface together by construction so any
13326 // future detour off the substrate-primitive
13327 // [`super::RestartPolicy::as_str`] accessor trips at caixa-
13328 // core test time.
13329 for &variant in RestartPolicy::ALL {
13330 let via_trait: std::sync::Arc<str> =
13331 <std::sync::Arc<str> as From<RestartPolicy>>::from(variant);
13332 let via_method: &'static str = variant.as_str();
13333 assert_eq!(
13334 via_trait.as_ref(),
13335 via_method,
13336 "From<RestartPolicy> for std::sync::Arc<str> impl \
13337 must round-trip RestartPolicy::{variant:?} to the \
13338 same lifted SUPERVISOR_CHILD_RESTART_* const \
13339 RestartPolicy::as_str returns — divergence signals \
13340 a silent detour off the substrate-primitive accessor"
13341 );
13342 let via_into: std::sync::Arc<str> = variant.into();
13343 assert_eq!(
13344 via_into.as_ref(),
13345 via_method,
13346 "Into<std::sync::Arc<str>>::into on \
13347 RestartPolicy::{variant:?} must byte-equal \
13348 RestartPolicy::as_str on the same input — the \
13349 blanket-derived Into shape must resolve to the same \
13350 as_str dispatch as the explicit From impl"
13351 );
13352 let owned_static: &'static str = <&'static str as From<RestartPolicy>>::from(variant);
13353 assert_eq!(
13354 via_trait.as_ref(),
13355 owned_static,
13356 "From<RestartPolicy> for std::sync::Arc<str> and \
13357 From<RestartPolicy> for &'static str must resolve \
13358 identically on RestartPolicy::{variant:?} — \
13359 divergence signals the owned-input std::sync::Arc<str> \
13360 and &'static str return-shape paths have drifted onto \
13361 different emit-sets"
13362 );
13363 let owned_string: String = <String as From<RestartPolicy>>::from(variant);
13364 assert_eq!(
13365 via_trait.as_ref(),
13366 owned_string.as_str(),
13367 "From<RestartPolicy> for std::sync::Arc<str> and \
13368 From<RestartPolicy> for String must resolve \
13369 identically on RestartPolicy::{variant:?} — \
13370 divergence signals the owned-input std::sync::Arc<str> \
13371 and owned-`String` return-shape paths have drifted \
13372 onto different emit-sets"
13373 );
13374 let owned_cow: std::borrow::Cow<'static, str> =
13375 <std::borrow::Cow<'static, str> as From<RestartPolicy>>::from(variant);
13376 assert_eq!(
13377 via_trait.as_ref(),
13378 owned_cow.as_ref(),
13379 "From<RestartPolicy> for std::sync::Arc<str> and \
13380 From<RestartPolicy> for Cow<'static, str> must \
13381 resolve identically on RestartPolicy::{variant:?} — \
13382 divergence signals the owned-input std::sync::Arc<str> \
13383 and Cow<'static, str> return-shape paths have drifted \
13384 onto different emit-sets"
13385 );
13386 let owned_box: Box<str> = <Box<str> as From<RestartPolicy>>::from(variant);
13387 assert_eq!(
13388 via_trait.as_ref(),
13389 owned_box.as_ref(),
13390 "From<RestartPolicy> for std::sync::Arc<str> and \
13391 From<RestartPolicy> for Box<str> must resolve \
13392 identically on RestartPolicy::{variant:?} — \
13393 divergence signals the owned-input std::sync::Arc<str> \
13394 and Box<str> return-shape paths have drifted onto \
13395 different emit-sets"
13396 );
13397 }
13398 }
13399
13400 #[test]
13401 fn restart_policy_from_borrowed_into_arc_str_routes_through_as_str_accessor() {
13402 // Fail-before-pass-after byte-parity pin on the newly lifted
13403 // `impl From<&RestartPolicy> for std::sync::Arc<str>` —
13404 // asserts the borrowed-input standard-library trait impl and
13405 // the substrate-primitive [`super::RestartPolicy::as_str`]
13406 // `pub const fn` accessor resolve to the same three-arm
13407 // emit-set across every arm the exhaustive
13408 // [`super::RestartPolicy::ALL`] slice enumerates. Rust's
13409 // standard library carries `impl From<&str> for
13410 // std::sync::Arc<str>` and `impl From<String> for
13411 // std::sync::Arc<str>` but no blanket
13412 // `impl<T: AsRef<str>> From<&T> for std::sync::Arc<str>` (nor
13413 // a `Copy`-based `impl<T: Copy, U: From<T>> From<&T> for U`),
13414 // so the borrowed-input [`std::sync::Arc<str>`] forward-
13415 // projection axis is a distinct trait-idiomatic surface that
13416 // a `let key: std::sync::Arc<str> = (&policy).into();`-shaped
13417 // call site or a
13418 // `RestartPolicy::ALL.iter().map(std::sync::Arc::<str>::from)`-
13419 // shaped pipe reaches through this impl and no other — the
13420 // paired owned-input [`From<RestartPolicy> for
13421 // std::sync::Arc<str>`] impl (b05724e) forces every borrowed-
13422 // input call site through an explicit [`Copy`] deref
13423 // (`std::sync::Arc::<str>::from((*policy).as_str())`) or a
13424 // `std::sync::Arc::<str>::from(policy.as_str())` open-code
13425 // whose type bounds have no compile-time link back to the
13426 // substrate primitive.
13427 //
13428 // Closes the `{Self, &Self}` input-shape corner of the
13429 // substrate-wide trait-idiomatic [`std::sync::Arc<str>`]
13430 // forward-projection family on the second (and third-and-
13431 // final) M2 OTP-shape closed-set fieldless typed enum peer
13432 // on the caixa surface (`:children :restart`), one commit
13433 // after b05724e opened the owned-input half — exactly as
13434 // b3e72d7 closed the paired [`std::sync::Arc<str>`] corner on
13435 // the sibling-restart [`RestartStrategy`] first-mover one
13436 // commit after its owning half (bca2ec8) landed, and as
13437 // cb1d068 closed the paired [`Box<str>`] corner on this
13438 // enum one commit after its owning half (0a1b313) landed.
13439 //
13440 // Also byte-parity witness against the paired owned-input
13441 // [`From<RestartPolicy> for std::sync::Arc<str>`] and the
13442 // sibling borrowed-input [`From<&RestartPolicy> for
13443 // &'static str`], [`From<&RestartPolicy> for String`],
13444 // [`From<&RestartPolicy> for Cow<'static, str>`], and
13445 // [`From<&RestartPolicy> for Box<str>`] return-shape axes —
13446 // locking the five return-shape × input-shape paths together
13447 // by construction so any future detour off the substrate-
13448 // primitive [`super::RestartPolicy::as_str`] accessor trips
13449 // at caixa-core test time. Then a
13450 // `.iter().map(std::sync::Arc::<str>::from)` pipe witness
13451 // over [`super::RestartPolicy::ALL`] — whose iterator yields
13452 // `&RestartPolicy` by construction, so the borrowed-input
13453 // [`std::sync::Arc<str>`] axis is what routes the pipe
13454 // through the substrate-primitive
13455 // [`super::RestartPolicy::as_str`] accessor without a
13456 // spurious [`Copy`] deref (which would only be reachable
13457 // through the owned-input
13458 // [`From<RestartPolicy> for std::sync::Arc<str>`] axis by
13459 // first calling `.copied()` on the iterator).
13460 for &variant in RestartPolicy::ALL {
13461 let via_trait: std::sync::Arc<str> =
13462 <std::sync::Arc<str> as From<&RestartPolicy>>::from(&variant);
13463 let via_method: &'static str = variant.as_str();
13464 assert_eq!(
13465 via_trait.as_ref(),
13466 via_method,
13467 "From<&RestartPolicy> for std::sync::Arc<str> impl \
13468 must round-trip &RestartPolicy::{variant:?} to the \
13469 same lifted SUPERVISOR_CHILD_RESTART_* const \
13470 RestartPolicy::as_str returns — divergence signals \
13471 a silent detour off the substrate-primitive accessor"
13472 );
13473 let via_into: std::sync::Arc<str> = (&variant).into();
13474 assert_eq!(
13475 via_into.as_ref(),
13476 via_method,
13477 "Into<std::sync::Arc<str>>::into on \
13478 &RestartPolicy::{variant:?} must byte-equal \
13479 RestartPolicy::as_str on the same input — the \
13480 blanket-derived Into shape must resolve to the same \
13481 as_str dispatch as the explicit From impl"
13482 );
13483 let owned_arc: std::sync::Arc<str> =
13484 <std::sync::Arc<str> as From<RestartPolicy>>::from(variant);
13485 assert_eq!(
13486 via_trait, owned_arc,
13487 "From<&RestartPolicy> for std::sync::Arc<str> and \
13488 From<RestartPolicy> for std::sync::Arc<str> must \
13489 resolve identically on RestartPolicy::{variant:?} — \
13490 divergence signals the borrowed-input and owned-input \
13491 std::sync::Arc<str> forward-projection input-shape \
13492 paths have drifted onto different emit-sets"
13493 );
13494 let borrowed_static: &'static str =
13495 <&'static str as From<&RestartPolicy>>::from(&variant);
13496 assert_eq!(
13497 via_trait.as_ref(),
13498 borrowed_static,
13499 "From<&RestartPolicy> for std::sync::Arc<str> and \
13500 From<&RestartPolicy> for &'static str must resolve \
13501 identically on RestartPolicy::{variant:?} — \
13502 divergence signals the borrowed-input std::sync::Arc<str> \
13503 and &'static str return-shape paths have drifted onto \
13504 different emit-sets"
13505 );
13506 let borrowed_string: String = <String as From<&RestartPolicy>>::from(&variant);
13507 assert_eq!(
13508 via_trait.as_ref(),
13509 borrowed_string.as_str(),
13510 "From<&RestartPolicy> for std::sync::Arc<str> and \
13511 From<&RestartPolicy> for String must resolve \
13512 identically on RestartPolicy::{variant:?} — \
13513 divergence signals the borrowed-input std::sync::Arc<str> \
13514 and owned-`String` return-shape paths have drifted \
13515 onto different emit-sets"
13516 );
13517 let borrowed_cow: std::borrow::Cow<'static, str> =
13518 <std::borrow::Cow<'static, str> as From<&RestartPolicy>>::from(&variant);
13519 assert_eq!(
13520 via_trait.as_ref(),
13521 borrowed_cow.as_ref(),
13522 "From<&RestartPolicy> for std::sync::Arc<str> and \
13523 From<&RestartPolicy> for Cow<'static, str> must \
13524 resolve identically on RestartPolicy::{variant:?} — \
13525 divergence signals the borrowed-input std::sync::Arc<str> \
13526 and Cow<'static, str> return-shape paths have drifted \
13527 onto different emit-sets"
13528 );
13529 let borrowed_box: Box<str> = <Box<str> as From<&RestartPolicy>>::from(&variant);
13530 assert_eq!(
13531 via_trait.as_ref(),
13532 borrowed_box.as_ref(),
13533 "From<&RestartPolicy> for std::sync::Arc<str> and \
13534 From<&RestartPolicy> for Box<str> must resolve \
13535 identically on RestartPolicy::{variant:?} — \
13536 divergence signals the borrowed-input std::sync::Arc<str> \
13537 and Box<str> return-shape paths have drifted onto \
13538 different emit-sets"
13539 );
13540 }
13541 let via_iter: Vec<std::sync::Arc<str>> = RestartPolicy::ALL
13542 .iter()
13543 .map(std::sync::Arc::<str>::from)
13544 .collect();
13545 let via_method: Vec<std::sync::Arc<str>> = RestartPolicy::ALL
13546 .iter()
13547 .map(|p| std::sync::Arc::<str>::from(p.as_str()))
13548 .collect();
13549 assert_eq!(
13550 via_iter, via_method,
13551 "`.iter().map(std::sync::Arc::<str>::from)` over \
13552 RestartPolicy::ALL — a call site whose iteration axis \
13553 holds `&RestartPolicy` by construction — must byte-\
13554 equal `.iter().map(|p| std::sync::Arc::<str>::from(p.as_str()))` \
13555 on every arm — the borrowed-input std::sync::Arc<str> \
13556 `From<&RestartPolicy> for std::sync::Arc<str>` axis is \
13557 what makes the `std::sync::Arc::<str>::from` composition \
13558 route through the substrate-primitive \
13559 `RestartPolicy::as_str` accessor without a spurious \
13560 `Copy` deref (which would only be reachable through the \
13561 owned-input `From<RestartPolicy> for std::sync::Arc<str>` \
13562 axis by first calling `.copied()` on the iterator)"
13563 );
13564 }
13565
13566 #[test]
13567 fn restart_policy_from_into_rc_str_routes_through_as_str_accessor() {
13568 // Fail-before-pass-after byte-parity pin on the newly lifted
13569 // `impl From<RestartPolicy> for std::rc::Rc<str>` — asserts
13570 // the owned-input standard-library trait impl and the
13571 // substrate-primitive [`super::RestartPolicy::as_str`]
13572 // `pub const fn` accessor resolve to the same three-arm emit-
13573 // set across every arm the exhaustive
13574 // [`super::RestartPolicy::ALL`] slice enumerates, and cross-
13575 // witnesses against every sibling owned-input `{&'static str,
13576 // String, Cow<'static, str>, Box<str>, std::sync::Arc<str>}`
13577 // return-shape axis so the six return-shape paths on the
13578 // owned-input surface lock together by construction. Closes
13579 // the substrate-wide [`std::rc::Rc<str>`] forward-projection
13580 // campaign on the M2-OTP-shape `:supervisor :estrategia` +
13581 // `:children :restart` slot pair the sibling-restart
13582 // [`RestartStrategy`] first-mover (71ad8f4) opened one
13583 // projection tier prior on the paired sibling enum.
13584 for &variant in RestartPolicy::ALL {
13585 let via_trait: std::rc::Rc<str> =
13586 <std::rc::Rc<str> as From<RestartPolicy>>::from(variant);
13587 let via_method: &'static str = variant.as_str();
13588 assert_eq!(
13589 via_trait.as_ref(),
13590 via_method,
13591 "From<RestartPolicy> for std::rc::Rc<str> impl must \
13592 round-trip RestartPolicy::{variant:?} to the same \
13593 lifted SUPERVISOR_CHILD_RESTART_* const \
13594 RestartPolicy::as_str returns — divergence signals \
13595 a silent detour off the substrate-primitive accessor"
13596 );
13597 let via_into: std::rc::Rc<str> = variant.into();
13598 assert_eq!(
13599 via_into.as_ref(),
13600 via_method,
13601 "Into<std::rc::Rc<str>>::into on \
13602 RestartPolicy::{variant:?} must byte-equal \
13603 RestartPolicy::as_str on the same input — the \
13604 blanket-derived Into shape must resolve to the same \
13605 as_str dispatch as the explicit From impl"
13606 );
13607 let owned_static: &'static str = <&'static str as From<RestartPolicy>>::from(variant);
13608 assert_eq!(
13609 via_trait.as_ref(),
13610 owned_static,
13611 "From<RestartPolicy> for std::rc::Rc<str> and \
13612 From<RestartPolicy> for &'static str must resolve \
13613 identically on RestartPolicy::{variant:?}"
13614 );
13615 let owned_string: String = <String as From<RestartPolicy>>::from(variant);
13616 assert_eq!(
13617 via_trait.as_ref(),
13618 owned_string.as_str(),
13619 "From<RestartPolicy> for std::rc::Rc<str> and \
13620 From<RestartPolicy> for String must resolve \
13621 identically on RestartPolicy::{variant:?}"
13622 );
13623 let owned_cow: std::borrow::Cow<'static, str> =
13624 <std::borrow::Cow<'static, str> as From<RestartPolicy>>::from(variant);
13625 assert_eq!(
13626 via_trait.as_ref(),
13627 owned_cow.as_ref(),
13628 "From<RestartPolicy> for std::rc::Rc<str> and \
13629 From<RestartPolicy> for Cow<'static, str> must \
13630 resolve identically on RestartPolicy::{variant:?}"
13631 );
13632 let owned_box: Box<str> = <Box<str> as From<RestartPolicy>>::from(variant);
13633 assert_eq!(
13634 via_trait.as_ref(),
13635 owned_box.as_ref(),
13636 "From<RestartPolicy> for std::rc::Rc<str> and \
13637 From<RestartPolicy> for Box<str> must resolve \
13638 identically on RestartPolicy::{variant:?}"
13639 );
13640 let owned_arc: std::sync::Arc<str> =
13641 <std::sync::Arc<str> as From<RestartPolicy>>::from(variant);
13642 assert_eq!(
13643 via_trait.as_ref(),
13644 owned_arc.as_ref(),
13645 "From<RestartPolicy> for std::rc::Rc<str> and \
13646 From<RestartPolicy> for std::sync::Arc<str> must \
13647 resolve identically on RestartPolicy::{variant:?}"
13648 );
13649 }
13650 }
13651
13652 #[test]
13653 fn restart_policy_from_borrowed_into_rc_str_routes_through_as_str_accessor() {
13654 // Fail-before-pass-after byte-parity pin on the newly lifted
13655 // `impl From<&RestartPolicy> for std::rc::Rc<str>` — asserts
13656 // the borrowed-input standard-library trait impl and the
13657 // substrate-primitive [`super::RestartPolicy::as_str`]
13658 // `pub const fn` accessor resolve to the same three-arm emit-
13659 // set across every arm the exhaustive
13660 // [`super::RestartPolicy::ALL`] slice enumerates. Closes the
13661 // `{Self, &Self}` input-shape corner of the
13662 // [`std::rc::Rc<str>`] axis on this enum, cross-witnesses
13663 // against the paired owned-input axis and every sibling
13664 // borrowed-input return-shape axis, and locks the
13665 // `.iter().map(std::rc::Rc::<str>::from)` pipe over
13666 // [`super::RestartPolicy::ALL`] to the substrate-primitive
13667 // accessor without a spurious [`Copy`] deref (which would only
13668 // be reachable through the owned-input axis by first calling
13669 // `.copied()` on the iterator).
13670 for &variant in RestartPolicy::ALL {
13671 let via_trait: std::rc::Rc<str> =
13672 <std::rc::Rc<str> as From<&RestartPolicy>>::from(&variant);
13673 let via_method: &'static str = variant.as_str();
13674 assert_eq!(
13675 via_trait.as_ref(),
13676 via_method,
13677 "From<&RestartPolicy> for std::rc::Rc<str> impl must \
13678 round-trip &RestartPolicy::{variant:?} to the same \
13679 lifted SUPERVISOR_CHILD_RESTART_* const \
13680 RestartPolicy::as_str returns"
13681 );
13682 let via_into: std::rc::Rc<str> = (&variant).into();
13683 assert_eq!(
13684 via_into.as_ref(),
13685 via_method,
13686 "Into<std::rc::Rc<str>>::into on \
13687 &RestartPolicy::{variant:?} must byte-equal \
13688 RestartPolicy::as_str on the same input"
13689 );
13690 let owned_rc: std::rc::Rc<str> =
13691 <std::rc::Rc<str> as From<RestartPolicy>>::from(variant);
13692 assert_eq!(
13693 via_trait, owned_rc,
13694 "From<&RestartPolicy> for std::rc::Rc<str> and \
13695 From<RestartPolicy> for std::rc::Rc<str> must \
13696 resolve identically on RestartPolicy::{variant:?}"
13697 );
13698 let borrowed_static: &'static str =
13699 <&'static str as From<&RestartPolicy>>::from(&variant);
13700 assert_eq!(
13701 via_trait.as_ref(),
13702 borrowed_static,
13703 "From<&RestartPolicy> for std::rc::Rc<str> and \
13704 From<&RestartPolicy> for &'static str must resolve \
13705 identically on RestartPolicy::{variant:?}"
13706 );
13707 let borrowed_string: String = <String as From<&RestartPolicy>>::from(&variant);
13708 assert_eq!(
13709 via_trait.as_ref(),
13710 borrowed_string.as_str(),
13711 "From<&RestartPolicy> for std::rc::Rc<str> and \
13712 From<&RestartPolicy> for String must resolve \
13713 identically on RestartPolicy::{variant:?}"
13714 );
13715 let borrowed_cow: std::borrow::Cow<'static, str> =
13716 <std::borrow::Cow<'static, str> as From<&RestartPolicy>>::from(&variant);
13717 assert_eq!(
13718 via_trait.as_ref(),
13719 borrowed_cow.as_ref(),
13720 "From<&RestartPolicy> for std::rc::Rc<str> and \
13721 From<&RestartPolicy> for Cow<'static, str> must \
13722 resolve identically on RestartPolicy::{variant:?}"
13723 );
13724 let borrowed_box: Box<str> = <Box<str> as From<&RestartPolicy>>::from(&variant);
13725 assert_eq!(
13726 via_trait.as_ref(),
13727 borrowed_box.as_ref(),
13728 "From<&RestartPolicy> for std::rc::Rc<str> and \
13729 From<&RestartPolicy> for Box<str> must resolve \
13730 identically on RestartPolicy::{variant:?}"
13731 );
13732 let borrowed_arc: std::sync::Arc<str> =
13733 <std::sync::Arc<str> as From<&RestartPolicy>>::from(&variant);
13734 assert_eq!(
13735 via_trait.as_ref(),
13736 borrowed_arc.as_ref(),
13737 "From<&RestartPolicy> for std::rc::Rc<str> and \
13738 From<&RestartPolicy> for std::sync::Arc<str> must \
13739 resolve identically on RestartPolicy::{variant:?}"
13740 );
13741 }
13742 let via_iter: Vec<std::rc::Rc<str>> = RestartPolicy::ALL
13743 .iter()
13744 .map(std::rc::Rc::<str>::from)
13745 .collect();
13746 let via_method: Vec<std::rc::Rc<str>> = RestartPolicy::ALL
13747 .iter()
13748 .map(|p| std::rc::Rc::<str>::from(p.as_str()))
13749 .collect();
13750 assert_eq!(
13751 via_iter, via_method,
13752 "`.iter().map(std::rc::Rc::<str>::from)` over \
13753 RestartPolicy::ALL — a call site whose iteration axis \
13754 holds `&RestartPolicy` by construction — must byte-\
13755 equal `.iter().map(|p| std::rc::Rc::<str>::from(p.as_str()))` \
13756 on every arm — the borrowed-input std::rc::Rc<str> \
13757 `From<&RestartPolicy> for std::rc::Rc<str>` axis is \
13758 what makes the `std::rc::Rc::<str>::from` composition \
13759 route through the substrate-primitive \
13760 `RestartPolicy::as_str` accessor without a spurious \
13761 `Copy` deref (which would only be reachable through the \
13762 owned-input `From<RestartPolicy> for std::rc::Rc<str>` \
13763 axis by first calling `.copied()` on the iterator)"
13764 );
13765 }
13766
13767 // ── drift-detection: serde-derive-to-SUPERVISOR_CHILD_RESTART_* identity ─
13768
13769 #[test]
13770 fn restart_policy_variants_serialize_to_lifted_scalar_values() {
13771 // The fail-before-pass-after pin: pre-lift there was no
13772 // single-source binding between the [`RestartPolicy`] variant
13773 // name the un-`rename`d `Serialize` derive emits under
13774 // [`crate::render::SUPERVISOR_CHILD_KEY_RESTART`] and the
13775 // byte-string every downstream cluster-side dispatcher (the
13776 // future wasm-operator's per-child post-exit restart-decision
13777 // branch, the future M4 `mesh.pleme.io/v1alpha1/Supervisor` CR
13778 // materializer's admission-time enum-arm bind, the
13779 // `caixa-operator`'s hierarchical reconciliation scheduler's
13780 // per-child-policy fan-out) probes verbatim. A future
13781 // `#[serde(rename_all = "kebab-case")]` attribute on the enum —
13782 // or a per-variant `#[serde(rename = "…")]` override, or a
13783 // variant rename in the source — would silently rebrand the
13784 // emitted scalar under one spelling while every downstream
13785 // dispatcher still probed the other, with the failure surfacing
13786 // at the operator's reconcile posture (children coming up under
13787 // the `default()` `Permanent` arm rather than the typed slot's
13788 // declared policy — a `:temporary` `oneShot` child would be
13789 // restarted on clean exit, treating the successful-completion
13790 // signal as failure and re-running the completion-terminal
13791 // one-shot indefinitely; a `:transient` child that clean-exited
13792 // would be restarted, masking the clean-completion contract)
13793 // far from the source rebrand commit and with no field naming
13794 // the drift. Pinning the two paths (the `Serialize` derive's
13795 // serialized string AND the [`RestartPolicy::as_str`] helper)
13796 // to the same three lifted
13797 // [`crate::render::SUPERVISOR_CHILD_RESTART_PERMANENT`] /
13798 // [`crate::render::SUPERVISOR_CHILD_RESTART_TEMPORARY`] /
13799 // [`crate::render::SUPERVISOR_CHILD_RESTART_TRANSIENT`]
13800 // byte-strings makes any future drift on either endpoint fail
13801 // here at caixa-core build time. Peer of the sibling
13802 // [`restart_strategy_variants_serialize_to_lifted_scalar_values`]
13803 // (09ffb2d) on the per-supervisor sibling-restart-strategy axis
13804 // and the M3
13805 // `placement_strategy_variants_serialize_to_lifted_scalar_values`
13806 // (3f0e21c) on the per-Aplicacao distribution-strategy axis —
13807 // same three-path-convergence discipline, extended to close the
13808 // third OTP-shaped closed-enum discriminator axis on the caixa
13809 // typed surface (per-child restart-decision policy).
13810 for (variant, expected) in [
13811 (
13812 RestartPolicy::Permanent,
13813 crate::render::SUPERVISOR_CHILD_RESTART_PERMANENT,
13814 ),
13815 (
13816 RestartPolicy::Temporary,
13817 crate::render::SUPERVISOR_CHILD_RESTART_TEMPORARY,
13818 ),
13819 (
13820 RestartPolicy::Transient,
13821 crate::render::SUPERVISOR_CHILD_RESTART_TRANSIENT,
13822 ),
13823 ] {
13824 let json = serde_json::to_string(&variant).unwrap();
13825 assert_eq!(
13826 json,
13827 format!("\"{expected}\""),
13828 "RestartPolicy::{variant:?} must serialize to {expected:?}"
13829 );
13830 assert_eq!(
13831 variant.as_str(),
13832 expected,
13833 "RestartPolicy::{variant:?}.as_str() must return the lifted \
13834 SUPERVISOR_CHILD_RESTART_* constant"
13835 );
13836 }
13837 }
13838
13839 #[test]
13840 fn supervisor_child_restart_consts_are_pairwise_distinct() {
13841 // Cross-arm drift-detection pin: a future collapse of two
13842 // canonical variant byte-strings onto the same value (e.g. an
13843 // accidental copy-paste flip of `SUPERVISOR_CHILD_RESTART_TRANSIENT`
13844 // to also read `"Permanent"`) would silently reroute every
13845 // downstream operator's per-child-policy dispatch onto the
13846 // sibling arm's reconcile branch and pass every propagation-probe
13847 // test that expected only the stale arm's value — a `:transient`
13848 // child would come up under the `:permanent` restart-decision
13849 // posture on every subsequent clean exit, so a completion-terminal
13850 // child would be restarted indefinitely against its declared
13851 // policy. Peer of the sibling
13852 // [`supervisor_estrategia_consts_are_pairwise_distinct`]
13853 // (09ffb2d) on the per-supervisor sibling-restart-strategy axis
13854 // and the four-way distinct pin
13855 // `supervisor_key_consts_are_pairwise_distinct` (40cc4e5) on the
13856 // top-level `SUPERVISOR_KEY_*` axis.
13857 let all = [
13858 crate::render::SUPERVISOR_CHILD_RESTART_PERMANENT,
13859 crate::render::SUPERVISOR_CHILD_RESTART_TEMPORARY,
13860 crate::render::SUPERVISOR_CHILD_RESTART_TRANSIENT,
13861 ];
13862 for (i, a) in all.iter().enumerate() {
13863 for (j, b) in all.iter().enumerate() {
13864 if i != j {
13865 assert_ne!(
13866 a, b,
13867 "SUPERVISOR_CHILD_RESTART_* consts must be pairwise distinct \
13868 — got duplicate {a:?} at indices {i} and {j}",
13869 );
13870 }
13871 }
13872 }
13873 }
13874
13875 #[test]
13876 fn restart_policy_display_routes_through_as_str_helper() {
13877 // The fail-before-pass-after pin on the first half of the
13878 // three-path convergence: pre-convergence [`RestartPolicy`]
13879 // carried a [`std::fmt::Display`] surface via its
13880 // `#[discriminant(also_display)]` gen-platform derive route,
13881 // which arrived kebab-case as `"permanent"` / `"temporary"`
13882 // / `"transient"` on this three-arm enum (whose variant
13883 // names each collapse to their own lowercase form under the
13884 // kebab-case transform) while the wire format ran as
13885 // PascalCase `"Permanent"` / `"Temporary"` / `"Transient"`
13886 // through the un-`rename`d serde derive. Every consumer
13887 // reaching for a policy byte-string past the wire format had
13888 // to pick between three paths ([`RestartPolicy::as_str`],
13889 // the `Serialize` derive's serialized string, or
13890 // `format!("{v}")` on the discriminant-Display route), any
13891 // two of which a future variant rename or
13892 // `#[serde(rename_all = "kebab-case")]` attribute would
13893 // silently desynchronize. Wiring [`std::fmt::Display`]
13894 // through [`RestartPolicy::as_str`] closes the third path:
13895 // every `format!("{v}")` call reaches the same lifted
13896 // [`crate::render::SUPERVISOR_CHILD_RESTART_*`] const the
13897 // wire format and the [`RestartPolicy::as_str`] helper
13898 // already route through, so a future variant rename lands at
13899 // exactly one place. Pin the routing here so a future
13900 // `impl std::fmt::Display for RestartPolicy`
13901 // reimplementation that hand-rolls the arms instead of
13902 // delegating to [`RestartPolicy::as_str`] fails at
13903 // caixa-core build time. Peer of the sibling
13904 // [`restart_strategy_display_routes_through_as_str_helper`]
13905 // on the per-supervisor sibling-restart-strategy axis and
13906 // the M3
13907 // `placement_strategy_display_routes_through_as_str_helper`
13908 // (cc8f749) — the third of three OTP-shape closed-enum
13909 // discriminator axes on the caixa typed surface now
13910 // converged onto the same three-path
13911 // (Display → as_str → lifted const) discipline.
13912 for variant in [
13913 RestartPolicy::Permanent,
13914 RestartPolicy::Temporary,
13915 RestartPolicy::Transient,
13916 ] {
13917 assert_eq!(
13918 variant.to_string(),
13919 variant.as_str(),
13920 "RestartPolicy::{variant:?} Display must route through \
13921 RestartPolicy::as_str (single source of truth: the lifted \
13922 SUPERVISOR_CHILD_RESTART_* const the wire format also emits)"
13923 );
13924 }
13925 }
13926
13927 #[test]
13928 fn restart_policy_display_matches_serialized_wire_byte_string() {
13929 // The fail-before-pass-after pin on the second half of the
13930 // three-path convergence: `Display` (user-facing text) agrees
13931 // byte-for-byte with the `Serialize` derive's wire format
13932 // (canonical camelCase-schema `SUPERVISOR_CHILD_KEY_RESTART`
13933 // scalar) on every variant. Pre-convergence the two paths
13934 // were structurally independent — a future
13935 // `#[serde(rename_all = "kebab-case")]` attribute on the
13936 // enum would silently rebrand the emitted wire scalar
13937 // (`permanent`, `temporary`, `transient`) while every
13938 // consumer that pretty-prints the policy (the future
13939 // wasm-operator's per-child post-exit restart-decision
13940 // diagnostic line, the future `feira app graph` per-child
13941 // restart column, the future M4
13942 // `mesh.pleme.io/v1alpha1/Supervisor` CR materializer's
13943 // per-child admission-webhook rejection body) would still
13944 // emit the PascalCase form the `as_str` / `Display` route
13945 // returns, with the mismatch surfacing at consumer parse
13946 // time / operator dispatch time far from the source rebrand
13947 // commit. Pin the two paths byte-for-byte here so any future
13948 // serde-attribute or variant-rename drift is a
13949 // caixa-core-build-time test failure at this call, not a
13950 // silent per-consumer dispatch miss. Peer of the sibling
13951 // [`restart_strategy_display_matches_serialized_wire_byte_string`]
13952 // on the per-supervisor sibling-restart-strategy axis and
13953 // the M3
13954 // `placement_strategy_display_matches_serialized_wire_byte_string`
13955 // (cc8f749).
13956 for variant in [
13957 RestartPolicy::Permanent,
13958 RestartPolicy::Temporary,
13959 RestartPolicy::Transient,
13960 ] {
13961 let wire = serde_json::to_string(&variant).unwrap();
13962 let unquoted = wire
13963 .strip_prefix('"')
13964 .and_then(|s| s.strip_suffix('"'))
13965 .expect("serialized RestartPolicy is a JSON string");
13966 assert_eq!(
13967 variant.to_string(),
13968 unquoted,
13969 "RestartPolicy::{variant:?} Display byte-string must match the \
13970 Serialize derive's wire byte-string (three-path convergence: \
13971 Display + as_str + Serialize all resolve to the same \
13972 SUPERVISOR_CHILD_RESTART_* const)"
13973 );
13974 }
13975 }
13976
13977 #[test]
13978 fn restart_policy_as_ref_str_routes_through_as_str_accessor() {
13979 // Fail-before-pass-after byte-parity pin on the lifted
13980 // `impl AsRef<str> for RestartPolicy` — asserts the
13981 // standard-library trait impl and the substrate-primitive
13982 // [`RestartPolicy::as_str`] `pub const fn` accessor resolve
13983 // to the same `&str` per instance across the three-arm
13984 // closed set, so any future silent detour that routes the
13985 // impl through a divergent projection (a per-arm inline
13986 // `match self { RestartPolicy::Permanent => "Permanent", … }`
13987 // re-inlining that opens a compile-time link to the un-lifted
13988 // arm-literal, a swap onto the kebab-case
13989 // [`gen_platform::Discriminant`] catalog identity that would
13990 // collide the wire axis with the dispatcher-catalog axis) trips
13991 // at caixa-core test time under `PartialEq` rather than at a
13992 // downstream `impl AsRef<str>`-bound consumer's silent split.
13993 // Sweeps every one of the three arms
13994 // [`RestartPolicy::ALL`] carries so no arm's projection is
13995 // covered only by the sibling wire-format `Serialize` derive
13996 // path. Peer of the sibling
13997 // [`restart_strategy_as_ref_str_routes_through_as_str_accessor`]
13998 // (63eb1a4) on the paired per-supervisor sibling-restart-
13999 // strategy axis and the [`crate::CaixaVersion`]
14000 // `AsRef<str>`-byte-parity pin (16d5c7e) on the paired
14001 // top-level `:versao` typed newtype — the three pins together
14002 // cover the substrate primitive's `AsRef<str>` projection axis
14003 // on the paired newtype + M2 closed-set-typed-enum surface.
14004 for &variant in RestartPolicy::ALL {
14005 assert_eq!(
14006 <RestartPolicy as AsRef<str>>::as_ref(&variant),
14007 variant.as_str(),
14008 "AsRef<str> impl on RestartPolicy::{variant:?} must \
14009 byte-equal RestartPolicy::as_str on the same instance \
14010 — divergence signals a silent detour off the substrate-\
14011 primitive accessor"
14012 );
14013 }
14014 }
14015
14016 #[test]
14017 fn restart_policy_as_ref_str_routes_through_display_via_shared_accessor() {
14018 // Fail-before-pass-after byte-parity pin on the three-path
14019 // convergence discipline the M2 per-child-restart-policy
14020 // primitive now carries on the `&str`-projection axis:
14021 // `<RestartPolicy as AsRef<str>>::as_ref(&v)` (the newly
14022 // lifted impl), `format!("{v}")` (the pre-existing
14023 // [`fmt::Display`] impl), and `v.as_str()` (the substrate-
14024 // primitive `pub const fn` accessor both trait impls delegate
14025 // through) must resolve to the same byte-string on every
14026 // instance across the three-arm closed set. Refuses any future
14027 // divergence between the two trait impls (a stray
14028 // [`fmt::Display::fmt`] rewrite that hand-rolls the arms
14029 // rather than delegating through the shared accessor; a
14030 // hypothetical `AsRef<str>` rewrite that inlines a per-arm
14031 // literal cascade) that would silently split the two
14032 // projection paths of the same closed-set typed enum. Mirrors
14033 // the sibling three-path-convergence discipline the peer
14034 // [`RestartStrategy`] typed enum carries on its
14035 // `AsRef<str>` / `Display` / `as_str` triple
14036 // (supervisor.rs pin
14037 // `restart_strategy_as_ref_str_routes_through_display_via_shared_accessor`,
14038 // 63eb1a4) and the [`crate::CaixaVersion`] typed newtype
14039 // carries on the same triple (version.rs pin
14040 // `caixa_version_as_ref_str_routes_through_display_via_shared_accessor`,
14041 // 16d5c7e).
14042 for &variant in RestartPolicy::ALL {
14043 let via_as_ref: &str = <RestartPolicy as AsRef<str>>::as_ref(&variant);
14044 let via_display: String = format!("{variant}");
14045 let via_accessor: &str = variant.as_str();
14046 assert_eq!(via_as_ref, via_accessor);
14047 assert_eq!(via_display, via_accessor);
14048 assert_eq!(via_as_ref, via_display.as_str());
14049 }
14050 }
14051
14052 // The `generic_bytes_sink(&variant)` and `borrowed_hasher.update(&variant)`
14053 // shapes below are the borrowed-input witness half of the by-value +
14054 // by-reference partition the paired witness pair carries: the pair proves
14055 // the trait bound accepts both owned (`variant`) and borrowed (`&variant`)
14056 // shapes through the same substrate-primitive `as_str` accessor, which is
14057 // the shape the caixa-lacre BLAKE3 content-address closure composes.
14058 // `clippy::needless_borrows_for_generic_args` would fold the borrowed half
14059 // into the owned half and collapse the by-value/by-reference partition
14060 // this test load-bears; the `#[allow]` documents that the partition is
14061 // deliberate, not an oversight.
14062 #[allow(clippy::needless_borrows_for_generic_args)]
14063 #[test]
14064 fn restart_policy_as_ref_bytes_routes_through_as_str_accessor() {
14065 // `<T: AsRef<[u8]>>`-bound generic-consumer witness: a byte-input
14066 // function that binds its argument through the standard-library
14067 // [`AsRef<[u8]>`] trait bound accepts a [`super::RestartPolicy`]
14068 // directly, without the caller open-coding the two-hop
14069 // `restart.as_str().as_bytes()` composition. Lifted to the top
14070 // of the function per `clippy::items_after_statements`.
14071 fn generic_bytes_sink<T: AsRef<[u8]>>(t: T) -> Vec<u8> {
14072 t.as_ref().to_vec()
14073 }
14074 // `blake3::Hasher::update`-shape byte-input surface mock: mirrors
14075 // `blake3::Hasher::update` / `ring::digest::Context::update` /
14076 // `sha2::Sha256::update`'s `impl AsRef<[u8]>`-bound `update`
14077 // signature so a per-child BLAKE3 content-address closure that
14078 // composes `hasher.update(restart)` on the [`crate::Lacre`]
14079 // closure builder reaches the substrate-primitive `as_str`
14080 // accessor through the [`super::RestartPolicy`] `AsRef<[u8]>`
14081 // axis and no other. Lifted to the top of the function per
14082 // `clippy::items_after_statements`.
14083 struct MockHasher(Vec<u8>);
14084 impl MockHasher {
14085 fn new() -> Self {
14086 Self(Vec::new())
14087 }
14088 fn update(&mut self, bytes: impl AsRef<[u8]>) -> &mut Self {
14089 self.0.extend_from_slice(bytes.as_ref());
14090 self
14091 }
14092 fn finalize(self) -> Vec<u8> {
14093 self.0
14094 }
14095 }
14096
14097 // Fail-before-pass-after byte-parity pin on the newly lifted
14098 // `impl AsRef<[u8]> for RestartPolicy` — asserts the trait-
14099 // idiomatic byte-view standard-library impl and the substrate-
14100 // primitive [`super::RestartPolicy::as_str`] `pub const fn`
14101 // accessor's `.as_bytes()` byte-tail resolve to the same three-
14102 // arm `PascalCase` wire byte-string emit-set across every arm
14103 // the exhaustive [`super::RestartPolicy::ALL`] slice enumerates.
14104 // Extends the trait-idiomatic byte-view axis onto the second
14105 // (and final) M2 OTP-shape closed-set fieldless typed enum peer
14106 // on the caixa surface (the paired per-child restart-decision
14107 // policy sibling on the same M2 `:supervisor` slot), closing
14108 // the byte-view axis across the `:supervisor :estrategia` +
14109 // `:children :restart` M2 slot pair the sibling
14110 // [`super::RestartStrategy`] first-mover (cd4c4e0) opened.
14111 //
14112 // Rust's standard library carries `impl AsRef<[u8]> for str` and
14113 // `impl AsRef<[u8]> for String`, so a two-hop composition
14114 // `restart.as_str().as_bytes()` (or the equally two-hop
14115 // `AsRef::<str>::as_ref(&restart).as_bytes()`) is reachable
14116 // through the pre-existing str-view axis alone. But that two-hop
14117 // shape has no compile-time link back to the byte-projection
14118 // axis, forces every downstream `<T: AsRef<[u8]>>`-bound
14119 // consumer to open-code the two-hop composition at every call
14120 // site, and admits a silent split whenever a future call site
14121 // takes a sibling reverse-projection axis whose `.as_bytes()`
14122 // byte-tail carries no compile-time byte-view surface. This
14123 // impl closes the byte-view axis at the substrate-primitive
14124 // [`super::RestartPolicy::as_str`] accessor so every future
14125 // `<T: AsRef<[u8]>>`-bound consumer reaches the same lifted
14126 // [`super::crate::render::SUPERVISOR_CHILD_RESTART_*`] const
14127 // roster the paired str-view axes already return through —
14128 // through one trait dispatch.
14129 for &variant in RestartPolicy::ALL {
14130 let via_trait: &[u8] = <RestartPolicy as AsRef<[u8]>>::as_ref(&variant);
14131 let via_method_bytes: &[u8] = variant.as_str().as_bytes();
14132 assert_eq!(
14133 via_trait, via_method_bytes,
14134 "AsRef<[u8]> for RestartPolicy impl must byte-equal \
14135 RestartPolicy::as_str().as_bytes() on \
14136 RestartPolicy::{variant:?} — divergence signals a \
14137 silent detour off the substrate-primitive accessor"
14138 );
14139 // Cross-axis witness against the paired str-view axes'
14140 // `.as_bytes()` byte-tails: [`AsRef<str>`] /
14141 // [`std::fmt::Display`] / [`super::RestartPolicy::as_str`]
14142 // all resolve to the same lifted
14143 // [`super::crate::render::SUPERVISOR_CHILD_RESTART_*`] const
14144 // roster, and the byte-view axis must byte-equal each of
14145 // their `.as_bytes()` byte-tails by construction — locking
14146 // the str-view and byte-view axes together at the
14147 // substrate-primitive accessor.
14148 let str_view_ref: &str = <RestartPolicy as AsRef<str>>::as_ref(&variant);
14149 assert_eq!(
14150 via_trait,
14151 str_view_ref.as_bytes(),
14152 "AsRef<[u8]> for RestartPolicy and AsRef<str> for \
14153 RestartPolicy must resolve to byte-equal byte-tails \
14154 on RestartPolicy::{variant:?} — divergence signals \
14155 the byte-view and str-view axes have drifted off the \
14156 same substrate-primitive as_str accessor"
14157 );
14158 let display_bytes = variant.to_string();
14159 assert_eq!(
14160 via_trait,
14161 display_bytes.as_bytes(),
14162 "AsRef<[u8]> for RestartPolicy and \
14163 <RestartPolicy as std::fmt::Display>::to_string must \
14164 resolve to byte-equal byte-tails on \
14165 RestartPolicy::{variant:?} — divergence signals the \
14166 byte-view axis and the Display formatter axis have \
14167 drifted off the same substrate-primitive as_str \
14168 accessor"
14169 );
14170 // Cross-axis witness against the paired reverse-projection
14171 // axes' `.as_bytes()` byte-tails: every one of `{&'static
14172 // str, String, Cow<'static, str>, Box<str>,
14173 // std::sync::Arc<str>}` allocates (or borrows) the same
14174 // `PascalCase` wire byte-string the substrate-primitive
14175 // accessor emits, so the byte-view axis must byte-equal
14176 // each of their `.as_bytes()` byte-tails by construction.
14177 let owned_static: &'static str = <&'static str as From<RestartPolicy>>::from(variant);
14178 assert_eq!(
14179 via_trait,
14180 owned_static.as_bytes(),
14181 "AsRef<[u8]> for RestartPolicy and From<RestartPolicy> \
14182 for &'static str must resolve to byte-equal byte-tails \
14183 on RestartPolicy::{variant:?}"
14184 );
14185 let owned_string: String = <String as From<RestartPolicy>>::from(variant);
14186 assert_eq!(
14187 via_trait,
14188 owned_string.as_bytes(),
14189 "AsRef<[u8]> for RestartPolicy and From<RestartPolicy> \
14190 for String must resolve to byte-equal byte-tails on \
14191 RestartPolicy::{variant:?}"
14192 );
14193 let owned_cow: std::borrow::Cow<'static, str> =
14194 <std::borrow::Cow<'static, str> as From<RestartPolicy>>::from(variant);
14195 assert_eq!(
14196 via_trait,
14197 owned_cow.as_bytes(),
14198 "AsRef<[u8]> for RestartPolicy and From<RestartPolicy> \
14199 for Cow<'static, str> must resolve to byte-equal byte-\
14200 tails on RestartPolicy::{variant:?}"
14201 );
14202 let owned_box: Box<str> = <Box<str> as From<RestartPolicy>>::from(variant);
14203 assert_eq!(
14204 via_trait,
14205 owned_box.as_bytes(),
14206 "AsRef<[u8]> for RestartPolicy and From<RestartPolicy> \
14207 for Box<str> must resolve to byte-equal byte-tails on \
14208 RestartPolicy::{variant:?}"
14209 );
14210 let owned_arc: std::sync::Arc<str> =
14211 <std::sync::Arc<str> as From<RestartPolicy>>::from(variant);
14212 assert_eq!(
14213 via_trait,
14214 owned_arc.as_bytes(),
14215 "AsRef<[u8]> for RestartPolicy and From<RestartPolicy> \
14216 for std::sync::Arc<str> must resolve to byte-equal \
14217 byte-tails on RestartPolicy::{variant:?}"
14218 );
14219 }
14220 // `<T: AsRef<[u8]>>`-bound-consumer witness: the generic byte-
14221 // input function `generic_bytes_sink` (lifted above per
14222 // `clippy::items_after_statements`) accepts a
14223 // [`super::RestartPolicy`] directly through the trait bound,
14224 // without the caller open-coding the two-hop
14225 // `restart.as_str().as_bytes()` composition. This is the shape
14226 // that reaches the caixa-lacre BLAKE3 content-address closure's
14227 // `blake3::Hasher::update(impl AsRef<[u8]>)` byte-input surface
14228 // through this impl and no other.
14229 for &variant in RestartPolicy::ALL {
14230 let via_generic = generic_bytes_sink(variant);
14231 let via_borrowed_generic = generic_bytes_sink(&variant);
14232 let via_method_bytes = variant.as_str().as_bytes().to_vec();
14233 assert_eq!(
14234 via_generic, via_method_bytes,
14235 "generic `<T: AsRef<[u8]>>`-bound consumer on \
14236 RestartPolicy::{variant:?} must yield the same byte-\
14237 tail RestartPolicy::as_str().as_bytes() returns — \
14238 divergence signals the byte-view axis fails to bridge \
14239 a generic byte-input trait bound to the substrate-\
14240 primitive accessor"
14241 );
14242 assert_eq!(
14243 via_borrowed_generic, via_method_bytes,
14244 "generic `<T: AsRef<[u8]>>`-bound consumer on \
14245 &RestartPolicy::{variant:?} must yield the same byte-\
14246 tail RestartPolicy::as_str().as_bytes() returns — the \
14247 borrowed-input surface must resolve to the same as_str \
14248 dispatch"
14249 );
14250 }
14251 // `blake3::Hasher::update`-shape byte-input surface witness on
14252 // the caixa-lacre compounding target: the `MockHasher` (lifted
14253 // above per `clippy::items_after_statements`) mirrors
14254 // `blake3::Hasher::update` / `ring::digest::Context::update` /
14255 // `sha2::Sha256::update`'s `impl AsRef<[u8]>`-bound update
14256 // signature and accepts a [`super::RestartPolicy`] directly,
14257 // routing its byte-tail through the substrate-primitive
14258 // `as_str` accessor — the shape a future per-child BLAKE3
14259 // content-address closure composes to fold a `:restart`
14260 // discriminator byte-tag into the [`crate::Lacre`] closure
14261 // body.
14262 for &variant in RestartPolicy::ALL {
14263 let mut owned_hasher = MockHasher::new();
14264 owned_hasher.update(variant);
14265 let owned_folded = owned_hasher.finalize();
14266 assert_eq!(
14267 owned_folded,
14268 variant.as_str().as_bytes(),
14269 "`hasher.update(restart)`-shape composition on \
14270 RestartPolicy::{variant:?} must fold the same byte-\
14271 tail RestartPolicy::as_str().as_bytes() returns — the \
14272 shape a future per-child BLAKE3 content-address \
14273 closure composes to fold a `:restart` discriminator \
14274 byte-tag into the Lacre closure body"
14275 );
14276 let mut borrowed_hasher = MockHasher::new();
14277 borrowed_hasher.update(&variant);
14278 let borrowed_folded = borrowed_hasher.finalize();
14279 assert_eq!(
14280 borrowed_folded,
14281 variant.as_str().as_bytes(),
14282 "`hasher.update(&restart)`-shape composition on \
14283 &RestartPolicy::{variant:?} must fold the same byte-\
14284 tail RestartPolicy::as_str().as_bytes() returns — the \
14285 borrowed-input surface must resolve to the same as_str \
14286 dispatch"
14287 );
14288 }
14289 }
14290
14291 #[test]
14292 #[expect(
14293 clippy::too_many_lines,
14294 reason = "the byte-owned reverse-projection axis is closed \
14295 here across the M2-OTP-shape :supervisor slot pair by \
14296 extending onto the second and final M2-OTP-shape \
14297 closed-set fieldless typed-enum peer, so the pin \
14298 binds the new impl against every paired byte-view \
14299 and str-owned axis on the same enum plus a generic \
14300 <T: Into<Vec<u8>>>-bound consumer witness and a \
14301 std::io::Write::write_all-shape owned-byte-sink \
14302 surface witness on both owned and borrowed input \
14303 shapes to lock the whole family against a future \
14304 silent regression"
14305 )]
14306 fn restart_policy_from_into_owned_vec_bytes_routes_through_as_str_accessor() {
14307 // `<T: Into<Vec<u8>>>`-bound-consumer witness helper: a generic
14308 // owned-byte-input function accepts a [`super::RestartPolicy`]
14309 // directly through the trait bound, without the caller open-
14310 // coding the three-hop `restart.as_str().as_bytes().to_vec()`
14311 // composition. Lifted to the top of the function per
14312 // `clippy::items_after_statements`.
14313 fn generic_owned_bytes_sink<T: Into<Vec<u8>>>(t: T) -> Vec<u8> {
14314 t.into()
14315 }
14316 // `std::io::Write::write_all`-shape owned-byte-sink surface
14317 // mock: mirrors `std::io::Write::write_all` /
14318 // `bytes::BytesMut::extend_from_slice` / any per-arm audit-log
14319 // byte-sink that consumes a `Vec<u8>` payload via
14320 // `Into<Vec<u8>>`, so a future per-child per-`:restart` audit-
14321 // log emit reaches the substrate-primitive `as_str` accessor
14322 // through the byte-owned reverse-projection axis and no
14323 // other. Lifted to the top of the function per
14324 // `clippy::items_after_statements`.
14325 struct MockOwnedByteSink(Vec<u8>);
14326 impl MockOwnedByteSink {
14327 fn new() -> Self {
14328 Self(Vec::new())
14329 }
14330 fn write_all(&mut self, bytes: impl Into<Vec<u8>>) -> &mut Self {
14331 self.0.extend(bytes.into());
14332 self
14333 }
14334 fn finalize(self) -> Vec<u8> {
14335 self.0
14336 }
14337 }
14338
14339 // Fail-before-pass-after byte-parity pin on the newly lifted
14340 // `impl From<RestartPolicy> for Vec<u8>` and
14341 // `impl From<&RestartPolicy> for Vec<u8>` — asserts the trait-
14342 // idiomatic byte-owned reverse-projection standard-library
14343 // impls and the substrate-primitive
14344 // [`super::RestartPolicy::as_str`] `pub const fn` accessor's
14345 // `.as_bytes().to_vec()` byte-tail resolve to the same three-
14346 // arm PascalCase wire byte-string emit-set across every arm
14347 // the exhaustive [`super::RestartPolicy::ALL`] slice
14348 // enumerates. Closes the substrate-wide trait-idiomatic byte-
14349 // owned reverse-projection axis on the M2-OTP-shape closed-
14350 // set typed-enum pair the sibling first-mover
14351 // [`super::RestartStrategy`] `From<{Self, &Self}> for Vec<u8>`
14352 // lift (63e5dd0) opened one commit prior, matching the
14353 // trajectory the paired [`AsRef<[u8]>`] borrowed byte-view
14354 // axis campaign already tracked across the same slot pair
14355 // (cd4c4e0 → 98b08fa).
14356 for &variant in RestartPolicy::ALL {
14357 let via_owned_from: Vec<u8> = <Vec<u8> as From<RestartPolicy>>::from(variant);
14358 let via_borrowed_from: Vec<u8> = <Vec<u8> as From<&RestartPolicy>>::from(&variant);
14359 let via_method_bytes: Vec<u8> = variant.as_str().as_bytes().to_vec();
14360 assert_eq!(
14361 via_owned_from, via_method_bytes,
14362 "From<RestartPolicy> for Vec<u8> impl must byte-equal \
14363 RestartPolicy::as_str().as_bytes().to_vec() on \
14364 RestartPolicy::{variant:?} — divergence signals a \
14365 silent detour off the substrate-primitive accessor"
14366 );
14367 assert_eq!(
14368 via_borrowed_from, via_method_bytes,
14369 "From<&RestartPolicy> for Vec<u8> impl must byte-\
14370 equal RestartPolicy::as_str().as_bytes().to_vec() \
14371 on RestartPolicy::{variant:?} — divergence signals \
14372 a silent detour off the substrate-primitive accessor"
14373 );
14374 assert_eq!(
14375 via_owned_from, via_borrowed_from,
14376 "From<RestartPolicy> for Vec<u8> and \
14377 From<&RestartPolicy> for Vec<u8> must byte-equal \
14378 each other on RestartPolicy::{variant:?} — \
14379 divergence signals the owned-input and borrowed-input \
14380 paths have drifted off the same substrate-primitive \
14381 as_str accessor"
14382 );
14383 // Cross-axis witness against the paired [`AsRef<[u8]>`]
14384 // borrowed byte-view axis (98b08fa): the byte-owned
14385 // reverse-projection axis must byte-equal the paired
14386 // borrowed byte-view axis by construction — locking the
14387 // byte-view and byte-owned axes together at the substrate-
14388 // primitive accessor.
14389 let borrowed_bytes: &[u8] = <RestartPolicy as AsRef<[u8]>>::as_ref(&variant);
14390 assert_eq!(
14391 via_owned_from,
14392 borrowed_bytes.to_vec(),
14393 "From<RestartPolicy> for Vec<u8> and AsRef<[u8]> for \
14394 RestartPolicy must resolve to byte-equal byte-tails \
14395 on RestartPolicy::{variant:?} — divergence signals \
14396 the byte-owned and byte-view axes have drifted off \
14397 the same substrate-primitive as_str accessor"
14398 );
14399 // Cross-axis witness against the str-owned reverse-
14400 // projection family's `.into_bytes()` / `.as_bytes().to_vec()`
14401 // byte-tails: every one of `{String, Cow<'static, str>,
14402 // Box<str>, std::sync::Arc<str>}` allocates (or borrows)
14403 // the same PascalCase wire byte-string the substrate-
14404 // primitive accessor emits, so the byte-owned axis must
14405 // byte-equal each of their owned byte-tails by
14406 // construction.
14407 let owned_string: String = <String as From<RestartPolicy>>::from(variant);
14408 assert_eq!(
14409 via_owned_from,
14410 owned_string.into_bytes(),
14411 "From<RestartPolicy> for Vec<u8> and \
14412 String::from(policy).into_bytes() must resolve to \
14413 byte-equal byte-tails on RestartPolicy::{variant:?}"
14414 );
14415 let owned_cow: std::borrow::Cow<'static, str> =
14416 <std::borrow::Cow<'static, str> as From<RestartPolicy>>::from(variant);
14417 assert_eq!(
14418 via_owned_from,
14419 owned_cow.as_bytes().to_vec(),
14420 "From<RestartPolicy> for Vec<u8> and \
14421 From<RestartPolicy> for Cow<'static, str> must \
14422 resolve to byte-equal byte-tails on \
14423 RestartPolicy::{variant:?}"
14424 );
14425 let owned_box: Box<str> = <Box<str> as From<RestartPolicy>>::from(variant);
14426 assert_eq!(
14427 via_owned_from,
14428 owned_box.as_bytes().to_vec(),
14429 "From<RestartPolicy> for Vec<u8> and \
14430 From<RestartPolicy> for Box<str> must resolve to \
14431 byte-equal byte-tails on RestartPolicy::{variant:?}"
14432 );
14433 let owned_arc: std::sync::Arc<str> =
14434 <std::sync::Arc<str> as From<RestartPolicy>>::from(variant);
14435 assert_eq!(
14436 via_owned_from,
14437 owned_arc.as_bytes().to_vec(),
14438 "From<RestartPolicy> for Vec<u8> and \
14439 From<RestartPolicy> for std::sync::Arc<str> must \
14440 resolve to byte-equal byte-tails on \
14441 RestartPolicy::{variant:?}"
14442 );
14443 }
14444 // `<T: Into<Vec<u8>>>`-bound-consumer witness on both owned
14445 // and borrowed input shapes: the generic owned-byte-input
14446 // function `generic_owned_bytes_sink` (lifted above per
14447 // `clippy::items_after_statements`) accepts a
14448 // [`super::RestartPolicy`] and a `&RestartPolicy` directly
14449 // through the trait bound, without the caller open-coding
14450 // the three-hop `restart.as_str().as_bytes().to_vec()`
14451 // composition.
14452 for &variant in RestartPolicy::ALL {
14453 let via_generic_owned = generic_owned_bytes_sink(variant);
14454 // Bind the borrowed-input path through an explicit
14455 // `&RestartPolicy` local so the generic-consumer witness
14456 // routes through `From<&RestartPolicy> for Vec<u8>` (T
14457 // binds to `&RestartPolicy`) rather than clippy-collapsing
14458 // the borrow onto the owned-input peer.
14459 let variant_ref: &RestartPolicy = &variant;
14460 let via_generic_borrowed = generic_owned_bytes_sink(variant_ref);
14461 let via_method_bytes = variant.as_str().as_bytes().to_vec();
14462 assert_eq!(
14463 via_generic_owned, via_method_bytes,
14464 "generic `<T: Into<Vec<u8>>>`-bound consumer on \
14465 RestartPolicy::{variant:?} must yield the same byte-\
14466 tail RestartPolicy::as_str().as_bytes() returns — \
14467 divergence signals the byte-owned axis fails to bridge \
14468 a generic owned-byte-input trait bound to the \
14469 substrate-primitive accessor"
14470 );
14471 assert_eq!(
14472 via_generic_borrowed, via_method_bytes,
14473 "generic `<T: Into<Vec<u8>>>`-bound consumer on \
14474 &RestartPolicy::{variant:?} must yield the same byte-\
14475 tail RestartPolicy::as_str().as_bytes() returns — \
14476 the borrowed-input surface must resolve to the same \
14477 as_str dispatch"
14478 );
14479 }
14480 // `std::io::Write::write_all`-shape owned-byte-sink surface
14481 // witness: the `MockOwnedByteSink` (lifted above per
14482 // `clippy::items_after_statements`) mirrors
14483 // `std::io::Write::write_all` /
14484 // `bytes::BytesMut::extend_from_slice`'s `impl Into<Vec<u8>>`-
14485 // bound owned-byte input signature and accepts a
14486 // [`super::RestartPolicy`] directly on both owned and
14487 // borrowed input shapes, routing its byte-tail through the
14488 // substrate-primitive `as_str` accessor — the shape a future
14489 // per-child per-`:restart` audit-log emit composes to fold a
14490 // `:restart` discriminator byte-tag into a downstream owned-
14491 // byte-sink surface.
14492 for &variant in RestartPolicy::ALL {
14493 let mut owned_sink = MockOwnedByteSink::new();
14494 owned_sink.write_all(variant);
14495 let owned_folded = owned_sink.finalize();
14496 assert_eq!(
14497 owned_folded,
14498 variant.as_str().as_bytes(),
14499 "`sink.write_all(restart)`-shape composition on \
14500 RestartPolicy::{variant:?} must fold the same byte-\
14501 tail RestartPolicy::as_str().as_bytes() returns"
14502 );
14503 let mut borrowed_sink = MockOwnedByteSink::new();
14504 let variant_ref: &RestartPolicy = &variant;
14505 borrowed_sink.write_all(variant_ref);
14506 let borrowed_folded = borrowed_sink.finalize();
14507 assert_eq!(
14508 borrowed_folded,
14509 variant.as_str().as_bytes(),
14510 "`sink.write_all(&restart)`-shape composition on \
14511 &RestartPolicy::{variant:?} must fold the same byte-\
14512 tail RestartPolicy::as_str().as_bytes() returns — \
14513 the borrowed-input surface must resolve to the same \
14514 as_str dispatch"
14515 );
14516 }
14517 }
14518
14519 #[test]
14520 fn restart_policy_all_enumerates_every_variant_exactly_once() {
14521 // Fail-before-pass-after pin on the [`RestartPolicy::ALL`]
14522 // exhaustive-iteration surface: every variant appears exactly
14523 // once, and the slice length matches the arm count of the
14524 // closed set. Every consumer that walks the accepted-policy
14525 // set (a future `feira supervisor --restart …` CLI-side
14526 // arg-parse's "did you mean" hint, a future M4 admission-
14527 // webhook's per-child rejection body naming the accepted-
14528 // `:restart` list, the [`RestartPolicy::from_wire`] reverse-
14529 // projection consumers that iterate the accept-set for
14530 // diagnostic rendering) reads through this slice, so a future
14531 // arm addition that grows the enum but forgets to grow
14532 // [`Self::ALL`] silently truncates every downstream consumer's
14533 // accept-set at the same pre-addition boundary — this pin
14534 // fails at caixa-core build time on the pairwise-distinct +
14535 // arm-count invariants.
14536 //
14537 // Peer of the sibling [`RestartStrategy::ALL`] (4eec29c) /
14538 // [`crate::CaixaKind::ALL`] (6b1f4fb) /
14539 // [`crate::aplicacao::PlacementStrategy::ALL`] (18c7342) /
14540 // [`crate::aplicacao::RateLimitUnit::ALL`] (6bce03d) /
14541 // [`crate::dep::DepList::ALL`] (45ee563) exhaustive-iteration
14542 // pins on the peer closed-set typed-enum axes.
14543 let all: &[RestartPolicy] = RestartPolicy::ALL;
14544 assert_eq!(
14545 all.len(),
14546 3,
14547 "RestartPolicy::ALL must enumerate every variant of the \
14548 three-arm closed set (Permanent, Temporary, Transient); \
14549 got {all:?}"
14550 );
14551 for (i, a) in all.iter().enumerate() {
14552 for (j, b) in all.iter().enumerate() {
14553 if i != j {
14554 assert_ne!(
14555 a, b,
14556 "RestartPolicy::ALL must carry every variant exactly \
14557 once — got duplicate {a:?} at indices {i} and {j}"
14558 );
14559 }
14560 }
14561 }
14562 for variant in [
14563 RestartPolicy::Permanent,
14564 RestartPolicy::Temporary,
14565 RestartPolicy::Transient,
14566 ] {
14567 assert!(
14568 all.contains(&variant),
14569 "RestartPolicy::ALL must contain {variant:?} — a future arm \
14570 addition that grows the enum but forgets to grow the ALL slice \
14571 silently truncates every downstream consumer's accept-set at \
14572 the pre-addition boundary"
14573 );
14574 }
14575 }
14576
14577 #[test]
14578 fn restart_policy_wire_names_covers_every_arm() {
14579 // Load-bearing pin on the substrate-canonical
14580 // [`RestartPolicy::WIRE_NAMES`] exhaustive accept-set roster on
14581 // the `PascalCase` wire byte-string axis: every variant of the
14582 // sibling [`RestartPolicy::ALL`] exhaustive-iteration surface
14583 // must project through [`RestartPolicy::as_str`] onto an entry
14584 // the [`RestartPolicy::WIRE_NAMES`] roster carries, and the
14585 // roster's length must byte-equal `RestartPolicy::ALL.len()` so
14586 // a silent skew between the [`RestartPolicy::as_str`] match's
14587 // arm-set and the roster's arm-set trips here at caixa-core
14588 // test time rather than at a downstream M4
14589 // `mesh.pleme.io/v1alpha1/Supervisor` CR admission-webhook
14590 // rejection body's wire-form `:restart` accepted-set
14591 // enumeration miss / a `feira supervisor --restart …` "did you
14592 // mean" hint drift / a future wasm-operator per-reconcile-step
14593 // diagnostic log line's accepted-wire-form enumeration miss.
14594 // A future arm addition (an OTP-`intrinsic` fourth arm the
14595 // theory
14596 // [`ABSORPTION-ROADMAP`](https://github.com/pleme-io/theory/blob/main/ABSORPTION-ROADMAP.md)
14597 // might reach for once the three canonical OTP restart policies
14598 // stop covering the substrate's discovered load-shape) extends
14599 // [`RestartPolicy::ALL`] as a single edit and this pin sweeps
14600 // the new arm by iteration; the paired
14601 // [`RestartPolicy::WIRE_NAMES`] roster must grow in lockstep or
14602 // this assertion trips. Every entry is further pinned to open
14603 // with an ASCII uppercase byte so a silent collapse of the
14604 // wire-form axis with the peer kebab-case dispatcher-catalog
14605 // axis (an entry byte-identical to a sibling
14606 // [`RestartPolicy::discriminant`] kebab byte-string that would
14607 // let a wire-axis consumer accept the dispatcher-catalog
14608 // vocabulary) trips here rather than at a downstream K8s-CR
14609 // round-trip miss.
14610 //
14611 // Peer of the sibling
14612 // [`restart_strategy_wire_names_covers_every_arm`] (3033f45)
14613 // pin on the first M2 OTP-shape sibling-restart closed-set
14614 // typed enum, the sibling
14615 // [`crate::aplicacao::tests::placement_strategy_wire_names_covers_every_arm`]
14616 // (3e5b194) pin on the first M3 mesh-shape distribution-strategy
14617 // closed-set typed enum, the sibling
14618 // [`crate::kind::tests::caixa_kind_wire_names_covers_every_arm`]
14619 // (bd708bd) pin on the top-level typed-kind discriminator's
14620 // `PascalCase` wire byte-string axis, and the sibling
14621 // [`crate::upgrade::tests::upgrade_instruction_wire_forms_covers_every_arm`]
14622 // (cc42c0e) /
14623 // [`crate::upgrade::tests::upgrade_instruction_lisp_forms_covers_every_arm`]
14624 // (1898d77) pins on the OTP-appup discriminator's two-axis
14625 // roster split — the same closed-set exhaustive-roster coverage
14626 // discipline extended here onto the second and final M2
14627 // OTP-shape sibling-enum on the caixa surface, closing the
14628 // per-child restart-decision-policy axis paired with the peer
14629 // per-supervisor sibling-restart-strategy axis on the same M2
14630 // `:supervisor` slot.
14631 //
14632 // Fail-before-pass-after locally verified by mutating one arm
14633 // of the paired [`crate::render::SUPERVISOR_CHILD_RESTART_*`]
14634 // const family (e.g. dropping the trailing `t` from
14635 // `"Permanent"` → `"Permanen"`) — the length pin still passes
14636 // but the `contains` check fires on the mutated arm; and by
14637 // shortening the roster to two entries — the length pin fires
14638 // first.
14639 assert_eq!(
14640 RestartPolicy::WIRE_NAMES.len(),
14641 RestartPolicy::ALL.len(),
14642 "RestartPolicy::WIRE_NAMES.len() must byte-equal \
14643 RestartPolicy::ALL.len() — a mismatch means the roster \
14644 and the enum's arm-set have drifted; downstream consumers \
14645 that fan through both will silently disagree on the \
14646 accepted arm-set"
14647 );
14648 for &variant in RestartPolicy::ALL {
14649 let wire = variant.as_str();
14650 assert!(
14651 RestartPolicy::WIRE_NAMES.contains(&wire),
14652 "RestartPolicy::{variant:?}.as_str() = {wire:?} must \
14653 be a member of RestartPolicy::WIRE_NAMES — the \
14654 emitter and the roster have drifted out of lockstep"
14655 );
14656 }
14657 for tag in RestartPolicy::WIRE_NAMES {
14658 let first = tag.chars().next().unwrap_or_else(|| {
14659 panic!(
14660 "RestartPolicy::WIRE_NAMES entry {tag:?} must be \
14661 a non-empty PascalCase byte-string"
14662 )
14663 });
14664 assert!(
14665 first.is_ascii_uppercase(),
14666 "RestartPolicy::WIRE_NAMES entry {tag:?} must open \
14667 with an ASCII uppercase byte (PascalCase wire form) — \
14668 a lowercase entry would collide the wire-form axis \
14669 with the peer kebab-case dispatcher-catalog axis \
14670 [`RestartPolicy::discriminant`] serves"
14671 );
14672 }
14673 }
14674
14675 #[test]
14676 fn restart_policy_from_wire_accepts_every_lifted_constant() {
14677 // Fail-before-pass-after pin on the forward accept-set of the
14678 // [`RestartPolicy::from_wire`] reverse projection: every
14679 // canonical [`crate::render::SUPERVISOR_CHILD_RESTART_*`]
14680 // constant the [`RestartPolicy::as_str`] emitter walks parses
14681 // back to its paired variant. Any future arm addition that
14682 // grows the emitter's `as_str` match but forgets to grow the
14683 // parser's `from_wire` match silently splits the two halves of
14684 // the round-trip — the wire byte-string one non-serde consumer
14685 // parses from the one the emitter wrote — with the failure
14686 // surfacing at the operator's reconcile posture (a `:temporary`
14687 // `oneShot` child restarted on clean exit, a `:transient` child
14688 // restarted after clean completion) far from the rebrand
14689 // commit. Pinning the three-arm accept-set here catches the
14690 // drift at caixa-core build time.
14691 //
14692 // Peer of the sibling [`RestartStrategy::from_wire`] (4eec29c)
14693 // + [`crate::CaixaKind::from_wire`] (2aa6d23)
14694 // + [`crate::aplicacao::PlacementStrategy::from_wire`] (18c7342)
14695 // accept-set pins on the peer closed-set typed-enum `str → Self`
14696 // axes.
14697 for (wire, expected) in [
14698 (
14699 crate::render::SUPERVISOR_CHILD_RESTART_PERMANENT,
14700 RestartPolicy::Permanent,
14701 ),
14702 (
14703 crate::render::SUPERVISOR_CHILD_RESTART_TEMPORARY,
14704 RestartPolicy::Temporary,
14705 ),
14706 (
14707 crate::render::SUPERVISOR_CHILD_RESTART_TRANSIENT,
14708 RestartPolicy::Transient,
14709 ),
14710 ] {
14711 let parsed = RestartPolicy::from_wire(wire).unwrap_or_else(|| {
14712 panic!(
14713 "RestartPolicy::from_wire({wire:?}) must accept every \
14714 SUPERVISOR_CHILD_RESTART_* constant — got None for the \
14715 lifted canonical byte-string that RestartPolicy::{expected:?} \
14716 serializes as under SUPERVISOR_CHILD_KEY_RESTART"
14717 )
14718 });
14719 assert_eq!(
14720 parsed, expected,
14721 "RestartPolicy::from_wire({wire:?}) must return \
14722 RestartPolicy::{expected:?}; got RestartPolicy::{parsed:?}"
14723 );
14724 }
14725 }
14726
14727 #[test]
14728 fn restart_policy_from_wire_round_trips_through_as_str() {
14729 // Fail-before-pass-after pin on the closed round-trip between
14730 // the forward [`RestartPolicy::as_str`] emitter and the
14731 // reverse [`RestartPolicy::from_wire`] parser: for every
14732 // variant in [`RestartPolicy::ALL`], parsing the emitter's
14733 // output must return exactly the same variant. Any per-arm
14734 // divergence — a future arm added to `as_str` but not
14735 // `from_wire`, an accidental copy-paste flip in one but not
14736 // the other — silently splits the emit and parse halves and
14737 // the failure surfaces at consumer parse time far from the
14738 // drift site. The `ALL`-iterating shape means a future arm
14739 // addition picks up the coverage by construction.
14740 //
14741 // Peer of the sibling
14742 // [`restart_strategy_from_wire_round_trips_through_as_str`]
14743 // (4eec29c) round-trip pin on
14744 // [`RestartStrategy::from_wire`] and the M3
14745 // [`crate::aplicacao::tests::placement_strategy_from_wire_round_trips_through_as_str`]
14746 // (18c7342) round-trip pin on
14747 // [`crate::aplicacao::PlacementStrategy::from_wire`].
14748 for &variant in RestartPolicy::ALL {
14749 let wire = variant.as_str();
14750 let parsed = RestartPolicy::from_wire(wire).unwrap_or_else(|| {
14751 panic!(
14752 "RestartPolicy::from_wire(RestartPolicy::{variant:?}.as_str()) \
14753 must be Some({variant:?}) — the two halves of the round-trip \
14754 dispatch on the same lifted SUPERVISOR_CHILD_RESTART_* consts; \
14755 got None on wire byte-string {wire:?}"
14756 )
14757 });
14758 assert_eq!(
14759 parsed, variant,
14760 "RestartPolicy::from_wire(RestartPolicy::{variant:?}.as_str()) \
14761 must round-trip to the same variant; got {parsed:?}"
14762 );
14763 }
14764 }
14765
14766 #[test]
14767 fn restart_policy_from_wire_rejects_unknown_byte_strings() {
14768 // Fail-before-pass-after pin on the closed-set refusal
14769 // discipline of [`RestartPolicy::from_wire`]: every
14770 // byte-string outside the three-arm accept-set returns `None`
14771 // rather than silently collapsing onto the [`Default`]
14772 // (`Permanent`) arm or an arbitrary neighbor. The refusal set
14773 // exercised here sweeps the load-bearing drift shapes: the
14774 // empty string (a stripped serde-attribute drift), all-
14775 // whitespace strings (the canonical text-editor accidental
14776 // padding shape), the kebab-case dispatcher-catalog identities
14777 // (`"permanent"` / `"temporary"` / `"transient"` — the
14778 // [`gen_platform::FromStrKind`]-derived [`std::str::FromStr`]
14779 // accept-set, which parses the *other* axis of this enum's
14780 // two-axis split and must not leak into the `from_wire`
14781 // PascalCase-wire accept-set — a lowercase leak here would
14782 // silently accept the operator's kebab-case
14783 // dispatcher-catalog probe under the wire-axis parser and mis-
14784 // route a `:permanent` intent), the padded canonical scalar
14785 // (`" Permanent "`), the trailing-newline shapes
14786 // (`"Permanent\n"`), the uppercase-single-word forms
14787 // (`"PERMANENT"`), and neighboring-but-unknown arms
14788 // (`"Restart"` — the canonical typo direction toward the
14789 // sibling [`RestartStrategy`] enum's own wire-arm namespace).
14790 //
14791 // Peer of the sibling
14792 // [`restart_strategy_from_wire_rejects_unknown_byte_strings`]
14793 // (4eec29c) +
14794 // [`crate::kind::tests::caixa_kind_from_wire_rejects_unknown_byte_strings`]
14795 // (2aa6d23) +
14796 // [`crate::aplicacao::tests::placement_strategy_from_wire_rejects_unknown_byte_strings`]
14797 // (18c7342) refusal pins on the peer closed-set typed-enum
14798 // axes.
14799 for bad in [
14800 "",
14801 " ",
14802 "\n",
14803 "\t",
14804 "permanent",
14805 "temporary",
14806 "transient",
14807 "PERMANENT",
14808 "TEMPORARY",
14809 "TRANSIENT",
14810 "Permanents",
14811 "Permanent ",
14812 " Permanent",
14813 " Transient ",
14814 "Permanent\n",
14815 "perma",
14816 "Trans",
14817 "OneForOne",
14818 "Restart",
14819 "?",
14820 ] {
14821 assert!(
14822 RestartPolicy::from_wire(bad).is_none(),
14823 "RestartPolicy::from_wire({bad:?}) must return None — the \
14824 parser's accept-set is exactly the three RestartPolicy::as_str \
14825 outputs (Permanent, Temporary, Transient), and this \
14826 byte-string is outside that closed set"
14827 );
14828 }
14829 }
14830
14831 #[test]
14832 fn restart_policy_from_wire_matches_serialize_derive_wire_byte_string() {
14833 // Fail-before-pass-after pin on the fourth path of the four-path
14834 // convergence: `from_wire` (the reverse projection) inverts the
14835 // `Serialize` derive's wire byte-string on every variant.
14836 // Together with the pre-existing three-path convergence
14837 // (`Display` + `as_str` + `Serialize` all resolve to the same
14838 // lifted [`crate::render::SUPERVISOR_CHILD_RESTART_*`] const,
14839 // pinned by
14840 // [`restart_policy_display_matches_serialized_wire_byte_string`])
14841 // this closes the round-trip: the wire byte-string the
14842 // `Serialize` derive emits parses back to the same variant
14843 // through `from_wire`, so any future serde-attribute or variant-
14844 // rename drift on the emit half now surfaces as a matched drift
14845 // on the parse half at caixa-core build time — the two halves
14846 // migrate as a unit through the lifted consts on any future
14847 // rename, and the round-trip cannot silently split.
14848 //
14849 // Peer of the sibling
14850 // [`restart_strategy_from_wire_matches_serialize_derive_wire_byte_string`]
14851 // (4eec29c) wire-format pin on
14852 // [`RestartStrategy::from_wire`] and the M3
14853 // [`crate::aplicacao::tests::placement_strategy_from_wire_matches_serialize_derive_wire_byte_string`]
14854 // (18c7342) wire-format pin on
14855 // [`crate::aplicacao::PlacementStrategy::from_wire`].
14856 for &variant in RestartPolicy::ALL {
14857 let wire = serde_json::to_string(&variant).unwrap();
14858 let unquoted = wire
14859 .strip_prefix('"')
14860 .and_then(|s| s.strip_suffix('"'))
14861 .expect("serialized RestartPolicy is a JSON string");
14862 let parsed = RestartPolicy::from_wire(unquoted).unwrap_or_else(|| {
14863 panic!(
14864 "RestartPolicy::from_wire({unquoted:?}) must accept the \
14865 Serialize derive's wire byte-string for \
14866 RestartPolicy::{variant:?} — the four-path convergence \
14867 (Display + as_str + Serialize + from_wire) resolves through \
14868 the same lifted SUPERVISOR_CHILD_RESTART_* const; got None"
14869 )
14870 });
14871 assert_eq!(
14872 parsed, variant,
14873 "RestartPolicy::from_wire of the Serialize derive's wire \
14874 byte-string for RestartPolicy::{variant:?} must round-trip \
14875 to the same variant; got {parsed:?}"
14876 );
14877 }
14878 }
14879
14880 // ── drift-detection: ChildSpec::nome accessor pins ────────────────────
14881 //
14882 // The M2 supervisor-tree sibling of the M3 `Membro::nome` (4a32abf) pin
14883 // pair (`membro_nome_returns_caixa_byte_equal_across_permutations` +
14884 // `membro_nome_borrows_from_caixa_storage`) — extended here to the M2
14885 // per-`:children` child-caixa `:nome` axis, sibling to the first M2
14886 // slot scalar accessor `UpgradeFromEntry::prior_versao` (75d27a8) on
14887 // the peer per-`:upgrade-from :from` axis. The three pins jointly
14888 // brace the accessor against every future silent detour that would
14889 // desynchronize it from the raw `.caixa` field access every consumer
14890 // previously open-coded.
14891
14892 #[test]
14893 fn child_spec_nome_returns_caixa_byte_equal_across_permutations() {
14894 // The canonical per-`:children` child-caixa `:nome`-scalar pin:
14895 // [`ChildSpec::nome`] must return the `:children :caixa` field
14896 // byte-for-byte across every DNS-1123-label value the upstream
14897 // [`crate::render::require_valid_dns_1123_label`] gate at
14898 // `SupervisorSpec::validate` admits. Peer of the sibling
14899 // `membro_nome_returns_caixa_byte_equal_across_permutations`
14900 // (4a32abf) pin on the M3 per-`:membros` axis — same "the
14901 // substrate-primitive accessor must byte-equal the raw field
14902 // access verbatim across every author-declared value" discipline
14903 // extended to the M2 supervisor-tree per-`:children` arm. Pins
14904 // against a future silent detour that re-normalized the child
14905 // identity (an accidental `.to_lowercase()` — every `:children
14906 // :caixa` is validated as a DNS-1123 label upstream, so any
14907 // re-normalization is redundant + a drift surface between the
14908 // validator and the accessor), a namespace-prefix rewrite (an
14909 // accidental `format!("{namespace}/{caixa}")` per-CR
14910 // fully-qualified rewrite that didn't land on the peer axes), or
14911 // a per-cluster alias stamp the future wasm-operator's
14912 // hierarchical reconciliation scheduler authors on one consumer
14913 // without the others. Five values sweep the accept-set the
14914 // DNS-1123 gate upstream admits (short single-word / dashed /
14915 // v-suffixed / mixed-digit child names).
14916 for name in [
14917 "worker",
14918 "cache-server",
14919 "scratch-job",
14920 "orders-v2",
14921 "session-8080",
14922 ] {
14923 let c = ChildSpec {
14924 caixa: name.into(),
14925 versao: "^0.1".into(),
14926 restart: RestartPolicy::Permanent,
14927 };
14928 assert_eq!(
14929 c.nome(),
14930 name,
14931 "ChildSpec::nome must return :children :caixa verbatim \
14932 (got {:?}, expected {name:?})",
14933 c.nome(),
14934 );
14935 assert_eq!(
14936 c.nome(),
14937 c.caixa.as_str(),
14938 "ChildSpec::nome must byte-equal the .caixa field access",
14939 );
14940 }
14941 }
14942
14943 #[test]
14944 fn child_spec_nome_borrows_from_caixa_storage() {
14945 // The borrow-not-copy pin: [`ChildSpec::nome`] must return a
14946 // `&str` slice that borrows from the typed slot's own [`String`]
14947 // storage — same-address invariant with `c.caixa.as_str()`. Pins
14948 // against a future silent detour that allocated a fresh `String`
14949 // (`self.caixa.clone()` in the body would type-check but silently
14950 // drop the borrow, and every downstream consumer that assumed
14951 // the returned slice outlives `&self` would break on a stale-
14952 // reference use-after-free — the [`crate::render::insert_first_seen`]
14953 // dedup key at [`SupervisorSpec::validate`], the
14954 // [`validate_no_self_supervision`] equality check against the
14955 // parent's `:nome` string slice, the DNS-1123 gate's `&str`
14956 // borrow — each would silently misbehave if this accessor
14957 // produced a detached copy). Peer of the sibling
14958 // `membro_nome_borrows_from_caixa_storage` (4a32abf) pin on the
14959 // M3 per-`:membros` axis and the
14960 // `prior_versao_borrows_from_from_storage` (75d27a8) pin on the
14961 // first M2 slot scalar accessor.
14962 let c = ChildSpec {
14963 caixa: "worker".into(),
14964 versao: "^0.1".into(),
14965 restart: RestartPolicy::Permanent,
14966 };
14967 let name = c.nome();
14968 let caixa_slice = c.caixa.as_str();
14969 assert_eq!(
14970 name.as_ptr(),
14971 caixa_slice.as_ptr(),
14972 "ChildSpec::nome must borrow from the .caixa String's backing \
14973 storage — a fresh allocation here means the accessor no \
14974 longer names the substrate-primitive typed dispatch and \
14975 every downstream consumer would silently carry a detached \
14976 copy",
14977 );
14978 assert_eq!(
14979 name.len(),
14980 caixa_slice.len(),
14981 "ChildSpec::nome and .caixa.as_str() must byte-equal in length \
14982 as well as in address",
14983 );
14984 }
14985
14986 #[test]
14987 fn validate_gates_child_nome_through_lifted_accessor() {
14988 // Bilateral coherence pin: every `:children :caixa` that
14989 // [`SupervisorSpec::validate`] accepts is one
14990 // [`crate::render::require_valid_dns_1123_label`] accepts on the
14991 // accessor-projected value, and vice versa on the reject side.
14992 // This closes the "the validator reads through the accessor"
14993 // contract structurally — a future silent detour that made the
14994 // accessor return a different byte-string than the validator
14995 // gates against would surface here as a coverage mismatch, not
14996 // as an apply-time DNS-1123 rejection at
14997 // `metadata.name: Invalid value` far from the caixa.lisp source.
14998 // Peer of the M2 sibling
14999 // `validate_parses_prior_versao_through_lifted_accessor`
15000 // (75d27a8) on the per-`:upgrade-from :from` axis and the M3
15001 // `validate_membros` peer discipline.
15002 //
15003 // Accept-set sweep: five DNS-1123-label values the upstream gate
15004 // admits.
15005 for ok_name in ["a", "worker", "cache-server", "orders-v2", "svc-8080"] {
15006 let s = SupervisorSpec {
15007 children: vec![ChildSpec {
15008 caixa: ok_name.into(),
15009 versao: "^0.1".into(),
15010 restart: RestartPolicy::Permanent,
15011 }],
15012 ..SupervisorSpec::default()
15013 };
15014 s.validate().unwrap_or_else(|e| {
15015 panic!(
15016 "SupervisorSpec::validate must accept :children :caixa {ok_name:?} \
15017 (upstream DNS-1123 gate accepts it): got {e:?}",
15018 );
15019 });
15020 let c = ChildSpec {
15021 caixa: ok_name.into(),
15022 versao: "^0.1".into(),
15023 restart: RestartPolicy::Permanent,
15024 };
15025 crate::render::require_valid_dns_1123_label(c.nome(), || (), |_reason| ())
15026 .unwrap_or_else(|()| {
15027 panic!(
15028 "require_valid_dns_1123_label must accept the accessor-projected \
15029 :children :caixa {ok_name:?}",
15030 );
15031 });
15032 }
15033 // Reject-set sweep: five DNS-1123-label-violating shapes the
15034 // upstream gate refuses (empty / uppercase / underscore / dot /
15035 // leading-hyphen). Every rejection at the validator must
15036 // correspond to a rejection when the accessor's projected value
15037 // is fed back through the shared gate.
15038 for bad_name in ["", "Worker", "my_worker", "team.worker", "-worker"] {
15039 let s = SupervisorSpec {
15040 children: vec![ChildSpec {
15041 caixa: bad_name.into(),
15042 versao: "^0.1".into(),
15043 restart: RestartPolicy::Permanent,
15044 }],
15045 ..SupervisorSpec::default()
15046 };
15047 let err = s.validate().unwrap_err();
15048 assert!(
15049 matches!(
15050 err,
15051 SupervisorError::EmptyChildName | SupervisorError::ChildCaixaInvalid { .. }
15052 ),
15053 "SupervisorSpec::validate must reject :children :caixa {bad_name:?} \
15054 via the DNS-1123 gate: got {err:?}",
15055 );
15056 let c = ChildSpec {
15057 caixa: bad_name.into(),
15058 versao: "^0.1".into(),
15059 restart: RestartPolicy::Permanent,
15060 };
15061 assert!(
15062 crate::render::require_valid_dns_1123_label(c.nome(), || (), |_reason| (),)
15063 .is_err(),
15064 "require_valid_dns_1123_label must reject the accessor-projected \
15065 :children :caixa {bad_name:?}",
15066 );
15067 }
15068 }
15069
15070 // ── drift-detection: ChildSpec::versao_requirement accessor pins ──────
15071 //
15072 // Sibling of the peer per-`:membros` `membro_versao_requirement_*`
15073 // (a40b0e3) pin pair on the M3 mesh-slot surface — extended here to the
15074 // M2 supervisor-tree per-`:children` child-`:versao` axis, sibling to
15075 // the just-landed [`ChildSpec::nome`] (57c61d0) child-`:nome` pin
15076 // trio on the peer per-`:children` `String`-carry axis. The three pins
15077 // jointly brace the accessor against every future silent detour that
15078 // would desynchronize it from the raw `.versao` field access the
15079 // requirement gate + error carrier previously open-coded.
15080 //
15081 // Closes the last unlifted per-`:children` `String`-carry axis: the
15082 // pair (`nome`, `versao_requirement`) now jointly projects the
15083 // (`.caixa`, `.versao`) field pair every OTP-shape supervisor-tree
15084 // consumer that fans on per-child identity + version pin reads,
15085 // matching the peer M3 (`Membro::nome`, `Membro::versao_requirement`)
15086 // pair discipline verbatim.
15087 #[test]
15088 fn child_spec_versao_requirement_returns_versao_byte_equal_across_permutations() {
15089 // The canonical per-`:children` child-`:versao`-scalar pin:
15090 // [`ChildSpec::versao_requirement`] must return the `:children
15091 // :versao` field byte-for-byte across every Cargo-shaped semver
15092 // requirement value the upstream
15093 // [`crate::render::require_valid_versao_requirement`] gate admits.
15094 // Peer of the sibling
15095 // `membro_versao_requirement_returns_versao_byte_equal_across_permutations`
15096 // (a40b0e3) pin on the M3 per-`:membros` axis — same "the
15097 // substrate-primitive accessor must byte-equal the raw field
15098 // access verbatim across every author-declared value" discipline
15099 // extended to the M2 supervisor-tree per-`:children` arm. Pins
15100 // against a future silent detour that re-canonicalized the
15101 // requirement (an accidental `.to_string()` via
15102 // [`crate::version::parse_requirement`] → [`std::fmt::Display`]
15103 // round-trip that collapsed `"^0.1"` to `">=0.1, <0.2"` and
15104 // silently drifted the error carrier's quoted requirement away
15105 // from the source `caixa.lisp`, an accidental whitespace trim on
15106 // `"^ 0.1"` that no consumer ever produced from the field-access
15107 // side, an accidental per-cluster lacre-projected concrete-version
15108 // rewrite that didn't land on the peer requirement-gate call).
15109 // Five values sweep the accept-set the shared
15110 // [`crate::render::require_valid_versao_requirement`] gate admits
15111 // (caret / tilde / exact / wildcard / bare-major).
15112 for req in ["^0.1", "~0.1.2", "0.1.0", "*", "^1"] {
15113 let c = ChildSpec {
15114 caixa: "worker".into(),
15115 versao: req.into(),
15116 restart: RestartPolicy::Permanent,
15117 };
15118 assert_eq!(
15119 c.versao_requirement(),
15120 req,
15121 "ChildSpec::versao_requirement must return :children :versao \
15122 verbatim (got {:?}, expected {req:?})",
15123 c.versao_requirement(),
15124 );
15125 assert_eq!(
15126 c.versao_requirement(),
15127 c.versao.as_str(),
15128 "ChildSpec::versao_requirement must byte-equal the .versao \
15129 field access",
15130 );
15131 }
15132 }
15133
15134 #[test]
15135 fn child_spec_versao_requirement_borrows_from_versao_storage() {
15136 // The borrow-not-copy pin: [`ChildSpec::versao_requirement`] must
15137 // return a `&str` slice that borrows from the typed slot's own
15138 // [`String`] storage — same-address invariant with
15139 // `c.versao.as_str()`. Pins against a future silent detour that
15140 // allocated a fresh `String` (`self.versao.clone()` in the body
15141 // would type-check but silently drop the borrow, and every
15142 // downstream consumer that assumed the returned slice outlives
15143 // `&self` — the [`crate::render::require_valid_versao_requirement`]
15144 // gate's `&str` borrow, the [`SupervisorError::ChildVersaoInvalid`]
15145 // `.to_string()` carrier's byte-length assumption — would silently
15146 // misbehave if this accessor produced a detached copy). Peer of
15147 // the sibling `child_spec_nome_borrows_from_caixa_storage`
15148 // (57c61d0) pin on the per-`:children` `:nome` axis and the M3
15149 // `membro_versao_requirement_borrows_from_versao_storage` (a40b0e3)
15150 // pin on the peer per-`:membros` `:versao` axis.
15151 let c = ChildSpec {
15152 caixa: "worker".into(),
15153 versao: "^0.1".into(),
15154 restart: RestartPolicy::Permanent,
15155 };
15156 let req = c.versao_requirement();
15157 let versao_slice = c.versao.as_str();
15158 assert_eq!(
15159 req.as_ptr(),
15160 versao_slice.as_ptr(),
15161 "ChildSpec::versao_requirement must borrow from the .versao \
15162 String's backing storage — a fresh allocation here means the \
15163 accessor no longer names the substrate-primitive typed \
15164 dispatch and every downstream consumer would silently carry \
15165 a detached copy",
15166 );
15167 assert_eq!(
15168 req.len(),
15169 versao_slice.len(),
15170 "ChildSpec::versao_requirement and .versao.as_str() must \
15171 byte-equal in length as well as in address",
15172 );
15173 }
15174
15175 #[test]
15176 fn validate_gates_child_versao_through_lifted_accessor() {
15177 // Bilateral coherence pin: every `:children :versao` that
15178 // [`SupervisorSpec::validate`] accepts is one
15179 // [`crate::render::require_valid_versao_requirement`] accepts on
15180 // the accessor-projected value, and vice versa on the reject side.
15181 // This closes the "the validator reads through the accessor"
15182 // contract structurally — a future silent detour that made the
15183 // accessor return a different byte-string than the validator gates
15184 // against would surface here as a coverage mismatch, not as a
15185 // resolver-time semver-parse rejection at lacre-closure time far
15186 // from the caixa.lisp source. Peer of the sibling
15187 // `validate_gates_child_nome_through_lifted_accessor` (57c61d0) on
15188 // the per-`:children :caixa` axis and the M2
15189 // `validate_parses_prior_versao_through_lifted_accessor` (75d27a8)
15190 // on the peer per-`:upgrade-from :from` axis.
15191 //
15192 // Accept-set sweep: five Cargo-shaped semver requirement values
15193 // the upstream gate admits (caret / tilde / exact / wildcard /
15194 // bare-major).
15195 for ok_req in ["^0.1", "~0.1.2", "0.1.0", "*", "^1"] {
15196 let s = SupervisorSpec {
15197 children: vec![ChildSpec {
15198 caixa: "worker".into(),
15199 versao: ok_req.into(),
15200 restart: RestartPolicy::Permanent,
15201 }],
15202 ..SupervisorSpec::default()
15203 };
15204 s.validate().unwrap_or_else(|e| {
15205 panic!(
15206 "SupervisorSpec::validate must accept :children :versao {ok_req:?} \
15207 (upstream versao-requirement gate accepts it): got {e:?}",
15208 );
15209 });
15210 let c = ChildSpec {
15211 caixa: "worker".into(),
15212 versao: ok_req.into(),
15213 restart: RestartPolicy::Permanent,
15214 };
15215 crate::render::require_valid_versao_requirement(
15216 c.versao_requirement(),
15217 || (),
15218 |_reason| (),
15219 )
15220 .unwrap_or_else(|()| {
15221 panic!(
15222 "require_valid_versao_requirement must accept the accessor-projected \
15223 :children :versao {ok_req:?}",
15224 );
15225 });
15226 }
15227 // Reject-set sweep: five requirement-violating shapes the upstream
15228 // gate refuses. The empty string closes the empty-first arm of the
15229 // shared [`crate::render::require_valid_versao_requirement`]
15230 // cascade; the four non-empty arms exercise distinct semver-parse
15231 // failure modes the M3 peer per-`:membros` reject-set already pins
15232 // (`rejects_invalid_membro_versao_requirement` on `^bad-version`,
15233 // `rejects_membro_versao_with_double_caret_typo` on `^^0.1`,
15234 // `rejects_membro_versao_with_v_prefixed_tag` on `v0.1`) — the
15235 // shared parser routing means the same reject-set must fail
15236 // identically at the M2 supervisor-tree per-`:children` accessor
15237 // arm here. Every rejection at the validator must correspond to a
15238 // rejection when the accessor's projected value is fed back
15239 // through the shared gate.
15240 //
15241 // (Bare partial magnitudes like `"0.1"` and bare identifiers like
15242 // `"not-a-semver"` are intentionally *not* in the reject-set: the
15243 // semver crate accepts `"0.1"` as an implicit `^0.1` requirement,
15244 // and the identifier-tail arm's grammar admits some non-canonical
15245 // shapes — matching what the M3 peer test suite already documents
15246 // as the shared parser's accept-set edges.)
15247 for bad_req in ["", "v0.1.0", "^bad-version", "^^0.1", "v0.1"] {
15248 let s = SupervisorSpec {
15249 children: vec![ChildSpec {
15250 caixa: "worker".into(),
15251 versao: bad_req.into(),
15252 restart: RestartPolicy::Permanent,
15253 }],
15254 ..SupervisorSpec::default()
15255 };
15256 let err = s.validate().unwrap_err();
15257 assert!(
15258 matches!(
15259 err,
15260 SupervisorError::EmptyChildVersion { .. }
15261 | SupervisorError::ChildVersaoInvalid { .. }
15262 ),
15263 "SupervisorSpec::validate must reject :children :versao {bad_req:?} \
15264 via the versao-requirement gate: got {err:?}",
15265 );
15266 let c = ChildSpec {
15267 caixa: "worker".into(),
15268 versao: bad_req.into(),
15269 restart: RestartPolicy::Permanent,
15270 };
15271 assert!(
15272 crate::render::require_valid_versao_requirement(
15273 c.versao_requirement(),
15274 || (),
15275 |_reason| (),
15276 )
15277 .is_err(),
15278 "require_valid_versao_requirement must reject the accessor-projected \
15279 :children :versao {bad_req:?}",
15280 );
15281 }
15282 }
15283
15284 // ── per-`:children` `:restart` typed-accessor coherence pins ──────────
15285 //
15286 // The [`ChildSpec::restart`] accessor lift closes the last unlifted
15287 // per-`:children` axis (the pair `nome()` + `versao_requirement()`
15288 // already project the `String`-carry `(caixa, versao)` fields; the
15289 // `Copy`-composite-enum `restart` field is the third and final axis).
15290 // Peer of the sibling per-`:supervisor` [`SupervisorSpec::estrategia`]
15291 // (eafb619) `Copy`-return [`RestartStrategy`] sibling-restart-strategy
15292 // scalar accessor and the M3 mesh-slot [`crate::Placement::estrategia`]
15293 // (921fe1b) `Copy`-return [`crate::PlacementStrategy`] distribution-
15294 // strategy scalar accessor — same "one typed dispatch on the substrate
15295 // primitive, `Copy`-projected closed-set enum-arm discriminator" shape
15296 // extended onto the M2 supervisor-slot per-`:children` restart-decision
15297 // axis. The pin below covers the accessor's byte-equal projection
15298 // against the raw field access across every variant in the closed
15299 // accept-set (`Permanent`, `Transient`, `Temporary`).
15300
15301 #[test]
15302 fn child_spec_restart_returns_restart_verbatim_across_permutations() {
15303 // The canonical per-`:children` restart-decision-policy-scalar
15304 // pin: [`ChildSpec::restart`] must return the `:children :restart`
15305 // field verbatim as a [`RestartPolicy`], `Copy`-projected from the
15306 // typed slot's own [`RestartPolicy`] storage across every variant
15307 // in the closed accept-set (`Permanent`, `Transient`, `Temporary`).
15308 // Pins against a future silent detour that re-derived the policy
15309 // from a peer axis (an accidental fallback to
15310 // `if is_supervisor_child { Permanent } else { Temporary }` that
15311 // collapsed the child's kind axis into the restart discriminator),
15312 // a variant remap the operator authors on one consumer without the
15313 // other, or a stale-derive detour that substituted
15314 // [`RestartPolicy::default`] when the field held any explicit
15315 // variant (which would silently collapse the distinction between
15316 // "author explicitly declared `:restart Permanent`" and "author
15317 // omitted the slot and inherited the default" the future
15318 // per-cluster restart-decision override slot depends on).
15319 //
15320 // Peer of the sibling per-`:supervisor`
15321 // `supervisor_spec_estrategia_returns_estrategia_verbatim_across_permutations`
15322 // (eafb619) pin on the M2 supervisor-slot sibling-restart-strategy
15323 // axis and the M3
15324 // `placement_estrategia_returns_estrategia_verbatim_across_permutations`
15325 // (921fe1b) pin on the per-`:placement` distribution-strategy axis
15326 // — same "the substrate-primitive accessor must byte-equal the raw
15327 // field access verbatim across every author-declared value"
15328 // discipline extended onto the M2 supervisor-slot per-`:children`
15329 // restart-decision-policy axis, closing the last unlifted axis on
15330 // the per-`:children` [`ChildSpec`] type.
15331 for restart in [
15332 RestartPolicy::Permanent,
15333 RestartPolicy::Transient,
15334 RestartPolicy::Temporary,
15335 ] {
15336 let c = ChildSpec {
15337 caixa: "worker".into(),
15338 versao: "^0.1".into(),
15339 restart,
15340 };
15341 assert_eq!(
15342 c.restart(),
15343 restart,
15344 "ChildSpec::restart must return :children :restart \
15345 verbatim (got {:?}, expected {restart:?})",
15346 c.restart(),
15347 );
15348 assert_eq!(
15349 c.restart(),
15350 c.restart,
15351 "ChildSpec::restart accessor and .restart field access \
15352 must byte-equal — the accessor is the substrate-primitive \
15353 typed dispatch every downstream per-child restart-\
15354 decision consumer must route through",
15355 );
15356 }
15357 }
15358
15359 // ── per-`:supervisor` `:estrategia` typed-accessor coherence pins ─────
15360 //
15361 // The [`SupervisorSpec::estrategia`] accessor lift extends the peer M3
15362 // [`crate::Placement::estrategia`] (921fe1b) `Copy`-return
15363 // distribution-strategy accessor discipline onto the M2 supervisor-slot
15364 // per-`:supervisor` sibling-restart-strategy `Copy`-composite-enum
15365 // scalar axis. The two pins below cover (1) the accessor's byte-equal
15366 // projection against the raw field access across every variant in the
15367 // closed accept-set, and (2) the two-consumer coherence between the
15368 // [`SupervisorSpec::validate`] partition-dispatch `match` arm and the
15369 // non-`SimpleOneForOne`-arm [`SupervisorError::NoChildren`] error
15370 // carrier's `estrategia:` field — peer of the sibling M3
15371 // `placement_estrategia_returns_estrategia_verbatim_across_permutations`
15372 // / `validate_placement_reads_through_lifted_estrategia_accessor` pin
15373 // pair on the per-`:placement` distribution-strategy axis.
15374
15375 #[test]
15376 fn supervisor_spec_estrategia_returns_estrategia_verbatim_across_permutations() {
15377 // The canonical per-`:supervisor` sibling-restart-strategy-scalar
15378 // pin: [`SupervisorSpec::estrategia`] must return the
15379 // `:supervisor :estrategia` field verbatim as a
15380 // [`RestartStrategy`], `Copy`-projected from the typed slot's own
15381 // [`RestartStrategy`] storage across every variant in the closed
15382 // accept-set (`OneForOne`, `OneForAll`, `RestForOne`,
15383 // `SimpleOneForOne`). Pins against a future silent detour that
15384 // re-derived the strategy from a peer axis (an accidental
15385 // fallback to `if children.is_empty() { SimpleOneForOne } else {
15386 // OneForOne }` collapse that read the children-count axis into
15387 // the strategy discriminator), a variant remap the operator
15388 // authors on one consumer without the other, or a stale-derive
15389 // detour that substituted [`RestartStrategy::default`] when the
15390 // field held any explicit variant (which would silently collapse
15391 // the distinction between "author explicitly declared
15392 // `:estrategia OneForOne`" and "author omitted the slot and
15393 // inherited the default" the future per-cluster strategy override
15394 // slot depends on). Peer of the sibling M3
15395 // `placement_estrategia_returns_estrategia_verbatim_across_permutations`
15396 // (921fe1b) pin on the M3 mesh-slot `Copy`-composite-enum scalar
15397 // axis — same "the substrate-primitive accessor must byte-equal
15398 // the raw field access verbatim across every author-declared
15399 // value" discipline extended onto the M2 supervisor-slot
15400 // per-`:supervisor` sibling-restart-strategy axis.
15401 for &estrategia in RestartStrategy::ALL {
15402 // `SimpleOneForOne` requires `children.is_empty()`; the peer
15403 // three strategies require a non-empty static children list.
15404 // Build each shape coherently so the pin's fixture would
15405 // itself pass [`SupervisorSpec::validate`] once fed through
15406 // the sibling coherence pin below — the byte-equal projection
15407 // asserted here is a strictly weaker property (a `Copy` field
15408 // read) that does not depend on `validate` running, but
15409 // keeping the fixture validate-clean means a future extension
15410 // of the pin to exercise `validate` end-to-end does not have
15411 // to re-author the children shape.
15412 //
15413 // Route the `SimpleOneForOne ↔ non-SimpleOneForOne` fixture-
15414 // shape partition through the [`gen_platform::IsVariant`]
15415 // derive-generated
15416 // [`RestartStrategy::is_simple_one_for_one`] predicate rather
15417 // than the raw `matches!(estrategia, RestartStrategy::
15418 // SimpleOneForOne)` open-coded pattern-match — same closed-
15419 // set-typed-enum arm-discriminator dispatch discipline the
15420 // sibling [`crate::upgrade::UpgradeInstruction::is_restart`]
15421 // convergence (915a934) extended onto its two paired positive
15422 // / negated `matches!` sites and the peer
15423 // [`crate::aplicacao::PlacementStrategy`] `IsVariant`-derived
15424 // predicate convergence (766ec63) extended onto the M3 mesh-
15425 // slot per-`:placement` distribution-strategy discriminator
15426 // axis. See the sibling `round_trip_all_strategies` and the
15427 // peer `manifest::tests::
15428 // caixa_estrategia_and_supervisor_view_reads_through_lifted_estrategia_accessor`
15429 // fixture for the two peer sites the same lift closes on.
15430 let children = if estrategia.is_simple_one_for_one() {
15431 Vec::new()
15432 } else {
15433 vec![ChildSpec {
15434 caixa: "worker".into(),
15435 versao: "^0.1".into(),
15436 restart: RestartPolicy::Permanent,
15437 }]
15438 };
15439 let s = SupervisorSpec {
15440 estrategia,
15441 children,
15442 ..SupervisorSpec::default()
15443 };
15444 assert_eq!(
15445 s.estrategia(),
15446 estrategia,
15447 "SupervisorSpec::estrategia must return :supervisor :estrategia \
15448 verbatim (got {:?}, expected {estrategia:?})",
15449 s.estrategia(),
15450 );
15451 assert_eq!(
15452 s.estrategia(),
15453 s.estrategia,
15454 "SupervisorSpec::estrategia accessor and .estrategia field \
15455 access must byte-equal — the accessor is the substrate-\
15456 primitive typed dispatch every downstream sibling-restart-\
15457 strategy consumer must route through",
15458 );
15459 }
15460 }
15461
15462 #[test]
15463 fn validate_reads_through_lifted_estrategia_accessor() {
15464 // Two-consumer coherence pin: the [`SupervisorSpec::validate`]
15465 // `SimpleOneForOne ↔ non-SimpleOneForOne` `match` partition
15466 // dispatch (which reads through [`SupervisorSpec::estrategia`]
15467 // to fan across the strategy-arm shape-gate cascades) and the
15468 // non-`SimpleOneForOne`-arm [`SupervisorError::NoChildren`]
15469 // error carrier's `estrategia:` field (which reads through
15470 // [`SupervisorSpec::estrategia`] to name the strategy the empty
15471 // `:children` list was declared against) must both key off the
15472 // lifted accessor, so any future rebrand on the typed slot's
15473 // reader shape lands at exactly one place. Pins the two-site
15474 // coherence by exercising the `NoChildren` error surface end-to-
15475 // end across every non-`SimpleOneForOne` variant and asserting
15476 // the surfaced `estrategia:` field byte-equals the accessor's
15477 // return. Peer of the sibling M3
15478 // `validate_placement_reads_through_lifted_estrategia_accessor`
15479 // (921fe1b) three-consumer coherence pin on the per-`:placement`
15480 // distribution-strategy axis.
15481 for estrategia in [
15482 RestartStrategy::OneForOne,
15483 RestartStrategy::OneForAll,
15484 RestartStrategy::RestForOne,
15485 ] {
15486 let s = SupervisorSpec {
15487 estrategia,
15488 children: Vec::new(),
15489 ..SupervisorSpec::default()
15490 };
15491 let err = s.validate().unwrap_err();
15492 match err {
15493 SupervisorError::NoChildren { estrategia: e } => {
15494 assert_eq!(
15495 e,
15496 s.estrategia(),
15497 "NoChildren.estrategia must byte-equal \
15498 SupervisorSpec::estrategia() — the empty-`:children` \
15499 refusal reads through the lifted accessor",
15500 );
15501 assert_eq!(
15502 e, estrategia,
15503 "NoChildren.estrategia must carry the author-declared \
15504 :supervisor :estrategia variant verbatim (got {e:?}, \
15505 expected {estrategia:?})",
15506 );
15507 }
15508 other => panic!("expected NoChildren, got {other:?} for estrategia={estrategia:?}"),
15509 }
15510 }
15511 }
15512
15513 // ── per-`:supervisor` `:max-restarts` typed-accessor coherence pins ────
15514 //
15515 // The [`SupervisorSpec::max_restarts`] accessor lift extends the peer M3
15516 // [`crate::CircuitBreaker::max_failures`] (3a74062) `Copy`-return
15517 // required-`u32` scalar accessor discipline onto the M2 supervisor-slot
15518 // per-`:supervisor` restart-budget-count `Copy`-`u32` scalar axis.
15519 // The two pins below cover (1) the accessor's byte-equal projection
15520 // against the raw field access across every representative value in
15521 // the `u32` accept-set (`1` lower boundary, `SUPERVISOR_MAX_RESTARTS_MAX`
15522 // upper boundary, `0` past-the-guard zero sentinel, `u32::MAX`
15523 // past-the-guard cap sentinel), and (2) the [`SupervisorSpec::validate`]
15524 // zero-floor / cap composition — the validate gate and the accessor
15525 // must route through the same substrate-primitive typed dispatch, so
15526 // any future silent detour that had the accessor perform a
15527 // bounds-collapsing clamp would fail here at caixa-core build time.
15528 // Peer of the sibling M3
15529 // `circuit_breaker_max_failures_returns_max_failures_u32_byte_equal_across_permutations`
15530 // (3a74062) pin on the per-`CircuitBreaker :max-failures` axis.
15531
15532 #[test]
15533 fn supervisor_spec_max_restarts_returns_max_restarts_u32_byte_equal_across_permutations() {
15534 // The canonical per-`:supervisor` restart-budget-count scalar pin:
15535 // [`SupervisorSpec::max_restarts`] must return the `:supervisor
15536 // :max-restarts` typed `u32` verbatim, `Copy`-projected from the
15537 // typed slot's own `u32` storage, byte-equal to the raw field
15538 // access across every representative value in the accept-set —
15539 // `1` (the lower boundary of the `1..=SUPERVISOR_MAX_RESTARTS_MAX`
15540 // accept-set the surrounding [`SupervisorSpec::validate`] gate
15541 // carves out on the sibling `ZeroMaxRestarts` refusal),
15542 // `SUPERVISOR_MAX_RESTARTS_MAX` (the upper boundary the same gate
15543 // carves out on the sibling `MaxRestartsExceedsCap` refusal), `0`
15544 // (a past-the-guard sentinel that pins the accessor doesn't
15545 // perform a silent bounds-collapse into `1` on the zero arm —
15546 // validate rejects zero but the accessor must ship the raw slot
15547 // verbatim so a validate-time gate regression surfaces at the
15548 // emit boundary rather than being silently absorbed), `u32::MAX`
15549 // (a past-the-guard sentinel that pins the accessor doesn't
15550 // perform a silent bounds-collapse through
15551 // `SUPERVISOR_MAX_RESTARTS_MAX` at the return path).
15552 //
15553 // Peer of the sibling M3
15554 // `circuit_breaker_max_failures_returns_max_failures_u32_byte_equal_across_permutations`
15555 // (3a74062) pin on the M3 mesh-slot `Copy`-`u32` sub-struct
15556 // required-scalar axis — same "the substrate-primitive accessor
15557 // must byte-equal the raw field access verbatim across every
15558 // value in the `u32` accept-set" discipline extended onto the M2
15559 // supervisor-slot per-`:supervisor` restart-budget-count axis.
15560 for max_restarts in [1u32, SUPERVISOR_MAX_RESTARTS_MAX, 0, u32::MAX] {
15561 let s = SupervisorSpec {
15562 max_restarts,
15563 ..SupervisorSpec::default()
15564 };
15565 assert_eq!(
15566 s.max_restarts(),
15567 max_restarts,
15568 "SupervisorSpec::max_restarts must return :supervisor \
15569 :max-restarts verbatim (got {}, expected {max_restarts})",
15570 s.max_restarts(),
15571 );
15572 assert_eq!(
15573 s.max_restarts(),
15574 s.max_restarts,
15575 "SupervisorSpec::max_restarts accessor and .max_restarts \
15576 field access must byte-equal — the accessor is the \
15577 substrate-primitive typed dispatch every downstream \
15578 restart-budget-count consumer must route through",
15579 );
15580 }
15581 }
15582
15583 #[test]
15584 fn validate_max_restarts_zero_floor_and_cap_arms_route_through_accessor() {
15585 // Composition pin: [`SupervisorSpec::validate`]'s `:max-restarts`
15586 // zero-floor + upper-cap bracket must key off
15587 // [`SupervisorSpec::max_restarts`], not the raw `.max_restarts`
15588 // field access. Structurally: a `SupervisorSpec { max_restarts:
15589 // 0, .. }` must surface the `ZeroMaxRestarts` refusal exactly, a
15590 // `SupervisorSpec { max_restarts: SUPERVISOR_MAX_RESTARTS_MAX + 1,
15591 // .. }` must surface the `MaxRestartsExceedsCap` refusal exactly
15592 // (with the offending count carried verbatim from the accessor
15593 // return), and a `SupervisorSpec { max_restarts: 1, .. }` (the
15594 // lower boundary of the accept-set) plus a `SupervisorSpec {
15595 // max_restarts: SUPERVISOR_MAX_RESTARTS_MAX, .. }` (the upper
15596 // boundary) must pass validate. The four together jointly pin the
15597 // accessor + validate-gate composition: any future silent detour
15598 // that had the accessor return a fresh `1` on the zero arm (a
15599 // `.max_restarts().max(1)` collapse) would silently absorb the
15600 // `ZeroMaxRestarts` refusal at the accessor boundary and the
15601 // validate gate would accept a struct-literal `SupervisorSpec {
15602 // max_restarts: 0, .. }` — the composition pin catches that at
15603 // caixa-core build time.
15604 //
15605 // Peer of the sibling M3
15606 // `validate_politicas_max_failures_zero_floor_arm_routes_through_accessor`
15607 // (3a74062) pin on the sibling per-`CircuitBreaker :max-failures`
15608 // composition axis — same "the validate / shape-gate predicate
15609 // must route through the substrate-primitive typed dispatch"
15610 // discipline extended onto the peer M2 supervisor-slot
15611 // required-`u32` composition axis.
15612 let child = ChildSpec {
15613 caixa: "worker".into(),
15614 versao: "^0.1".into(),
15615 restart: RestartPolicy::Permanent,
15616 };
15617 // Zero-floor arm.
15618 let s = SupervisorSpec {
15619 max_restarts: 0,
15620 children: vec![child.clone()],
15621 ..SupervisorSpec::default()
15622 };
15623 assert_eq!(
15624 s.validate().unwrap_err(),
15625 SupervisorError::ZeroMaxRestarts,
15626 "validate must reject max_restarts == 0 with ZeroMaxRestarts \
15627 — the accessor and the validate gate must route through the \
15628 same substrate-primitive typed dispatch on the zero-floor arm",
15629 );
15630 // Cap arm — the surfaced `max_restarts:` field must byte-equal
15631 // the accessor's return so a future rebrand on the accessor
15632 // lands in the diagnostic without a coordinated rewrite.
15633 let over_cap = SUPERVISOR_MAX_RESTARTS_MAX + 1;
15634 let s = SupervisorSpec {
15635 max_restarts: over_cap,
15636 children: vec![child.clone()],
15637 ..SupervisorSpec::default()
15638 };
15639 match s.validate().unwrap_err() {
15640 SupervisorError::MaxRestartsExceedsCap { max_restarts } => {
15641 assert_eq!(
15642 max_restarts,
15643 s.max_restarts(),
15644 "MaxRestartsExceedsCap.max_restarts must byte-equal \
15645 SupervisorSpec::max_restarts() — the cap-arm refusal \
15646 reads through the lifted accessor",
15647 );
15648 assert_eq!(
15649 max_restarts, over_cap,
15650 "MaxRestartsExceedsCap.max_restarts must carry the \
15651 author-declared :supervisor :max-restarts value \
15652 verbatim (got {max_restarts}, expected {over_cap})",
15653 );
15654 }
15655 other => panic!("expected MaxRestartsExceedsCap, got {other:?}"),
15656 }
15657 // Lower + upper accept-set boundaries.
15658 for max_restarts in [1u32, SUPERVISOR_MAX_RESTARTS_MAX] {
15659 let s = SupervisorSpec {
15660 max_restarts,
15661 children: vec![child.clone()],
15662 ..SupervisorSpec::default()
15663 };
15664 assert!(
15665 s.validate().is_ok(),
15666 "validate must accept max_restarts == {max_restarts} \
15667 (an accept-set boundary of \
15668 1..=SUPERVISOR_MAX_RESTARTS_MAX)",
15669 );
15670 }
15671 }
15672
15673 // ── per-`:supervisor` `:restart-window` typed-accessor coherence pins ─
15674 //
15675 // The [`SupervisorSpec::restart_window`] accessor lift extends the peer
15676 // M2 [`crate::LimitsSpec::wall_clock`] (8cb717b) `Option<Duration>`
15677 // accessor discipline and the peer M3 [`crate::MeshPolicy::timeout`]
15678 // (7073d0f) `Option<Duration>` accessor discipline onto the M2
15679 // supervisor-slot per-`:supervisor` restart-intensity-denominator
15680 // `Option<Duration>` scalar axis — third `Copy`-return accessor on the
15681 // M2 supervisor-slot `SupervisorSpec` type, closing the last unlifted
15682 // per-`:supervisor` scalar-value axis. The three pins below cover
15683 // (1) the accessor's byte-equal projection against the raw field
15684 // access across every representative value in the `Option<Duration>`
15685 // accept-set (`None` never-reset sentinel, `Some(Duration::from_millis(1))`
15686 // lower boundary, `Some(SUPERVISOR_RESTART_WINDOW_MAX)` upper boundary,
15687 // `Some(Duration::ZERO)` past-the-guard zero sentinel, `Some(Duration::MAX)`
15688 // past-the-guard above-cap sentinel), (2) the [`SupervisorSpec::validate`]
15689 // `if let Some(w) = self.restart_window() { … }` bracket-arm
15690 // composition — the validate gate and the accessor must route through
15691 // the same substrate-primitive typed dispatch, so any future silent
15692 // detour that had the accessor perform a bounds-collapsing clamp
15693 // would fail here at caixa-core build time, and (3) the accessor's
15694 // by-copy idempotence pin — the returned `Option<Duration>` must
15695 // outlive `&self` and two successive calls must return byte-equal
15696 // values. Peer of the sibling M2
15697 // `limits_wall_clock_returns_option_duration_byte_equal_across_permutations`
15698 // (8cb717b) pin on the per-`:limits :wall-clock` axis and the sibling
15699 // M3 `mesh_policy_timeout_returns_timeout_option_byte_equal_across_permutations`
15700 // (7073d0f) pin on the per-`:politicas :timeout` axis.
15701
15702 #[test]
15703 fn supervisor_spec_restart_window_returns_option_duration_byte_equal_across_permutations() {
15704 // The canonical per-`:supervisor` restart-intensity-denominator
15705 // scalar pin: [`SupervisorSpec::restart_window`] must return the
15706 // `:supervisor :restart-window` typed [`Duration`] verbatim as an
15707 // `Option<Duration>`, `Copy`-projected from the typed slot's own
15708 // `Option<Duration>` storage, byte-equal to the raw field access
15709 // across every representative value in the accept-set — `None`
15710 // (the "never reset — every restart across the supervisor's
15711 // lifetime counts against the sibling `:max-restarts` budget"
15712 // sentinel the field's own docstring names and the peer
15713 // `validate_accepts_none_restart_window` pin locks in on the
15714 // [`SupervisorSpec::validate`] entry-side),
15715 // `Some(Duration::from_millis(1))` (the structural minimum a
15716 // validated `:restart-window` may carry, the integer-millisecond
15717 // floor [`SupervisorError::RestartWindowNotCanonical`] rejects
15718 // everything sub-ms; `Duration::ZERO` is separately rejected by
15719 // [`SupervisorError::RestartWindowZero`]),
15720 // `Some(SUPERVISOR_RESTART_WINDOW_MAX)` (the upper boundary the
15721 // surrounding [`SupervisorSpec::validate`] gate carves out on the
15722 // sibling [`SupervisorError::RestartWindowExceedsCap`] refusal),
15723 // `Some(Duration::ZERO)` (a past-the-guard sentinel that pins the
15724 // accessor doesn't perform a silent bounds-collapse into `None` on
15725 // the zero-Duration arm — validate rejects zero but the accessor
15726 // must ship the raw slot verbatim so a validate-time gate
15727 // regression surfaces at the emit boundary rather than being
15728 // silently absorbed), and `Some(Duration::MAX)` (a past-the-guard
15729 // sentinel that pins the accessor doesn't perform a silent
15730 // bounds-collapse through [`SUPERVISOR_RESTART_WINDOW_MAX`] at the
15731 // return path).
15732 //
15733 // Peer of the sibling M2
15734 // `limits_wall_clock_returns_option_duration_byte_equal_across_permutations`
15735 // (8cb717b) pin on the per-`:limits :wall-clock` axis and the
15736 // sibling M3
15737 // `mesh_policy_timeout_returns_timeout_option_byte_equal_across_permutations`
15738 // (7073d0f) pin on the per-`:politicas :timeout` axis — same "the
15739 // substrate-primitive accessor must byte-equal the raw field
15740 // access verbatim across every value in the `Option<Duration>`
15741 // accept-set" discipline extended onto the M2 supervisor-slot
15742 // per-`:supervisor` `Option<Duration>` axis. Pins against a future
15743 // silent detour that re-derived the restart-window from a peer
15744 // axis (an accidental `.max_restarts.into()` collapse that read
15745 // the restart-budget-count as a duration — the two axes serve
15746 // different halves of the `MaxIntensity / Period` restart-
15747 // intensity ratio, and confusing them silently inverts the
15748 // ratio's numerator and denominator), a `None → Some(Duration::ZERO)`
15749 // "zero means never reset" collapse (the canonical
15750 // `Option<Duration>` → `Duration` collapse footgun the
15751 // [`SupervisorError::RestartWindowZero`] validate arm guards on
15752 // the peer zero-floor axis; a zero period either trips on the
15753 // first failure or never trips depending on operator
15754 // interpretation, neither of which is the author's "never reset"
15755 // intent that `None` expresses structurally), or a per-arm
15756 // variant swap that landed on one consumer without the other.
15757 for restart_window in [
15758 None,
15759 Some(Duration::from_millis(1)),
15760 Some(SUPERVISOR_RESTART_WINDOW_MAX),
15761 Some(Duration::ZERO),
15762 Some(Duration::MAX),
15763 ] {
15764 let s = SupervisorSpec {
15765 restart_window,
15766 ..SupervisorSpec::default()
15767 };
15768 assert_eq!(
15769 s.restart_window(),
15770 restart_window,
15771 "SupervisorSpec::restart_window must return :supervisor \
15772 :restart-window verbatim (got {:?}, expected {restart_window:?})",
15773 s.restart_window(),
15774 );
15775 assert_eq!(
15776 s.restart_window(),
15777 s.restart_window,
15778 "SupervisorSpec::restart_window accessor and \
15779 .restart_window field access must byte-equal — the \
15780 accessor is the substrate-primitive typed dispatch every \
15781 downstream restart-intensity-denominator consumer must \
15782 route through",
15783 );
15784 }
15785 }
15786
15787 #[test]
15788 fn validate_restart_window_bracket_arm_routes_through_accessor() {
15789 // Composition pin: [`SupervisorSpec::validate`]'s
15790 // `:restart-window` `if let Some(w) = self.restart_window() { … }`
15791 // zero-floor + integer-millisecond canonical-form + upper-cap
15792 // bracket-arm must key off [`SupervisorSpec::restart_window`], not
15793 // the raw `.restart_window` field access. Structurally: a
15794 // `SupervisorSpec { restart_window: None, .. }` must pass the
15795 // arm gate structurally (the `if let Some(_)` shape returns
15796 // early on the `None` arm — the accessor and the validate gate
15797 // must agree on `None → skip the bracket cascade` so an authored
15798 // `:restart-window ()` structurally routes through the "never
15799 // reset" sentinel path), a `SupervisorSpec { restart_window:
15800 // Some(Duration::ZERO), .. }` must surface the `RestartWindowZero`
15801 // refusal exactly, a `SupervisorSpec { restart_window:
15802 // Some(Duration::from_micros(1500)), .. }` must surface the
15803 // `RestartWindowNotCanonical` refusal exactly (with the offending
15804 // duration carried verbatim from the accessor return), a
15805 // `SupervisorSpec { restart_window: Some(SUPERVISOR_RESTART_WINDOW_MAX
15806 // + Duration::from_millis(1)), .. }` must surface the
15807 // `RestartWindowExceedsCap` refusal exactly (with the offending
15808 // duration carried verbatim from the accessor return), and a
15809 // `SupervisorSpec { restart_window: Some(Duration::from_millis(1)),
15810 // .. }` (the lower boundary of the accept-set) plus a
15811 // `SupervisorSpec { restart_window: Some(SUPERVISOR_RESTART_WINDOW_MAX),
15812 // .. }` (the upper boundary) must pass validate. The six together
15813 // jointly pin the accessor + validate-gate composition: any future
15814 // silent detour that had the accessor return a fresh `None` on any
15815 // `Some` arm (a `.restart_window().filter(|w| !w.is_zero())`
15816 // collapse) would silently absorb the `RestartWindowZero` refusal
15817 // at the accessor boundary and the validate gate would accept a
15818 // struct-literal `SupervisorSpec { restart_window:
15819 // Some(Duration::ZERO), .. }` — the composition pin catches that
15820 // at caixa-core build time.
15821 //
15822 // Peer of the sibling M2 [`crate::LimitsSpec::wall_clock`]
15823 // (8cb717b) validate-arm-route pin on the per-`:limits :wall-clock`
15824 // axis and the peer M3 [`crate::MeshPolicy::timeout`] (7073d0f)
15825 // accessor-composition pin on the per-`:politicas :timeout` axis —
15826 // same "the validate / shape-gate predicate must route through
15827 // the substrate-primitive typed dispatch" discipline extended
15828 // onto the peer M2 supervisor-slot optional-`Duration` axis.
15829 let child = ChildSpec {
15830 caixa: "worker".into(),
15831 versao: "^0.1".into(),
15832 restart: RestartPolicy::Permanent,
15833 };
15834 // None arm — must not surface any :restart-window-shaped refusal;
15835 // the `if let Some(_)` bracket returns early on `None` structurally.
15836 let s = SupervisorSpec {
15837 restart_window: None,
15838 children: vec![child.clone()],
15839 ..SupervisorSpec::default()
15840 };
15841 assert!(
15842 s.validate().is_ok(),
15843 "validate must accept restart_window: None (the never-reset \
15844 sentinel) — the `if let Some(_)` bracket returns early on \
15845 the None arm and the accessor must agree",
15846 );
15847 // Zero-floor arm.
15848 let s = SupervisorSpec {
15849 restart_window: Some(Duration::ZERO),
15850 children: vec![child.clone()],
15851 ..SupervisorSpec::default()
15852 };
15853 assert_eq!(
15854 s.validate().unwrap_err(),
15855 SupervisorError::RestartWindowZero,
15856 "validate must reject restart_window == Some(Duration::ZERO) \
15857 with RestartWindowZero — the accessor and the validate gate \
15858 must route through the same substrate-primitive typed \
15859 dispatch on the zero-floor arm",
15860 );
15861 // Non-canonical (sub-ms) arm — the surfaced `window:` field must
15862 // byte-equal the accessor's return so a future rebrand on the
15863 // accessor lands in the diagnostic without a coordinated rewrite.
15864 let sub_ms = Duration::from_micros(1500);
15865 let s = SupervisorSpec {
15866 restart_window: Some(sub_ms),
15867 children: vec![child.clone()],
15868 ..SupervisorSpec::default()
15869 };
15870 match s.validate().unwrap_err() {
15871 SupervisorError::RestartWindowNotCanonical { window } => {
15872 assert_eq!(
15873 Some(window),
15874 s.restart_window(),
15875 "RestartWindowNotCanonical.window must byte-equal \
15876 SupervisorSpec::restart_window().unwrap() — the \
15877 non-canonical-arm refusal reads through the lifted \
15878 accessor",
15879 );
15880 assert_eq!(
15881 window, sub_ms,
15882 "RestartWindowNotCanonical.window must carry the \
15883 author-declared :supervisor :restart-window value \
15884 verbatim (got {window:?}, expected {sub_ms:?})",
15885 );
15886 }
15887 other => panic!("expected RestartWindowNotCanonical, got {other:?}"),
15888 }
15889 // Cap arm — the surfaced `window:` field must byte-equal the
15890 // accessor's return.
15891 let over_cap = SUPERVISOR_RESTART_WINDOW_MAX + Duration::from_millis(1);
15892 let s = SupervisorSpec {
15893 restart_window: Some(over_cap),
15894 children: vec![child.clone()],
15895 ..SupervisorSpec::default()
15896 };
15897 match s.validate().unwrap_err() {
15898 SupervisorError::RestartWindowExceedsCap { window } => {
15899 assert_eq!(
15900 Some(window),
15901 s.restart_window(),
15902 "RestartWindowExceedsCap.window must byte-equal \
15903 SupervisorSpec::restart_window().unwrap() — the \
15904 cap-arm refusal reads through the lifted accessor",
15905 );
15906 assert_eq!(
15907 window, over_cap,
15908 "RestartWindowExceedsCap.window must carry the \
15909 author-declared :supervisor :restart-window value \
15910 verbatim (got {window:?}, expected {over_cap:?})",
15911 );
15912 }
15913 other => panic!("expected RestartWindowExceedsCap, got {other:?}"),
15914 }
15915 // Lower + upper accept-set boundaries.
15916 for restart_window in [Duration::from_millis(1), SUPERVISOR_RESTART_WINDOW_MAX] {
15917 let s = SupervisorSpec {
15918 restart_window: Some(restart_window),
15919 children: vec![child.clone()],
15920 ..SupervisorSpec::default()
15921 };
15922 assert!(
15923 s.validate().is_ok(),
15924 "validate must accept restart_window == Some({restart_window:?}) \
15925 (an accept-set boundary of \
15926 1ms..=SUPERVISOR_RESTART_WINDOW_MAX)",
15927 );
15928 }
15929 }
15930
15931 #[test]
15932 fn supervisor_spec_restart_window_projects_option_duration_by_copy() {
15933 // The by-copy pin: [`SupervisorSpec::restart_window`] returns
15934 // `Option<Duration>` by copy — `Duration` is `Copy` (so
15935 // `Option<Duration>` is `Copy`) and the accessor must return by
15936 // value, not by reference. Peer of the sibling M2
15937 // [`crate::LimitsSpec::wall_clock`] (8cb717b) by-copy pin on the
15938 // per-`:limits :wall-clock` axis and the sibling M3
15939 // [`crate::MeshPolicy::timeout`] (7073d0f) by-copy pin on the
15940 // per-`:politicas :timeout` axis, extended onto the peer M2
15941 // supervisor-slot `Option<Duration>` copy-invariant shape — the
15942 // accessor's returned `Option<Duration>` must outlive `&self`
15943 // (multiple calls must return equal values from a dropped-`&self`
15944 // copy, since the returned Option carries no borrow), and calling
15945 // the accessor twice on the same SupervisorSpec must yield the
15946 // same `Option<Duration>` verbatim (idempotent, no side effects
15947 // on `&self`).
15948 //
15949 // Pins against a future silent detour that returned
15950 // `Option<&Duration>` (which would type-check but silently break
15951 // every downstream caller — the future wasm-operator's
15952 // per-supervisor restart-intensity counter consumes `Duration` by
15953 // value and `&Duration` would fold to a detached copy at the call
15954 // site), an accidental `Option::as_ref()` projection
15955 // (`self.restart_window.as_ref()` would also type-check but
15956 // return `Option<&Duration>`), or a one-arm-only accessor that
15957 // reads `Some(*w)` in the Some arm but reads a fresh
15958 // `Default::default()` (which would collapse to `Duration::ZERO`,
15959 // not `None`) in the None arm — a footgun the
15960 // [`SupervisorError::RestartWindowZero`] validate arm explicitly
15961 // closes since Erlang/OTP's `MaxIntensity / Period` invariant
15962 // requires `Period > 0` and `None` structurally expresses "never
15963 // reset" instead.
15964 for restart_window in [
15965 None,
15966 Some(Duration::from_millis(1)),
15967 Some(Duration::from_secs(60)),
15968 Some(SUPERVISOR_RESTART_WINDOW_MAX),
15969 ] {
15970 let s = SupervisorSpec {
15971 restart_window,
15972 ..SupervisorSpec::default()
15973 };
15974 let first = s.restart_window();
15975 let second = s.restart_window();
15976 assert_eq!(
15977 first, second,
15978 "SupervisorSpec::restart_window must be idempotent — two \
15979 successive calls on the same &self must return the \
15980 same Option<Duration>",
15981 );
15982 assert_eq!(
15983 first, restart_window,
15984 "SupervisorSpec::restart_window must return :supervisor \
15985 :restart-window verbatim by copy — got {first:?}, \
15986 expected {restart_window:?}",
15987 );
15988 }
15989 }
15990
15991 // ── per-`:supervisor` `:children` typed-accessor coherence pins ─────────
15992 //
15993 // The [`SupervisorSpec::children`] accessor lift is the seed of the
15994 // slice-return (`&[T]`) accessor discipline on the substrate — the four
15995 // peer `Vec`-carry axes ([`crate::Placement::clusters`],
15996 // [`crate::AplicacaoSpec::membros`], [`crate::AplicacaoSpec::contratos`],
15997 // [`crate::UpgradeFromEntry::instructions`]) still key off the raw field
15998 // access at the time of this seed, and inherit this pin family's
15999 // discipline as future compounding runs migrate their consumers. The
16000 // three pins below cover (1) the accessor's byte-equal projection
16001 // against the raw field access across the empty / singleton / cohort
16002 // fixtures the [`SupervisorSpec::validate`] partition-dispatch fans
16003 // between, (2) the [`SupervisorSpec::validate`] `SimpleOneForOne ↔
16004 // non-SimpleOneForOne` partition dispatch's paired `.is_empty()`
16005 // consumer routing through the accessor on both arms, and (3) the
16006 // per-child validate loop's traversal reading the same slice-view the
16007 // accessor projects. Peer of the sibling M2
16008 // [`validate_reads_through_lifted_estrategia_accessor`] (eafb619)
16009 // two-consumer coherence pin on the per-`:supervisor`
16010 // sibling-restart-strategy `Copy`-composite-enum scalar axis, extended
16011 // onto the per-`:supervisor` static-child-list `Vec`-carry axis.
16012
16013 #[test]
16014 fn supervisor_spec_children_returns_children_slice_byte_equal_across_permutations() {
16015 // The canonical per-`:supervisor` static-child-list scalar-shape
16016 // pin: [`SupervisorSpec::children`] must return the `:supervisor
16017 // :children` typed `Vec<ChildSpec>` verbatim as a `&[ChildSpec]`
16018 // slice-view over the same backing buffer the raw
16019 // `self.children.as_slice()` field access borrows from, byte-
16020 // equal across every representative fixture in the accept-set —
16021 // the empty slice (the `SimpleOneForOne`-arm sentinel),
16022 // the singleton slice (the minimal non-`SimpleOneForOne` shape),
16023 // and a two-child cohort (a peer non-`SimpleOneForOne` shape
16024 // with the peer three restart-policy variants in play).
16025 //
16026 // Pins against a future silent detour that returned
16027 // `&Vec<ChildSpec>` (which would type-check but leak the
16028 // storage-side `Vec`'s grow/push/reserve surface no consumer of
16029 // the typed view reaches for), a fresh-allocated
16030 // `Vec<ChildSpec>` copy (which would type-check via a coercion
16031 // but silently break every downstream caller that relied on the
16032 // slice sharing the backing buffer's identity), or an
16033 // out-of-order or length-drifted projection (which would silently
16034 // split the per-child validate loop's traversal input from the
16035 // paired partition-dispatch `.is_empty()` probe's input).
16036 //
16037 // Peer of the sibling
16038 // `supervisor_spec_estrategia_returns_estrategia_verbatim_across_permutations`
16039 // (eafb619) `Copy`-composite-enum byte-equal pin on the
16040 // per-`:supervisor` sibling-restart-strategy axis, extended onto
16041 // the per-`:supervisor` static-child-list `Vec`-carry axis.
16042 let fixtures: Vec<Vec<ChildSpec>> = vec![
16043 Vec::new(),
16044 vec![child("worker", "^0.1", RestartPolicy::Permanent)],
16045 vec![
16046 child("worker", "^0.1", RestartPolicy::Permanent),
16047 child("cache-server", "^0.1", RestartPolicy::Transient),
16048 ],
16049 vec![
16050 child("worker", "^0.1", RestartPolicy::Permanent),
16051 child("cache-server", "^0.1", RestartPolicy::Transient),
16052 child("scratch-job", "^0.1", RestartPolicy::Temporary),
16053 ],
16054 ];
16055 for children in fixtures {
16056 let s = SupervisorSpec {
16057 children: children.clone(),
16058 ..SupervisorSpec::default()
16059 };
16060 assert_eq!(
16061 s.children(),
16062 children.as_slice(),
16063 "SupervisorSpec::children must return :supervisor \
16064 :children verbatim (got {:?}, expected {:?})",
16065 s.children(),
16066 children.as_slice(),
16067 );
16068 assert_eq!(
16069 s.children(),
16070 s.children.as_slice(),
16071 "SupervisorSpec::children accessor and \
16072 .children.as_slice() field access must byte-equal — \
16073 the accessor is the substrate-primitive typed \
16074 dispatch every downstream static-child-list consumer \
16075 must route through",
16076 );
16077 assert_eq!(
16078 s.children().len(),
16079 s.children.len(),
16080 "SupervisorSpec::children().len() must byte-equal \
16081 self.children.len() — a length-drift would silently \
16082 split the paired partition-dispatch `.is_empty()` \
16083 probe input from the per-child validate loop's \
16084 traversal input",
16085 );
16086 }
16087 }
16088
16089 #[test]
16090 fn validate_reads_through_lifted_children_accessor() {
16091 // Three-consumer coherence pin: the [`SupervisorSpec::validate`]
16092 // `SimpleOneForOne`-arm `!self.children().is_empty()` refusal
16093 // probe (which must trip [`SupervisorError::SimpleOneForOneWithStaticChildren`]
16094 // when the accessor projects a non-empty slice under a
16095 // `SimpleOneForOne` estrategia), the peer non-`SimpleOneForOne`-arm
16096 // `self.children().is_empty()` refusal probe (which must trip
16097 // [`SupervisorError::NoChildren`] when the accessor projects the
16098 // empty slice under any peer estrategia), and the per-child
16099 // validate loop's `for child in self.children()` traversal
16100 // (which must reach every entry in the same order the accessor
16101 // projects) must all key off the lifted accessor, so any future
16102 // rebrand on the typed slot's reader shape lands at exactly one
16103 // place. Pins the three-site coherence by exercising each
16104 // production consumer end-to-end: (1) the
16105 // `SimpleOneForOneWithStaticChildren` refusal under a non-empty
16106 // slice + `SimpleOneForOne` estrategia, (2) the `NoChildren`
16107 // refusal under the empty slice + non-`SimpleOneForOne`
16108 // estrategia across every peer variant, and (3) the per-child
16109 // duplicate-detection surface fires on the second entry of a
16110 // two-child cohort that shares a `:caixa` name (which requires
16111 // the loop to reach both entries — a first-entry-only projection
16112 // would silently pass since the dedup HashSet has room for the
16113 // first insert).
16114 //
16115 // Peer of the sibling M2
16116 // [`validate_reads_through_lifted_estrategia_accessor`] (eafb619)
16117 // two-consumer coherence pin on the per-`:supervisor`
16118 // sibling-restart-strategy axis, extended onto the
16119 // per-`:supervisor` static-child-list `Vec`-carry axis.
16120
16121 // (1) `SimpleOneForOne`-arm probe: a non-empty slice under a
16122 // `SimpleOneForOne` estrategia must trip
16123 // `SimpleOneForOneWithStaticChildren`.
16124 let s = SupervisorSpec {
16125 estrategia: RestartStrategy::SimpleOneForOne,
16126 children: vec![child("worker", "^0.1", RestartPolicy::Permanent)],
16127 ..SupervisorSpec::default()
16128 };
16129 assert_eq!(
16130 s.validate().unwrap_err(),
16131 SupervisorError::SimpleOneForOneWithStaticChildren,
16132 "SimpleOneForOne + non-empty children must trip \
16133 SimpleOneForOneWithStaticChildren — the accessor projects \
16134 a non-empty slice, and the SimpleOneForOne-arm refusal \
16135 probe reads through the lifted accessor",
16136 );
16137 assert!(
16138 !s.children().is_empty(),
16139 "the SimpleOneForOne-arm refusal input must be a non-empty \
16140 slice per the accessor's projection",
16141 );
16142
16143 // (2) Peer non-`SimpleOneForOne`-arm probe: the empty slice
16144 // under any peer estrategia must trip `NoChildren`.
16145 for estrategia in [
16146 RestartStrategy::OneForOne,
16147 RestartStrategy::OneForAll,
16148 RestartStrategy::RestForOne,
16149 ] {
16150 let s = SupervisorSpec {
16151 estrategia,
16152 children: Vec::new(),
16153 ..SupervisorSpec::default()
16154 };
16155 match s.validate().unwrap_err() {
16156 SupervisorError::NoChildren { estrategia: e } => {
16157 assert_eq!(
16158 e, estrategia,
16159 "NoChildren.estrategia must carry the author-\
16160 declared :supervisor :estrategia variant \
16161 verbatim (got {e:?}, expected {estrategia:?})",
16162 );
16163 }
16164 other => panic!(
16165 "expected NoChildren, got {other:?} for \
16166 estrategia={estrategia:?}"
16167 ),
16168 }
16169 assert!(
16170 s.children().is_empty(),
16171 "the non-SimpleOneForOne-arm refusal input must be the \
16172 empty slice per the accessor's projection",
16173 );
16174 }
16175
16176 // (3) Per-child validate loop: a two-child cohort that shares a
16177 // `:caixa` name must trip `DuplicateChildCaixa` — the loop must
16178 // reach both entries through the accessor.
16179 let s = SupervisorSpec {
16180 estrategia: RestartStrategy::OneForOne,
16181 children: vec![
16182 child("worker", "^0.1", RestartPolicy::Permanent),
16183 child("worker", "^0.2", RestartPolicy::Transient),
16184 ],
16185 ..SupervisorSpec::default()
16186 };
16187 match s.validate().unwrap_err() {
16188 SupervisorError::DuplicateChildCaixa { caixa } => {
16189 assert_eq!(
16190 caixa, "worker",
16191 "DuplicateChildCaixa.caixa must carry the shared \
16192 child `:caixa` name verbatim",
16193 );
16194 }
16195 other => panic!("expected DuplicateChildCaixa, got {other:?}"),
16196 }
16197 assert_eq!(
16198 s.children().len(),
16199 2,
16200 "the per-child validate loop's traversal input must be a \
16201 two-element slice per the accessor's projection",
16202 );
16203 }
16204
16205 // Shared helper for the M2 per-`:children` per-slot-gate ≡
16206 // `validate` equivalence pins: builds an `OneForOne`-estrategia
16207 // one-cohort spec whose peer `:estrategia`↔`:children.is_empty()`
16208 // partition, `:max-restarts` zero-floor/cap, and `:restart-window`
16209 // bracket all pass cleanly so the sole failing surface is the
16210 // per-child cascade [`SupervisorSpec::validate_children`] owns, and
16211 // pins the two-altitude equivalence on the paired probe.
16212 fn assert_validate_children_matches_gate(children: Vec<ChildSpec>, expected: &SupervisorError) {
16213 let s = SupervisorSpec {
16214 estrategia: RestartStrategy::OneForOne,
16215 children,
16216 ..SupervisorSpec::default()
16217 };
16218 let via_gate = s.validate_children().unwrap_err();
16219 let via_validate = s.validate().unwrap_err();
16220 assert_eq!(&via_gate, expected, "validate_children direct dispatch",);
16221 assert_eq!(&via_validate, expected, "validate() end-to-end dispatch",);
16222 assert_eq!(
16223 via_gate, via_validate,
16224 "per-slot gate ≡ validate() must discriminate the same \
16225 refusal shape",
16226 );
16227 }
16228
16229 #[test]
16230 fn validate_children_matches_gate_on_per_axis_refusal_shapes() {
16231 // Fail-before-pass-after equivalence pin on the M2
16232 // per-`:children` per-slot gate ≡ [`SupervisorSpec::validate`]
16233 // convergence — sibling of the M3 mesh-slot
16234 // `validate_membros_*` / `validate_contratos_*` /
16235 // `validate_entrada_*` per-slot-gate ≡ `validate` pins on the
16236 // peer per-entry axes. Sweeps four of the five refusal shapes
16237 // the per-slot gate owns: (1) `EmptyChildName` on an empty-
16238 // `:caixa` child, (2) `ChildCaixaInvalid` on a structurally
16239 // invalid `:caixa` DNS-1123 label, (3) `EmptyChildVersion` on
16240 // an empty-`:versao` child, (4) `DuplicateChildCaixa` on a
16241 // duplicate-`:caixa` fan-out. Companion pin
16242 // `validate_children_matches_gate_on_versao_invalid_and_clean_pass`
16243 // covers `ChildVersaoInvalid` (whose parser-owned reason string
16244 // needs pattern-matching, not equality) and the clean-pass
16245 // canonical fixture; together the two pins guarantee the
16246 // per-slot gate and `validate` discriminate the same set on
16247 // every per-child-covered input.
16248 assert_validate_children_matches_gate(
16249 vec![child("", "^0.1", RestartPolicy::Permanent)],
16250 &SupervisorError::EmptyChildName,
16251 );
16252 assert_validate_children_matches_gate(
16253 vec![child("Worker", "^0.1", RestartPolicy::Permanent)],
16254 &SupervisorError::ChildCaixaInvalid {
16255 caixa: "Worker".into(),
16256 reason: "contains uppercase character 'W' (K8s DNS-1123 label names are lowercase-only; use \"worker\")".into(),
16257 },
16258 );
16259 assert_validate_children_matches_gate(
16260 vec![child("worker", "", RestartPolicy::Permanent)],
16261 &SupervisorError::EmptyChildVersion {
16262 caixa: "worker".into(),
16263 },
16264 );
16265 assert_validate_children_matches_gate(
16266 vec![
16267 child("worker", "^0.1", RestartPolicy::Permanent),
16268 child("worker", "^0.2", RestartPolicy::Transient),
16269 ],
16270 &SupervisorError::DuplicateChildCaixa {
16271 caixa: "worker".into(),
16272 },
16273 );
16274 }
16275
16276 #[test]
16277 fn validate_children_matches_gate_on_versao_invalid_and_clean_pass() {
16278 // Second half of the two-altitude equivalence pin — covers the
16279 // one refusal shape whose reason string is parser-owned
16280 // (`ChildVersaoInvalid`, whose reason comes from the shared
16281 // [`crate::version::parse_requirement`] impl and may drift) and
16282 // the clean-pass canonical fixture. Sibling pin
16283 // `validate_children_matches_gate_on_per_axis_refusal_shapes`
16284 // covers the four equality-comparable refusal shapes.
16285 let s_bad_versao = SupervisorSpec {
16286 estrategia: RestartStrategy::OneForOne,
16287 children: vec![child("worker", "not-a-req", RestartPolicy::Permanent)],
16288 ..SupervisorSpec::default()
16289 };
16290 let via_gate = s_bad_versao.validate_children().unwrap_err();
16291 let via_validate = s_bad_versao.validate().unwrap_err();
16292 match (&via_gate, &via_validate) {
16293 (
16294 SupervisorError::ChildVersaoInvalid {
16295 caixa: cg,
16296 versao: vg,
16297 ..
16298 },
16299 SupervisorError::ChildVersaoInvalid {
16300 caixa: cv,
16301 versao: vv,
16302 ..
16303 },
16304 ) => {
16305 assert_eq!(cg, "worker", "per-slot gate :caixa carrier");
16306 assert_eq!(vg, "not-a-req", "per-slot gate :versao carrier");
16307 assert_eq!(cv, "worker", "validate() :caixa carrier");
16308 assert_eq!(vv, "not-a-req", "validate() :versao carrier");
16309 }
16310 other => panic!("expected ChildVersaoInvalid on both altitudes, got {other:?}"),
16311 }
16312 assert_eq!(
16313 via_gate, via_validate,
16314 "per-slot gate ≡ validate() on ChildVersaoInvalid full envelope",
16315 );
16316
16317 let s_ok = SupervisorSpec {
16318 estrategia: RestartStrategy::OneForOne,
16319 children: vec![
16320 child("worker-a", "^0.1", RestartPolicy::Permanent),
16321 child("worker-b", "~0.2.3", RestartPolicy::Transient),
16322 child("collector", "*", RestartPolicy::Temporary),
16323 ],
16324 ..SupervisorSpec::default()
16325 };
16326 s_ok.validate_children()
16327 .expect("per-slot gate must accept the clean-pass fixture");
16328 s_ok.validate()
16329 .expect("validate() must accept the clean-pass fixture");
16330 }
16331
16332 #[test]
16333 fn validate_children_is_self_contained_on_children_slot() {
16334 // Self-containment pin: [`SupervisorSpec::validate_children`]
16335 // resolves the per-child cascade against `&self` alone, without
16336 // depending on the peer `:estrategia`/`:max-restarts`/
16337 // `:restart-window` gates having run first — same posture the M3
16338 // peer per-slot gates carry (`validate_membros`,
16339 // `validate_contratos`, `validate_entrada`, `validate_placement`,
16340 // routing through their own oracles rather than borrowing state
16341 // threaded down from `validate`). A future consumer that reaches
16342 // the per-slot gate directly on a spec whose peer slots would
16343 // fail `validate` still surfaces the per-child refusal, not the
16344 // peer refusal.
16345 //
16346 // Construct a spec whose `:max-restarts` is `0` (which would
16347 // trip [`SupervisorError::ZeroMaxRestarts`] at `validate` after
16348 // the partition-dispatch) and whose `:children` carries a
16349 // `DuplicateChildCaixa` shape: the per-slot gate called directly
16350 // must surface `DuplicateChildCaixa`, proving it does not depend
16351 // on the peer `:max-restarts` gate running first.
16352 let s = SupervisorSpec {
16353 estrategia: RestartStrategy::OneForOne,
16354 max_restarts: 0,
16355 restart_window: Some(Duration::from_secs(60)),
16356 children: vec![
16357 child("worker", "^0.1", RestartPolicy::Permanent),
16358 child("worker", "^0.2", RestartPolicy::Transient),
16359 ],
16360 };
16361 assert_eq!(
16362 s.validate_children().unwrap_err(),
16363 SupervisorError::DuplicateChildCaixa {
16364 caixa: "worker".into(),
16365 },
16366 "per-slot gate must resolve per-child refusal directly against \
16367 `&self` — a dependency on the peer `:max-restarts` gate \
16368 running first would surface ZeroMaxRestarts here instead",
16369 );
16370 // The peer gate is still the surface `validate` reaches — pin
16371 // the ordering to establish that `validate_children` truly runs
16372 // last in `validate`'s dispatch, so a direct call bypasses the
16373 // peer gates on any spec whose per-child cascade would fail.
16374 assert_eq!(
16375 s.validate().unwrap_err(),
16376 SupervisorError::ZeroMaxRestarts,
16377 "validate() must surface the peer `:max-restarts` gate before \
16378 reaching the per-child cascade — this pins the dispatch \
16379 ordering the per-slot gate's self-containment complements",
16380 );
16381 }
16382
16383 #[test]
16384 fn child_spec_restart_accessor_is_const_fn() {
16385 // The [`ChildSpec::restart`] per-`:children` restart-decision-
16386 // policy `Copy`-return scalar accessor is declared
16387 // `#[must_use] pub const fn` — matching the sibling M2
16388 // per-`:supervisor` [`SupervisorSpec::estrategia`] (pinned by
16389 // [`supervisor_spec_estrategia_accessor_is_const_fn`] below,
16390 // both converted in this commit), the sibling M2
16391 // per-`:supervisor` [`SupervisorSpec::max_restarts`] (b698ec0)
16392 // `Copy`-`u32` accessor already `pub const fn`, and the peer M3
16393 // mesh-slot per-`:entrada` [`crate::Entrada::port`] (bafa004) /
16394 // per-`:placement` [`crate::Placement::estrategia`] (bafa004)
16395 // `Copy`-return `pub const fn` scalar accessors on the sibling
16396 // M3 surface. Pin the `const`-eval posture here so a future
16397 // accidental downgrade to non-`const` (an added runtime helper
16398 // reachable only from a non-`const` context, an
16399 // `Option<RestartPolicy>`-shape migration on the per-child
16400 // restart-decision axis once heterogeneous per-cluster
16401 // restart-policy overlays land that would silently drop the
16402 // `const` qualifier, a manual hand-rolled shadow) trips at
16403 // caixa-core build time rather than surfacing as a downstream
16404 // `const`-context regression far from the declaration.
16405 //
16406 // Same shape as the sibling M3
16407 // [`crate::aplicacao::tests::placement_estrategia_accessor_is_const_fn`]
16408 // and [`crate::aplicacao::tests::entrada_port_accessor_is_const_fn`]
16409 // (bafa004) pins on the peer M3 mesh-slot `Copy`-return scalar
16410 // accessor axis — the load-bearing witness lives in the
16411 // module-scope `const fn` wrapper `restart_via_const_fn` below:
16412 // a body that calls [`ChildSpec::restart`] under a `const fn`
16413 // signature is well-formed only when the callee is itself
16414 // `const fn`, so any future accidental downgrade of
16415 // [`ChildSpec::restart`] to non-`const` fails at caixa-core
16416 // build time (const-eval E0015 `cannot call non-const method`),
16417 // strictly stronger than a runtime `assert!(CONST)` and
16418 // side-stepping the destructor-in-const restriction that
16419 // blocks direct `const _: RestartPolicy = FIXTURE.restart()`
16420 // items on `ChildSpec`'s `String` carriers.
16421 //
16422 // The runtime body sweeps every closed-set [`RestartPolicy`]
16423 // arm and asserts the wrapped and direct dispatches agree.
16424 const fn restart_via_const_fn(c: &ChildSpec) -> RestartPolicy {
16425 c.restart()
16426 }
16427 for restart in [
16428 RestartPolicy::Permanent,
16429 RestartPolicy::Transient,
16430 RestartPolicy::Temporary,
16431 ] {
16432 let c = ChildSpec {
16433 caixa: "worker".into(),
16434 versao: "^0.1".into(),
16435 restart,
16436 };
16437 assert_eq!(
16438 restart_via_const_fn(&c),
16439 c.restart(),
16440 "const-fn-wrapped and direct dispatch on \
16441 ChildSpec::restart must agree for {restart:?}",
16442 );
16443 assert_eq!(
16444 c.restart(),
16445 restart,
16446 "ChildSpec::restart must return the storage-side \
16447 RestartPolicy verbatim for {restart:?} (a violation \
16448 means the accessor stopped being a raw field-return \
16449 copy)",
16450 );
16451 }
16452 }
16453
16454 #[test]
16455 fn supervisor_spec_estrategia_accessor_is_const_fn() {
16456 // The [`SupervisorSpec::estrategia`] per-`:supervisor`
16457 // sibling-restart-strategy `Copy`-return scalar accessor is
16458 // declared `#[must_use] pub const fn` — matching the sibling M2
16459 // per-`:children` [`ChildSpec::restart`] (pinned by
16460 // [`child_spec_restart_accessor_is_const_fn`] above, both
16461 // converted in this commit), the sibling M2 per-`:supervisor`
16462 // [`SupervisorSpec::max_restarts`] (b698ec0) `Copy`-`u32`
16463 // accessor already `pub const fn`, and mirroring the peer M3
16464 // mesh-slot per-`:placement`
16465 // [`crate::Placement::estrategia`] (bafa004) `Copy`-return
16466 // `pub const fn` scalar accessor whose method-name discipline
16467 // the [`SupervisorSpec::estrategia`] method was authored to
16468 // match. Pin the `const`-eval posture here so a future
16469 // accidental downgrade to non-`const` (an added runtime helper
16470 // reachable only from a non-`const` context, an
16471 // `Option<RestartStrategy>`-shape migration once the substrate
16472 // grows per-cluster strategy overlays that would silently drop
16473 // the `const` qualifier, a manual hand-rolled shadow) trips at
16474 // caixa-core build time rather than surfacing as a downstream
16475 // `const`-context regression far from the declaration.
16476 //
16477 // Same shape as the sibling
16478 // [`child_spec_restart_accessor_is_const_fn`] pin above — the
16479 // load-bearing witness lives in the module-scope `const fn`
16480 // wrapper `estrategia_via_const_fn` below: a body that calls
16481 // [`SupervisorSpec::estrategia`] under a `const fn` signature
16482 // is well-formed only when the callee is itself `const fn`,
16483 // side-stepping the destructor-in-const restriction that would
16484 // otherwise block a direct
16485 // `const _: RestartStrategy = FIXTURE.estrategia()` item on
16486 // `SupervisorSpec`'s `Vec<ChildSpec>` / `Option<Duration>`
16487 // carriers.
16488 //
16489 // The runtime body sweeps every closed-set [`RestartStrategy`]
16490 // arm via [`RestartStrategy::ALL`] and asserts the wrapped and
16491 // direct dispatches agree.
16492 const fn estrategia_via_const_fn(s: &SupervisorSpec) -> RestartStrategy {
16493 s.estrategia()
16494 }
16495 for &estrategia in RestartStrategy::ALL {
16496 let s = SupervisorSpec {
16497 estrategia,
16498 max_restarts: 5,
16499 restart_window: Some(Duration::from_secs(60)),
16500 children: Vec::new(),
16501 };
16502 assert_eq!(
16503 estrategia_via_const_fn(&s),
16504 s.estrategia(),
16505 "const-fn-wrapped and direct dispatch on \
16506 SupervisorSpec::estrategia must agree for {estrategia:?}",
16507 );
16508 assert_eq!(
16509 s.estrategia(),
16510 estrategia,
16511 "SupervisorSpec::estrategia must return the storage-side \
16512 RestartStrategy verbatim for {estrategia:?} (a violation \
16513 means the accessor stopped being a raw field-return \
16514 copy)",
16515 );
16516 }
16517 }
16518
16519 // Per-variant equivalence pins for the [`supervisor_caixa_only_ctors!`]
16520 // macro definition (see the paired doc-block above the macro
16521 // definition) — every generated `<ctor>(caixa: &str) -> Self`
16522 // constructor folds the uniform `Self::<Variant> { caixa:
16523 // caixa.to_string() }` one-field struct-literal onto one substrate
16524 // primitive. The three per-variant equivalence pins below
16525 // (fail-before-pass-after by construction — a byte-mismatched macro
16526 // arm would trip its equivalence pin first) lock each generated
16527 // constructor to its struct-literal peer under `PartialEq`, so
16528 // every wire-up in [`SupervisorSpec::validate_children`] and
16529 // [`validate_no_self_supervision`] on that variant produces a
16530 // byte-equal `SupervisorError` to the pre-lift open-coded
16531 // struct-literal. The cross-axis pin that follows (non-default
16532 // caixa name) routes the sole constructor input axis through
16533 // `.to_string()`, so the fold does not silently collapse onto a
16534 // fixed name.
16535 //
16536 // Peer of the sibling `<slot>_ctor_matches_tuple_literal_wrap` /
16537 // `<slot>_violation_ctor_matches_struct_literal_wrap` /
16538 // `<slot>_slots_on_non_<owner>_ctor_matches_struct_literal_wrap` /
16539 // `missing_entry_ctor_matches_struct_literal_wrap` /
16540 // `entrada_host_invalid_ctor_matches_struct_literal_wrap` /
16541 // `contrato_wrong_target_ctor_matches_struct_literal_wrap` /
16542 // `contrato_missing_target_ctor_matches_struct_literal_wrap` /
16543 // `<variant>_ctor_matches_struct_literal_wrap` equivalence pins
16544 // on the six sibling ctor families the recent trajectory closed
16545 // on the peer `LayoutError` / `AplicacaoError` envelopes.
16546
16547 #[test]
16548 fn empty_child_version_ctor_matches_struct_literal_wrap() {
16549 assert_eq!(
16550 SupervisorError::empty_child_version("worker"),
16551 SupervisorError::EmptyChildVersion {
16552 caixa: "worker".to_string(),
16553 },
16554 "generated empty_child_version ctor must produce byte-equal \
16555 SupervisorError to the open-coded struct-literal wrap on the \
16556 same &str fixture",
16557 );
16558 }
16559
16560 #[test]
16561 fn duplicate_child_caixa_ctor_matches_struct_literal_wrap() {
16562 assert_eq!(
16563 SupervisorError::duplicate_child_caixa("worker"),
16564 SupervisorError::DuplicateChildCaixa {
16565 caixa: "worker".to_string(),
16566 },
16567 "generated duplicate_child_caixa ctor must produce byte-equal \
16568 SupervisorError to the open-coded struct-literal wrap on the \
16569 same &str fixture",
16570 );
16571 }
16572
16573 #[test]
16574 fn child_supervises_self_ctor_matches_struct_literal_wrap() {
16575 assert_eq!(
16576 SupervisorError::child_supervises_self("orquestra"),
16577 SupervisorError::ChildSupervisesSelf {
16578 caixa: "orquestra".to_string(),
16579 },
16580 "generated child_supervises_self ctor must produce byte-equal \
16581 SupervisorError to the open-coded struct-literal wrap on the \
16582 same &str fixture",
16583 );
16584 }
16585
16586 // Per-variant equivalence pins for the two lifted
16587 // [`SupervisorError::child_caixa_invalid`] /
16588 // [`SupervisorError::child_versao_invalid`] inherent constructors
16589 // (fail-before-pass-after by construction — a byte-mismatched ctor body
16590 // would trip its equivalence pin first). Each pins the ctor output to
16591 // its pre-lift struct-literal peer under `PartialEq`, so every wire-up
16592 // in [`SupervisorSpec::validate_children`] on the two variants
16593 // produces a byte-equal `SupervisorError` to the pre-lift open-coded
16594 // struct-literal on the same scalar fixtures. Peers of the sibling
16595 // `membro_caixa_invalid_ctor_matches_struct_literal_wrap` /
16596 // `entrada_para_invalid_ctor_matches_struct_literal_wrap` / … pins on
16597 // the peer `AplicacaoError` envelope's
16598 // [`crate::aplicacao::aplicacao_field_reason_ctors!`] fold.
16599
16600 #[test]
16601 fn child_caixa_invalid_ctor_matches_struct_literal_wrap() {
16602 let caixa = "Worker";
16603 let reason = "sample reason text";
16604 assert_eq!(
16605 SupervisorError::child_caixa_invalid(caixa, reason),
16606 SupervisorError::ChildCaixaInvalid {
16607 caixa: caixa.to_string(),
16608 reason: reason.to_string(),
16609 },
16610 "lifted child_caixa_invalid ctor must produce byte-equal \
16611 SupervisorError to the open-coded struct-literal wrap on the \
16612 same (&str, reason) fixture",
16613 );
16614 }
16615
16616 #[test]
16617 fn child_versao_invalid_ctor_matches_struct_literal_wrap() {
16618 let caixa = "worker";
16619 let versao = "not-a-req";
16620 let reason = "sample reason text";
16621 assert_eq!(
16622 SupervisorError::child_versao_invalid(caixa, versao, reason),
16623 SupervisorError::ChildVersaoInvalid {
16624 caixa: caixa.to_string(),
16625 versao: versao.to_string(),
16626 reason: reason.to_string(),
16627 },
16628 "lifted child_versao_invalid ctor must produce byte-equal \
16629 SupervisorError to the open-coded struct-literal wrap on the \
16630 same (&str, &str, reason) fixture",
16631 );
16632 }
16633
16634 #[test]
16635 fn supervisor_child_reason_ctors_route_reason_through_into_uniformly() {
16636 // Cross-axis pin: sweep the two lifted `{ …, reason }` ctors
16637 // against a `&str`-literal vs. `format!(…)` reason input to pin
16638 // both constructors accept the `impl Into<String>` bound
16639 // uniformly, so neither wire-up site drifts under a per-arm
16640 // wrapper transformation on the caller-side `reason` axis. Peer
16641 // of the sibling
16642 // `aplicacao_field_reason_ctors_route_reason_through_into_uniformly`
16643 // sweep on the peer `AplicacaoError` envelope.
16644 let via_literal = "literal reason text";
16645 let via_format = format!("{} reason text", "literal");
16646 assert_eq!(
16647 SupervisorError::child_caixa_invalid("Worker", via_literal),
16648 SupervisorError::child_caixa_invalid("Worker", via_format.clone()),
16649 );
16650 assert_eq!(
16651 SupervisorError::child_versao_invalid("worker", "not-a-req", via_literal),
16652 SupervisorError::child_versao_invalid("worker", "not-a-req", via_format),
16653 );
16654 }
16655
16656 #[test]
16657 fn supervisor_caixa_only_ctors_route_caixa_through_to_string() {
16658 // Cross-axis pin: sweep the sole constructor input axis (`caixa:
16659 // &str`) through a non-default fixture name against every
16660 // generated arm in the [`supervisor_caixa_only_ctors!`] macro,
16661 // so any wrapper-side lowercase / trim / truncate / re-order on
16662 // the `caixa.to_string()` sole-field construction surfaces
16663 // here rather than at a downstream diagnostic-shape mismatch.
16664 // Peer of the sibling `nome_only_ctor_routes_caixa_through_
16665 // nome_accessor` / `entrada_host_invalid_ctor_routes_host_
16666 // through_to_string` / `contrato_target_ctors_route_edge_
16667 // triple_through_verbatim` / `contrato_empty_pair_ctors_
16668 // route_edge_pair_through_verbatim` cross-axis routing pins on
16669 // the peer `LayoutError` / `AplicacaoError` envelopes; extended
16670 // here onto the `SupervisorError` `{ caixa: String }` envelope
16671 // so every substrate-primitive ctor family in caixa-core
16672 // guarantees the sole-field construction routes the caller's
16673 // `&str` through `.to_string()` verbatim.
16674 let name = "cache-v2";
16675 assert_eq!(
16676 SupervisorError::empty_child_version(name),
16677 SupervisorError::EmptyChildVersion {
16678 caixa: name.to_string(),
16679 },
16680 );
16681 assert_eq!(
16682 SupervisorError::duplicate_child_caixa(name),
16683 SupervisorError::DuplicateChildCaixa {
16684 caixa: name.to_string(),
16685 },
16686 );
16687 assert_eq!(
16688 SupervisorError::child_supervises_self(name),
16689 SupervisorError::ChildSupervisesSelf {
16690 caixa: name.to_string(),
16691 },
16692 );
16693 }
16694
16695 // ── supervisor_scalar_ctors! per-variant + cross-axis pins ──────────────
16696 //
16697 // Per-variant byte-equality pins guaranteeing every generated ctor arm in
16698 // the [`supervisor_scalar_ctors!`] macro produces a `SupervisorError`
16699 // structurally identical to the pre-lift `Self::<variant> { <field>: <val> }`
16700 // one-line struct-literal on the same `Copy`-`RestartStrategy | u32 |
16701 // Duration` fixture, plus one cross-axis sweep that routes each per-variant
16702 // `<field>: <ty>` scalar through the sole `$field:ident: $ty:ty` axis the
16703 // macro exposes so any wrapper-side truncation / re-order / silent `.into()`
16704 // / silent constant-substitution on any one variant surfaces here rather
16705 // than at a downstream per-`:supervisor` diagnostic-shape drift. Peer of the
16706 // sibling per-variant pins on `aplicacao_policy_scalar_ctors!` (7ef425e,
16707 // the 8-variant `AplicacaoError` `{ <field>: Duration | u32 }` fold on the
16708 // per-`:politicas` per-axis cap / canonical-form arms), plus the sibling
16709 // `supervisor_caixa_only_ctors!` (db09650), `SupervisorError::
16710 // {child_caixa_invalid,child_versao_invalid}` (d2ef2ec), and the peer
16711 // `DepError` / `AplicacaoError` / `LayoutError` / `LimitsError` /
16712 // `BehaviorError` / `UpgradeError` per-envelope ctor-macro pins.
16713 #[test]
16714 fn no_children_ctor_matches_struct_literal_wrap() {
16715 let estrategia = RestartStrategy::OneForAll;
16716 assert_eq!(
16717 SupervisorError::no_children(estrategia),
16718 SupervisorError::NoChildren { estrategia },
16719 "generated no_children ctor must produce byte-equal \
16720 `SupervisorError::NoChildren` to the pre-lift struct-literal wrap \
16721 on the same `Copy`-`RestartStrategy` fixture",
16722 );
16723 }
16724
16725 #[test]
16726 fn max_restarts_exceeds_cap_ctor_matches_struct_literal_wrap() {
16727 let max_restarts = SUPERVISOR_MAX_RESTARTS_MAX + 1;
16728 assert_eq!(
16729 SupervisorError::max_restarts_exceeds_cap(max_restarts),
16730 SupervisorError::MaxRestartsExceedsCap { max_restarts },
16731 "generated max_restarts_exceeds_cap ctor must produce byte-equal \
16732 `SupervisorError::MaxRestartsExceedsCap` to the pre-lift \
16733 struct-literal wrap on the same `Copy`-`u32` fixture",
16734 );
16735 }
16736
16737 #[test]
16738 fn restart_window_not_canonical_ctor_matches_struct_literal_wrap() {
16739 let window = Duration::from_micros(1_500);
16740 assert_eq!(
16741 SupervisorError::restart_window_not_canonical(window),
16742 SupervisorError::RestartWindowNotCanonical { window },
16743 "generated restart_window_not_canonical ctor must produce \
16744 byte-equal `SupervisorError::RestartWindowNotCanonical` to the \
16745 pre-lift struct-literal wrap on the same `Copy`-`Duration` fixture",
16746 );
16747 }
16748
16749 #[test]
16750 fn restart_window_exceeds_cap_ctor_matches_struct_literal_wrap() {
16751 let window = SUPERVISOR_RESTART_WINDOW_MAX + Duration::from_millis(1);
16752 assert_eq!(
16753 SupervisorError::restart_window_exceeds_cap(window),
16754 SupervisorError::RestartWindowExceedsCap { window },
16755 "generated restart_window_exceeds_cap ctor must produce \
16756 byte-equal `SupervisorError::RestartWindowExceedsCap` to the \
16757 pre-lift struct-literal wrap on the same `Copy`-`Duration` fixture",
16758 );
16759 }
16760
16761 #[test]
16762 fn supervisor_scalar_ctors_route_field_through_copy_uniformly() {
16763 // Cross-axis routing pin: sweep each generated `<field>: <ty>`
16764 // constructor input axis through a non-default `Copy` fixture against
16765 // every arm in the [`supervisor_scalar_ctors!`] macro, so any wrapper-
16766 // side silent `.into()` / silent constant-substitution / silent field
16767 // re-name away from the canonical `estrategia | max_restarts | window`
16768 // axes on any one variant, or a `RestartStrategy | u32 | Duration`
16769 // axis silently rerouted through some other `Copy` coercion, surfaces
16770 // here rather than at a downstream per-`:supervisor` diagnostic-shape
16771 // drift. Peer of the sibling
16772 // `aplicacao_policy_scalar_ctors_route_field_through_copy_uniformly`
16773 // (7ef425e) cross-axis routing pin on the peer `AplicacaoError`
16774 // envelope's per-`:politicas` per-axis ctor family, extended here onto
16775 // the last M2 per-`:supervisor` `Copy`-scalar `SupervisorError`
16776 // variant family folded onto a substrate primitive.
16777 //
16778 // Fixtures picked out of each variant's accept-set boundary rather
16779 // than the default value so a silent constant-substitution to a per-
16780 // variant sentinel surfaces here on the structural-equality assertion.
16781 // The `RestartStrategy` fixture picks `RestForOne` (a non-default arm
16782 // that isn't the `OneForOne` [`SUPERVISOR_ESTRATEGIA_DEFAULT`] and
16783 // isn't the `SimpleOneForOne` arm the sibling
16784 // `SimpleOneForOneWithStaticChildren` unit variant intercepts). The
16785 // `max_restarts` fixture picks an above-cap magnitude the cap arm
16786 // rejects; the two `Duration` fixtures pick the sub-millisecond and
16787 // above-cap ends of the `:restart-window` canonical-form + cap
16788 // bracket respectively.
16789 let estrategia = RestartStrategy::RestForOne;
16790 let above_cap_restarts = SUPERVISOR_MAX_RESTARTS_MAX + 137;
16791 let sub_ms = Duration::from_micros(1_500);
16792 let above_hour = SUPERVISOR_RESTART_WINDOW_MAX + Duration::from_secs(1);
16793 assert_eq!(
16794 SupervisorError::no_children(estrategia),
16795 SupervisorError::NoChildren { estrategia },
16796 );
16797 assert_eq!(
16798 SupervisorError::max_restarts_exceeds_cap(above_cap_restarts),
16799 SupervisorError::MaxRestartsExceedsCap {
16800 max_restarts: above_cap_restarts,
16801 },
16802 );
16803 assert_eq!(
16804 SupervisorError::restart_window_not_canonical(sub_ms),
16805 SupervisorError::RestartWindowNotCanonical { window: sub_ms },
16806 );
16807 assert_eq!(
16808 SupervisorError::restart_window_exceeds_cap(above_hour),
16809 SupervisorError::RestartWindowExceedsCap { window: above_hour },
16810 );
16811 }
16812
16813 #[test]
16814 fn restart_strategy_try_from_bytes_routes_through_from_wire_accessor() {
16815 // Fail-before-pass-after byte-parity pin on the newly lifted
16816 // `impl TryFrom<&[u8]> for RestartStrategy` — asserts the trait-
16817 // idiomatic byte-view reverse-projection standard-library impl
16818 // and the substrate-primitive [`RestartStrategy::from_wire`]
16819 // `Option<Self>` accessor resolve to the same four-arm
16820 // `PascalCase` wire accept-set across every arm the exhaustive
16821 // [`RestartStrategy::ALL`] slice enumerates. Extends the
16822 // substrate-wide trait-idiomatic byte-view reverse-projection
16823 // axis onto the first M2-OTP-shape supervisor-slot closed-set
16824 // fieldless typed enum peer — mirror of the paired
16825 // [`TryFrom<&str> for RestartStrategy`] str-view reverse-
16826 // projection axis on the same enum, and the byte-view companion
16827 // of the pre-existing byte-owned reverse-projection family
16828 // ([`AsRef<[u8]>`], [`From<RestartStrategy> for Vec<u8>`],
16829 // [`From<&RestartStrategy> for Vec<u8>`]) on this same enum.
16830 // Peer of the sibling
16831 // [`crate::kind::tests::caixa_kind_try_from_bytes_routes_through_from_wire_accessor`]
16832 // (18d1940),
16833 // [`crate::dialeto::tests::caixa_dialeto_try_from_bytes_routes_through_from_wire_accessor`]
16834 // (d102cb8), and
16835 // [`crate::dep::tests::dep_list_try_from_bytes_routes_through_from_wire_accessor`]
16836 // (b8f25d5) — tracks the "route through `from_wire` via
16837 // `std::str::from_utf8`" discipline the first-mover established.
16838 //
16839 // Rust's standard library carries no blanket
16840 // `impl<T: for<'a> TryFrom<&'a str>> TryFrom<&[u8]> for T`, so
16841 // a two-hop composition through [`std::str::from_utf8`] + the
16842 // paired [`TryFrom<&str>`] axis is reachable through the pre-
16843 // existing str-view reverse-projection axis alone. But that
16844 // two-hop shape has no compile-time link back to the byte-view
16845 // reverse-projection axis, forces every downstream
16846 // `<T: for<'a> TryFrom<&'a [u8]>>`-bound consumer to open-code
16847 // the composition at every call site, and admits a silent split
16848 // whenever a future call site takes a sibling byte-projection
16849 // axis whose parse arm-set carries no compile-time byte-view
16850 // surface. This impl closes the byte-view reverse-projection
16851 // axis at the substrate-primitive [`RestartStrategy::from_wire`]
16852 // accessor so every future `<T: for<'a> TryFrom<&'a [u8]>>`-
16853 // bound consumer reaches the same four-arm `PascalCase` wire
16854 // accept-set through one trait dispatch.
16855 for &variant in RestartStrategy::ALL {
16856 let wire_bytes: &[u8] = variant.as_str().as_bytes();
16857 assert_eq!(
16858 <RestartStrategy as TryFrom<&[u8]>>::try_from(wire_bytes),
16859 Ok(variant),
16860 "TryFrom<&[u8]> impl on RestartStrategy must round-trip \
16861 RestartStrategy::{variant:?}.as_str().as_bytes() back to \
16862 Ok(RestartStrategy::{variant:?}) — divergence from \
16863 RestartStrategy::from_wire signals a silent detour off \
16864 the substrate-primitive accessor"
16865 );
16866 assert_eq!(
16867 <RestartStrategy as TryFrom<&[u8]>>::try_from(wire_bytes).ok(),
16868 RestartStrategy::from_wire(variant.as_str()),
16869 "TryFrom<&[u8]> ok()-projection on \
16870 RestartStrategy::{variant:?}.as_str().as_bytes() must \
16871 byte-equal RestartStrategy::from_wire on the paired \
16872 &str input"
16873 );
16874 // Cross-axis witness: the byte-view reverse-projection axis
16875 // must agree with the paired str-view reverse-projection
16876 // axis ([`TryFrom<&str>`]) on every accepted arm — the two
16877 // reverse paths share one `PascalCase` accept-set through
16878 // the substrate-primitive `from_wire` accessor.
16879 let via_str: Result<RestartStrategy, ()> =
16880 <RestartStrategy as TryFrom<&str>>::try_from(variant.as_str());
16881 let via_bytes: Result<RestartStrategy, ()> =
16882 <RestartStrategy as TryFrom<&[u8]>>::try_from(wire_bytes);
16883 assert_eq!(
16884 via_bytes, via_str,
16885 "TryFrom<&[u8]> and TryFrom<&str> reverse-projection \
16886 axes on RestartStrategy must agree on \
16887 RestartStrategy::{variant:?} — divergence signals the \
16888 byte-view and str-view reverse paths have drifted off \
16889 the same substrate-primitive from_wire accessor"
16890 );
16891 // Forward/reverse byte-view cross-axis witness: feed the
16892 // paired [`AsRef<[u8]>`] byte-tail back through the new
16893 // impl and assert it round-trips to the originating arm.
16894 let via_asref: &[u8] = <RestartStrategy as AsRef<[u8]>>::as_ref(&variant);
16895 assert_eq!(
16896 <RestartStrategy as TryFrom<&[u8]>>::try_from(via_asref),
16897 Ok(variant),
16898 "TryFrom<&[u8]> ∘ AsRef<[u8]> must round-trip \
16899 RestartStrategy::{variant:?} — divergence signals the \
16900 forward and reverse byte-view axes have drifted off \
16901 the same substrate-primitive as_str/from_wire pair"
16902 );
16903 }
16904 }
16905
16906 #[test]
16907 fn restart_strategy_try_from_bytes_rejects_unknown_and_non_utf8_bytes() {
16908 // Rejection witness on the `impl TryFrom<&[u8]> for
16909 // RestartStrategy` — sweeps two rejection paths the byte-view
16910 // reverse-projection axis collapses onto the single unit-error
16911 // `Err(())` return: the invalid-UTF-8 rejection path
16912 // ([`std::str::from_utf8`] returns `Err` before
16913 // [`RestartStrategy::from_wire`] runs) and the valid-UTF-8-but-
16914 // unknown-wire rejection path ([`RestartStrategy::from_wire`]
16915 // returns `None` on a byte-string outside the four-arm
16916 // `PascalCase` accept-set). Both must reject, so a future
16917 // accidental widening of the trait impl's accept-set (a case-
16918 // fold path, a silent acceptance of the kebab-case dispatcher-
16919 // catalog byte-strings on this axis — which would collide the
16920 // two-axis wire/catalog split the sibling
16921 // [`RestartStrategy::from_wire`] doc block makes load-bearing —
16922 // a `#[serde(rename_all = "…")]` attribute drift that widens
16923 // the parse arm-set silently, a stray fallback that maps
16924 // invalid UTF-8 onto a default arm rather than the trait-
16925 // idiomatic `Err(())`) trips at caixa-core test time. Peer of
16926 // the sibling
16927 // [`crate::kind::tests::caixa_kind_try_from_bytes_rejects_unknown_and_non_utf8_bytes`]
16928 // (18d1940),
16929 // [`crate::dialeto::tests::caixa_dialeto_try_from_bytes_rejects_unknown_and_non_utf8_bytes`]
16930 // (d102cb8), and
16931 // [`crate::dep::tests::dep_list_try_from_bytes_rejects_unknown_and_non_utf8_bytes`]
16932 // (b8f25d5) rejection witnesses.
16933 //
16934 // Non-UTF-8 candidates:
16935 // - a lone 0xFF byte (never valid as a UTF-8 leading byte)
16936 // - a lone 0x80 continuation byte with no leading byte
16937 // - a truncated multi-byte sequence (0xC3 without its continuation)
16938 // - a UTF-16 BOM-style byte pair the UTF-8 validator rejects
16939 // - a UTF-16 surrogate half rejected by UTF-8
16940 let non_utf8_rejected: &[&[u8]] = &[
16941 &[0xFF],
16942 &[0x80],
16943 &[0xC3],
16944 &[0xFF, 0xFE],
16945 &[0xED, 0xA0, 0x80],
16946 ];
16947 for &input in non_utf8_rejected {
16948 assert_eq!(
16949 <RestartStrategy as TryFrom<&[u8]>>::try_from(input),
16950 Err(()),
16951 "TryFrom<&[u8]> impl on RestartStrategy must reject the \
16952 non-UTF-8 byte-sequence {input:?} with Err(()) — \
16953 silent acceptance signals the UTF-8 validation path \
16954 collapsed onto a default arm rather than the trait-\
16955 idiomatic unit-error"
16956 );
16957 }
16958 // Valid-UTF-8-but-unknown-wire candidates mirror the corpus
16959 // the sibling `restart_strategy_try_from_str_rejects_unknown_byte_strings`
16960 // (5b828ed) str-view rejection witness already pins on the
16961 // paired [`TryFrom<&str>`] axis: the empty byte-string,
16962 // whitespace-only padding, the kebab-case dispatcher-catalog
16963 // byte-strings on the sibling axis the pre-existing
16964 // [`std::str::FromStr`] impl the [`gen_platform::FromStrKind`]
16965 // derive installs parses onto (a caller who confuses the two
16966 // axes trips here rather than at a downstream K8s-CR round-
16967 // trip miss), lowercase / uppercase / mixed-case folds of each
16968 // `PascalCase` arm, whitespace-padded / trailing-newline /
16969 // quote-wrapped forms, and plausible-but-wrong English rebrand
16970 // candidates.
16971 let unknown_wire_rejected: &[&[u8]] = &[
16972 b"",
16973 b" ",
16974 b"\n",
16975 b"\t",
16976 b"one-for-one",
16977 b"one-for-all",
16978 b"rest-for-one",
16979 b"simple-one-for-one",
16980 b"oneforone",
16981 b"one_for_one",
16982 b"OneForOnes",
16983 b"ONEFORONE",
16984 b"oneforall",
16985 b"restforone",
16986 b"simpleoneforone",
16987 b"OneForOne ",
16988 b" OneForOne",
16989 b" OneForAll ",
16990 b"OneForOne\n",
16991 b"RestForOne\t",
16992 b"OneForEach",
16993 b"AllForOne",
16994 b"one for one",
16995 b"\"OneForOne\"",
16996 b"?",
16997 ];
16998 for &input in unknown_wire_rejected {
16999 assert_eq!(
17000 <RestartStrategy as TryFrom<&[u8]>>::try_from(input),
17001 Err(()),
17002 "TryFrom<&[u8]> impl on RestartStrategy must reject the \
17003 valid-UTF-8-but-unknown-wire byte-string {input:?} \
17004 with Err(()) — silent acceptance signals an accept-\
17005 set widening off the paired RestartStrategy::from_wire \
17006 resolver"
17007 );
17008 // Cross-axis witness: on a byte-string that is valid UTF-8,
17009 // the byte-view reverse-projection axis must agree with the
17010 // paired str-view reverse-projection axis
17011 // ([`TryFrom<&str>`]) — both route through the same
17012 // [`RestartStrategy::from_wire`] resolver, so the two
17013 // rejection paths align by construction.
17014 if let Ok(s) = std::str::from_utf8(input) {
17015 assert_eq!(
17016 <RestartStrategy as TryFrom<&[u8]>>::try_from(input),
17017 <RestartStrategy as TryFrom<&str>>::try_from(s),
17018 "TryFrom<&[u8]> and TryFrom<&str> reverse-\
17019 projection axes on RestartStrategy must agree on \
17020 the valid-UTF-8 input {input:?} — divergence \
17021 signals the two reverse paths have drifted off \
17022 the same substrate-primitive from_wire accessor"
17023 );
17024 }
17025 }
17026 }
17027
17028 #[test]
17029 fn restart_strategy_try_from_vec_bytes_routes_through_borrowed_byte_view_axis() {
17030 // Fail-before-pass-after byte-parity pin on the newly lifted
17031 // `impl TryFrom<Vec<u8>> for RestartStrategy` — asserts the trait-
17032 // idiomatic owned-byte-vec reverse-projection standard-library
17033 // impl and the sibling borrowed-input [`TryFrom<&[u8]>`] axis
17034 // resolve to the same four-arm `PascalCase` wire accept-set
17035 // across every arm the exhaustive [`RestartStrategy::ALL`] slice
17036 // enumerates. Extends the substrate-wide trait-idiomatic byte-
17037 // owned reverse-projection axis onto the first M2-OTP-shape
17038 // supervisor-slot closed-set fieldless typed enum peer — owned-
17039 // input mirror of the paired [`TryFrom<&[u8]>`] byte-view
17040 // reverse-projection axis (c699a83), and byte-owned reverse
17041 // companion of the pre-existing byte-owned *forward*-projection
17042 // pair ([`From<RestartStrategy> for Vec<u8>`],
17043 // [`From<&RestartStrategy> for Vec<u8>`]) on this same enum.
17044 // Peer of the sibling first-mover
17045 // [`crate::kind::tests::caixa_kind_try_from_vec_bytes_routes_through_borrowed_byte_view_axis`]
17046 // (99c2849) on the [`crate::CaixaKind`] closed-set typed-enum
17047 // peer, the sibling second-mover
17048 // [`crate::dialeto::tests::caixa_dialeto_try_from_vec_bytes_routes_through_borrowed_byte_view_axis`]
17049 // (83a1526) on the [`crate::CaixaDialeto`] peer, and the sibling
17050 // third-mover
17051 // [`crate::dep::tests::dep_list_try_from_vec_bytes_routes_through_borrowed_byte_view_axis`]
17052 // (42091cb) on the [`crate::dep::DepList`] peer — tracks the
17053 // "delegate through `TryFrom<&[u8]>` on the `Vec<u8>::as_slice`
17054 // borrow" discipline the first-mover established.
17055 //
17056 // Rust's standard library carries no blanket
17057 // `impl<T: for<'a> TryFrom<&'a [u8]>> TryFrom<Vec<u8>> for T`,
17058 // so an owned-byte-vec caller otherwise picks between an open-
17059 // coded `<T as TryFrom<&[u8]>>::try_from(bytes.as_slice())` at
17060 // every call site whose type bounds have no compile-time link
17061 // back to the byte-owned reverse-projection axis, or a
17062 // `String::from_utf8(bytes)` two-hop shape whose error surface
17063 // leaks the standard-library `FromUtf8Error` type. This impl
17064 // closes the byte-owned reverse-projection axis at the
17065 // substrate-primitive [`RestartStrategy::from_wire`] accessor so
17066 // every future `<T: TryFrom<Vec<u8>>>`-bound owned-byte-vec
17067 // consumer reaches the same four-arm `PascalCase` wire accept-
17068 // set through one trait dispatch.
17069 for &variant in RestartStrategy::ALL {
17070 let wire_bytes: Vec<u8> = variant.as_str().as_bytes().to_vec();
17071 assert_eq!(
17072 <RestartStrategy as TryFrom<Vec<u8>>>::try_from(wire_bytes.clone()),
17073 Ok(variant),
17074 "TryFrom<Vec<u8>> impl on RestartStrategy must round-trip \
17075 RestartStrategy::{variant:?}.as_str().as_bytes().to_vec() \
17076 back to Ok(RestartStrategy::{variant:?}) — divergence \
17077 from the sibling TryFrom<&[u8]> axis signals a silent \
17078 detour off the substrate-primitive from_wire accessor"
17079 );
17080 // Cross-axis witness: the owned-byte-vec reverse-projection
17081 // axis must agree with the borrowed byte-slice reverse-
17082 // projection axis on every accepted arm — the two axes share
17083 // one `PascalCase` wire vocabulary through the substrate-
17084 // primitive `from_wire` accessor, and the owned-input axis
17085 // delegates to the borrowed peer by design.
17086 let via_owned: Result<RestartStrategy, ()> =
17087 <RestartStrategy as TryFrom<Vec<u8>>>::try_from(wire_bytes.clone());
17088 let via_borrowed: Result<RestartStrategy, ()> =
17089 <RestartStrategy as TryFrom<&[u8]>>::try_from(wire_bytes.as_slice());
17090 assert_eq!(
17091 via_owned, via_borrowed,
17092 "TryFrom<Vec<u8>> and TryFrom<&[u8]> reverse-projection \
17093 axes on RestartStrategy must agree on \
17094 RestartStrategy::{variant:?} — divergence signals the \
17095 owned-input and borrowed-input byte-view reverse paths \
17096 have drifted off the same substrate-primitive \
17097 from_wire accessor"
17098 );
17099 // Cross-axis witness against the paired str-view reverse
17100 // axis ([`TryFrom<&str>`]) — the three reverse paths (str-
17101 // view, byte-view borrowed, byte-view owned) share one
17102 // substrate primitive.
17103 let via_str: Result<RestartStrategy, ()> =
17104 <RestartStrategy as TryFrom<&str>>::try_from(variant.as_str());
17105 assert_eq!(
17106 via_owned, via_str,
17107 "TryFrom<Vec<u8>> and TryFrom<&str> reverse-projection \
17108 axes on RestartStrategy must agree on \
17109 RestartStrategy::{variant:?} — divergence signals the \
17110 byte-owned and str-view reverse paths have drifted off \
17111 the same substrate-primitive from_wire accessor"
17112 );
17113 // Four-corner witness: because [`RestartStrategy`] carries
17114 // no wire-vs-diagnostic split (as_str and from_wire share
17115 // one `PascalCase` byte-vocabulary — unlike the sibling
17116 // [`crate::CaixaKind`] whose peer test deliberately declines
17117 // this witness), the byte-owned reverse-projection axis on
17118 // this enum *does* round-trip against the paired byte-owned
17119 // forward-projection pair. Pin every corner of the {owned-
17120 // input, borrowed-input} × {From<Self> → Vec<u8>,
17121 // From<&Self> → Vec<u8>} square onto the same Ok(variant)
17122 // return so a future accident that drops one corner off the
17123 // substrate-primitive accessor trips here.
17124 let owned_forward: Vec<u8> = <Vec<u8> as From<RestartStrategy>>::from(variant);
17125 let borrowed_forward: Vec<u8> = <Vec<u8> as From<&RestartStrategy>>::from(&variant);
17126 assert_eq!(
17127 owned_forward, wire_bytes,
17128 "From<RestartStrategy> for Vec<u8> forward projection on \
17129 RestartStrategy::{variant:?} must byte-equal \
17130 variant.as_str().as_bytes().to_vec() — divergence \
17131 signals the paired forward pair drifted off the \
17132 substrate-primitive as_str accessor"
17133 );
17134 assert_eq!(
17135 borrowed_forward, wire_bytes,
17136 "From<&RestartStrategy> for Vec<u8> forward projection \
17137 on &RestartStrategy::{variant:?} must byte-equal \
17138 variant.as_str().as_bytes().to_vec() — divergence \
17139 signals the paired forward pair drifted off the \
17140 substrate-primitive as_str accessor"
17141 );
17142 assert_eq!(
17143 <RestartStrategy as TryFrom<Vec<u8>>>::try_from(owned_forward.clone()),
17144 Ok(variant),
17145 "Four-corner round-trip on RestartStrategy::{variant:?} \
17146 through From<RestartStrategy> for Vec<u8> then \
17147 TryFrom<Vec<u8>> for RestartStrategy must return \
17148 Ok(variant) — divergence signals the byte-owned \
17149 forward pair and the byte-owned reverse axis have \
17150 drifted apart"
17151 );
17152 assert_eq!(
17153 <RestartStrategy as TryFrom<Vec<u8>>>::try_from(borrowed_forward),
17154 Ok(variant),
17155 "Four-corner round-trip on RestartStrategy::{variant:?} \
17156 through From<&RestartStrategy> for Vec<u8> then \
17157 TryFrom<Vec<u8>> for RestartStrategy must return \
17158 Ok(variant) — divergence signals the borrowed-input \
17159 forward corner and the owned-input reverse corner have \
17160 drifted apart"
17161 );
17162 }
17163 }
17164
17165 #[test]
17166 fn restart_strategy_try_from_vec_bytes_rejects_unknown_and_non_utf8_bytes() {
17167 // Rejection witness on the `impl TryFrom<Vec<u8>> for
17168 // RestartStrategy` — sweeps the same two rejection paths the
17169 // sibling borrowed `TryFrom<&[u8]>` axis collapses onto the
17170 // single unit-error return: the invalid-UTF-8 rejection path
17171 // (`std::str::from_utf8` on the underlying byte-slice returns
17172 // `Err` before [`RestartStrategy::from_wire`] runs) and the
17173 // valid-UTF-8-but-unknown-wire rejection path
17174 // ([`RestartStrategy::from_wire`] returns `None` on a byte-
17175 // string outside the four-arm `PascalCase` accept-set). Both
17176 // must reject so a future accidental widening of the trait
17177 // impl's accept-set (a case-fold path, a silent acceptance of
17178 // the kebab-case dispatcher-catalog byte-strings on this axis —
17179 // which would collide the two-axis wire/catalog split the
17180 // sibling [`RestartStrategy::from_wire`] doc block makes load-
17181 // bearing — a `#[serde(rename_all = "…")]` attribute drift that
17182 // widens the parse arm-set silently, a stray
17183 // `String::from_utf8_lossy` detour that widens the input
17184 // surface with the U+FFFD replacement character, an
17185 // `Option::unwrap_or_default`-shape fallback that maps invalid
17186 // UTF-8 onto a default arm rather than the trait-idiomatic
17187 // `Err(())`) trips at caixa-core test time. Peer of the sibling
17188 // first-mover
17189 // [`crate::kind::tests::caixa_kind_try_from_vec_bytes_rejects_unknown_and_non_utf8_bytes`]
17190 // (99c2849) on the [`crate::CaixaKind`] peer, the sibling
17191 // second-mover
17192 // [`crate::dialeto::tests::caixa_dialeto_try_from_vec_bytes_rejects_unknown_and_non_utf8_bytes`]
17193 // (83a1526) on the [`crate::CaixaDialeto`] peer, and the
17194 // sibling third-mover
17195 // [`crate::dep::tests::dep_list_try_from_vec_bytes_rejects_unknown_and_non_utf8_bytes`]
17196 // (42091cb) on the [`crate::dep::DepList`] peer rejection
17197 // witnesses.
17198 let non_utf8_rejected: &[&[u8]] = &[
17199 &[0xFF],
17200 &[0x80],
17201 &[0xC3],
17202 &[0xFF, 0xFE],
17203 &[0xED, 0xA0, 0x80], // UTF-16 surrogate half — rejected by UTF-8
17204 ];
17205 for &input in non_utf8_rejected {
17206 let owned: Vec<u8> = input.to_vec();
17207 assert_eq!(
17208 <RestartStrategy as TryFrom<Vec<u8>>>::try_from(owned),
17209 Err(()),
17210 "TryFrom<Vec<u8>> impl on RestartStrategy must reject \
17211 the non-UTF-8 byte-sequence {input:?} with Err(()) — \
17212 silent acceptance signals the UTF-8 validation path \
17213 collapsed onto a default arm rather than the trait-\
17214 idiomatic unit-error"
17215 );
17216 // Cross-axis witness: the owned-input axis must agree with
17217 // the borrowed-input axis on every rejected input.
17218 assert_eq!(
17219 <RestartStrategy as TryFrom<Vec<u8>>>::try_from(input.to_vec()),
17220 <RestartStrategy as TryFrom<&[u8]>>::try_from(input),
17221 "TryFrom<Vec<u8>> and TryFrom<&[u8]> reverse-projection \
17222 axes on RestartStrategy must agree on the non-UTF-8 \
17223 input {input:?} — divergence signals the owned-input \
17224 and borrowed-input byte-view reverse paths have drifted \
17225 off the same substrate-primitive from_wire accessor"
17226 );
17227 }
17228 // Valid-UTF-8-but-unknown-wire candidates mirror the corpus the
17229 // sibling borrowed-input rejection witness
17230 // [`restart_strategy_try_from_bytes_rejects_unknown_and_non_utf8_bytes`]
17231 // (c699a83) already pins on the paired byte-view axis: the
17232 // empty byte-string, whitespace-only padding, the kebab-case
17233 // dispatcher-catalog byte-strings on the sibling axis the pre-
17234 // existing [`std::str::FromStr`] impl the
17235 // [`gen_platform::FromStrKind`] derive installs parses onto (a
17236 // caller who confuses the two axes trips here rather than at a
17237 // downstream K8s-CR round-trip miss), lowercase / uppercase /
17238 // mixed-case folds of each `PascalCase` arm, whitespace-padded
17239 // / trailing-newline / quote-wrapped forms, and plausible-but-
17240 // wrong English rebrand candidates.
17241 let unknown_wire_rejected: &[&[u8]] = &[
17242 b"",
17243 b" ",
17244 b"\n",
17245 b"\t",
17246 b"one-for-one",
17247 b"one-for-all",
17248 b"rest-for-one",
17249 b"simple-one-for-one",
17250 b"oneforone",
17251 b"one_for_one",
17252 b"OneForOnes",
17253 b"ONEFORONE",
17254 b"oneforall",
17255 b"restforone",
17256 b"simpleoneforone",
17257 b"OneForOne ",
17258 b" OneForOne",
17259 b" OneForAll ",
17260 b"OneForOne\n",
17261 b"RestForOne\t",
17262 b"OneForEach",
17263 b"AllForOne",
17264 b"one for one",
17265 b"\"OneForOne\"",
17266 b"?",
17267 ];
17268 for &input in unknown_wire_rejected {
17269 let owned: Vec<u8> = input.to_vec();
17270 assert_eq!(
17271 <RestartStrategy as TryFrom<Vec<u8>>>::try_from(owned),
17272 Err(()),
17273 "TryFrom<Vec<u8>> impl on RestartStrategy must reject \
17274 the valid-UTF-8-but-unknown-wire byte-string {input:?} \
17275 with Err(()) — silent acceptance signals an accept-\
17276 set widening off the paired RestartStrategy::from_wire \
17277 resolver"
17278 );
17279 // Cross-axis witness against the borrowed byte-view axis:
17280 // the two paths must agree by construction, since the owned
17281 // axis delegates to the borrowed peer.
17282 assert_eq!(
17283 <RestartStrategy as TryFrom<Vec<u8>>>::try_from(input.to_vec()),
17284 <RestartStrategy as TryFrom<&[u8]>>::try_from(input),
17285 "TryFrom<Vec<u8>> and TryFrom<&[u8]> reverse-projection \
17286 axes on RestartStrategy must agree on the valid-UTF-8-\
17287 but-unknown-wire input {input:?} — divergence signals \
17288 the owned-input and borrowed-input byte-view reverse \
17289 paths have drifted off the same substrate-primitive \
17290 from_wire accessor"
17291 );
17292 }
17293 }
17294
17295 #[test]
17296 fn restart_policy_try_from_bytes_routes_through_from_wire_accessor() {
17297 // Fail-before-pass-after byte-parity pin on the newly lifted
17298 // `impl TryFrom<&[u8]> for RestartPolicy` — asserts the trait-
17299 // idiomatic byte-view reverse-projection standard-library impl
17300 // and the substrate-primitive [`RestartPolicy::from_wire`]
17301 // `Option<Self>` accessor resolve to the same three-arm
17302 // `PascalCase` wire accept-set across every arm the exhaustive
17303 // [`RestartPolicy::ALL`] slice enumerates. Closes the substrate-
17304 // wide trait-idiomatic byte-view reverse-projection axis on the
17305 // M2-OTP-shape `:supervisor :estrategia` + `:children :restart`
17306 // slot pair the sibling [`RestartStrategy`] first-mover
17307 // (c699a83) opened one commit prior — mirror of the paired
17308 // [`TryFrom<&str> for RestartPolicy`] str-view reverse-
17309 // projection axis on the same enum, and the byte-view companion
17310 // of the pre-existing byte-owned reverse-projection family
17311 // ([`AsRef<[u8]>`], [`From<RestartPolicy> for Vec<u8>`],
17312 // [`From<&RestartPolicy> for Vec<u8>`]) on this same enum. Peer
17313 // of the sibling
17314 // [`restart_strategy_try_from_bytes_routes_through_from_wire_accessor`]
17315 // (c699a83),
17316 // [`crate::kind::tests::caixa_kind_try_from_bytes_routes_through_from_wire_accessor`]
17317 // (18d1940),
17318 // [`crate::dialeto::tests::caixa_dialeto_try_from_bytes_routes_through_from_wire_accessor`]
17319 // (d102cb8), and
17320 // [`crate::dep::tests::dep_list_try_from_bytes_routes_through_from_wire_accessor`]
17321 // (b8f25d5) — tracks the "route through `from_wire` via
17322 // `std::str::from_utf8`" discipline the first-mover established.
17323 //
17324 // Rust's standard library carries no blanket
17325 // `impl<T: for<'a> TryFrom<&'a str>> TryFrom<&[u8]> for T`, so a
17326 // two-hop composition through [`std::str::from_utf8`] + the
17327 // paired [`TryFrom<&str>`] axis is reachable through the pre-
17328 // existing str-view reverse-projection axis alone. But that
17329 // two-hop shape has no compile-time link back to the byte-view
17330 // reverse-projection axis, forces every downstream
17331 // `<T: for<'a> TryFrom<&'a [u8]>>`-bound consumer to open-code
17332 // the composition at every call site, and admits a silent split
17333 // whenever a future call site takes a sibling byte-projection
17334 // axis whose parse arm-set carries no compile-time byte-view
17335 // surface. This impl closes the byte-view reverse-projection
17336 // axis at the substrate-primitive [`RestartPolicy::from_wire`]
17337 // accessor so every future `<T: for<'a> TryFrom<&'a [u8]>>`-
17338 // bound consumer reaches the same three-arm `PascalCase` wire
17339 // accept-set through one trait dispatch.
17340 for &variant in RestartPolicy::ALL {
17341 let wire_bytes: &[u8] = variant.as_str().as_bytes();
17342 assert_eq!(
17343 <RestartPolicy as TryFrom<&[u8]>>::try_from(wire_bytes),
17344 Ok(variant),
17345 "TryFrom<&[u8]> impl on RestartPolicy must round-trip \
17346 RestartPolicy::{variant:?}.as_str().as_bytes() back to \
17347 Ok(RestartPolicy::{variant:?}) — divergence from \
17348 RestartPolicy::from_wire signals a silent detour off \
17349 the substrate-primitive accessor"
17350 );
17351 assert_eq!(
17352 <RestartPolicy as TryFrom<&[u8]>>::try_from(wire_bytes).ok(),
17353 RestartPolicy::from_wire(variant.as_str()),
17354 "TryFrom<&[u8]> ok()-projection on \
17355 RestartPolicy::{variant:?}.as_str().as_bytes() must \
17356 byte-equal RestartPolicy::from_wire on the paired \
17357 &str input"
17358 );
17359 // Cross-axis witness: the byte-view reverse-projection axis
17360 // must agree with the paired str-view reverse-projection
17361 // axis ([`TryFrom<&str>`]) on every accepted arm — the two
17362 // reverse paths share one `PascalCase` accept-set through
17363 // the substrate-primitive `from_wire` accessor.
17364 let via_str: Result<RestartPolicy, ()> =
17365 <RestartPolicy as TryFrom<&str>>::try_from(variant.as_str());
17366 let via_bytes: Result<RestartPolicy, ()> =
17367 <RestartPolicy as TryFrom<&[u8]>>::try_from(wire_bytes);
17368 assert_eq!(
17369 via_bytes, via_str,
17370 "TryFrom<&[u8]> and TryFrom<&str> reverse-projection \
17371 axes on RestartPolicy must agree on \
17372 RestartPolicy::{variant:?} — divergence signals the \
17373 byte-view and str-view reverse paths have drifted off \
17374 the same substrate-primitive from_wire accessor"
17375 );
17376 // Forward/reverse byte-view cross-axis witness: feed the
17377 // paired [`AsRef<[u8]>`] byte-tail back through the new
17378 // impl and assert it round-trips to the originating arm.
17379 let via_asref: &[u8] = <RestartPolicy as AsRef<[u8]>>::as_ref(&variant);
17380 assert_eq!(
17381 <RestartPolicy as TryFrom<&[u8]>>::try_from(via_asref),
17382 Ok(variant),
17383 "TryFrom<&[u8]> ∘ AsRef<[u8]> must round-trip \
17384 RestartPolicy::{variant:?} — divergence signals the \
17385 forward and reverse byte-view axes have drifted off \
17386 the same substrate-primitive as_str/from_wire pair"
17387 );
17388 }
17389 }
17390
17391 #[test]
17392 fn restart_policy_try_from_bytes_rejects_unknown_and_non_utf8_bytes() {
17393 // Rejection witness on the `impl TryFrom<&[u8]> for RestartPolicy`
17394 // — sweeps two rejection paths the byte-view reverse-projection
17395 // axis collapses onto the single unit-error `Err(())` return: the
17396 // invalid-UTF-8 rejection path ([`std::str::from_utf8`] returns
17397 // `Err` before [`RestartPolicy::from_wire`] runs) and the
17398 // valid-UTF-8-but-unknown-wire rejection path
17399 // ([`RestartPolicy::from_wire`] returns `None` on a byte-string
17400 // outside the three-arm `PascalCase` accept-set). Both must
17401 // reject, so a future accidental widening of the trait impl's
17402 // accept-set (a case-fold path, a silent acceptance of the
17403 // kebab-case dispatcher-catalog byte-strings on this axis — which
17404 // would collide the two-axis wire/catalog split the sibling
17405 // [`RestartPolicy::from_wire`] doc block makes load-bearing — a
17406 // `#[serde(rename_all = "…")]` attribute drift that widens the
17407 // parse arm-set silently, a stray fallback that maps invalid
17408 // UTF-8 onto a default arm rather than the trait-idiomatic
17409 // `Err(())`) trips at caixa-core test time. Peer of the sibling
17410 // [`restart_strategy_try_from_bytes_rejects_unknown_and_non_utf8_bytes`]
17411 // (c699a83),
17412 // [`crate::kind::tests::caixa_kind_try_from_bytes_rejects_unknown_and_non_utf8_bytes`]
17413 // (18d1940),
17414 // [`crate::dialeto::tests::caixa_dialeto_try_from_bytes_rejects_unknown_and_non_utf8_bytes`]
17415 // (d102cb8), and
17416 // [`crate::dep::tests::dep_list_try_from_bytes_rejects_unknown_and_non_utf8_bytes`]
17417 // (b8f25d5) rejection witnesses.
17418 //
17419 // Non-UTF-8 candidates:
17420 // - a lone 0xFF byte (never valid as a UTF-8 leading byte)
17421 // - a lone 0x80 continuation byte with no leading byte
17422 // - a truncated multi-byte sequence (0xC3 without its continuation)
17423 // - a UTF-16 BOM-style byte pair the UTF-8 validator rejects
17424 // - a UTF-16 surrogate half rejected by UTF-8
17425 let non_utf8_rejected: &[&[u8]] = &[
17426 &[0xFF],
17427 &[0x80],
17428 &[0xC3],
17429 &[0xFF, 0xFE],
17430 &[0xED, 0xA0, 0x80],
17431 ];
17432 for &input in non_utf8_rejected {
17433 assert_eq!(
17434 <RestartPolicy as TryFrom<&[u8]>>::try_from(input),
17435 Err(()),
17436 "TryFrom<&[u8]> impl on RestartPolicy must reject the \
17437 non-UTF-8 byte-sequence {input:?} with Err(()) — \
17438 silent acceptance signals the UTF-8 validation path \
17439 collapsed onto a default arm rather than the trait-\
17440 idiomatic unit-error"
17441 );
17442 }
17443 // Valid-UTF-8-but-unknown-wire candidates mirror the corpus the
17444 // sibling `restart_policy_try_from_str_rejects_unknown_byte_strings`
17445 // str-view rejection witness already pins on the paired
17446 // [`TryFrom<&str>`] axis: the empty byte-string, whitespace-only
17447 // padding, the kebab-case dispatcher-catalog byte-strings on the
17448 // sibling axis the pre-existing [`std::str::FromStr`] impl the
17449 // [`gen_platform::FromStrKind`] derive installs parses onto (a
17450 // caller who confuses the two axes trips here rather than at a
17451 // downstream K8s-CR round-trip miss), lowercase / uppercase /
17452 // mixed-case folds of each `PascalCase` arm, whitespace-padded /
17453 // trailing-newline / quote-wrapped forms, and plausible-but-wrong
17454 // English rebrand candidates (`Ephemeral`, `Always`, `Never`,
17455 // `OnAbnormalExit`, `intrinsic`).
17456 let unknown_wire_rejected: &[&[u8]] = &[
17457 b"",
17458 b" ",
17459 b"\n",
17460 b"\t",
17461 b"permanent",
17462 b"temporary",
17463 b"transient",
17464 b"PERMANENT",
17465 b"TEMPORARY",
17466 b"TRANSIENT",
17467 b"Permanents",
17468 b"Permanent ",
17469 b" Permanent",
17470 b" Temporary ",
17471 b"Permanent\n",
17472 b"Transient\t",
17473 b"\"Permanent\"",
17474 b"Ephemeral",
17475 b"Always",
17476 b"Never",
17477 b"OnAbnormalExit",
17478 b"intrinsic",
17479 b"?",
17480 ];
17481 for &input in unknown_wire_rejected {
17482 assert_eq!(
17483 <RestartPolicy as TryFrom<&[u8]>>::try_from(input),
17484 Err(()),
17485 "TryFrom<&[u8]> impl on RestartPolicy must reject the \
17486 valid-UTF-8-but-unknown-wire byte-string {input:?} \
17487 with Err(()) — silent acceptance signals an accept-\
17488 set widening off the paired RestartPolicy::from_wire \
17489 resolver"
17490 );
17491 // Cross-axis witness: on a byte-string that is valid UTF-8,
17492 // the byte-view reverse-projection axis must agree with the
17493 // paired str-view reverse-projection axis
17494 // ([`TryFrom<&str>`]) — both route through the same
17495 // [`RestartPolicy::from_wire`] resolver, so the two
17496 // rejection paths align by construction.
17497 if let Ok(s) = std::str::from_utf8(input) {
17498 assert_eq!(
17499 <RestartPolicy as TryFrom<&[u8]>>::try_from(input),
17500 <RestartPolicy as TryFrom<&str>>::try_from(s),
17501 "TryFrom<&[u8]> and TryFrom<&str> reverse-\
17502 projection axes on RestartPolicy must agree on \
17503 the valid-UTF-8 input {input:?} — divergence \
17504 signals the two reverse paths have drifted off \
17505 the same substrate-primitive from_wire accessor"
17506 );
17507 }
17508 }
17509 }
17510
17511 #[test]
17512 fn supervisor_scalar_ctors_are_const_zero_runtime_work() {
17513 // Const-eval pin: the [`supervisor_scalar_ctors!`] macro spells every
17514 // generated ctor `const fn` so a caller can pin a `SupervisorError`
17515 // at compile time — the same zero-runtime-work property the pre-lift
17516 // `|<slot>| SupervisorError::<Variant> { <slot> }` closure carried on
17517 // its `Copy`-pass-through construction path (no `.to_string()` /
17518 // `.into()` allocation, no branching). If any future edit silently
17519 // drops the `const` qualifier from the macro body the per-arm `const`
17520 // bindings below fail to compile, which surfaces the regression at
17521 // the substrate-primitive definition rather than at some downstream
17522 // consumer that had come to rely on the `const`-constructibility.
17523 // Peer of the sibling
17524 // `aplicacao_policy_scalar_ctors_are_const_zero_runtime_work`
17525 // (7ef425e) const-eval pin on the peer `AplicacaoError` envelope's
17526 // per-`:politicas` per-axis ctor family.
17527 const NO_CHILDREN: SupervisorError =
17528 SupervisorError::no_children(RestartStrategy::OneForAll);
17529 const MAX_RESTARTS_CAP: SupervisorError = SupervisorError::max_restarts_exceeds_cap(1_337);
17530 const WINDOW_NC: SupervisorError =
17531 SupervisorError::restart_window_not_canonical(Duration::from_micros(1));
17532 const WINDOW_CAP: SupervisorError =
17533 SupervisorError::restart_window_exceeds_cap(Duration::from_secs(3_601));
17534 assert!(matches!(NO_CHILDREN, SupervisorError::NoChildren { .. }));
17535 assert!(matches!(
17536 MAX_RESTARTS_CAP,
17537 SupervisorError::MaxRestartsExceedsCap { .. }
17538 ));
17539 assert!(matches!(
17540 WINDOW_NC,
17541 SupervisorError::RestartWindowNotCanonical { .. }
17542 ));
17543 assert!(matches!(
17544 WINDOW_CAP,
17545 SupervisorError::RestartWindowExceedsCap { .. }
17546 ));
17547 }
17548
17549 #[test]
17550 fn restart_policy_try_from_vec_bytes_routes_through_borrowed_byte_view_axis() {
17551 // Fail-before-pass-after byte-parity pin on the newly lifted
17552 // `impl TryFrom<Vec<u8>> for RestartPolicy` — asserts the trait-
17553 // idiomatic owned-byte-vec reverse-projection standard-library
17554 // impl and the sibling borrowed-input [`TryFrom<&[u8]>`] axis
17555 // resolve to the same three-arm `PascalCase` wire accept-set
17556 // across every arm the exhaustive [`RestartPolicy::ALL`] slice
17557 // enumerates. Closes the substrate-wide trait-idiomatic byte-
17558 // owned reverse-projection axis on the M2-OTP-shape
17559 // `:supervisor :estrategia` + `:children :restart` slot pair the
17560 // sibling [`RestartStrategy`] first-mover
17561 // [`restart_strategy_try_from_vec_bytes_routes_through_borrowed_byte_view_axis`]
17562 // (34951fe) opened one commit-window prior — owned-input mirror
17563 // of the paired [`TryFrom<&[u8]>`] byte-view reverse-projection
17564 // axis on this same enum (d9ef5f0), and byte-owned reverse
17565 // companion of the pre-existing byte-owned *forward*-projection
17566 // pair ([`From<RestartPolicy> for Vec<u8>`],
17567 // [`From<&RestartPolicy> for Vec<u8>`]) on this same enum. Peer
17568 // of the sibling first-mover
17569 // [`crate::kind::tests::caixa_kind_try_from_vec_bytes_routes_through_borrowed_byte_view_axis`]
17570 // (99c2849) on the [`crate::CaixaKind`] closed-set typed-enum
17571 // peer, the sibling second-mover
17572 // [`crate::dialeto::tests::caixa_dialeto_try_from_vec_bytes_routes_through_borrowed_byte_view_axis`]
17573 // (83a1526) on the [`crate::CaixaDialeto`] peer, the sibling
17574 // third-mover
17575 // [`crate::dep::tests::dep_list_try_from_vec_bytes_routes_through_borrowed_byte_view_axis`]
17576 // (42091cb) on the [`crate::dep::DepList`] peer, and the sibling
17577 // fourth-mover
17578 // [`restart_strategy_try_from_vec_bytes_routes_through_borrowed_byte_view_axis`]
17579 // (34951fe) on the [`RestartStrategy`] peer — tracks the
17580 // "delegate through `TryFrom<&[u8]>` on the `Vec<u8>::as_slice`
17581 // borrow" discipline the first-mover established.
17582 //
17583 // Rust's standard library carries no blanket
17584 // `impl<T: for<'a> TryFrom<&'a [u8]>> TryFrom<Vec<u8>> for T`,
17585 // so an owned-byte-vec caller otherwise picks between an open-
17586 // coded `<T as TryFrom<&[u8]>>::try_from(bytes.as_slice())` at
17587 // every call site whose type bounds have no compile-time link
17588 // back to the byte-owned reverse-projection axis, or a
17589 // `String::from_utf8(bytes)` two-hop shape whose error surface
17590 // leaks the standard-library `FromUtf8Error` type. This impl
17591 // closes the byte-owned reverse-projection axis at the
17592 // substrate-primitive [`RestartPolicy::from_wire`] accessor so
17593 // every future `<T: TryFrom<Vec<u8>>>`-bound owned-byte-vec
17594 // consumer reaches the same three-arm `PascalCase` wire accept-
17595 // set through one trait dispatch.
17596 for &variant in RestartPolicy::ALL {
17597 let wire_bytes: Vec<u8> = variant.as_str().as_bytes().to_vec();
17598 assert_eq!(
17599 <RestartPolicy as TryFrom<Vec<u8>>>::try_from(wire_bytes.clone()),
17600 Ok(variant),
17601 "TryFrom<Vec<u8>> impl on RestartPolicy must round-trip \
17602 RestartPolicy::{variant:?}.as_str().as_bytes().to_vec() \
17603 back to Ok(RestartPolicy::{variant:?}) — divergence \
17604 from the sibling TryFrom<&[u8]> axis signals a silent \
17605 detour off the substrate-primitive from_wire accessor"
17606 );
17607 // Cross-axis witness: the owned-byte-vec reverse-projection
17608 // axis must agree with the borrowed byte-slice reverse-
17609 // projection axis on every accepted arm — the two axes share
17610 // one `PascalCase` wire vocabulary through the substrate-
17611 // primitive `from_wire` accessor, and the owned-input axis
17612 // delegates to the borrowed peer by design.
17613 let via_owned: Result<RestartPolicy, ()> =
17614 <RestartPolicy as TryFrom<Vec<u8>>>::try_from(wire_bytes.clone());
17615 let via_borrowed: Result<RestartPolicy, ()> =
17616 <RestartPolicy as TryFrom<&[u8]>>::try_from(wire_bytes.as_slice());
17617 assert_eq!(
17618 via_owned, via_borrowed,
17619 "TryFrom<Vec<u8>> and TryFrom<&[u8]> reverse-projection \
17620 axes on RestartPolicy must agree on \
17621 RestartPolicy::{variant:?} — divergence signals the \
17622 owned-input and borrowed-input byte-view reverse paths \
17623 have drifted off the same substrate-primitive \
17624 from_wire accessor"
17625 );
17626 // Cross-axis witness against the paired str-view reverse
17627 // axis ([`TryFrom<&str>`]) — the three reverse paths (str-
17628 // view, byte-view borrowed, byte-view owned) share one
17629 // substrate primitive.
17630 let via_str: Result<RestartPolicy, ()> =
17631 <RestartPolicy as TryFrom<&str>>::try_from(variant.as_str());
17632 assert_eq!(
17633 via_owned, via_str,
17634 "TryFrom<Vec<u8>> and TryFrom<&str> reverse-projection \
17635 axes on RestartPolicy must agree on \
17636 RestartPolicy::{variant:?} — divergence signals the \
17637 byte-owned and str-view reverse paths have drifted off \
17638 the same substrate-primitive from_wire accessor"
17639 );
17640 // Four-corner witness: because [`RestartPolicy`] carries
17641 // no wire-vs-diagnostic split (as_str and from_wire share
17642 // one `PascalCase` byte-vocabulary — like the sibling
17643 // [`RestartStrategy`] and unlike the sibling
17644 // [`crate::CaixaKind`] whose peer test deliberately declines
17645 // this witness), the byte-owned reverse-projection axis on
17646 // this enum *does* round-trip against the paired byte-owned
17647 // forward-projection pair. Pin every corner of the {owned-
17648 // input, borrowed-input} × {From<Self> → Vec<u8>,
17649 // From<&Self> → Vec<u8>} square onto the same Ok(variant)
17650 // return so a future accident that drops one corner off the
17651 // substrate-primitive accessor trips here.
17652 let owned_forward: Vec<u8> = <Vec<u8> as From<RestartPolicy>>::from(variant);
17653 let borrowed_forward: Vec<u8> = <Vec<u8> as From<&RestartPolicy>>::from(&variant);
17654 assert_eq!(
17655 owned_forward, wire_bytes,
17656 "From<RestartPolicy> for Vec<u8> forward projection on \
17657 RestartPolicy::{variant:?} must byte-equal \
17658 variant.as_str().as_bytes().to_vec() — divergence \
17659 signals the paired forward pair drifted off the \
17660 substrate-primitive as_str accessor"
17661 );
17662 assert_eq!(
17663 borrowed_forward, wire_bytes,
17664 "From<&RestartPolicy> for Vec<u8> forward projection \
17665 on &RestartPolicy::{variant:?} must byte-equal \
17666 variant.as_str().as_bytes().to_vec() — divergence \
17667 signals the paired forward pair drifted off the \
17668 substrate-primitive as_str accessor"
17669 );
17670 assert_eq!(
17671 <RestartPolicy as TryFrom<Vec<u8>>>::try_from(owned_forward.clone()),
17672 Ok(variant),
17673 "Four-corner round-trip on RestartPolicy::{variant:?} \
17674 through From<RestartPolicy> for Vec<u8> then \
17675 TryFrom<Vec<u8>> for RestartPolicy must return \
17676 Ok(variant) — divergence signals the byte-owned \
17677 forward pair and the byte-owned reverse axis have \
17678 drifted apart"
17679 );
17680 assert_eq!(
17681 <RestartPolicy as TryFrom<Vec<u8>>>::try_from(borrowed_forward),
17682 Ok(variant),
17683 "Four-corner round-trip on RestartPolicy::{variant:?} \
17684 through From<&RestartPolicy> for Vec<u8> then \
17685 TryFrom<Vec<u8>> for RestartPolicy must return \
17686 Ok(variant) — divergence signals the borrowed-input \
17687 forward corner and the owned-input reverse corner have \
17688 drifted apart"
17689 );
17690 }
17691 }
17692
17693 #[test]
17694 fn restart_policy_try_from_vec_bytes_rejects_unknown_and_non_utf8_bytes() {
17695 // Rejection witness on the `impl TryFrom<Vec<u8>> for
17696 // RestartPolicy` — sweeps the same two rejection paths the
17697 // sibling borrowed `TryFrom<&[u8]>` axis collapses onto the
17698 // single unit-error return: the invalid-UTF-8 rejection path
17699 // (`std::str::from_utf8` on the underlying byte-slice returns
17700 // `Err` before [`RestartPolicy::from_wire`] runs) and the
17701 // valid-UTF-8-but-unknown-wire rejection path
17702 // ([`RestartPolicy::from_wire`] returns `None` on a byte-
17703 // string outside the three-arm `PascalCase` accept-set). Both
17704 // must reject so a future accidental widening of the trait
17705 // impl's accept-set (a case-fold path, a silent acceptance of
17706 // the kebab-case dispatcher-catalog byte-strings on this axis —
17707 // which would collide the two-axis wire/catalog split the
17708 // sibling [`RestartPolicy::from_wire`] doc block makes load-
17709 // bearing — a `#[serde(rename_all = "…")]` attribute drift that
17710 // widens the parse arm-set silently, a stray
17711 // `String::from_utf8_lossy` detour that widens the input
17712 // surface with the U+FFFD replacement character, an
17713 // `Option::unwrap_or_default`-shape fallback that maps invalid
17714 // UTF-8 onto a default arm rather than the trait-idiomatic
17715 // `Err(())`) trips at caixa-core test time. Peer of the sibling
17716 // first-mover
17717 // [`crate::kind::tests::caixa_kind_try_from_vec_bytes_rejects_unknown_and_non_utf8_bytes`]
17718 // (99c2849) on the [`crate::CaixaKind`] peer, the sibling
17719 // second-mover
17720 // [`crate::dialeto::tests::caixa_dialeto_try_from_vec_bytes_rejects_unknown_and_non_utf8_bytes`]
17721 // (83a1526) on the [`crate::CaixaDialeto`] peer, the sibling
17722 // third-mover
17723 // [`crate::dep::tests::dep_list_try_from_vec_bytes_rejects_unknown_and_non_utf8_bytes`]
17724 // (42091cb) on the [`crate::dep::DepList`] peer, and the
17725 // sibling fourth-mover
17726 // [`restart_strategy_try_from_vec_bytes_rejects_unknown_and_non_utf8_bytes`]
17727 // (34951fe) on the [`RestartStrategy`] peer rejection
17728 // witnesses.
17729 let non_utf8_rejected: &[&[u8]] = &[
17730 &[0xFF],
17731 &[0x80],
17732 &[0xC3],
17733 &[0xFF, 0xFE],
17734 &[0xED, 0xA0, 0x80], // UTF-16 surrogate half — rejected by UTF-8
17735 ];
17736 for &input in non_utf8_rejected {
17737 let owned: Vec<u8> = input.to_vec();
17738 assert_eq!(
17739 <RestartPolicy as TryFrom<Vec<u8>>>::try_from(owned),
17740 Err(()),
17741 "TryFrom<Vec<u8>> impl on RestartPolicy must reject \
17742 the non-UTF-8 byte-sequence {input:?} with Err(()) — \
17743 silent acceptance signals the UTF-8 validation path \
17744 collapsed onto a default arm rather than the trait-\
17745 idiomatic unit-error"
17746 );
17747 // Cross-axis witness: the owned-input axis must agree with
17748 // the borrowed-input axis on every rejected input.
17749 assert_eq!(
17750 <RestartPolicy as TryFrom<Vec<u8>>>::try_from(input.to_vec()),
17751 <RestartPolicy as TryFrom<&[u8]>>::try_from(input),
17752 "TryFrom<Vec<u8>> and TryFrom<&[u8]> reverse-projection \
17753 axes on RestartPolicy must agree on the non-UTF-8 \
17754 input {input:?} — divergence signals the owned-input \
17755 and borrowed-input byte-view reverse paths have drifted \
17756 off the same substrate-primitive from_wire accessor"
17757 );
17758 }
17759 // Valid-UTF-8-but-unknown-wire candidates mirror the corpus the
17760 // sibling borrowed-input rejection witness
17761 // [`restart_policy_try_from_bytes_rejects_unknown_and_non_utf8_bytes`]
17762 // (d9ef5f0) already pins on the paired byte-view axis: the
17763 // empty byte-string, whitespace-only padding, the kebab-case
17764 // dispatcher-catalog byte-strings on the sibling axis the pre-
17765 // existing [`std::str::FromStr`] impl the
17766 // [`gen_platform::FromStrKind`] derive installs parses onto (a
17767 // caller who confuses the two axes trips here rather than at a
17768 // downstream K8s-CR round-trip miss), lowercase / uppercase /
17769 // mixed-case folds of each `PascalCase` arm, whitespace-padded /
17770 // trailing-newline / quote-wrapped forms, and plausible-but-
17771 // wrong English rebrand candidates (`Ephemeral`, `Always`,
17772 // `Never`, `OnAbnormalExit`, `intrinsic`).
17773 let unknown_wire_rejected: &[&[u8]] = &[
17774 b"",
17775 b" ",
17776 b"\n",
17777 b"\t",
17778 b"permanent",
17779 b"temporary",
17780 b"transient",
17781 b"PERMANENT",
17782 b"TEMPORARY",
17783 b"TRANSIENT",
17784 b"Permanents",
17785 b"Permanent ",
17786 b" Permanent",
17787 b" Temporary ",
17788 b"Permanent\n",
17789 b"Transient\t",
17790 b"\"Permanent\"",
17791 b"Ephemeral",
17792 b"Always",
17793 b"Never",
17794 b"OnAbnormalExit",
17795 b"intrinsic",
17796 b"?",
17797 ];
17798 for &input in unknown_wire_rejected {
17799 let owned: Vec<u8> = input.to_vec();
17800 assert_eq!(
17801 <RestartPolicy as TryFrom<Vec<u8>>>::try_from(owned),
17802 Err(()),
17803 "TryFrom<Vec<u8>> impl on RestartPolicy must reject \
17804 the valid-UTF-8-but-unknown-wire byte-string {input:?} \
17805 with Err(()) — silent acceptance signals an accept-\
17806 set widening off the paired RestartPolicy::from_wire \
17807 resolver"
17808 );
17809 // Cross-axis witness against the borrowed byte-view axis:
17810 // the two paths must agree by construction, since the owned
17811 // axis delegates to the borrowed peer.
17812 assert_eq!(
17813 <RestartPolicy as TryFrom<Vec<u8>>>::try_from(input.to_vec()),
17814 <RestartPolicy as TryFrom<&[u8]>>::try_from(input),
17815 "TryFrom<Vec<u8>> and TryFrom<&[u8]> reverse-projection \
17816 axes on RestartPolicy must agree on the valid-UTF-8-\
17817 but-unknown-wire input {input:?} — divergence signals \
17818 the owned-input and borrowed-input byte-view reverse \
17819 paths have drifted off the same substrate-primitive \
17820 from_wire accessor"
17821 );
17822 }
17823 }
17824
17825 #[test]
17826 fn restart_strategy_try_from_owned_string_routes_through_borrowed_str_view_axis() {
17827 // Fail-before-pass-after byte-parity pin on the newly lifted
17828 // `impl TryFrom<String> for RestartStrategy` — asserts the
17829 // trait-idiomatic string-owned reverse-projection standard-
17830 // library impl and the sibling borrowed-input [`TryFrom<&str>`]
17831 // axis resolve to the same four-arm `PascalCase` wire accept-set
17832 // across every arm the exhaustive [`RestartStrategy::ALL`] slice
17833 // enumerates. Extends the substrate-wide trait-idiomatic string-
17834 // owned reverse-projection axis onto the first M2-OTP-shape
17835 // supervisor-slot closed-set fieldless typed-enum peer — owned-
17836 // input mirror of the paired [`TryFrom<&str>`] str-view reverse-
17837 // projection axis, and string-owned reverse companion of the
17838 // pre-existing string-owned *forward*-projection pair
17839 // ([`From<RestartStrategy> for String`],
17840 // [`From<&RestartStrategy> for String`]) on this same enum. Peer
17841 // of the sibling opener
17842 // [`crate::aplicacao::tests::rate_limit_try_from_owned_string_routes_through_borrowed_str_view_axis`]
17843 // (a2e6f02) on the compound [`crate::aplicacao::RateLimit`]
17844 // primitive, the sibling first-mover
17845 // [`crate::aplicacao::tests::wit_shape_try_from_owned_string_routes_through_borrowed_str_view_axis`]
17846 // (e6aac29) on the [`crate::aplicacao::WitShape`] closed-set peer,
17847 // the sibling second-mover
17848 // [`crate::aplicacao::tests::rate_limit_unit_try_from_owned_string_routes_through_borrowed_str_view_axis`]
17849 // (94a9c5e) on the [`crate::aplicacao::RateLimitUnit`] peer, and
17850 // the sibling third-mover
17851 // [`crate::aplicacao::tests::placement_strategy_try_from_owned_string_routes_through_borrowed_str_view_axis`]
17852 // (d81a70a) on the [`crate::aplicacao::PlacementStrategy`] peer —
17853 // tracks the "delegate through `TryFrom<&str>` on the
17854 // `String::as_str` borrow" discipline the compound-primitive
17855 // opener and closed-set-peer first-mover established.
17856 //
17857 // Rust's standard library carries no blanket
17858 // `impl<T: for<'a> TryFrom<&'a str>> TryFrom<String> for T`, so
17859 // an owned-`String` caller otherwise picks between an open-coded
17860 // `<T as TryFrom<&str>>::try_from(s.as_str())` at every call
17861 // site (whose type bounds have no compile-time link back to the
17862 // string-owned reverse-projection axis) or a `let s: &str = &s;
17863 // T::try_from(s)` two-step whose borrow arithmetic leaks a per-
17864 // call-site lifetime dance. This impl closes the string-owned
17865 // reverse-projection axis at the substrate-primitive
17866 // [`RestartStrategy::from_wire`] accessor so every future
17867 // `<T: TryFrom<String>>`-bound owned-string consumer reaches the
17868 // same four-arm `PascalCase` accept-set through one trait
17869 // dispatch.
17870 for &variant in RestartStrategy::ALL {
17871 let wire_string: String = variant.as_str().to_string();
17872 assert_eq!(
17873 <RestartStrategy as TryFrom<String>>::try_from(wire_string.clone()),
17874 Ok(variant),
17875 "TryFrom<String> impl on RestartStrategy must round-trip \
17876 RestartStrategy::{variant:?}.as_str().to_string() back \
17877 to Ok(RestartStrategy::{variant:?}) — divergence from \
17878 the sibling TryFrom<&str> axis signals a silent detour \
17879 off the substrate-primitive from_wire accessor"
17880 );
17881 // Cross-axis witness: the string-owned reverse-projection
17882 // axis must agree with the borrowed `&str` reverse-projection
17883 // axis on every accepted arm — the two axes share one
17884 // `PascalCase` wire vocabulary through the substrate-primitive
17885 // `from_wire` accessor, and the owned-input axis delegates to
17886 // the borrowed peer by design.
17887 let via_owned: Result<RestartStrategy, ()> =
17888 <RestartStrategy as TryFrom<String>>::try_from(wire_string.clone());
17889 let via_borrowed: Result<RestartStrategy, ()> =
17890 <RestartStrategy as TryFrom<&str>>::try_from(wire_string.as_str());
17891 assert_eq!(
17892 via_owned, via_borrowed,
17893 "TryFrom<String> and TryFrom<&str> reverse-projection \
17894 axes on RestartStrategy must agree on \
17895 RestartStrategy::{variant:?} — divergence signals the \
17896 owned-`String` and borrowed-`&str` reverse paths have \
17897 drifted off the same substrate-primitive from_wire \
17898 accessor"
17899 );
17900 // Cross-axis witness against the paired byte-view and byte-
17901 // owned reverse axes — the four reverse paths (str-view
17902 // borrowed, string-owned, byte-view borrowed, byte-owned)
17903 // share one substrate primitive.
17904 let via_bytes_borrowed: Result<RestartStrategy, ()> =
17905 <RestartStrategy as TryFrom<&[u8]>>::try_from(wire_string.as_bytes());
17906 let via_bytes_owned: Result<RestartStrategy, ()> =
17907 <RestartStrategy as TryFrom<Vec<u8>>>::try_from(wire_string.as_bytes().to_vec());
17908 assert_eq!(
17909 via_owned, via_bytes_borrowed,
17910 "TryFrom<String> and TryFrom<&[u8]> reverse-projection \
17911 axes on RestartStrategy must agree on \
17912 RestartStrategy::{variant:?} — divergence signals the \
17913 string-owned and byte-view reverse paths have drifted \
17914 off the same substrate-primitive from_wire accessor"
17915 );
17916 assert_eq!(
17917 via_owned, via_bytes_owned,
17918 "TryFrom<String> and TryFrom<Vec<u8>> reverse-projection \
17919 axes on RestartStrategy must agree on \
17920 RestartStrategy::{variant:?} — divergence signals the \
17921 string-owned and byte-owned reverse paths have drifted \
17922 off the same substrate-primitive from_wire accessor"
17923 );
17924 // Closed-cycle witness against the paired string-owned
17925 // forward-projection pair: `Self → String → TryFrom<String>
17926 // → Self` round-trips to the originating arm on every
17927 // canonical `PascalCase` scalar. Both the owned-input
17928 // `From<RestartStrategy> for String` and the borrowed-input
17929 // `From<&RestartStrategy> for String` corners must feed back
17930 // through the new impl to `Ok(variant)`.
17931 let owned_forward: String = <String as From<RestartStrategy>>::from(variant);
17932 let borrowed_forward: String = <String as From<&RestartStrategy>>::from(&variant);
17933 assert_eq!(
17934 owned_forward, wire_string,
17935 "From<RestartStrategy> for String forward projection on \
17936 RestartStrategy::{variant:?} must byte-equal \
17937 variant.as_str().to_string() — divergence signals the \
17938 paired forward pair drifted off the substrate-primitive \
17939 as_str accessor"
17940 );
17941 assert_eq!(
17942 borrowed_forward, wire_string,
17943 "From<&RestartStrategy> for String forward projection on \
17944 &RestartStrategy::{variant:?} must byte-equal \
17945 variant.as_str().to_string() — divergence signals the \
17946 paired forward pair drifted off the substrate-primitive \
17947 as_str accessor"
17948 );
17949 assert_eq!(
17950 <RestartStrategy as TryFrom<String>>::try_from(owned_forward.clone()),
17951 Ok(variant),
17952 "Closed-cycle round-trip on RestartStrategy::{variant:?} \
17953 through From<RestartStrategy> for String then \
17954 TryFrom<String> for RestartStrategy must return \
17955 Ok(variant) — divergence signals the string-owned \
17956 forward pair and the string-owned reverse axis have \
17957 drifted apart"
17958 );
17959 assert_eq!(
17960 <RestartStrategy as TryFrom<String>>::try_from(borrowed_forward),
17961 Ok(variant),
17962 "Closed-cycle round-trip on RestartStrategy::{variant:?} \
17963 through From<&RestartStrategy> for String then \
17964 TryFrom<String> for RestartStrategy must return \
17965 Ok(variant) — divergence signals the borrowed-input \
17966 forward corner and the owned-input string reverse \
17967 corner have drifted apart"
17968 );
17969 }
17970 }
17971
17972 #[test]
17973 fn restart_strategy_try_from_owned_string_rejects_unknown_wire_strings() {
17974 // Rejection witness on the `impl TryFrom<String> for
17975 // RestartStrategy` — sweeps the corpus of valid-UTF-8-but-
17976 // unknown-wire byte-strings the sibling borrowed [`TryFrom<&str>`]
17977 // axis already rejects and asserts every one lands on `Err(())`,
17978 // so a future accidental widening of the trait impl's accept-set
17979 // (a case-fold path, a silent inclusion of the kebab-case
17980 // dispatcher-catalog byte-strings on the sibling axis that would
17981 // collide the two-axis wire/catalog split the sibling
17982 // [`RestartStrategy::from_wire`] doc block makes load-bearing, a
17983 // stray fallback that maps whitespace-padded canonical scalars
17984 // onto their unpadded arm rather than the trait-idiomatic
17985 // `Err(())`) trips at caixa-core test time. Peer of the sibling
17986 // borrowed-input rejection witness
17987 // [`restart_strategy_try_from_str_rejects_unknown_byte_strings`]
17988 // on the same enum, and the sibling byte-view / byte-owned
17989 // rejection witnesses
17990 // [`restart_strategy_try_from_bytes_rejects_unknown_and_non_utf8_bytes`]
17991 // (c699a83) /
17992 // [`restart_strategy_try_from_vec_bytes_rejects_unknown_and_non_utf8_bytes`]
17993 // (34951fe) on the same enum.
17994 let unknown_wire_rejected: &[&str] = &[
17995 "",
17996 " ",
17997 "\n",
17998 "\t",
17999 "one-for-one",
18000 "one-for-all",
18001 "rest-for-one",
18002 "simple-one-for-one",
18003 "oneforone",
18004 "one_for_one",
18005 "OneForOnes",
18006 "ONEFORONE",
18007 "oneforall",
18008 "restforone",
18009 "simpleoneforone",
18010 "OneForOne ",
18011 " OneForOne",
18012 " OneForAll ",
18013 "OneForOne\n",
18014 "RestForOne\t",
18015 "OneForEach",
18016 "AllForOne",
18017 "one for one",
18018 "\"OneForOne\"",
18019 "?",
18020 ];
18021 for &input in unknown_wire_rejected {
18022 let owned: String = input.to_string();
18023 assert_eq!(
18024 <RestartStrategy as TryFrom<String>>::try_from(owned),
18025 Err(()),
18026 "TryFrom<String> impl on RestartStrategy must reject the \
18027 valid-UTF-8-but-unknown-wire byte-string {input:?} with \
18028 Err(()) — silent acceptance signals an accept-set \
18029 widening off the paired RestartStrategy::from_wire \
18030 resolver"
18031 );
18032 // Cross-axis witness against the borrowed str-view axis:
18033 // the two paths must agree by construction, since the owned
18034 // axis delegates to the borrowed peer.
18035 assert_eq!(
18036 <RestartStrategy as TryFrom<String>>::try_from(input.to_string()),
18037 <RestartStrategy as TryFrom<&str>>::try_from(input),
18038 "TryFrom<String> and TryFrom<&str> reverse-projection \
18039 axes on RestartStrategy must agree on the valid-UTF-8-\
18040 but-unknown-wire input {input:?} — divergence signals \
18041 the owned-`String` and borrowed-`&str` reverse paths \
18042 have drifted off the same substrate-primitive from_wire \
18043 accessor"
18044 );
18045 }
18046 }
18047
18048 #[test]
18049 fn restart_policy_try_from_owned_string_routes_through_borrowed_str_view_axis() {
18050 // Fail-before-pass-after byte-parity pin on the newly lifted
18051 // `impl TryFrom<String> for RestartPolicy` — asserts the trait-
18052 // idiomatic string-owned reverse-projection standard-library impl
18053 // and the sibling borrowed-input [`TryFrom<&str>`] axis resolve
18054 // to the same three-arm `PascalCase` wire accept-set across every
18055 // arm the exhaustive [`RestartPolicy::ALL`] slice enumerates.
18056 // Extends the substrate-wide trait-idiomatic string-owned reverse-
18057 // projection axis onto the second (and final) M2-OTP-shape
18058 // supervisor-slot closed-set fieldless typed-enum peer — owned-
18059 // input mirror of the paired [`TryFrom<&str>`] str-view reverse-
18060 // projection axis, and string-owned reverse companion of the
18061 // pre-existing string-owned *forward*-projection pair
18062 // ([`From<RestartPolicy> for String`],
18063 // [`From<&RestartPolicy> for String`]) on this same enum. Peer
18064 // of the sibling first-mover
18065 // [`crate::aplicacao::tests::rate_limit_try_from_owned_string_routes_through_borrowed_str_view_axis`]
18066 // (a2e6f02) on the compound [`crate::aplicacao::RateLimit`]
18067 // primitive, and the sibling
18068 // [`restart_strategy_try_from_owned_string_routes_through_borrowed_str_view_axis`]
18069 // (78fe8c8) on the sibling first M2-OTP-shape supervisor-slot
18070 // [`RestartStrategy`] peer — tracks the "delegate through
18071 // `TryFrom<&str>` on the `String::as_str` borrow" discipline the
18072 // compound-primitive opener and closed-set-peer first-mover
18073 // established. This closes the string-owned reverse-projection
18074 // axis on the M2-OTP-shape `:supervisor :estrategia` +
18075 // `:children :restart` slot pair.
18076 for &variant in RestartPolicy::ALL {
18077 let wire_string: String = variant.as_str().to_string();
18078 assert_eq!(
18079 <RestartPolicy as TryFrom<String>>::try_from(wire_string.clone()),
18080 Ok(variant),
18081 "TryFrom<String> impl on RestartPolicy must round-trip \
18082 RestartPolicy::{variant:?}.as_str().to_string() back \
18083 to Ok(RestartPolicy::{variant:?}) — divergence from \
18084 the sibling TryFrom<&str> axis signals a silent detour \
18085 off the substrate-primitive from_wire accessor"
18086 );
18087 // Cross-axis witness: the string-owned reverse-projection
18088 // axis must agree with the borrowed `&str` reverse-projection
18089 // axis on every accepted arm — the two axes share one
18090 // `PascalCase` wire vocabulary through the substrate-
18091 // primitive `from_wire` accessor, and the owned-input axis
18092 // delegates to the borrowed peer by design.
18093 let via_owned: Result<RestartPolicy, ()> =
18094 <RestartPolicy as TryFrom<String>>::try_from(wire_string.clone());
18095 let via_borrowed: Result<RestartPolicy, ()> =
18096 <RestartPolicy as TryFrom<&str>>::try_from(wire_string.as_str());
18097 assert_eq!(
18098 via_owned, via_borrowed,
18099 "TryFrom<String> and TryFrom<&str> reverse-projection \
18100 axes on RestartPolicy must agree on \
18101 RestartPolicy::{variant:?} — divergence signals the \
18102 owned-`String` and borrowed-`&str` reverse paths have \
18103 drifted off the same substrate-primitive from_wire \
18104 accessor"
18105 );
18106 // Cross-axis witness against the paired byte-view and byte-
18107 // owned reverse axes — the four reverse paths (str-view
18108 // borrowed, string-owned, byte-view borrowed, byte-owned)
18109 // share one substrate primitive.
18110 let via_bytes_borrowed: Result<RestartPolicy, ()> =
18111 <RestartPolicy as TryFrom<&[u8]>>::try_from(wire_string.as_bytes());
18112 let via_bytes_owned: Result<RestartPolicy, ()> =
18113 <RestartPolicy as TryFrom<Vec<u8>>>::try_from(wire_string.as_bytes().to_vec());
18114 assert_eq!(
18115 via_owned, via_bytes_borrowed,
18116 "TryFrom<String> and TryFrom<&[u8]> reverse-projection \
18117 axes on RestartPolicy must agree on \
18118 RestartPolicy::{variant:?} — divergence signals the \
18119 string-owned and byte-view reverse paths have drifted \
18120 off the same substrate-primitive from_wire accessor"
18121 );
18122 assert_eq!(
18123 via_owned, via_bytes_owned,
18124 "TryFrom<String> and TryFrom<Vec<u8>> reverse-projection \
18125 axes on RestartPolicy must agree on \
18126 RestartPolicy::{variant:?} — divergence signals the \
18127 string-owned and byte-owned reverse paths have drifted \
18128 off the same substrate-primitive from_wire accessor"
18129 );
18130 // Closed-cycle witness against the paired string-owned
18131 // forward-projection pair: `Self → String → TryFrom<String>
18132 // → Self` round-trips to the originating arm on every
18133 // canonical `PascalCase` scalar. Both the owned-input
18134 // `From<RestartPolicy> for String` and the borrowed-input
18135 // `From<&RestartPolicy> for String` corners must feed back
18136 // through the new impl to `Ok(variant)`.
18137 let owned_forward: String = <String as From<RestartPolicy>>::from(variant);
18138 let borrowed_forward: String = <String as From<&RestartPolicy>>::from(&variant);
18139 assert_eq!(
18140 owned_forward, wire_string,
18141 "From<RestartPolicy> for String forward projection on \
18142 RestartPolicy::{variant:?} must byte-equal \
18143 variant.as_str().to_string() — divergence signals the \
18144 paired forward pair drifted off the substrate-primitive \
18145 as_str accessor"
18146 );
18147 assert_eq!(
18148 borrowed_forward, wire_string,
18149 "From<&RestartPolicy> for String forward projection on \
18150 &RestartPolicy::{variant:?} must byte-equal \
18151 variant.as_str().to_string() — divergence signals the \
18152 paired forward pair drifted off the substrate-primitive \
18153 as_str accessor"
18154 );
18155 assert_eq!(
18156 <RestartPolicy as TryFrom<String>>::try_from(owned_forward.clone()),
18157 Ok(variant),
18158 "Closed-cycle round-trip on RestartPolicy::{variant:?} \
18159 through From<RestartPolicy> for String then \
18160 TryFrom<String> for RestartPolicy must return \
18161 Ok(variant) — divergence signals the string-owned \
18162 forward pair and the string-owned reverse axis have \
18163 drifted apart"
18164 );
18165 assert_eq!(
18166 <RestartPolicy as TryFrom<String>>::try_from(borrowed_forward),
18167 Ok(variant),
18168 "Closed-cycle round-trip on RestartPolicy::{variant:?} \
18169 through From<&RestartPolicy> for String then \
18170 TryFrom<String> for RestartPolicy must return \
18171 Ok(variant) — divergence signals the borrowed-input \
18172 forward corner and the owned-input string reverse \
18173 corner have drifted apart"
18174 );
18175 }
18176 }
18177
18178 #[test]
18179 fn restart_policy_try_from_owned_string_rejects_unknown_wire_strings() {
18180 // Rejection witness on the `impl TryFrom<String> for
18181 // RestartPolicy` — sweeps the corpus of valid-UTF-8-but-
18182 // unknown-wire byte-strings the sibling borrowed [`TryFrom<&str>`]
18183 // axis already rejects and asserts every one lands on `Err(())`,
18184 // so a future accidental widening of the trait impl's accept-set
18185 // (a case-fold path, a silent inclusion of the kebab-case
18186 // dispatcher-catalog byte-strings on the sibling axis that would
18187 // collide the two-axis wire/catalog split the sibling
18188 // [`RestartPolicy::from_wire`] doc block makes load-bearing, a
18189 // stray fallback that maps whitespace-padded canonical scalars
18190 // onto their unpadded arm rather than the trait-idiomatic
18191 // `Err(())`) trips at caixa-core test time. Peer of the sibling
18192 // borrowed-input rejection witness
18193 // [`restart_policy_try_from_str_rejects_unknown_byte_strings`]
18194 // on the same enum, and the sibling byte-view / byte-owned
18195 // rejection witnesses
18196 // [`restart_policy_try_from_bytes_rejects_unknown_and_non_utf8_bytes`]
18197 // (d9ef5f0) /
18198 // [`restart_policy_try_from_vec_bytes_rejects_unknown_and_non_utf8_bytes`]
18199 // (7592085) on the same enum.
18200 let unknown_wire_rejected: &[&str] = &[
18201 "",
18202 " ",
18203 "\n",
18204 "\t",
18205 "permanent",
18206 "temporary",
18207 "transient",
18208 "PERMANENT",
18209 "TEMPORARY",
18210 "TRANSIENT",
18211 "Permanents",
18212 "Permanent ",
18213 " Permanent",
18214 " Temporary ",
18215 "Permanent\n",
18216 "Transient\t",
18217 "\"Permanent\"",
18218 "Ephemeral",
18219 "Always",
18220 "Never",
18221 "OnAbnormalExit",
18222 "intrinsic",
18223 "?",
18224 ];
18225 for &input in unknown_wire_rejected {
18226 let owned: String = input.to_string();
18227 assert_eq!(
18228 <RestartPolicy as TryFrom<String>>::try_from(owned),
18229 Err(()),
18230 "TryFrom<String> impl on RestartPolicy must reject the \
18231 valid-UTF-8-but-unknown-wire byte-string {input:?} with \
18232 Err(()) — silent acceptance signals an accept-set \
18233 widening off the paired RestartPolicy::from_wire \
18234 resolver"
18235 );
18236 // Cross-axis witness against the borrowed str-view axis:
18237 // the two paths must agree by construction, since the owned
18238 // axis delegates to the borrowed peer.
18239 assert_eq!(
18240 <RestartPolicy as TryFrom<String>>::try_from(input.to_string()),
18241 <RestartPolicy as TryFrom<&str>>::try_from(input),
18242 "TryFrom<String> and TryFrom<&str> reverse-projection \
18243 axes on RestartPolicy must agree on the valid-UTF-8-\
18244 but-unknown-wire input {input:?} — divergence signals \
18245 the owned-`String` and borrowed-`&str` reverse paths \
18246 have drifted off the same substrate-primitive from_wire \
18247 accessor"
18248 );
18249 }
18250 }
18251}