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/// Substrate-canonical [`AsRef<[u8]>`] byte-view projection on the M2
1327/// OTP-shape sibling-restart [`RestartStrategy`] closed-set fieldless
1328/// typed enum — routes byte-for-byte through the substrate-primitive
1329/// [`RestartStrategy::as_str`] `pub const fn` accessor via
1330/// [`str::as_bytes`] on the returned `&'static str`, so any future
1331/// consumer that binds a [`RestartStrategy`] through a standard-library
1332/// `<T: AsRef<[u8]>>` trait bound reaches the same four-arm lifted
1333/// [`crate::render::SUPERVISOR_ESTRATEGIA_ONE_FOR_ONE`] /
1334/// [`crate::render::SUPERVISOR_ESTRATEGIA_ONE_FOR_ALL`] /
1335/// [`crate::render::SUPERVISOR_ESTRATEGIA_REST_FOR_ONE`] /
1336/// [`crate::render::SUPERVISOR_ESTRATEGIA_SIMPLE_ONE_FOR_ONE`]
1337/// `PascalCase` wire byte-string emit-set the paired sibling
1338/// [`AsRef<str>`] (5b828ed) / [`std::fmt::Display`] /
1339/// [`RestartStrategy::as_str`] str-view surfaces and every
1340/// `{Self, &Self} × {&'static str, String, Cow<'static, str>, Box<str>,
1341/// std::sync::Arc<str>}` reverse-projection corner already return —
1342/// through the byte-view axis, which the str-view axes cannot express.
1343///
1344/// Rust's standard library carries `impl AsRef<[u8]> for str` and
1345/// `impl AsRef<[u8]> for String`, so the two-hop composition
1346/// `strategy.as_str().as_bytes()` (or, equivalently,
1347/// `AsRef::<str>::as_ref(&strategy).as_bytes()`) is reachable through
1348/// the pre-existing str-view axis alone. But that two-hop shape has no
1349/// compile-time link back to the byte-projection axis, forces every
1350/// downstream `<T: AsRef<[u8]>>`-bound consumer to open-code the
1351/// two-hop composition at every call site, and admits a silent split
1352/// whenever a future call site takes a sibling reverse-projection axis
1353/// whose `.as_bytes()` byte-tail carries no compile-time byte-view
1354/// surface (`Display` returns a formatter, `String` / `Box<str>` /
1355/// `Arc<str>` allocate). The lifted single-hop impl closes the
1356/// byte-view axis so every future `<T: AsRef<[u8]>>`-bound consumer
1357/// reaches the substrate primitive through one trait dispatch, and
1358/// every future arm addition (an OTP-`rest_for_all` fifth arm the
1359/// theory
1360/// [`ABSORPTION-ROADMAP`](https://github.com/pleme-io/theory/blob/main/ABSORPTION-ROADMAP.md)
1361/// might reach for once the four canonical OTP strategies stop covering
1362/// the substrate's discovered load-shape) grows the byte-view axis
1363/// through one edit on the substrate-primitive `as_str` accessor, not a
1364/// coordinated rewrite across every future `<T: AsRef<[u8]>>`-bound
1365/// consumer's arm-set.
1366///
1367/// The primary compounding target is the same `caixa-lacre` BLAKE3
1368/// content-address closure the peer [`crate::CaixaKind`] (69d8d86),
1369/// [`crate::dialeto::CaixaDialeto`] (8151347),
1370/// [`crate::dep::DepList`] (05ffaca),
1371/// [`crate::aplicacao::PlacementStrategy`] (daa8705), and
1372/// [`crate::aplicacao::RateLimitUnit`] (4867e0f) `AsRef<[u8]>` impls
1373/// open onto: [`blake3::hash`] and [`blake3::Hasher::update`] both bind
1374/// their input through `impl AsRef<[u8]>`, so any future per-supervisor
1375/// content-address tag that folds an `:estrategia` discriminator
1376/// byte-tag into the [`crate::Lacre`] closure (a hypothetical
1377/// `hasher.update(estrategia);`-shape composition partitioning the
1378/// four OTP restart-topology closures at content-address time so
1379/// downstream `Lacre` consumers key per-strategy reconciliation caches
1380/// off the typed discriminator rather than the sibling `&'static str`
1381/// wire scalar) reaches the substrate-primitive `as_str` accessor
1382/// through this impl and no other.
1383///
1384/// Opens the trait-idiomatic byte-view axis on the first M2 OTP-shape
1385/// closed-set fieldless typed enum peer on the caixa surface
1386/// (`:supervisor :estrategia`), extending the substrate-wide byte-view
1387/// campaign the sibling [`crate::CaixaKind`] first-mover (69d8d86)
1388/// opened onto the fifth in-caixa-core enum peer. The remaining
1389/// in-caixa-core closed-set fieldless typed-enum peers
1390/// ([`RestartPolicy`], [`crate::aplicacao::WitShape`],
1391/// [`crate::upgrade::UpgradeInstruction`],
1392/// [`crate::render::PathShapeViolation`]) each carry the same
1393/// [`AsRef<str>`] + `pub const fn as_str` substrate-primitive accessor
1394/// discipline, so a future extension of the byte-view axis onto each
1395/// peer reaches through one impl per enum keyed to that peer's
1396/// substrate-primitive accessor.
1397///
1398/// Pinned load-bearing by
1399/// [`tests::restart_strategy_as_ref_bytes_routes_through_as_str_accessor`]
1400/// (fail-before-pass-after byte-parity pin against
1401/// [`RestartStrategy::as_str`] `.as_bytes()` across the four-arm
1402/// [`RestartStrategy::ALL`] emit-set, cross-axis witness against the
1403/// paired str-view [`AsRef<str>`] / [`std::fmt::Display`] /
1404/// [`RestartStrategy::as_str`] axes' `.as_bytes()` byte-tails,
1405/// cross-axis witness against the paired reverse-projection
1406/// `{&'static str, String, Cow<'static, str>, Box<str>,
1407/// std::sync::Arc<str>}` return-shape axes' `.as_bytes()` byte-tails,
1408/// a `<T: AsRef<[u8]>>`-bound-consumer witness that a generic
1409/// byte-input function accepts a [`RestartStrategy`] directly through
1410/// the trait bound, and a `blake3::Hasher::update`-shape byte-input
1411/// surface witness routed through the `<T: AsRef<[u8]>>`-bound
1412/// consumer axis to reach the caixa-lacre compounding target). Any
1413/// future silent detour that routes the byte-view impl off the
1414/// substrate-primitive [`RestartStrategy::as_str`] accessor (a per-arm
1415/// inline `b"OneForOne".as_slice()`-shaped re-inlining that opens a
1416/// compile-time link to the un-lifted arm-literal, a swap onto the
1417/// kebab-case [`gen_platform::Discriminant`] catalog identity that
1418/// would collide the wire axis with the dispatcher-catalog axis) trips
1419/// at caixa-core test time rather than at a downstream byte-consumer's
1420/// silent split.
1421impl AsRef<[u8]> for RestartStrategy {
1422 fn as_ref(&self) -> &[u8] {
1423 self.as_str().as_bytes()
1424 }
1425}
1426
1427/// Trait-idiomatic *owned-input, owned-`Vec<u8>` output* byte-owned
1428/// reverse projection on the first M2 OTP-shape closed-set fieldless
1429/// typed enum peer on the caixa surface ([`RestartStrategy`]) — the
1430/// byte-mirror of the [`From<RestartStrategy> for String`] str-owned
1431/// reverse-projection axis and the owned-`Vec<u8>` reverse-projection
1432/// sibling of the paired [`AsRef<[u8]>`] borrowed byte-view axis
1433/// (cd4c4e0) lifted on this same enum. Routes byte-for-byte through
1434/// the substrate-primitive [`RestartStrategy::as_str`] `pub const fn`
1435/// accessor via [`str::as_bytes`] + [`slice::to_vec`] so every
1436/// consumer that binds a [`RestartStrategy`] through the standard-
1437/// library `impl From<RestartStrategy> for Vec<u8>` axis
1438/// (equivalently `<T: Into<Vec<u8>>>`) — a future
1439/// [`std::io::Write::write_all`]-shape per-supervisor audit-log byte-
1440/// sink whose input parameter is an owned [`Vec<u8>`] payload, a
1441/// future `bytes::Bytes::from(Vec::<u8>::from(strategy))` composer
1442/// folding the per-arm sibling-restart-topology byte-tag into the
1443/// [`bytes::Bytes`] framing surface, a future
1444/// `hasher.update(&Vec::<u8>::from(strategy))`-shape BLAKE3 content-
1445/// address closure that needs the owned byte-tail buffered before
1446/// folding into the [`crate::Lacre`] closure body, a future per-
1447/// strategy protobuf/CBOR/msgpack payload composer whose framer takes
1448/// an owned [`Vec<u8>`] rather than a borrowed byte-slice — reaches
1449/// the substrate primitive through one trait dispatch rather than an
1450/// open-coded per-call-site `strategy.as_str().as_bytes().to_vec()`
1451/// composition whose type bounds have no compile-time link back to
1452/// the substrate primitive.
1453///
1454/// Extends the substrate-wide trait-idiomatic byte-owned reverse-
1455/// projection axis onto the first M2-OTP-shape closed-set fieldless
1456/// typed-enum peer, matching the trajectory the first-mover
1457/// [`crate::CaixaKind`] `From<{Self, &Self}> for Vec<u8>` lift
1458/// (b245fd6), the second-mover [`crate::dialeto::CaixaDialeto`] lift
1459/// (4cceaf5), and the third-mover [`crate::dep::DepList`] lift
1460/// (e974ca2) established across the caixa-core-internal tier. Every
1461/// future arm addition (an OTP-`rest_for_all` fifth arm the theory
1462/// [`ABSORPTION-ROADMAP`](https://github.com/pleme-io/theory/blob/main/ABSORPTION-ROADMAP.md)
1463/// might reach for once the four canonical OTP strategies stop
1464/// covering the substrate's discovered load-shape) grows the byte-
1465/// owned axis through one edit on the substrate-primitive
1466/// [`RestartStrategy::as_str`] accessor, mirroring the discipline the
1467/// paired [`AsRef<[u8]>`] borrowed byte-view axis campaign already
1468/// tracked across every closed-set fieldless typed enum peer on the
1469/// substrate.
1470///
1471/// Pinned load-bearing by
1472/// [`tests::restart_strategy_from_into_owned_vec_bytes_routes_through_as_str_accessor`]
1473/// (byte-parity pin against [`RestartStrategy::as_str`] across the
1474/// four-arm [`RestartStrategy::ALL`] emit-set binding the byte-owned
1475/// reverse-projection axis against the paired [`AsRef<[u8]>`]
1476/// borrowed byte-view axis and the str-owned reverse-projection
1477/// family (`String`, `Cow<'static, str>`, `Box<str>`,
1478/// `std::sync::Arc<str>`) `.into_bytes()` / `.as_bytes().to_vec()`
1479/// byte-tails, a `<T: Into<Vec<u8>>>`-bound generic-consumer witness,
1480/// and a `std::io::Write::write_all`-shape owned-byte-sink surface
1481/// witness on both owned and borrowed input shapes).
1482impl From<RestartStrategy> for Vec<u8> {
1483 fn from(strategy: RestartStrategy) -> Vec<u8> {
1484 strategy.as_str().as_bytes().to_vec()
1485 }
1486}
1487
1488/// Trait-idiomatic *borrowed-input, owned-`Vec<u8>` output* byte-
1489/// owned reverse projection on the first M2 OTP-shape closed-set
1490/// fieldless typed enum peer on the caixa surface
1491/// ([`RestartStrategy`]) — the borrowed-input peer of
1492/// [`From<RestartStrategy> for Vec<u8>`], closing the
1493/// `{Self, &Self} → Vec<u8>` pair on the byte-owned reverse-projection
1494/// axis in one lift. Routes byte-for-byte through the substrate-
1495/// primitive [`RestartStrategy::as_str`] `pub const fn` accessor so
1496/// every consumer that holds a borrowed [`&RestartStrategy`] and
1497/// needs an owned [`Vec<u8>`] — a future
1498/// `.iter().map(Vec::<u8>::from).collect()` pipe over
1499/// `&[RestartStrategy]` (whose iterator yields `&RestartStrategy`,
1500/// not `RestartStrategy`, so the owned-input axis alone forces every
1501/// call site through an explicit `.copied()` / spurious [`Copy`]
1502/// deref restatement rather than the direct trait-idiomatic
1503/// projection), a future admission-webhook rejection body composer
1504/// that walks [`RestartStrategy::ALL`] through an `Into<Vec<u8>>`-
1505/// bound per-arm byte-writer to surface the accepted `:estrategia`
1506/// set — reaches the substrate primitive through one trait dispatch
1507/// rather than a `Vec::<u8>::from(*strategy)` spurious-`Copy`-deref
1508/// restatement.
1509impl From<&RestartStrategy> for Vec<u8> {
1510 fn from(strategy: &RestartStrategy) -> Vec<u8> {
1511 strategy.as_str().as_bytes().to_vec()
1512 }
1513}
1514
1515/// Trait-idiomatic *borrowed byte-slice input* reverse projection on the
1516/// first M2-OTP-shape closed-set fieldless typed enum peer on the caixa
1517/// surface ([`RestartStrategy`]) — the byte-view mirror of the str-view
1518/// reverse-projection axis carried by the paired
1519/// [`TryFrom<&str> for RestartStrategy`] impl (which routes through the
1520/// substrate-primitive [`RestartStrategy::from_wire`] `Option<Self>`
1521/// accessor on the four-arm `PascalCase` accept-set the sibling
1522/// [`RestartStrategy::as_str`] emitter returns). Routes byte-for-byte
1523/// through the standard-library [`std::str::from_utf8`] UTF-8 validator
1524/// and then through [`RestartStrategy::from_wire`] so every consumer that
1525/// holds a borrowed [`&[u8]`] and needs to project it back into a typed
1526/// [`RestartStrategy`] — a future `bytes::Bytes::as_ref()`-fed reader
1527/// that parses a per-supervisor `:estrategia` `PascalCase` wire scalar
1528/// from an already-borrowed framing byte-tail (a
1529/// `tracing::field::valuable::Value::Bytes` recorder on the future
1530/// wasm-operator's per-supervisor sibling-restart-strategy diagnostic
1531/// emission path, a future audit-report re-loader binding a prior
1532/// [`RestartStrategy::as_str`] output from a mmap'd byte-slice back
1533/// through the typed enum for cross-run comparison), a future M4
1534/// `mesh.pleme.io/v1alpha1/Supervisor` CR admission-webhook rejection
1535/// body that reads a `spec.estrategia` field off a raw HTTP body byte-
1536/// slice before UTF-8 validation commits allocation, a future generic
1537/// `<T: for<'a> TryFrom<&'a [u8]>>`-bound loader over any of the
1538/// substrate's closed-set typed enums — reaches the same four-arm
1539/// `PascalCase` wire accept-set the sibling method-named
1540/// [`RestartStrategy::from_wire`] resolver and the paired trait-idiomatic
1541/// [`TryFrom<&str>`] axis already resolve against, rather than an open-
1542/// coded per-call-site
1543/// `std::str::from_utf8(bytes).ok().and_then(RestartStrategy::from_wire)`
1544/// composition or a
1545/// `<RestartStrategy as TryFrom<&str>>::try_from(std::str::from_utf8(bytes)?)`
1546/// two-hop shape whose type bounds have no compile-time link to the
1547/// substrate primitive.
1548///
1549/// Extends the substrate-wide trait-idiomatic *byte-view reverse-
1550/// projection* family — opened on the structurally most fundamental
1551/// closed-set fieldless typed enum peer ([`crate::CaixaKind`], commit
1552/// 18d1940), extended onto the second caixa-core-internal peer
1553/// ([`crate::CaixaDialeto`], commit d102cb8) and the third
1554/// ([`crate::dep::DepList`], commit b8f25d5) — onto the first
1555/// M2-OTP-shape supervisor-slot closed-set fieldless typed enum peer,
1556/// tracking the "route through `from_wire` via `std::str::from_utf8`"
1557/// discipline the first-mover established. Rust's standard library
1558/// carries no blanket
1559/// `impl<T: for<'a> TryFrom<&'a str>> TryFrom<&[u8]> for T`, so a two-
1560/// hop composition through [`std::str::from_utf8`] + the paired
1561/// [`TryFrom<&str>`] axis is reachable at every call site but has no
1562/// compile-time link back to the byte-view reverse-projection axis.
1563/// Every remaining closed-set fieldless typed enum peer on the substrate
1564/// ([`RestartPolicy`], [`crate::aplicacao::PlacementStrategy`],
1565/// [`crate::aplicacao::RateLimitUnit`], [`crate::aplicacao::WitShape`],
1566/// and the outside-`caixa-core` peers `PathShapeViolation`,
1567/// `InvariantKind`, `ArchVerdict`, `Severity`, `FixSafety`, `Semantic`,
1568/// `FerriteRuntime`) is a future target of the campaign, mirroring the
1569/// trajectory the closed byte-owned reverse-projection family walked
1570/// arm-by-arm onto each peer.
1571///
1572/// `type Error = ()` matches the sibling [`RestartStrategy::from_wire`]'s
1573/// `Option<Self>` return-shape's deliberate deferral of error typing and
1574/// the paired trait-idiomatic [`TryFrom<&str>`] axis's unit-error shape —
1575/// the caller picks the diagnostic form appropriate for its use site (a
1576/// future `feira supervisor --estrategia …` arg-parse composes its own
1577/// per-verb "unknown strategy: <arg> — accepted: {…}" message enumerating
1578/// [`RestartStrategy::WIRE_NAMES`]; a future admission-webhook rejection
1579/// body wraps the `Err(())` outcome with the accepted-set enumeration for
1580/// operator diagnostics; a `Result::map_err` at the call site lifts the
1581/// unit-error to a per-verb error type). Two rejection paths route
1582/// through the single unit-error: an invalid UTF-8 byte-sequence
1583/// ([`std::str::from_utf8`] returns `Err`) and a valid UTF-8 byte-string
1584/// that falls outside the four-arm `PascalCase` accept-set
1585/// ([`RestartStrategy::from_wire`] returns `None`) — both collapse onto
1586/// `Err(())` so the trait signature stays consistent with the sibling
1587/// str-view reverse axis, and a caller that needs to distinguish the two
1588/// failure modes composes [`std::str::from_utf8`] +
1589/// [`RestartStrategy::from_wire`] explicitly.
1590///
1591/// Pinned load-bearing by
1592/// [`tests::restart_strategy_try_from_bytes_routes_through_from_wire_accessor`]
1593/// (byte-parity pin against [`RestartStrategy::from_wire`] across the
1594/// four-arm [`RestartStrategy::ALL`] accept-set on the borrowed byte-
1595/// slice surface, plus a cross-axis witness that the byte-view reverse
1596/// projection agrees with the paired [`TryFrom<&str>`] str-view reverse
1597/// axis on every accepted arm) and
1598/// [`tests::restart_strategy_try_from_bytes_rejects_unknown_and_non_utf8_bytes`]
1599/// (rejection witness against silent accept-set widening on both the
1600/// non-UTF-8 byte-sequence rejection path and the unknown-wire-vocabulary
1601/// rejection path — the latter includes the sibling kebab-case
1602/// dispatcher-catalog byte-strings on the two-axis wire/catalog split so
1603/// a caller that confuses the two axes trips here rather than at a
1604/// downstream K8s-CR round-trip miss).
1605impl TryFrom<&[u8]> for RestartStrategy {
1606 type Error = ();
1607
1608 fn try_from(bytes: &[u8]) -> Result<Self, Self::Error> {
1609 std::str::from_utf8(bytes)
1610 .ok()
1611 .and_then(Self::from_wire)
1612 .ok_or(())
1613 }
1614}
1615
1616/// Trait-idiomatic *owned byte-vec input* reverse projection on the first
1617/// M2-OTP-shape supervisor-slot closed-set fieldless typed enum peer on the
1618/// caixa surface ([`RestartStrategy`]) — the owned-input peer of
1619/// [`TryFrom<&[u8]> for RestartStrategy`], mirroring the closed
1620/// [`From<RestartStrategy> for Vec<u8>`] + [`From<&RestartStrategy> for
1621/// Vec<u8>`] byte-owned *forward*-projection pair on this same enum onto
1622/// the byte-owned *reverse*-projection axis. Routes byte-for-byte through
1623/// [`<Self as TryFrom<&[u8]>>::try_from`] on the [`Vec<u8>::as_slice`]
1624/// borrow, so the owned-input surface reaches the same
1625/// [`std::str::from_utf8`] + [`RestartStrategy::from_wire`] resolution
1626/// chain the borrowed-input peer already carries — one substrate-primitive
1627/// accessor, one trait dispatch, no per-consumer detour.
1628///
1629/// Rust's standard library carries no blanket
1630/// `impl<T: for<'a> TryFrom<&'a [u8]>> TryFrom<Vec<u8>> for T`, so a
1631/// consumer that holds an owned [`Vec<u8>`] and needs a typed
1632/// [`RestartStrategy`] otherwise picks between (a) an open-coded
1633/// `<RestartStrategy as TryFrom<&[u8]>>::try_from(bytes.as_slice())` at
1634/// every call site (whose type bounds have no compile-time link to the
1635/// byte-owned reverse-projection axis), (b) a two-hop
1636/// `String::from_utf8(bytes)` + [`RestartStrategy::from_wire`] composition
1637/// whose error surface leaks the standard-library
1638/// [`std::string::FromUtf8Error`] (widening the sibling [`TryFrom<&[u8]>`]
1639/// axis's unit-error) and silently allocates a [`String`] on inputs that
1640/// will never make it past the wire vocabulary, or (c) an intermediate
1641/// `<RestartStrategy as TryFrom<&str>>::try_from(std::str::from_utf8(&bytes)?)`
1642/// three-hop shape. This impl closes the owned-byte-vec reverse-projection
1643/// axis at the substrate-primitive [`RestartStrategy::from_wire`] accessor
1644/// so every future `<T: TryFrom<Vec<u8>>>`-bound owned-byte-vec consumer —
1645/// a future M4 `mesh.pleme.io/v1alpha1/Supervisor` CR admission-webhook
1646/// body reader that hands the `spec.estrategia` byte-tail off as a
1647/// [`Vec<u8>`] before UTF-8 validation commits allocation, a
1648/// `bytes::Bytes::to_vec()`-shape wire-body composer walking a prior
1649/// audit's per-supervisor rejection payload back to the typed enum, a
1650/// `std::io::Read::read_to_end`-shape audit-log source whose framing
1651/// yields an owned byte-vec per per-strategy scalar, an
1652/// `<T: TryFrom<Vec<u8>>>`-bound generic loader over any of the
1653/// substrate's closed-set typed enums — reaches the same four-arm
1654/// `PascalCase` wire accept-set through one trait dispatch.
1655///
1656/// Extends the substrate-wide trait-idiomatic *byte-owned reverse-
1657/// projection* family — opened on the structurally most fundamental
1658/// closed-set fieldless typed enum peer ([`crate::CaixaKind`], commit
1659/// 99c2849), extended onto the second caixa-core-internal peer
1660/// ([`crate::CaixaDialeto`], commit 83a1526) and the third
1661/// ([`crate::dep::DepList`], commit 42091cb) — onto the first M2-OTP-shape
1662/// supervisor-slot closed-set fieldless typed enum peer, tracking the
1663/// "delegate through `TryFrom<&[u8]>` on the `Vec<u8>::as_slice` borrow"
1664/// discipline the first-mover established. Every remaining closed-set
1665/// fieldless typed enum peer on the substrate ([`RestartPolicy`],
1666/// [`crate::aplicacao::PlacementStrategy`],
1667/// [`crate::aplicacao::RateLimitUnit`], [`crate::aplicacao::WitShape`],
1668/// [`crate::render::PathShapeViolation`], and the outside-`caixa-core`
1669/// peers `InvariantKind`, `ArchVerdict`, `Severity`, `FixSafety`,
1670/// `Semantic`, `FerriteRuntime`) is a future target of the campaign,
1671/// mirroring the trajectory the closed byte-view reverse-projection
1672/// family (`TryFrom<&[u8]>`) and the closed byte-owned forward-projection
1673/// family (`From<{Self, &Self}> for Vec<u8>`) already walked.
1674///
1675/// `type Error = ()` matches the sibling [`TryFrom<&[u8]> for
1676/// RestartStrategy`] unit-error shape, preserving the trait-family
1677/// consistency across the borrowed-and-owned byte-view reverse-projection
1678/// pair. The owned [`Vec<u8>`] input is dropped on the error path (the
1679/// standard-library `String::from_utf8` convention of returning the input
1680/// in the error deliberately declined — a caller that needs the bytes
1681/// back holds a clone before the call, and the closed-set-enum use site
1682/// rarely wants the raw bytes back past a "did you mean" diagnostic that
1683/// operates on the wire vocabulary rather than the input).
1684///
1685/// Pinned load-bearing by
1686/// [`tests::restart_strategy_try_from_vec_bytes_routes_through_borrowed_byte_view_axis`]
1687/// (byte-parity pin against the paired borrowed [`TryFrom<&[u8]>`] axis
1688/// across the four-arm [`RestartStrategy::ALL`] accept-set on the owned
1689/// byte-vec surface, cross-axis witness that the byte-owned reverse
1690/// projection agrees with the paired str-view reverse-projection axis
1691/// ([`TryFrom<&str>`]) on every accepted arm through the shared
1692/// substrate-primitive [`RestartStrategy::from_wire`] accessor, and a
1693/// four-corner {owned-input, borrowed-input} × {`From<Self>` → `Vec<u8>`,
1694/// `From<&Self>` → `Vec<u8>`} round-trip witness available on this enum
1695/// because [`RestartStrategy::as_str`] and [`RestartStrategy::from_wire`]
1696/// share one `PascalCase` byte-vocabulary — unlike the sibling
1697/// [`crate::CaixaKind`] which its peer test deliberately declines the
1698/// four-corner witness on because the wire/diagnostic split makes the
1699/// forward and reverse pairs speak different byte-strings) and
1700/// [`tests::restart_strategy_try_from_vec_bytes_rejects_unknown_and_non_utf8_bytes`]
1701/// (rejection witness against silent accept-set widening on both the
1702/// non-UTF-8 byte-sequence rejection path and the unknown-wire-vocabulary
1703/// rejection path — the latter includes the sibling kebab-case
1704/// dispatcher-catalog byte-strings on the two-axis wire/catalog split so
1705/// a caller that confuses the two axes trips here rather than at a
1706/// downstream K8s-CR round-trip miss, plus a cross-axis witness that the
1707/// owned byte-vec reverse-projection axis agrees with the borrowed byte-
1708/// slice reverse-projection axis on every rejected input).
1709impl TryFrom<Vec<u8>> for RestartStrategy {
1710 type Error = ();
1711
1712 fn try_from(bytes: Vec<u8>) -> Result<Self, Self::Error> {
1713 <Self as TryFrom<&[u8]>>::try_from(bytes.as_slice())
1714 }
1715}
1716
1717/// Trait-idiomatic *owned-`String` input, `Result<Self, ()>` output*
1718/// string-owned reverse projection on the first M2-OTP-shape supervisor-slot
1719/// closed-set fieldless typed enum peer on the caixa surface
1720/// ([`RestartStrategy`]) — the owned-input peer of the paired
1721/// [`TryFrom<&str> for RestartStrategy`] str-view reverse-projection axis, and
1722/// the string-owned reverse companion of the pre-existing string-owned
1723/// *forward* pair ([`From<RestartStrategy> for String`],
1724/// [`From<&RestartStrategy> for String`]) already lifted on this same enum.
1725/// Routes owned [`String`] input through the paired borrowed-input
1726/// [`TryFrom<&str>`] axis via [`String::as_str`] so every consumer that holds
1727/// an owned `String` — a future M4 `mesh.pleme.io/v1alpha1/Supervisor` CR
1728/// admission-webhook body reader that hands the `spec.estrategia`
1729/// `PascalCase` scalar off as an owned [`String`] after UTF-8 validation, a
1730/// `serde_yaml::from_str` / `serde_json::from_str` de-serialize round-trip
1731/// whose composer surfaces the `:estrategia` scalar as an owned [`String`]
1732/// typed field, a `feira supervisor --estrategia <OneForOne|OneForAll|
1733/// RestForOne|SimpleOneForOne>` `clap`-derived arg-parse whose owned-`String`
1734/// positional lands the canonical arm at the typed dispatch, a
1735/// per-`:supervisor`-slot overlay resolver reading an owned [`String`] out of
1736/// a `ConfigMap` `data.supervisor-estrategia` scalar, an
1737/// `<T: TryFrom<String>>`-bound generic loader over any of the substrate's
1738/// closed-set typed enums — reaches the same four-arm `PascalCase` accept-set
1739/// through one trait dispatch.
1740///
1741/// Extends the substrate-wide trait-idiomatic *string-owned reverse-
1742/// projection* family — opened on the compound M3-mesh
1743/// `:politicas :rate-limit` primitive [`crate::aplicacao::RateLimit`]
1744/// (a2e6f02), lifted onto the first closed-set fieldless typed-enum peer
1745/// [`crate::aplicacao::WitShape`] (e6aac29), extended onto the second closed-
1746/// set fieldless typed-enum peer [`crate::aplicacao::RateLimitUnit`]
1747/// (94a9c5e), extended onto the third closed-set fieldless typed-enum peer
1748/// [`crate::aplicacao::PlacementStrategy`] (d81a70a) — onto the first
1749/// M2-OTP-shape supervisor-slot closed-set fieldless typed-enum peer, the
1750/// per-`:supervisor` sibling-restart-strategy discriminator. The peers
1751/// [`RestartPolicy`], [`crate::CaixaKind`], [`crate::CaixaDialeto`], and
1752/// [`crate::dep::DepList`] remain the next targets of the campaign, mirroring
1753/// the trajectory the closed byte-view / byte-owned reverse-projection
1754/// families already walked across the same closed-set peers.
1755///
1756/// Rust's standard library carries no blanket
1757/// `impl<T: for<'a> TryFrom<&'a str>> TryFrom<String> for T`, so a consumer
1758/// that holds an owned [`String`] and needs a typed [`RestartStrategy`]
1759/// otherwise picks between (a) an open-coded
1760/// `<RestartStrategy as TryFrom<&str>>::try_from(s.as_str())` at every call
1761/// site whose type bounds have no compile-time link back to the string-owned
1762/// reverse-projection axis, (b) a `let s: &str = &s;
1763/// RestartStrategy::try_from(s)` two-step whose borrow arithmetic leaks a
1764/// per-call-site lifetime dance rather than a single trait dispatch, or (c) a
1765/// `String::into_bytes` + [`TryFrom<Vec<u8>>`] detour that reaches the
1766/// substrate-primitive `from_wire` accessor through a UTF-8 re-validation hop
1767/// the owned-`String` axis already knows to skip. This impl closes the
1768/// string-owned reverse-projection axis at the substrate-primitive
1769/// [`RestartStrategy::from_wire`] accessor so every future
1770/// `<T: TryFrom<String>>`-bound owned-string consumer reaches the same
1771/// four-arm `PascalCase` accept-set through one trait dispatch.
1772///
1773/// `type Error = ()` matches the sibling [`TryFrom<&str> for
1774/// RestartStrategy`], [`TryFrom<&[u8]> for RestartStrategy`], and
1775/// [`TryFrom<Vec<u8>> for RestartStrategy`] unit-error shapes, preserving the
1776/// trait-family consistency across the {str-view, byte-view, byte-owned,
1777/// string-owned} reverse-projection square. The owned [`String`] input is
1778/// dropped on the error path (the standard-library `String::from_utf8`
1779/// convention of returning the input in the error deliberately declined — a
1780/// caller that needs the string back holds a clone before the call, and the
1781/// closed-set-enum use site rarely wants the raw string back past a "did you
1782/// mean" diagnostic that operates on the wire vocabulary rather than the
1783/// input).
1784///
1785/// Pinned load-bearing by
1786/// [`tests::restart_strategy_try_from_owned_string_routes_through_borrowed_str_view_axis`]
1787/// (byte-parity pin against the paired borrowed [`TryFrom<&str>`] axis across
1788/// the four-arm [`RestartStrategy::ALL`] accept-set on the owned-`String`
1789/// surface, cross-axis witness that the string-owned reverse projection
1790/// agrees with the sibling byte-view / byte-owned reverse-projection axes on
1791/// every accepted arm through the shared substrate-primitive
1792/// [`RestartStrategy::from_wire`] accessor, and a closed-cycle witness
1793/// against the paired string-owned forward-projection pair — `Self → String
1794/// → TryFrom<String> → Self` round-trips to the originating arm on every
1795/// canonical `PascalCase` scalar) and
1796/// [`tests::restart_strategy_try_from_owned_string_rejects_unknown_wire_strings`]
1797/// (rejection witness against silent accept-set widening — mirrors the
1798/// corpus the paired [`TryFrom<&str>`] rejection witness already pins,
1799/// including empty / whitespace-only inputs, the sibling kebab-case
1800/// dispatcher-catalog byte-strings on the two-axis wire/catalog split so a
1801/// caller that confuses the two axes trips here rather than at a downstream
1802/// K8s-CR round-trip miss, case-fold rebrand candidates, whitespace-padded /
1803/// trailing-newline / quote-wrapped forms, and English-rebrand candidates,
1804/// with per-input cross-axis parity against the borrowed [`TryFrom<&str>`]
1805/// reverse-projection axis).
1806impl TryFrom<String> for RestartStrategy {
1807 type Error = ();
1808
1809 fn try_from(s: String) -> Result<Self, Self::Error> {
1810 <Self as TryFrom<&str>>::try_from(s.as_str())
1811 }
1812}
1813
1814/// Per-child restart policy.
1815///
1816/// Permanent / Temporary / Transient match Erlang/OTP semantics 1:1.
1817#[derive(
1818 Serialize,
1819 Deserialize,
1820 Debug,
1821 Clone,
1822 Copy,
1823 PartialEq,
1824 Eq,
1825 Hash,
1826 gen_platform::TypedDispatcher,
1827 gen_platform::Discriminant,
1828 gen_platform::IsVariant,
1829 gen_platform::FromStrKind,
1830)]
1831pub enum RestartPolicy {
1832 /// Always restart the child, regardless of how it died. Used for
1833 /// long-running services that must always be up.
1834 Permanent,
1835 /// Never restart. Used for one-shot work whose completion is
1836 /// itself the success signal (`oneShot` triggers map here).
1837 Temporary,
1838 /// Restart only when the child died *abnormally* (non-zero exit
1839 /// or unhandled exception). A clean exit completes the child.
1840 Transient,
1841}
1842
1843impl Default for RestartPolicy {
1844 fn default() -> Self {
1845 // Route the [`Default for RestartPolicy`] impl's return arm through
1846 // the substrate-canonical [`SUPERVISOR_CHILD_RESTART_DEFAULT`] typed
1847 // `pub const` rather than a raw `Self::Permanent` arm — one source
1848 // of truth for the Erlang/OTP-canonical `permanent` worker-child
1849 // default across the two production consumers that currently
1850 // dispatch on it (this impl at the [`RestartPolicy::default`] call
1851 // and the serde-side `#[serde(default)]` on
1852 // [`ChildSpec::restart`] that resolves an author-omitted
1853 // `:children :restart` slot through `RestartPolicy::default()`).
1854 // Peer of the sibling per-`:supervisor` axis
1855 // [`Default for RestartStrategy`] → [`SUPERVISOR_ESTRATEGIA_DEFAULT`]
1856 // route (95ffacc) — the two impls now share one substrate-primitive
1857 // lift discipline, so any future coherent rebrand of the OTP-shape
1858 // supervisor+child default set migrates through typed constants in
1859 // lockstep instead of splitting a lifted supervisor half against
1860 // an open-coded child half. Pinned by
1861 // `restart_policy_default_routes_through_lifted_default` +
1862 // `child_spec_serde_default_restart_routes_through_lifted_default`
1863 // in the tests module.
1864 SUPERVISOR_CHILD_RESTART_DEFAULT
1865 }
1866}
1867
1868impl RestartPolicy {
1869 /// Exhaustive iteration surface for every consumer that walks the
1870 /// closed three-arm [`RestartPolicy`] discriminator set (the future
1871 /// M4 `mesh.pleme.io/v1alpha1/Supervisor` CR materializer's
1872 /// per-child admission-webhook rejection body naming the accepted-
1873 /// `:restart` list, a future `feira supervisor --restart …` CLI
1874 /// arg-parse's "did you mean" hint via a [`Self::from_wire`]-scan
1875 /// over the slice, the future `feira app graph` per-child restart
1876 /// column, any future round-trip fuzz harness that sweeps every
1877 /// arm). A future arm addition (an OTP-`intrinsic` fourth arm the
1878 /// theory
1879 /// [`ABSORPTION-ROADMAP`](https://github.com/pleme-io/theory/blob/main/ABSORPTION-ROADMAP.md)
1880 /// might reach for once the three canonical OTP restart policies
1881 /// stop covering the substrate's discovered load-shape) extends
1882 /// this slice as one edit and every consumer picks up the new entry
1883 /// by construction; the compiler-checked exhaustiveness on the
1884 /// sibling method `match` arms ([`Self::as_str`] / [`Self::from_wire`])
1885 /// is the build-time guarantee that no arm forgets to grow.
1886 ///
1887 /// Peer of the sibling closed-set typed enums'
1888 /// [`RestartStrategy::ALL`] (4eec29c) /
1889 /// [`crate::CaixaKind::ALL`] (6b1f4fb) /
1890 /// [`crate::aplicacao::PlacementStrategy::ALL`] (18c7342) /
1891 /// [`crate::aplicacao::RateLimitUnit::ALL`] (6bce03d) /
1892 /// [`crate::dep::DepList::ALL`] (45ee563) exhaustive-iteration
1893 /// surfaces — the sixth (and the third and final M2 OTP-shape)
1894 /// closed-set typed enum on the caixa surface to converge onto the
1895 /// same one-canonical-arm-list-per-enum discipline. Sibling axis to
1896 /// the peer [`RestartStrategy::ALL`] on the per-supervisor
1897 /// sibling-restart-strategy axis; this closes the per-child
1898 /// restart-decision-policy axis on the same M2 `:supervisor` slot.
1899 pub const ALL: &'static [Self] = &[Self::Permanent, Self::Temporary, Self::Transient];
1900
1901 /// Substrate-canonical exhaustive accept-set on the [`RestartPolicy`]
1902 /// `PascalCase` wire byte-string axis — the closed three-arm roster
1903 /// of every byte-string [`Self::as_str`] returns, routed byte-for-byte
1904 /// through the paired
1905 /// [`crate::render::SUPERVISOR_CHILD_RESTART_PERMANENT`] /
1906 /// [`crate::render::SUPERVISOR_CHILD_RESTART_TEMPORARY`] /
1907 /// [`crate::render::SUPERVISOR_CHILD_RESTART_TRANSIENT`] lifted
1908 /// `pub const` roster the [`Self::as_str`] emitter (and the
1909 /// [`std::fmt::Display`] impl / `Serialize` derive routed through it)
1910 /// walks — and byte-for-byte the same three strings the un-`rename`d
1911 /// `Serialize` derive emits under the paired
1912 /// [`crate::render::SUPERVISOR_CHILD_KEY_RESTART`] tag key on every
1913 /// JSON / YAML CR round-trip.
1914 ///
1915 /// Peer of the sibling [`crate::CaixaKind::WIRE_NAMES`] (bd708bd)
1916 /// roster on the top-level typed-kind discriminator's `PascalCase`
1917 /// wire byte-string axis, the sibling
1918 /// [`RestartStrategy::WIRE_NAMES`] (3033f45) roster on the per-
1919 /// supervisor sibling-restart-strategy axis (the first M2 OTP-shape
1920 /// closed-set typed enum to converge onto the paired-roster
1921 /// discipline), the sibling
1922 /// [`crate::aplicacao::PlacementStrategy::WIRE_NAMES`] (3e5b194)
1923 /// roster on the first M3 mesh-shape distribution-strategy closed-
1924 /// set typed enum, and the sibling
1925 /// [`crate::upgrade::UpgradeInstruction::WIRE_FORMS`] (cc42c0e) /
1926 /// [`crate::upgrade::UpgradeInstruction::LISP_FORMS`] (1898d77)
1927 /// rosters on the OTP-appup discriminator's two-axis roster split —
1928 /// the same closed-set exhaustive-accept-set roster discipline
1929 /// extended here onto the second and final M2 OTP-shape sibling-
1930 /// enum on the caixa surface, closing the per-child restart-decision-
1931 /// policy axis paired with the peer [`RestartStrategy::WIRE_NAMES`]
1932 /// per-supervisor sibling-restart-strategy axis on the same M2
1933 /// `:supervisor` slot.
1934 ///
1935 /// Downstream consumers of the closed accepted-wire-form set — a
1936 /// future M4 `mesh.pleme.io/v1alpha1/Supervisor` CR admission-
1937 /// webhook rejection body enumerating the accepted JSON `:restart`
1938 /// values verbatim (as distinct from the kebab-case dispatcher-
1939 /// catalog enumeration [`Self::discriminant`] serves, whose per-arm
1940 /// form `"permanent"` / `"temporary"` / `"transient"` structurally
1941 /// disagrees with the wire byte-string these `PascalCase` entries
1942 /// carry — the split the sibling
1943 /// [`tests::restart_policy_display_matches_serialized_wire_byte_string`]
1944 /// pin already makes load-bearing), a future `feira supervisor
1945 /// --restart …` CLI-side "did you mean" hint whose candidate-list
1946 /// must byte-match the wire form the operator's per-child dispatch
1947 /// keys off, a future `feira app graph` per-child `:restart`-
1948 /// histogram column that renders zero-count arms, a future
1949 /// `caixa-operator` per-reconcile-step diagnostic log line
1950 /// enumerating accepted wire forms on an unknown-policy rejection,
1951 /// a future
1952 /// `tracing::field::valuable::Value::List` structured-log accepted-
1953 /// wire-form emit — now reach for one lifted substrate-primitive
1954 /// roster rather than open-coding a three-string array-literal
1955 /// (`["Permanent", "Temporary", "Transient"]`) whose arm-set has no
1956 /// compile-time link back to the typed [`RestartPolicy`] enum. A
1957 /// future arm addition (an OTP-`intrinsic` fourth arm the theory
1958 /// [`ABSORPTION-ROADMAP`](https://github.com/pleme-io/theory/blob/main/ABSORPTION-ROADMAP.md)
1959 /// might reach for once the three canonical OTP restart policies
1960 /// stop covering the substrate's discovered load-shape) extends
1961 /// this roster as a single edit — paired with the [`Self::as_str`]
1962 /// match's compiler-checked exhaustiveness on the new arm — and
1963 /// every consumer picks up the new wire form by construction rather
1964 /// than a coordinated array-literal rewrite across every downstream
1965 /// site.
1966 ///
1967 /// Length is pinned load-bearing at `RestartPolicy::ALL.len()`
1968 /// (three) by
1969 /// [`tests::restart_policy_wire_names_covers_every_arm`], every
1970 /// variant's [`Self::as_str`] projection is pinned to a member of
1971 /// the roster so a silent skew between the emitter's arm-set and
1972 /// this const's arm-set trips at caixa-core test time rather than at
1973 /// a downstream consumer's accepted-set enumeration miss, and every
1974 /// entry is further pinned to open with an ASCII uppercase byte so
1975 /// a silent collapse of the `PascalCase` wire-form axis with the
1976 /// peer kebab-case dispatcher-catalog axis (an entry byte-identical
1977 /// to a sibling [`Self::discriminant`] kebab byte-string that would
1978 /// let a wire-axis consumer accept the dispatcher-catalog
1979 /// vocabulary) trips here rather than at a downstream K8s-CR round-
1980 /// trip miss.
1981 pub const WIRE_NAMES: &'static [&'static str] = &[
1982 crate::render::SUPERVISOR_CHILD_RESTART_PERMANENT,
1983 crate::render::SUPERVISOR_CHILD_RESTART_TEMPORARY,
1984 crate::render::SUPERVISOR_CHILD_RESTART_TRANSIENT,
1985 ];
1986
1987 /// Canonical PascalCase discriminator scalar this variant serializes
1988 /// as under [`crate::render::SUPERVISOR_CHILD_KEY_RESTART`]. The three
1989 /// arms return the paired
1990 /// [`crate::render::SUPERVISOR_CHILD_RESTART_PERMANENT`] /
1991 /// [`crate::render::SUPERVISOR_CHILD_RESTART_TEMPORARY`] /
1992 /// [`crate::render::SUPERVISOR_CHILD_RESTART_TRANSIENT`] lifted
1993 /// constants so every substrate consumer that dispatches on the
1994 /// per-child restart-decision policy (the future wasm-operator's
1995 /// per-child post-exit restart-decision branch, the future M4
1996 /// `mesh.pleme.io/v1alpha1/Supervisor` CR materializer's
1997 /// admission-time enum-arm bind, the `caixa-operator`'s hierarchical
1998 /// reconciliation scheduler's per-child-policy fan-out) reads the
1999 /// same byte-string the `Serialize` derive emits — the pin test in
2000 /// [`tests::restart_policy_variants_serialize_to_lifted_scalar_values`]
2001 /// asserts the two paths agree, peer of the M2
2002 /// [`RestartStrategy::as_str`] (09ffb2d) on the sibling per-supervisor
2003 /// sibling-restart-strategy axis and the M3
2004 /// [`crate::aplicacao::PlacementStrategy::as_str`] (cc8f749) on the
2005 /// per-Aplicacao distribution-strategy axis — the third of three
2006 /// OTP-shaped closed-enum discriminator axes on the caixa typed
2007 /// surface to converge onto the same three-path-convergence
2008 /// (`Serialize` derive → `as_str` helper → lifted constant)
2009 /// drift-detection posture.
2010 #[must_use]
2011 pub const fn as_str(self) -> &'static str {
2012 match self {
2013 Self::Permanent => crate::render::SUPERVISOR_CHILD_RESTART_PERMANENT,
2014 Self::Temporary => crate::render::SUPERVISOR_CHILD_RESTART_TEMPORARY,
2015 Self::Transient => crate::render::SUPERVISOR_CHILD_RESTART_TRANSIENT,
2016 }
2017 }
2018
2019 /// Substrate-canonical reverse projection on the `:children :restart`
2020 /// closed-set axis — parses the `PascalCase` discriminator scalar
2021 /// back to the typed variant, or `None` when `s` is outside the
2022 /// closed-set arm-string set [`Self::as_str`] emits. Dispatches on
2023 /// the same lifted
2024 /// [`crate::render::SUPERVISOR_CHILD_RESTART_PERMANENT`] /
2025 /// [`crate::render::SUPERVISOR_CHILD_RESTART_TEMPORARY`] /
2026 /// [`crate::render::SUPERVISOR_CHILD_RESTART_TRANSIENT`] constants
2027 /// the [`Self::as_str`] emitter walks, so the parse and emit halves
2028 /// of the round-trip migrate through one caixa-core edit on any
2029 /// future arm addition.
2030 ///
2031 /// Prior to this lift the substrate carried only the forward
2032 /// `Self → &str` projection on the OTP per-child restart-policy
2033 /// axis (the [`Self::as_str`] emitter, the [`std::fmt::Display`]
2034 /// impl routed through it, the `Serialize` derive that emits the
2035 /// same byte-string under [`crate::render::SUPERVISOR_CHILD_KEY_RESTART`])
2036 /// plus the kebab-case dispatcher-catalog identity via
2037 /// [`Self::discriminant`] — every non-serde consumer that wanted to
2038 /// parse a wire-form `PascalCase` policy scalar had to re-inline a
2039 /// three-arm `match s { "Permanent" => …, "Temporary" => …,
2040 /// "Transient" => …, _ => … }` cascade that expressed no
2041 /// compile-time link back to the typed variant's canonical lifted
2042 /// constant. A future variant rename or per-arm serde-attribute
2043 /// drift would silently split the wire byte-string one non-serde
2044 /// consumer parsed from the one the emitter wrote, with the failure
2045 /// surfacing at the operator's reconcile posture (a `:temporary`
2046 /// `oneShot` child being restarted on clean exit, treating the
2047 /// successful-completion signal as failure and re-running the
2048 /// completion-terminal one-shot indefinitely; a `:transient` child
2049 /// that clean-exited being restarted, masking the clean-completion
2050 /// contract) far from the rebrand commit and with no field naming
2051 /// the drift.
2052 ///
2053 /// Distinct axis from the [`std::str::FromStr`] impl the
2054 /// [`gen_platform::FromStrKind`] derive already installs on this
2055 /// enum by design, not by drift: `FromStr` parses the *kebab-case*
2056 /// dispatcher-catalog identity (`"permanent"` / `"temporary"` /
2057 /// `"transient"` — the inverse of [`Self::discriminant`]), while
2058 /// this method inverts the `PascalCase` wire byte-string
2059 /// [`Self::as_str`] emits. The two-axis split lets the dispatcher-
2060 /// catalog identity live in kebab-case (where every peer catalog
2061 /// identifier already lives) without forcing a wire-format rename
2062 /// on the tatara-lisp author surface (`:restart Permanent`,
2063 /// `PascalCase`) — the same two-axis distinction the sibling
2064 /// [`RestartStrategy::from_wire`] (4eec29c) /
2065 /// [`crate::CaixaKind::from_wire`] (2aa6d23) /
2066 /// [`crate::aplicacao::PlacementStrategy::from_wire`] (18c7342)
2067 /// carry on their peer closed-set typed-enum wire round-trips.
2068 ///
2069 /// Same closed-set-reverse-projection discipline the sibling
2070 /// [`RestartStrategy::from_wire`] (4eec29c) /
2071 /// [`crate::CaixaKind::from_wire`] (2aa6d23) /
2072 /// [`crate::aplicacao::PlacementStrategy::from_wire`] (18c7342) /
2073 /// [`crate::aplicacao::RateLimitUnit::from_suffix`] typed enums
2074 /// carry on the peer wire-side `str → Self` axes — extended onto
2075 /// the M2 OTP-shape per-child restart-policy closed-set axis, the
2076 /// sixth substrate-side closed-set typed enum (and the third and
2077 /// final OTP-shape closed-enum discriminator axis) to converge on
2078 /// the two-way `str ↔ Self` round-trip. Method-named `from_wire`
2079 /// (not `from_str`) to match the peer [`RestartStrategy::from_wire`]
2080 /// shape verbatim and side-step the [`std::str::FromStr`] impl the
2081 /// derive already installs on the sibling kebab-case axis. Returns
2082 /// `Option<Self>` (rather than `Result<Self, _>`) to match the peer
2083 /// shapes: the caller picks the diagnostic form appropriate for
2084 /// its use site.
2085 #[must_use]
2086 pub fn from_wire(s: &str) -> Option<Self> {
2087 match s {
2088 crate::render::SUPERVISOR_CHILD_RESTART_PERMANENT => Some(Self::Permanent),
2089 crate::render::SUPERVISOR_CHILD_RESTART_TEMPORARY => Some(Self::Temporary),
2090 crate::render::SUPERVISOR_CHILD_RESTART_TRANSIENT => Some(Self::Transient),
2091 _ => None,
2092 }
2093 }
2094}
2095
2096/// [`std::fmt::Display`] routed through [`RestartPolicy::as_str`], so the
2097/// pretty-printed byte-string every consumer that formats the policy as
2098/// user-facing text lands on (the future wasm-operator's per-child
2099/// post-exit restart-decision diagnostic line, the future `feira app
2100/// graph` per-child restart column, the future M4
2101/// `mesh.pleme.io/v1alpha1/Supervisor` CR materializer's per-child
2102/// admission-webhook rejection body) reaches for the same lifted
2103/// [`crate::render::SUPERVISOR_CHILD_RESTART_PERMANENT`] /
2104/// [`crate::render::SUPERVISOR_CHILD_RESTART_TEMPORARY`] /
2105/// [`crate::render::SUPERVISOR_CHILD_RESTART_TRANSIENT`] const the
2106/// wire-format `Serialize` derive already emits under
2107/// [`crate::render::SUPERVISOR_CHILD_KEY_RESTART`] and the
2108/// [`RestartPolicy::as_str`] helper already returns.
2109///
2110/// Pre-convergence the two paths structurally disagreed — the
2111/// `#[derive(gen_platform::Discriminant)]` + `#[discriminant(also_display)]`
2112/// route (now retired here) sent [`std::fmt::Display`] through the
2113/// gen-platform discriminant catalog string, which arrives kebab-case as
2114/// `"permanent"` / `"temporary"` / `"transient"` on this three-arm enum
2115/// (whose variant names each collapse to their own lowercase form under
2116/// the kebab-case transform), while the wire format ran as `PascalCase`
2117/// `"Permanent"` / `"Temporary"` / `"Transient"` through the un-`rename`d
2118/// serde derive. Every consumer that formatted the policy for a
2119/// diagnostic line, a graph column, or a rejection body under
2120/// `format!("{v}")` therefore landed under a different byte-string than
2121/// the wire format the operator's per-child-policy dispatch keyed off —
2122/// a silent split whose apply-time symptom (a `format!("{v}")`-carrying
2123/// diagnostic quoting `"permanent"` while the wire scalar the operator
2124/// probed was `"Permanent"`) surfaced as a confused correlate at
2125/// operator-log time far from the two-declaration site.
2126///
2127/// Routing `Display` through [`RestartPolicy::as_str`] closes the third
2128/// path: every `format!("{v}")` call reaches the same lifted
2129/// [`crate::render::SUPERVISOR_CHILD_RESTART_*`] const the wire format
2130/// and the [`RestartPolicy::as_str`] helper route through — `Debug` (the
2131/// compiler-derived variant name), `Display` (via `as_str`), and `Serialize`
2132/// (via the un-`rename`d derive) all resolve to the same `PascalCase`
2133/// byte-string per variant. A future variant rename or
2134/// `#[serde(rename_all = "kebab-case")]` attribute reaches every path at
2135/// exactly one place, structurally.
2136///
2137/// The dispatcher-catalog identity remains kebab-case — [`Self::discriminant`]
2138/// (from `#[derive(gen_platform::Discriminant)]`) still returns
2139/// `"permanent"` / `"temporary"` / `"transient"`, and the fleet-wide
2140/// [`gen_platform::register_dispatcher!("caixa.restart-policy", …)`]
2141/// registration keys the catalog off the same kebab identity. The two
2142/// naming worlds now live on separate typed methods (`Display` /
2143/// `as_str` for the wire byte-string, `discriminant` for the catalog
2144/// identity) rather than sharing one `Display` route that structurally
2145/// disagrees with the wire format.
2146///
2147/// Pin tests
2148/// [`tests::restart_policy_display_routes_through_as_str_helper`]
2149/// and
2150/// [`tests::restart_policy_display_matches_serialized_wire_byte_string`]
2151/// assert the three paths agree byte-for-byte on every variant, so a
2152/// future variant rename or per-arm serde attribute drift is a build
2153/// error visible at caixa-core test time, not a silent per-consumer
2154/// dispatch miss at apply / reconcile time.
2155///
2156/// Mirrors the M3 [`crate::aplicacao::PlacementStrategy`] `Display` impl
2157/// (aplicacao.rs:2306) on the per-Aplicacao distribution-strategy axis
2158/// and the sibling [`RestartStrategy`] `Display` impl on the
2159/// per-supervisor sibling-restart-strategy axis — same three-path-
2160/// convergence discipline, extended to close the third and final of
2161/// three OTP-shaped closed-enum discriminator axes on the caixa typed
2162/// surface.
2163impl std::fmt::Display for RestartPolicy {
2164 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
2165 f.write_str(self.as_str())
2166 }
2167}
2168
2169/// Substrate-canonical [`AsRef<str>`] projection on the M2
2170/// per-child-restart-policy [`RestartPolicy`] closed-set typed enum —
2171/// routes through the same [`RestartPolicy::as_str`] `pub const fn`
2172/// scalar accessor the paired [`std::fmt::Display`] impl and the
2173/// un-`rename`d [`serde::Serialize`] derive already key off, so any
2174/// future consumer that binds a [`RestartPolicy`] through the
2175/// standard-library `impl AsRef<str>` bound (a future
2176/// [`caixa-feira`] `feira supervisor --restart <arm>` verb that
2177/// composes the emitted `PascalCase` wire scalar into a
2178/// [`std::process::Command::arg`] shell-out of the future
2179/// wasm-operator's per-child admission gate, a per-child structured-
2180/// log recorder on the future `caixa-operator`'s hierarchical
2181/// reconciliation surface that accepts `impl AsRef<str>` at the
2182/// `tracing::field::Value` `Str`-arm, a [`std::collections::HashMap`]
2183/// lookup keyed on the restart-policy wire byte through
2184/// `map.get::<str>(policy.as_ref())` on a future per-policy
2185/// dispatch table) reaches the paired
2186/// [`crate::render::SUPERVISOR_CHILD_RESTART_PERMANENT`] /
2187/// [`crate::render::SUPERVISOR_CHILD_RESTART_TEMPORARY`] /
2188/// [`crate::render::SUPERVISOR_CHILD_RESTART_TRANSIENT`]
2189/// lifted-const through one substrate-primitive dispatch rather
2190/// than an open-coded `.as_str()` projection at every wire-up.
2191///
2192/// Peer of the sibling [`std::fmt::Display`] impl on the same
2193/// primitive — both delegate to the shared [`RestartPolicy::as_str`]
2194/// `pub const fn` accessor, so [`format!("{v}")`], `v.as_str()`, and
2195/// `<RestartPolicy as AsRef<str>>::as_ref(&v)` resolve to the same
2196/// byte-string per instance by construction. A future variant rename
2197/// or `#[serde(rename_all = "kebab-case")]` attribute-drift on the
2198/// enum reaches every one of the three paths (plus the wire-format
2199/// `Serialize` derive that already routes through the same lifted
2200/// const) through exactly one caixa-core edit.
2201///
2202/// Same "route the trait impl through the substrate-primitive
2203/// accessor" discipline the sibling [`crate::CaixaVersion`]
2204/// [`AsRef<str>`] impl (16d5c7e) and the paired M2
2205/// [`RestartStrategy`] [`AsRef<str>`] impl (63eb1a4) carry — extends
2206/// the axis onto the paired per-child-restart-decision-policy
2207/// sibling on the same M2 `:supervisor` slot (the second M2
2208/// OTP-shape closed-set typed enum to converge onto the standard-
2209/// library [`AsRef<str>`] projection). Rust-side newtype/typed-enum
2210/// convention pairs [`AsRef<str>`] and [`fmt::Display`] on the same
2211/// primitive so a caller who has one has both; before this lift,
2212/// [`RestartPolicy`] carried [`fmt::Display`] but not the paired
2213/// [`AsRef<str>`] impl the convention names.
2214///
2215/// Pinned load-bearing by
2216/// [`tests::restart_policy_as_ref_str_routes_through_as_str_accessor`]
2217/// (byte-parity pin against [`RestartPolicy::as_str`] across the
2218/// three-arm closed set) and
2219/// [`tests::restart_policy_as_ref_str_routes_through_display_via_shared_accessor`]
2220/// (three-path convergence: `AsRef<str>` + `Display` + `as_str` all
2221/// resolve to the same lifted `SUPERVISOR_CHILD_RESTART_*` const per
2222/// arm) — any future silent detour that routes the impl through a
2223/// divergent projection (a per-arm inline `match self { … }`
2224/// re-inlining that opens a compile-time link to the un-lifted
2225/// arm-literal, a swap onto the kebab-case
2226/// [`gen_platform::Discriminant`] catalog identity that would
2227/// collide the wire axis with the dispatcher-catalog axis) trips at
2228/// caixa-core test time under `assert_eq!` rather than at a
2229/// downstream `impl AsRef<str>`-bound consumer's silent split.
2230impl AsRef<str> for RestartPolicy {
2231 fn as_ref(&self) -> &str {
2232 self.as_str()
2233 }
2234}
2235
2236/// Trait-idiomatic reverse projection on the M2-OTP-shape per-child
2237/// restart-policy [`RestartPolicy`] closed-set typed enum — routes
2238/// byte-for-byte through the paired substrate-primitive
2239/// [`RestartPolicy::from_wire`] `Option<Self>` accessor so every future
2240/// consumer that binds a `PascalCase` `:children :restart` wire
2241/// byte-string through the standard-library `.try_into()` / [`TryFrom`]
2242/// axis (a future [`caixa-feira`] `feira supervisor --restart
2243/// <Permanent|Temporary|Transient>` CLI arg-parse that composes into
2244/// `let restart: RestartPolicy = s.try_into()?`, a future
2245/// `mesh.pleme.io/v1alpha1/Supervisor` CR admission-webhook that folds a
2246/// `spec.children[*].restart: String` field through
2247/// `RestartPolicy::try_from(&s)?`, a generic
2248/// `<T: TryFrom<&str>>`-bound loader over any of the substrate's closed-
2249/// set typed enums) reaches the same three-arm accept-set the sibling
2250/// [`RestartPolicy::from_wire`] resolver parses through and the sibling
2251/// [`RestartPolicy::as_str`] emits, rather than an open-coded per-arm
2252/// `match s { "Permanent" => …, "Temporary" => …, "Transient" => …, _ =>
2253/// … }` cascade whose arm-set has no compile-time link back to the
2254/// substrate primitive.
2255///
2256/// Complements the pre-existing forward-projection triple
2257/// ([`std::fmt::Display`], [`AsRef<str>`], [`RestartPolicy::as_str`])
2258/// with the paired trait-idiomatic reverse-projection axis: Rust-side
2259/// newtype/typed-enum convention pairs [`AsRef<str>`] with either
2260/// [`std::str::FromStr`] or [`TryFrom<&str>`] on the same primitive so a
2261/// caller who can project *out to* a `&str` can also project *in from*
2262/// one. The [`TryFrom<&str>`] axis is deliberately chosen over
2263/// [`std::str::FromStr`] to sidestep the `clippy::should_implement_trait`
2264/// lint the sibling method-named [`RestartPolicy::from_wire`] would
2265/// trigger under a `FromStr` impl and to avoid colliding with the
2266/// [`std::str::FromStr`] impl the [`gen_platform::FromStrKind`] derive
2267/// already installs on the paired *kebab-case dispatcher-catalog* axis
2268/// (which parses `"permanent"` / `"temporary"` / `"transient"`, the
2269/// inverse of [`Self::discriminant`]) — this impl closes the trait-
2270/// idiomatic reverse axis on the *`PascalCase` wire* half without
2271/// disturbing either the method-named `from_wire` shape every sibling
2272/// closed-set typed enum on the substrate already carries or the
2273/// pre-existing `FromStr` on the dispatcher-catalog half, keeping the
2274/// two-axis split the sibling [`Self::from_wire`] doc block motivates.
2275///
2276/// `type Error = ()` matches the sibling [`RestartPolicy::from_wire`]'s
2277/// `Option<Self>` return-shape's deliberate deferral of error typing: the
2278/// caller picks the diagnostic form appropriate for its use site (a
2279/// future `feira supervisor --restart` arg-parse composes its own
2280/// per-verb "unknown restart: <arg> — accepted: {…}" message enumerating
2281/// [`RestartPolicy::ALL`], a future M4 admission-webhook rejection body
2282/// wraps the `Err(())` outcome with the accepted-set enumeration for
2283/// operator diagnostics, a `Result::map_err` at the call site lifts the
2284/// unit-error to a per-verb error type). Same shape the peer
2285/// [`RestartStrategy`] (5b828ed) on the sibling per-supervisor axis,
2286/// [`crate::CaixaKind`] (3c83606), [`crate::CaixaDialeto`] (bf33136), and
2287/// [`crate::aplicacao::PlacementStrategy`] (6fd00cd) blocks motivate on
2288/// their peer closed-set typed enums' reverse projections.
2289///
2290/// The paired [`TryFrom<&str>`] impl reaches the same three-arm accept-
2291/// set the [`RestartPolicy::from_wire`] resolver dispatches through, so
2292/// any future arm addition (an OTP-`intrinsic` fourth arm the theory
2293/// [`ABSORPTION-ROADMAP`](https://github.com/pleme-io/theory/blob/main/ABSORPTION-ROADMAP.md)
2294/// might reach for once the three canonical OTP restart policies stop
2295/// covering the substrate's discovered load-shape) grows the trait-
2296/// idiomatic axis by construction — one caixa-core edit on
2297/// [`RestartPolicy::from_wire`] extends both the method-named reverse
2298/// projection every existing consumer keys off and the trait-idiomatic
2299/// reverse projection this impl exposes, without a coordinated rewrite
2300/// across every future `TryFrom<&str>`-bound consumer's arm-set.
2301///
2302/// Extends the substrate-wide closed-set-enum reverse-projection family
2303/// ([`crate::CaixaKind`] via 3c83606, [`crate::CaixaDialeto`] via
2304/// bf33136, [`crate::aplicacao::PlacementStrategy`] via 6fd00cd, and
2305/// [`RestartStrategy`] via 5b828ed) onto the third and final OTP-shape
2306/// closed-enum discriminator axis on the caixa surface — the paired
2307/// per-child `:children :restart` closed set the future wasm-operator's
2308/// hierarchical reconciliation scheduler's per-child post-exit
2309/// restart-decision branch keys off end-to-end.
2310///
2311/// Pinned load-bearing by
2312/// [`tests::restart_policy_try_from_str_routes_through_from_wire_accessor`]
2313/// (byte-parity pin against [`RestartPolicy::from_wire`] across the
2314/// three-arm accept-set),
2315/// [`tests::restart_policy_try_from_str_rejects_unknown_byte_strings`]
2316/// (rejection witness against silent accept-set widening), and
2317/// [`tests::restart_policy_try_from_str_and_from_wire_partition_the_accept_set`]
2318/// (cross-axis partition pin locking the trait and method-named
2319/// projections onto one accept-set).
2320impl TryFrom<&str> for RestartPolicy {
2321 type Error = ();
2322
2323 fn try_from(s: &str) -> Result<Self, Self::Error> {
2324 Self::from_wire(s).ok_or(())
2325 }
2326}
2327
2328/// Trait-idiomatic forward projection on the M2-OTP-shape per-child
2329/// restart-policy [`RestartPolicy`] closed-set typed enum — routes
2330/// byte-for-byte through the paired substrate-primitive
2331/// [`RestartPolicy::as_str`] `pub const fn` accessor. Return type is
2332/// `&'static str` by construction — every [`RestartPolicy::as_str`] arm
2333/// resolves to a [`crate::render::SUPERVISOR_CHILD_RESTART_*`] `pub const
2334/// &str` with `'static` lifetime, so the trait's return-type promise is
2335/// upheld structurally without a [`String::leak`] cast or a per-arm inline
2336/// literal.
2337///
2338/// Every future consumer that specifically needs `&'static str` lifetime
2339/// bytes on the per-child restart-decision axis (a
2340/// [`tracing::field::valuable::Value::Str`] recording where the `Str`
2341/// arm's typing demands `&'static str`, a
2342/// [`std::borrow::Cow::Borrowed`]`::<'static, str>(policy.into())` composer
2343/// on the future M4 admission-webhook rejection body where the
2344/// `Cow<'static, str>` typing rules out the sibling [`AsRef<str>`]
2345/// borrowed return, a generic `<T: Into<&'static str>>`-bound serializer
2346/// or error formatter that requires the `'static` bound) reaches the same
2347/// lifted [`crate::render::SUPERVISOR_CHILD_RESTART_PERMANENT`] /
2348/// [`crate::render::SUPERVISOR_CHILD_RESTART_TEMPORARY`] /
2349/// [`crate::render::SUPERVISOR_CHILD_RESTART_TRANSIENT`] substrate-
2350/// primitive dispatch rather than an open-coded per-arm literal cascade
2351/// whose arm-set has no compile-time link back to the substrate primitive.
2352///
2353/// Peer of the sibling M2-OTP-shape [`RestartStrategy`] forward-projection
2354/// impl (523157d) on the per-supervisor sibling-restart-strategy axis —
2355/// the second (and second-of-two-in-M2) closed-set typed enum on the
2356/// caixa surface to converge onto the paired trait-idiomatic forward-
2357/// projection axis. With this lift the paired per-child
2358/// `:children :restart` closed-set typed enum carries the full sibling
2359/// quintet ([`std::fmt::Display`], [`AsRef<str>`], [`Self::as_str`],
2360/// [`TryFrom<&str>`] via 6fdd0d9, `From<Self> for &'static str` via this
2361/// lift) plus the round-trip witness through both the trait-idiomatic
2362/// (`From<Self> for &'static str` + `TryFrom<&str>`) and the method-named
2363/// (`as_str` + `from_wire`) axis pairs — mirrors the sibling
2364/// [`RestartStrategy`] surface arm-for-arm, so every future arm addition
2365/// (an OTP-`intrinsic` fourth arm the theory
2366/// [`ABSORPTION-ROADMAP`](https://github.com/pleme-io/theory/blob/main/ABSORPTION-ROADMAP.md)
2367/// might reach for once the three canonical OTP restart policies stop
2368/// covering the substrate's discovered load-shape) grows the trait-
2369/// idiomatic forward axis by construction: one caixa-core edit on
2370/// [`RestartPolicy::as_str`] extends every one of the five sibling
2371/// forward-projection paths ([`std::fmt::Display`], [`AsRef<str>`],
2372/// [`Self::as_str`] itself, this `From<Self> for &'static str`, and the
2373/// un-`rename`d [`serde::Serialize`] derive that also emits `as_str`'s
2374/// bytes) without a coordinated rewrite across every future
2375/// `Into<&'static str>`-bound consumer's arm-set.
2376///
2377/// Pinned load-bearing by
2378/// [`tests::restart_policy_from_into_static_str_routes_through_as_str_accessor`]
2379/// (byte-parity pin against [`RestartPolicy::as_str`] across the
2380/// three-arm emit-set, plus a `const`-context materialization witness for
2381/// the `&'static str` lifetime promise) and
2382/// [`tests::restart_policy_from_into_static_str_and_as_str_partition_the_emit_set`]
2383/// (partition pin asserting `<&'static str as From<RestartPolicy>>::from`
2384/// and [`RestartPolicy::as_str`] agree on every arm, plus a two-way
2385/// round-trip witness through the paired trait-idiomatic reverse-
2386/// projection axis [`TryFrom<&str>`] (6fdd0d9): every
2387/// `policy.into::<&'static str>()` output re-parses back through
2388/// [`RestartPolicy::try_from`] to the original variant, closing the two-
2389/// way `Self ↔ &'static str` round-trip on the trait-idiomatic axis pair).
2390impl From<RestartPolicy> for &'static str {
2391 fn from(policy: RestartPolicy) -> &'static str {
2392 policy.as_str()
2393 }
2394}
2395
2396/// Trait-idiomatic *forward* projection on [`RestartPolicy`] from a
2397/// *borrowed* input onto the `&'static str` axis — the borrowed-input
2398/// companion to the paired owned-input [`From<RestartPolicy> for
2399/// &'static str`] impl immediately above. Routes byte-for-byte through
2400/// the same substrate-primitive [`RestartPolicy::as_str`] `pub const
2401/// fn` accessor so every consumer that binds a `&RestartPolicy`
2402/// through the standard-library `.into()` / [`From<&Self> for &'static
2403/// str`] axis (a `RestartPolicy::ALL.iter().map(<&'static
2404/// str>::from).collect::<Vec<_>>()` per-arm accept-set materializer —
2405/// whose iterator over `&'static [RestartPolicy]` yields
2406/// `&RestartPolicy`, not `RestartPolicy`, so the owned-input
2407/// [`From<RestartPolicy>`] axis alone forces every call site through
2408/// an explicit `.copied()` / dereference / [`Copy`]-bound restatement
2409/// rather than the direct trait-idiomatic projection; a future generic
2410/// `<T: Copy + for<'a> Into<&'static str>>`-bound diagnostic column
2411/// that walks the `iter().map(Into::into)` shape verbatim across every
2412/// substrate-wide closed-set typed enum; the future wasm-operator's
2413/// per-child post-exit restart-decision diagnostic line that composes
2414/// the accepted-set enumeration from an iterated
2415/// `RestartPolicy::ALL.iter().map(|p| p.into())` pipe rather than a
2416/// per-arm `match p { … }` cascade; a future
2417/// `HashMap::<&'static str, RestartPolicy>::from_iter(
2418/// RestartPolicy::ALL.iter().map(|p| (p.into(), *p)))`-style
2419/// per-policy reverse-lookup table the sibling [`TryFrom<&str>`] impl
2420/// cannot compose without this borrowed-input axis in place) reaches
2421/// the same three-arm lifted
2422/// [`crate::render::SUPERVISOR_CHILD_RESTART_PERMANENT`] /
2423/// [`crate::render::SUPERVISOR_CHILD_RESTART_TEMPORARY`] /
2424/// [`crate::render::SUPERVISOR_CHILD_RESTART_TRANSIENT`] const the
2425/// paired owned-input [`From<RestartPolicy> for &'static str`], the
2426/// sibling [`std::fmt::Display`], [`AsRef<str>`], and
2427/// [`RestartPolicy::as_str`] surfaces already return.
2428///
2429/// Fifth peer on the substrate-wide trait-idiomatic *borrowed-input*
2430/// forward-projection family opened on [`crate::dep::DepList`]
2431/// (64aa742) and extended onto [`crate::CaixaKind`] (5ab993a),
2432/// [`crate::CaixaDialeto`] (807b0b5), and the paired
2433/// per-supervisor sibling-restart-strategy [`RestartStrategy`]
2434/// (e941836). Rust's `From` trait does not auto-derive the
2435/// `From<&Self>` sibling from a `From<Self>` impl (the blanket
2436/// `impl<T, U> From<&T> for U where T: Copy, U: From<T>` does not
2437/// exist in `core`), so every closed-set typed enum that carries the
2438/// owned-input axis but not the borrowed-input axis forces every
2439/// borrowed-input call site through a `.copied()` /
2440/// `<&'static str>::from(*policy)` / `policy.as_str()` detour whose
2441/// type bounds have no compile-time link to the substrate primitive.
2442/// [`RestartPolicy`] is the second (and second-of-two-in-M2)
2443/// OTP-shape peer to converge onto this campaign — sibling of the
2444/// paired per-supervisor [`RestartStrategy`] borrowed-input axis, so
2445/// with this lift both closed-set typed enums on the M2 `:supervisor`
2446/// slot now carry the full sibling quintet ([`std::fmt::Display`],
2447/// [`AsRef<str>`], [`Self::as_str`], `From<Self> for &'static str`,
2448/// `From<&Self> for &'static str`) plus the paired trait-idiomatic
2449/// reverse projection [`TryFrom<&str>`], closing the borrowed-input
2450/// forward-projection axis on the M2 OTP-shape slot as a unit.
2451///
2452/// Same three-path convergence discipline as the paired owned-input
2453/// impl (this borrowed-input axis, the paired owned-input
2454/// [`From<RestartPolicy> for &'static str`], and
2455/// [`RestartPolicy::as_str`] all route through the same lifted
2456/// [`crate::render::SUPERVISOR_CHILD_RESTART_*`] const), so a future
2457/// variant rename or per-arm serde-attribute drift reaches every one
2458/// of the six sibling forward-projection paths
2459/// ([`std::fmt::Display`], [`AsRef<str>`], [`Self::as_str`],
2460/// [`From<Self> for &'static str`], this [`From<&Self> for &'static
2461/// str`], and the un-`rename`d [`serde::Serialize`] derive that also
2462/// emits [`Self::as_str`]'s bytes) through exactly one caixa-core
2463/// edit.
2464///
2465/// The [`RestartPolicy::as_str`] emit and [`RestartPolicy::from_wire`]
2466/// parse share the same `PascalCase` vocabulary by construction, so
2467/// the borrowed-input forward axis and the reverse axis compose
2468/// directly — the round-trip witness pin below locks this direct
2469/// composition without the intermediate wire-vocab hop the peer
2470/// [`crate::CaixaKind`] axis pair requires.
2471///
2472/// Pinned load-bearing by
2473/// [`tests::restart_policy_from_borrowed_into_static_str_routes_through_as_str_accessor`]
2474/// (byte-parity pin against [`RestartPolicy::as_str`] across the
2475/// three-arm emit-set via a borrowed input, plus a `const`-context
2476/// materialization witness for the `&'static str` lifetime promise,
2477/// plus a blanket `.into()` shape) and
2478/// [`tests::restart_policy_from_owned_and_borrowed_into_static_str_agree_on_every_arm`]
2479/// (cross-axis partition pin against the paired owned-input
2480/// [`From<RestartPolicy> for &'static str`] impl, plus a
2481/// `.iter().map(Into::into)` pipe witness over
2482/// [`RestartPolicy::ALL`], plus a direct round-trip witness through
2483/// [`TryFrom<&str>`] that closes the two-way `&Self → &'static str →
2484/// Self` round-trip without the wire-vocab intermediate the peer
2485/// [`crate::CaixaKind`] axis pair requires).
2486impl From<&RestartPolicy> for &'static str {
2487 fn from(policy: &RestartPolicy) -> &'static str {
2488 policy.as_str()
2489 }
2490}
2491
2492/// Trait-idiomatic *owned-`String`* forward projection on the second
2493/// M2 OTP-shape closed-set typed enum ([`RestartPolicy`]) — the
2494/// owned-heap-string companion to the paired `&'static str`-returning
2495/// [`From<RestartPolicy> for &'static str`] / [`From<&RestartPolicy>
2496/// for &'static str`] impls immediately above. Routes byte-for-byte
2497/// through the substrate-primitive [`RestartPolicy::as_str`] `pub
2498/// const fn` accessor (via [`str::to_owned`]) so every consumer that
2499/// binds a [`RestartPolicy`] through the standard-library `.into()` /
2500/// [`From<Self> for String`] (equivalently [`Into<String>`]) axis — a
2501/// future `serde_json::Value::String(policy.into())` structured-payload
2502/// composer where the `Value::String` arm typing demands an owned
2503/// [`String`] and the sibling [`&'static str`]-returning axis forces
2504/// an explicit `.to_owned()` / `String::from` restatement at every
2505/// call site, a future `HashMap::<String, RestartPolicy>::from_iter(
2506/// RestartPolicy::ALL.iter().map(|p| (p.into(), *p)))` per-policy
2507/// lookup where the map's key type is owned [`String`] rather than
2508/// [`&'static str`], a future `Cow::<'static, str>::Owned(policy.into())`
2509/// composer on the future M4 admission-webhook rejection body's
2510/// owned-arm, the future wasm-operator's per-child post-exit
2511/// diagnostic emit `serde_json::json!({ "restart": policy })` where the
2512/// JSON serializer's `Serialize` impl on [`String`] owns the emit-path
2513/// — reaches the same three-arm lifted
2514/// [`crate::render::SUPERVISOR_CHILD_RESTART_PERMANENT`] /
2515/// [`crate::render::SUPERVISOR_CHILD_RESTART_TEMPORARY`] /
2516/// [`crate::render::SUPERVISOR_CHILD_RESTART_TRANSIENT`] const the
2517/// paired [`std::fmt::Display`], [`AsRef<str>`],
2518/// [`RestartPolicy::as_str`], and the two `&'static str`-returning
2519/// forward-projection impls already return.
2520///
2521/// Extends the trait-idiomatic *owned-`String`* forward-projection
2522/// axis onto the second-of-two M2 OTP-shape closed-set typed enums on
2523/// the caixa surface — mirror of the first-mover
2524/// [`From<RestartStrategy> for String`] (7baa18a) that opened this
2525/// axis on the sibling supervisor-level strategy enum. Rust's standard
2526/// library does not carry a blanket `impl<T: AsRef<str>> From<T> for
2527/// String` (nor an `impl<T: fmt::Display> From<T> for String`), so
2528/// every closed-set typed enum that carries the paired `AsRef<str>` /
2529/// `Display` / `From<Self> for &'static str` triple but not the
2530/// owned-[`String`] axis forces every owned-string call site through a
2531/// `.to_string()` / `.as_str().to_owned()` / `String::from(policy.as_str())`
2532/// detour whose type bounds have no compile-time link to the
2533/// substrate primitive.
2534///
2535/// Deliberately routes through the human-readable
2536/// [`RestartPolicy::as_str`] axis — for this enum the wire format
2537/// (`PascalCase`, tatara-lisp author surface `:restart Permanent`) and
2538/// the diagnostic byte-string share the same vocabulary by
2539/// construction (unlike the sibling [`crate::CaixaKind`] enum whose
2540/// two axes diverge), so the owned-[`String`] projection lands
2541/// byte-identically on both the wire vocabulary the paired
2542/// [`serde::Serialize`] derive emits and the diagnostic vocabulary the
2543/// [`RestartPolicy::as_str`] helper returns, and — because the paired
2544/// [`TryFrom<&str>`] / [`RestartPolicy::from_wire`] reverse-projection
2545/// axis parses the same `PascalCase` vocabulary — the direct two-way
2546/// `Self → String → Self` round-trip composes without the wire-vocab
2547/// intermediate hop the peer [`crate::CaixaKind`] owned-[`String`]
2548/// axis pair requires.
2549///
2550/// Pinned load-bearing by
2551/// [`tests::restart_policy_from_into_owned_string_routes_through_as_str_accessor`]
2552/// (byte-parity pin against [`RestartPolicy::as_str`] across the
2553/// three-arm emit-set, plus a blanket `.into::<String>()` shape
2554/// witness) and
2555/// [`tests::restart_policy_from_into_owned_string_and_static_str_agree_on_every_arm`]
2556/// (cross-axis partition pin against the paired owned-input
2557/// [`From<RestartPolicy> for &'static str`] impl and the sibling
2558/// [`ToString::to_string`] surface routed through [`std::fmt::Display`],
2559/// plus a `.iter().copied().map(String::from)` pipe witness over
2560/// [`RestartPolicy::ALL`], plus a direct round-trip witness through
2561/// [`TryFrom<&str>`] on the owned-[`String`]'s [`String::as_str`]
2562/// borrow that closes the two-way `Self → String → Self` round-trip
2563/// on the trait-idiomatic owned-[`String`] forward + reverse axis
2564/// pair).
2565impl From<RestartPolicy> for String {
2566 fn from(policy: RestartPolicy) -> String {
2567 policy.as_str().to_owned()
2568 }
2569}
2570
2571/// Trait-idiomatic *borrowed-input, owned-`String` output* forward
2572/// projection on the second-of-two M2 OTP-shape closed-set typed enum
2573/// ([`RestartPolicy`]) — the fourth (and closing) corner of the
2574/// `{Self, &Self} × {&'static str, String}` 2×2 trait-idiomatic
2575/// projection family on this enum, mirror of the first-mover
2576/// [`From<&RestartStrategy> for String`] (579385f) that opened the
2577/// 2×2-completion corner on the sibling supervisor-level strategy
2578/// enum. Routes byte-for-byte through the substrate-primitive
2579/// [`RestartPolicy::as_str`] `pub const fn` accessor (via
2580/// [`str::to_owned`]) so every consumer that holds a borrowed
2581/// [`&RestartPolicy`] and needs an owned [`String`] — a future
2582/// `serde_json::Value::String(String::from(&policy))` structured-payload
2583/// composer over a borrowed field, a future `Iterator::map` over
2584/// `&[RestartPolicy]` that projects to owned keys through
2585/// `.iter().map(String::from)`, a future `HashMap::<String,
2586/// RestartPolicy>::from_iter` that keys off a borrowed-iteration axis
2587/// where dereferencing the policy would force an unnecessary `Copy` at
2588/// every step, the future wasm-operator's per-supervisor
2589/// `child_policies.iter().map(String::from).collect()` per-child post-
2590/// exit restart-decision diagnostic emit whose iteration axis is
2591/// borrowed by construction — reaches the same three-arm lifted
2592/// [`crate::render::SUPERVISOR_CHILD_RESTART_PERMANENT`] /
2593/// [`crate::render::SUPERVISOR_CHILD_RESTART_TEMPORARY`] /
2594/// [`crate::render::SUPERVISOR_CHILD_RESTART_TRANSIENT`] const the
2595/// paired [`std::fmt::Display`], [`AsRef<str>`],
2596/// [`RestartPolicy::as_str`], and the three other trait-idiomatic
2597/// forward-projection impls
2598/// ([`From<RestartPolicy> for &'static str`],
2599/// [`From<&RestartPolicy> for &'static str`],
2600/// [`From<RestartPolicy> for String`]) already return.
2601///
2602/// Second peer on the substrate-wide trait-idiomatic *borrowed-input,
2603/// owned-`String` output* forward-projection family opened on
2604/// [`crate::supervisor::RestartStrategy`] (579385f) — closes the
2605/// `{Self, &Self} × {&'static str, String}` 2×2 projection corner on
2606/// both M2 OTP-shape sibling peers (the paired supervisor-level
2607/// sibling-restart-strategy axis and the per-child restart-decision-
2608/// policy axis), so the whole M2 OTP-shape axis pair now carries the
2609/// full four-corner family by construction. Rust's standard library
2610/// does not carry a blanket `impl<T: AsRef<str>> From<&T> for String`
2611/// (nor an `impl<T: fmt::Display> From<&T> for String`), so every
2612/// closed-set typed enum that carries the paired `AsRef<str>` /
2613/// `Display` / `From<Self> for &'static str` / `From<&Self> for
2614/// &'static str` / `From<Self> for String` quintuple but not the
2615/// borrowed-input owned-[`String`] axis forces every borrowed-input
2616/// owned-string call site through a `policy.as_str().to_owned()` /
2617/// `String::from(*policy)` (with a spurious `Copy`) /
2618/// `policy.to_string()` (through `Display`) detour whose type bounds
2619/// have no compile-time link to the substrate primitive.
2620///
2621/// Deliberately routes through the human-readable
2622/// [`RestartPolicy::as_str`] axis — for this enum the wire format
2623/// (`PascalCase`, tatara-lisp author surface `:restart Permanent`) and
2624/// the diagnostic byte-string share the same vocabulary by
2625/// construction (unlike the sibling [`crate::CaixaKind`] enum whose
2626/// two axes diverge), so the borrowed-input owned-[`String`]
2627/// projection lands byte-identically on both the wire vocabulary the
2628/// paired [`serde::Serialize`] derive emits and the diagnostic
2629/// vocabulary the [`RestartPolicy::as_str`] helper returns, and —
2630/// because the paired [`TryFrom<&str>`] / [`RestartPolicy::from_wire`]
2631/// reverse-projection axis parses the same `PascalCase` vocabulary —
2632/// the direct two-way `&Self → String → Self` round-trip composes
2633/// without the wire-vocab intermediate hop the peer
2634/// [`crate::CaixaKind`] axis pair requires.
2635///
2636/// The remaining thirteen closed-set typed enums on the caixa
2637/// substrate surface (`CaixaKind`, `CaixaDialeto`, `DepList`,
2638/// `PlacementStrategy`, `WitShape`, `RateLimitUnit`,
2639/// `PathShapeViolation`, `InvariantKind`, `ArchVerdict`, `Severity`,
2640/// `FixSafety`, `Semantic`, `FerriteRuntime`) are the future targets
2641/// of this 2×2-completion campaign — each carries the same paired
2642/// quintuple that this borrowed-input owned-[`String`] axis extends
2643/// onto.
2644///
2645/// Pinned load-bearing by
2646/// [`tests::restart_policy_from_into_borrowed_owned_string_routes_through_as_str_accessor`]
2647/// (byte-parity pin against [`RestartPolicy::as_str`] across the
2648/// three-arm emit-set through the borrowed-input surface) and
2649/// [`tests::restart_policy_from_into_borrowed_owned_string_agrees_with_paired_axes_on_every_arm`]
2650/// (cross-axis partition pin against the paired owned-input owned-
2651/// [`String`] [`From<RestartPolicy> for String`] impl, the paired
2652/// borrowed-input owned-[`&'static str`] [`From<&RestartPolicy> for
2653/// &'static str`] impl, and the sibling [`ToString::to_string`]
2654/// surface routed through [`std::fmt::Display`], plus a direct round-
2655/// trip witness through [`TryFrom<&str>`] on the owned-[`String`]'s
2656/// [`String::as_str`] borrow that closes the two-way
2657/// `&Self → String → Self` round-trip on the trait-idiomatic
2658/// borrowed-input owned-[`String`] forward + reverse axis pair).
2659impl From<&RestartPolicy> for String {
2660 fn from(policy: &RestartPolicy) -> String {
2661 policy.as_str().to_owned()
2662 }
2663}
2664
2665/// Trait-idiomatic *owned-input, [`std::borrow::Cow<'static, str>`]
2666/// output* forward projection on the M2 OTP-shape per-child-restart
2667/// [`RestartPolicy`] closed-set typed enum — extends the substrate-
2668/// wide [`std::borrow::Cow<'static, str>`] forward-projection family
2669/// opened on [`crate::CaixaKind`] (99c1735 owned-input, d45c409
2670/// borrowed-input) and first extended off it onto the sibling M2
2671/// OTP-shape sibling-restart [`RestartStrategy`] (7dd28b3 owned-input,
2672/// 9b3e4b3 borrowed-input) onto the second (and second-of-two-in-M2)
2673/// M2 OTP-shape closed-set fieldless typed enum peer on the caixa
2674/// surface (`:children :restart`). Routes byte-for-byte through the
2675/// substrate-primitive [`RestartPolicy::as_str`] `pub const fn`
2676/// accessor (via [`std::borrow::Cow::Borrowed`]) so every consumer
2677/// that binds a [`RestartPolicy`] through the trait-idiomatic
2678/// [`std::borrow::Cow<'static, str>`] axis — a future
2679/// `axum::response::IntoResponse` composer whose per-policy
2680/// diagnostic-body typing rules out the sibling [`AsRef<str>`]
2681/// borrowed return, a future M4 admission-webhook rejection body
2682/// that composes the accepted-policy enumeration through the same
2683/// `RestartPolicy::ALL.iter().map(Cow::from)` shape [`crate::CaixaKind`]
2684/// and [`RestartStrategy`] already route through, a generic `<T: for<'a>
2685/// Into<std::borrow::Cow<'static, str>>>`-bound structured-log
2686/// emitter on a per-child-policy diagnostic column — reaches the same
2687/// three-arm lifted [`crate::render::SUPERVISOR_CHILD_RESTART_PERMANENT`]
2688/// / [`crate::render::SUPERVISOR_CHILD_RESTART_TEMPORARY`] /
2689/// [`crate::render::SUPERVISOR_CHILD_RESTART_TRANSIENT`] const the
2690/// paired [`std::fmt::Display`], [`AsRef<str>`],
2691/// [`RestartPolicy::as_str`], and the four
2692/// `{Self, &Self} × {&'static str, String}` 2×2 trait-idiomatic
2693/// forward-projection corners already return.
2694///
2695/// Deliberately returns [`std::borrow::Cow::Borrowed`] rather than
2696/// [`std::borrow::Cow::Owned`] — the substrate-primitive
2697/// [`RestartPolicy::as_str`] accessor's return carries the `&'static
2698/// str` lifetime by construction (each `match` arm resolves to a
2699/// [`crate::render::SUPERVISOR_CHILD_RESTART_*`] `pub const &str`
2700/// with static lifetime), so the zero-alloc borrowed arm is the
2701/// type-correct projection with no runtime allocation.
2702///
2703/// Rust's standard library carries no blanket `impl<T: AsRef<str>>
2704/// From<T> for Cow<'static, str>` (nor an `impl<T: fmt::Display>
2705/// From<T> for Cow<'static, str>`), so the paired sibling
2706/// [`From<RestartPolicy> for &'static str`] (9fb37d0),
2707/// [`From<RestartPolicy> for String`] (7851725), [`AsRef<str>`], and
2708/// [`std::fmt::Display`] surfaces do not implicitly extend to a
2709/// [`Cow<'static, str>`]-bound call site — every such site is forced
2710/// through a `Cow::Borrowed(policy.as_str())` /
2711/// `Cow::Owned(policy.to_string())` open-code whose type bounds have
2712/// no compile-time link back to the substrate primitive until this
2713/// lift.
2714///
2715/// Second peer to extend the substrate-wide trait-idiomatic
2716/// [`std::borrow::Cow<'static, str>`] forward-projection axis off the
2717/// top-level [`crate::CaixaKind`] enum (99c1735 owned-input, d45c409
2718/// borrowed-input) onto the wider substrate — closes the M2 OTP-shape
2719/// tier of the campaign (both sibling peers, `RestartStrategy` and
2720/// `RestartPolicy`, now carry the owned-input Cow<'static, str>
2721/// forward projection) so the remaining eleven peers
2722/// (`PlacementStrategy`, `RateLimitUnit`, `DepList`, `CaixaDialeto`,
2723/// and the outside-`caixa-core` peers `WitShape`, `PathShapeViolation`,
2724/// `InvariantKind`, `ArchVerdict`, `Severity`, `FixSafety`, `Semantic`,
2725/// `FerriteRuntime`) are the future targets. Every future arm addition
2726/// (an OTP-`intrinsic` fourth restart policy the ABSORPTION-ROADMAP
2727/// might reach for once the three canonical OTP restart policies stop
2728/// covering the substrate's discovered load-shape) grows the
2729/// Cow<'static, str> axis by construction through one caixa-core edit
2730/// on [`RestartPolicy::as_str`] — rather than a coordinated rewrite
2731/// across every future Cow<'static, str>-bound consumer site.
2732///
2733/// Pinned load-bearing by
2734/// [`tests::restart_policy_from_into_static_cow_str_routes_through_as_str_accessor`]
2735/// (byte-parity + zero-alloc [`std::borrow::Cow::Borrowed`]-arm pin
2736/// against [`RestartPolicy::as_str`] across the three-arm
2737/// [`RestartPolicy::ALL`]) and
2738/// [`tests::restart_policy_from_into_static_cow_str_agrees_with_paired_axes_on_every_arm`]
2739/// (cross-axis partition pin against the paired [`From<RestartPolicy>
2740/// for &'static str`], [`From<RestartPolicy> for String`], and
2741/// [`ToString`]-through-[`std::fmt::Display`] axes, plus a
2742/// `.iter().copied().map(Cow::from)` pipe witness over
2743/// [`RestartPolicy::ALL`] that materializes the three-arm accept-set
2744/// through the [`Cow<'static, str>`] axis alone and pins the
2745/// zero-alloc discipline on every element).
2746impl From<RestartPolicy> for std::borrow::Cow<'static, str> {
2747 fn from(policy: RestartPolicy) -> std::borrow::Cow<'static, str> {
2748 std::borrow::Cow::Borrowed(policy.as_str())
2749 }
2750}
2751
2752/// Trait-idiomatic *borrowed-input, [`std::borrow::Cow<'static, str>`]
2753/// output* forward projection on the M2 OTP-shape per-child-restart
2754/// [`RestartPolicy`] closed-set typed enum — the borrowed-input
2755/// companion to the paired owned-input
2756/// [`From<RestartPolicy> for std::borrow::Cow<'static, str>`] impl
2757/// immediately above (0612398). Routes byte-for-byte through the same
2758/// substrate-primitive [`RestartPolicy::as_str`] `pub const fn`
2759/// accessor (via [`std::borrow::Cow::Borrowed`]) so every consumer
2760/// that holds a `&RestartPolicy` and needs a
2761/// [`std::borrow::Cow<'static, str>`] — a
2762/// `RestartPolicy::ALL.iter().map(std::borrow::Cow::from).collect::<Vec<_>>()`
2763/// per-arm accept-set materializer (whose iterator over
2764/// `&'static [RestartPolicy]` yields `&RestartPolicy`, not
2765/// `RestartPolicy`, so the paired owned-input
2766/// [`From<RestartPolicy> for std::borrow::Cow<'static, str>`] axis
2767/// alone forces every call site through an explicit `.copied()` /
2768/// dereference / [`Copy`]-bound restatement rather than the direct
2769/// trait-idiomatic projection), a future generic
2770/// `<T: for<'a> Into<std::borrow::Cow<'static, str>>>`-bound emitter
2771/// on a per-child-policy diagnostic column that walks the
2772/// `iter().map(Into::into)` shape verbatim, the future M4 admission-
2773/// webhook rejection body that composes the accepted-policy
2774/// enumeration from an iterated
2775/// `RestartPolicy::ALL.iter().map(|p| p.into())` pipe rather than a
2776/// per-arm `match p { … }` cascade — reaches the same three-arm
2777/// lifted [`crate::render::SUPERVISOR_CHILD_RESTART_PERMANENT`] /
2778/// [`crate::render::SUPERVISOR_CHILD_RESTART_TEMPORARY`] /
2779/// [`crate::render::SUPERVISOR_CHILD_RESTART_TRANSIENT`] const the
2780/// paired [`std::fmt::Display`], [`AsRef<str>`],
2781/// [`RestartPolicy::as_str`], the four
2782/// `{Self, &Self} × {&'static str, String}` 2×2 trait-idiomatic
2783/// forward-projection corners, and the paired owned-input
2784/// [`From<RestartPolicy> for std::borrow::Cow<'static, str>`] impl
2785/// already return.
2786///
2787/// Deliberately returns [`std::borrow::Cow::Borrowed`] rather than
2788/// [`std::borrow::Cow::Owned`] — the substrate-primitive
2789/// [`RestartPolicy::as_str`] accessor's return carries the
2790/// `&'static str` lifetime by construction (each `match` arm resolves
2791/// to a [`crate::render::SUPERVISOR_CHILD_RESTART_*`] `pub const &str`
2792/// with static lifetime), so the zero-alloc borrowed arm is the
2793/// type-correct projection with no runtime allocation.
2794///
2795/// Closes the `{Self, &Self}` input-shape corner on the M2 OTP-shape
2796/// per-child-restart [`std::borrow::Cow<'static, str>`] axis opened
2797/// one commit prior (0612398) on the paired owned-input
2798/// [`From<RestartPolicy> for std::borrow::Cow<'static, str>`] impl —
2799/// second-of-two-in-M2 closed-set fieldless typed enum peer on the
2800/// caixa surface (paired with the sibling-restart [`RestartStrategy`]
2801/// which carries both {Self, &Self} × Cow<'static, str> corners since
2802/// 7dd28b3 owned-input, 9b3e4b3 borrowed-input), exactly as d45c409
2803/// closed it on the top-level [`crate::CaixaKind`] one commit after
2804/// the owning half (99c1735) landed. This lift closes the whole M2
2805/// OTP-shape tier of the substrate-wide [`Cow<'static, str>`]
2806/// forward-projection campaign on both input-shape corners
2807/// ({Self, &Self}) of both M2 OTP-shape sibling peers
2808/// ([`RestartStrategy`] and [`RestartPolicy`]), so the remaining
2809/// eleven substrate-wide peers (`PlacementStrategy`, `RateLimitUnit`,
2810/// `DepList`, `CaixaDialeto`, `WitShape`, `PathShapeViolation`,
2811/// `InvariantKind`, `ArchVerdict`, `Severity`, `FixSafety`, `Semantic`,
2812/// `FerriteRuntime`) become the future targets of the campaign. Rust's
2813/// standard library does not carry a blanket
2814/// `impl<T: AsRef<str>> From<&T> for Cow<'static, str>` (nor an
2815/// `impl<T: fmt::Display> From<&T> for Cow<'static, str>`), so every
2816/// closed-set fieldless typed enum peer on the substrate that carries
2817/// the paired owned-input [`Cow<'static, str>`] axis but not the
2818/// borrowed-input axis forces every borrowed-input
2819/// [`Cow<'static, str>`]-parameterized call site through a spurious
2820/// [`Copy`] deref (`std::borrow::Cow::from(*policy)`) or a
2821/// `std::borrow::Cow::Borrowed(policy.as_str())` open-code whose type
2822/// bounds have no compile-time link to the substrate primitive.
2823///
2824/// Pinned load-bearing by
2825/// [`tests::restart_policy_from_borrowed_into_static_cow_str_routes_through_as_str_accessor`]
2826/// (byte-parity + zero-alloc [`std::borrow::Cow::Borrowed`]-arm pin
2827/// against [`RestartPolicy::as_str`] across the three-arm
2828/// [`RestartPolicy::ALL`] through the borrowed-input surface) and
2829/// [`tests::restart_policy_from_borrowed_into_static_cow_str_agrees_with_paired_axes_on_every_arm`]
2830/// (cross-axis partition pin against the paired owned-input
2831/// [`From<RestartPolicy> for std::borrow::Cow<'static, str>`], the
2832/// paired borrowed-input owned-`&'static str`
2833/// [`From<&RestartPolicy> for &'static str`], and the paired
2834/// borrowed-input owned-`String` [`From<&RestartPolicy> for String`]
2835/// impls, plus a `.iter().map(std::borrow::Cow::from)` pipe witness
2836/// over [`RestartPolicy::ALL`] — whose iterator yields
2837/// `&RestartPolicy` by construction, so the borrowed-input
2838/// [`Cow<'static, str>`] axis is what routes the pipe through the
2839/// substrate-primitive [`RestartPolicy::as_str`] accessor with the
2840/// zero-alloc [`Cow::Borrowed`] arm by construction and without a
2841/// spurious [`Copy`] deref).
2842impl From<&RestartPolicy> for std::borrow::Cow<'static, str> {
2843 fn from(policy: &RestartPolicy) -> std::borrow::Cow<'static, str> {
2844 std::borrow::Cow::Borrowed(policy.as_str())
2845 }
2846}
2847
2848/// Trait-idiomatic *owned-input, [`Box<str>`] output* forward
2849/// projection on the M2 OTP-shape per-child-restart [`RestartPolicy`]
2850/// closed-set fieldless typed enum — extends the substrate-wide
2851/// `Box<str>` forward-projection campaign tier opened one commit prior
2852/// (69ef45c) on the paired sibling-restart [`RestartStrategy`] onto
2853/// the second (and third-and-final) M2 OTP-shape closed-set fieldless
2854/// typed enum peer on the caixa surface (`:children :restart`),
2855/// immediately after the paired `Cow<'static, str>` axis (0612398 /
2856/// b4dc55c) closed the
2857/// `{Self, &Self} × {&'static str, String, Cow<'static, str>}` 2×3
2858/// corner on this enum. Routes byte-for-byte through the
2859/// substrate-primitive [`RestartPolicy::as_str`] `pub const fn`
2860/// accessor via [`Box::<str>::from`] on the returned `&'static str`,
2861/// so every consumer that binds a
2862/// `let key: Box<str> = policy.into();`-shaped call site — a
2863/// per-child metric-key materializer that stashes the policy
2864/// discriminator in a `Box<str>`-typed heap-owned scalar for cheap
2865/// clone (a shared-nothing per-policy accept-set the `caixa-operator`
2866/// hierarchical reconciliation scheduler's per-child restart-decision
2867/// fan-out carries), a future admission-webhook rejection body whose
2868/// per-arm `Box<str>` field composes from an owned `RestartPolicy`
2869/// handle — reaches the same three-arm lifted
2870/// [`crate::render::SUPERVISOR_CHILD_RESTART_PERMANENT`] /
2871/// [`crate::render::SUPERVISOR_CHILD_RESTART_TEMPORARY`] /
2872/// [`crate::render::SUPERVISOR_CHILD_RESTART_TRANSIENT`] const the
2873/// sibling
2874/// `{Self, &Self} × {&'static str, String, Cow<'static, str>}`
2875/// forward-projection corner already returns. Rust's standard library
2876/// carries `impl From<&str> for Box<str>` and
2877/// `impl From<String> for Box<str>` but no blanket
2878/// `impl<T: AsRef<str>> From<T> for Box<str>` (nor any
2879/// `impl<T: Copy, U: From<T>> From<T> for U` route from the enum), so
2880/// this axis is a distinct trait-idiomatic surface that a downstream
2881/// `RestartPolicy → Box<str>` `.into()` reaches through this impl and
2882/// no other — without a `Box::from(policy.as_str())` open-code whose
2883/// type bounds have no compile-time link back to the substrate
2884/// primitive.
2885///
2886/// Second peer on the substrate-wide trait-idiomatic [`Box<str>`]
2887/// forward-projection family opened on the sibling-restart
2888/// [`RestartStrategy`] (69ef45c / 59ae5dc) — closes the whole M2
2889/// OTP-shape tier of the substrate-wide [`Box<str>`] forward-
2890/// projection campaign's owned-input corner on both M2 OTP-shape
2891/// sibling peers ([`RestartStrategy`] and [`RestartPolicy`]), the
2892/// paired borrowed-input `From<&RestartPolicy> for Box<str>` closer
2893/// and the remaining fieldless-enum peers on the M3 mesh-shape /
2894/// outside-M3 caixa-core / render-side / outside-caixa-core tiers
2895/// are the future targets of the campaign.
2896///
2897/// Pinned load-bearing by
2898/// [`tests::restart_policy_from_into_box_str_routes_through_as_str_accessor`]
2899/// (byte-parity pin against [`RestartPolicy::as_str`] across the
2900/// three-arm [`RestartPolicy::ALL`] emit-set on the owned-input
2901/// surface, plus a blanket-derived [`Into`] shape witness).
2902impl From<RestartPolicy> for Box<str> {
2903 fn from(policy: RestartPolicy) -> Box<str> {
2904 Box::<str>::from(policy.as_str())
2905 }
2906}
2907
2908/// Trait-idiomatic *borrowed-input, [`Box<str>`] output* forward
2909/// projection on the M2 OTP-shape per-child-restart [`RestartPolicy`]
2910/// closed-set fieldless typed enum — the borrowed-input companion to
2911/// the paired owned-input [`From<RestartPolicy> for Box<str>`] impl
2912/// (0a1b313, one commit prior) that closes the `{Self, &Self}`
2913/// input-shape corner of the substrate-wide [`Box<str>`] forward-
2914/// projection axis on the second (and third-and-final) M2 OTP-shape
2915/// closed-set fieldless typed enum peer on the caixa surface
2916/// (`:children :restart`), routing byte-for-byte through the
2917/// substrate-primitive [`RestartPolicy::as_str`] `pub const fn`
2918/// accessor via [`Box::<str>::from`] on the returned `&'static str`.
2919/// Every consumer that holds a `&RestartPolicy` and needs a
2920/// [`Box<str>`] — a
2921/// `RestartPolicy::ALL.iter().map(Box::<str>::from).collect::<Vec<_>>()`
2922/// per-arm accept-set materializer (whose iterator over
2923/// `&'static [RestartPolicy]` yields `&RestartPolicy`, not
2924/// `RestartPolicy`, so the paired owned-input
2925/// [`From<RestartPolicy> for Box<str>`] axis alone forces every
2926/// call site through an explicit [`Copy`] deref or a
2927/// `.copied()` restatement rather than the direct trait-idiomatic
2928/// projection), a per-child metric-key materializer holding
2929/// `&RestartPolicy` through a `caixa-operator` hierarchical
2930/// reconciliation scheduler's borrow lifetime, a future admission-
2931/// webhook rejection body whose per-arm `Box<str>` field composes
2932/// from a borrowed `&RestartPolicy` handle — reaches the
2933/// substrate-primitive [`RestartPolicy::as_str`] accessor through
2934/// this impl and no other, without a
2935/// `Box::<str>::from(policy.as_str())` open-code whose type bounds
2936/// have no compile-time link back to the substrate primitive.
2937///
2938/// Rust's standard library carries `impl From<&str> for Box<str>`
2939/// and `impl From<String> for Box<str>` but no blanket
2940/// `impl<T: AsRef<str>> From<&T> for Box<str>` (nor a
2941/// `Copy`-based `impl<T: Copy, U: From<&T> for U`), so every closed-
2942/// set fieldless typed enum peer on the substrate that carries the
2943/// paired owned-input `Box<str>` axis but not the borrowed-input
2944/// axis forces every borrowed-input `Box<str>`-parameterized call
2945/// site through a spurious [`Copy`] deref
2946/// (`Box::<str>::from((*policy).as_str())`) or a
2947/// `Box::<str>::from(policy.as_str())` open-code whose type bounds
2948/// have no compile-time link back to the substrate primitive.
2949///
2950/// Fourth (and closing) peer on the substrate-wide trait-idiomatic
2951/// [`Box<str>`] forward-projection family on the M2 OTP-shape tier
2952/// — closes the whole `{Self, &Self}` input-shape corner of the
2953/// [`Box<str>`] axis on both M2 OTP-shape sibling peers
2954/// ([`RestartStrategy`] and [`RestartPolicy`]), exactly as b4dc55c
2955/// closed the paired [`Cow<'static, str>`] axis one commit after
2956/// its owning half (0612398) landed on this enum. The remaining
2957/// fieldless-enum peers on the M3 mesh-shape / outside-M3 caixa-
2958/// core / render-side / outside-caixa-core tiers are the future
2959/// targets of the [`Box<str>`] campaign.
2960///
2961/// Pinned load-bearing by
2962/// [`tests::restart_policy_from_borrowed_into_box_str_routes_through_as_str_accessor`]
2963/// (byte-parity pin against [`RestartPolicy::as_str`] across the
2964/// three-arm [`RestartPolicy::ALL`] emit-set on the borrowed-input
2965/// surface, plus a blanket-derived [`Into`] shape witness, a
2966/// cross-axis partition pin against the paired owned-input
2967/// [`From<RestartPolicy> for Box<str>`] and the sibling borrowed-
2968/// input `{&'static str, String, Cow<'static, str>}` return-shape
2969/// axes, and a `.iter().map(Box::<str>::from)` pipe witness over
2970/// [`RestartPolicy::ALL`] — whose iterator yields `&RestartPolicy`
2971/// by construction, so the borrowed-input [`Box<str>`] axis is
2972/// what routes the pipe through the substrate-primitive
2973/// [`RestartPolicy::as_str`] accessor without a spurious [`Copy`]
2974/// deref).
2975impl From<&RestartPolicy> for Box<str> {
2976 fn from(policy: &RestartPolicy) -> Box<str> {
2977 Box::<str>::from(policy.as_str())
2978 }
2979}
2980
2981/// Trait-idiomatic *owned-input, [`std::sync::Arc<str>`] output*
2982/// forward projection on the M2 OTP-shape per-child-restart
2983/// [`RestartPolicy`] closed-set fieldless typed enum — routes byte-
2984/// for-byte through the substrate-primitive [`RestartPolicy::as_str`]
2985/// `pub const fn` accessor via [`std::sync::Arc::<str>::from`] on the
2986/// returned `&'static str`, so every consumer that binds a
2987/// [`RestartPolicy`] through the standard-library `.into()` /
2988/// [`From<Self> for std::sync::Arc<str>`] (equivalently
2989/// [`Into<std::sync::Arc<str>>`]) axis — a future admission-webhook's
2990/// per-request `Sync` + `Send`-safe structured-log field composed
2991/// across an `.await` boundary through a
2992/// `<T: Into<std::sync::Arc<str>>>`-bound diagnostic-column dispatch,
2993/// a future wasm-operator's per-child post-exit restart-decision
2994/// pipeline holding a shared-ownership per-arm cache key, a
2995/// `<T: Into<std::sync::Arc<str>>>`-bound `tracing`-span attributes
2996/// collector recording a per-child-policy field onto the parent
2997/// span's shared-ownership context — reaches the same three-arm
2998/// lifted [`crate::render::SUPERVISOR_CHILD_RESTART_PERMANENT`] /
2999/// [`crate::render::SUPERVISOR_CHILD_RESTART_TEMPORARY`] /
3000/// [`crate::render::SUPERVISOR_CHILD_RESTART_TRANSIENT`] const the
3001/// sibling
3002/// `{Self, &Self} × {&'static str, String, Cow<'static, str>, Box<str>}`
3003/// forward-projection corner already returns.
3004///
3005/// Second peer on the substrate-wide trait-idiomatic
3006/// [`std::sync::Arc<str>`] forward-projection family opened one
3007/// projection tier prior (bca2ec8) on the paired sibling-restart
3008/// [`RestartStrategy`] owned-input first-mover — extends the tier
3009/// onto the second (and third-and-final) M2 OTP-shape closed-set
3010/// fieldless typed enum peer on the caixa surface
3011/// (`:children :restart`), immediately after the paired [`Box<str>`]
3012/// axis (0a1b313 / cb1d068) closed the whole
3013/// `{Self, &Self} × {&'static str, String, Cow<'static, str>, Box<str>}`
3014/// 2×4 corner on this enum. Rust's standard library carries
3015/// `impl From<&str> for std::sync::Arc<str>` and
3016/// `impl From<String> for std::sync::Arc<str>` but no blanket
3017/// `impl<T: AsRef<str>> From<T> for std::sync::Arc<str>` (nor an
3018/// `impl<T: fmt::Display> From<T> for std::sync::Arc<str>`), so this
3019/// axis is a distinct trait-idiomatic surface that a
3020/// `let key: std::sync::Arc<str> = policy.into();`-shaped call site
3021/// reaches through this impl and no other — a paired
3022/// `std::sync::Arc::<str>::from(policy.as_str())` open-code has no
3023/// compile-time link back to the substrate primitive, and a two-step
3024/// `std::sync::Arc::<str>::from(String::from(policy))` composition
3025/// through the owned-`String` axis allocates twice (once into the
3026/// intermediate `String`, once into the [`Arc<str>`] on the
3027/// `From<String>` conversion) where the single-step trait impl
3028/// allocates once.
3029///
3030/// Peer of the sibling [`Box<str>`] second-tier extender (0a1b313) —
3031/// same "extends the substrate-wide projection tier onto the next
3032/// M2 OTP-shape peer" discipline, extended onto the
3033/// [`std::sync::Arc<str>`] axis whose shared-ownership + [`Sync`] +
3034/// [`Send`] contract is the distinct value the [`Box<str>`] axis's
3035/// owned-move return-shape cannot provide.
3036///
3037/// Pinned load-bearing by
3038/// [`tests::restart_policy_from_into_arc_str_routes_through_as_str_accessor`]
3039/// (byte-parity pin against [`RestartPolicy::as_str`] across the
3040/// three-arm [`RestartPolicy::ALL`] emit-set on the owned-input
3041/// surface, plus a blanket-derived [`Into`] shape witness and cross-
3042/// axis byte-parity pins against the sibling owned-input
3043/// `{&'static str, String, Cow<'static, str>, Box<str>}` return-shape
3044/// axes).
3045impl From<RestartPolicy> for std::sync::Arc<str> {
3046 fn from(policy: RestartPolicy) -> std::sync::Arc<str> {
3047 std::sync::Arc::<str>::from(policy.as_str())
3048 }
3049}
3050
3051/// Trait-idiomatic *borrowed-input, [`std::sync::Arc<str>`] output*
3052/// forward projection on the M2 OTP-shape per-child-restart
3053/// [`RestartPolicy`] closed-set fieldless typed enum — closes the
3054/// `{Self, &Self}` input-shape corner of the [`std::sync::Arc<str>`]
3055/// forward-projection axis on the second (and third-and-final) M2
3056/// OTP-shape closed-set fieldless typed enum peer on the caixa
3057/// surface (`:children :restart`), companion to the paired
3058/// owned-input [`From<RestartPolicy> for std::sync::Arc<str>`] impl
3059/// one commit prior (b05724e). Routes byte-for-byte through the
3060/// substrate-primitive [`RestartPolicy::as_str`] `pub const fn`
3061/// accessor (via [`std::sync::Arc::<str>::from`] on the returned
3062/// `&'static str`), so every consumer that binds a
3063/// [`&RestartPolicy`] through the standard-library `.into()` /
3064/// [`From<&Self> for std::sync::Arc<str>`] (equivalently
3065/// [`Into<std::sync::Arc<str>>`]) axis — a future admission-webhook's
3066/// per-request borrowed-`&RestartPolicy` handle rendering a per-arm
3067/// `Sync` + `Send`-safe structured-log field across an `.await`
3068/// boundary through a `<T: Into<std::sync::Arc<str>>>`-bound
3069/// diagnostic-column dispatch, a future wasm-operator's per-child
3070/// post-exit restart-decision pipeline whose
3071/// `.iter().map(std::sync::Arc::<str>::from)` collector reaches
3072/// into the shared-ownership per-arm key without a spurious [`Copy`]
3073/// deref (which would only be reachable through the owned-input
3074/// [`From<RestartPolicy> for std::sync::Arc<str>`] axis by first
3075/// calling `.copied()` on the iterator), a future
3076/// `<T: Into<std::sync::Arc<str>>>`-bound `tracing`-span attributes
3077/// collector recording a borrowed-`&RestartPolicy` per-arm field
3078/// onto the parent span's shared-ownership context — reaches the
3079/// same three-arm lifted
3080/// [`crate::render::SUPERVISOR_CHILD_RESTART_PERMANENT`] /
3081/// [`crate::render::SUPERVISOR_CHILD_RESTART_TEMPORARY`] /
3082/// [`crate::render::SUPERVISOR_CHILD_RESTART_TRANSIENT`] const the
3083/// paired owned-input [`From<RestartPolicy> for std::sync::Arc<str>`]
3084/// impl and the sibling `{&'static str, String, Cow<'static, str>,
3085/// Box<str>}` forward-projection corner already return.
3086///
3087/// Closes the substrate-wide trait-idiomatic
3088/// [`std::sync::Arc<str>`] forward-projection family opened one
3089/// commit prior (b05724e) on the paired owned-input
3090/// [`From<RestartPolicy> for std::sync::Arc<str>`] impl — closes
3091/// the `{Self, &Self}` input-shape corner of the
3092/// [`std::sync::Arc<str>`] axis on the second (and third-and-final)
3093/// M2 OTP-shape closed-set fieldless typed enum peer on the caixa
3094/// surface, exactly as b3e72d7 closed the paired
3095/// [`std::sync::Arc<str>`] corner on the sibling-restart
3096/// [`RestartStrategy`] first-mover one commit after its owning half
3097/// (bca2ec8) landed, and as cb1d068 closed the paired [`Box<str>`]
3098/// corner on this enum one commit after its owning half (0a1b313)
3099/// landed. Rust's standard library carries `impl From<&str> for
3100/// std::sync::Arc<str>` and `impl From<String> for
3101/// std::sync::Arc<str>` but no blanket `impl<T: AsRef<str>> From<&T>
3102/// for std::sync::Arc<str>` (nor a `Copy`-based `impl<T: Copy,
3103/// U: From<T>> From<&T> for U`), so every closed-set fieldless typed
3104/// enum peer on the substrate that carries the paired owned-input
3105/// [`std::sync::Arc<str>`] axis but not the borrowed-input axis
3106/// forces every borrowed-input [`std::sync::Arc<str>`]-parameterized
3107/// call site through a spurious [`Copy`] deref
3108/// (`std::sync::Arc::<str>::from((*policy).as_str())`) or a
3109/// `std::sync::Arc::<str>::from(policy.as_str())` open-code whose
3110/// type bounds have no compile-time link back to the substrate
3111/// primitive.
3112///
3113/// Pinned load-bearing by
3114/// [`tests::restart_policy_from_borrowed_into_arc_str_routes_through_as_str_accessor`]
3115/// (byte-parity pin against [`RestartPolicy::as_str`] across the
3116/// three-arm [`RestartPolicy::ALL`] emit-set on the borrowed-input
3117/// surface, plus a blanket-derived [`Into`] shape witness, a
3118/// cross-axis pin against the paired owned-input
3119/// [`From<RestartPolicy> for std::sync::Arc<str>`] and the sibling
3120/// borrowed-input `{&'static str, String, Cow<'static, str>,
3121/// Box<str>}` return-shape axes, and a
3122/// `.iter().map(std::sync::Arc::<str>::from)` pipe witness over
3123/// [`RestartPolicy::ALL`]).
3124impl From<&RestartPolicy> for std::sync::Arc<str> {
3125 fn from(policy: &RestartPolicy) -> std::sync::Arc<str> {
3126 std::sync::Arc::<str>::from(policy.as_str())
3127 }
3128}
3129
3130/// Trait-idiomatic byte-view surface on the per-child restart-decision
3131/// policy typed enum.
3132///
3133/// Every consumer that binds its input through the standard-library
3134/// [`AsRef<[u8]>`] trait bound — a byte-keyed
3135/// `HashMap<K: AsRef<[u8]>, V>` per-policy reconciliation-decision
3136/// table lookup on the future wasm-operator supervisor scheduler; a
3137/// `blake3::Hasher::update` / `ring::digest::Context::update` /
3138/// `sha2::Sha256::update` byte-input surface on any future per-child
3139/// content-address digest folded into the [`crate::Lacre`] closure so
3140/// downstream cache-keys partition on the three OTP restart policies
3141/// (`Permanent`, `Temporary`, `Transient`) at content-address time; an
3142/// `std::io::Write::write_all`-bound structured-log per-arm byte-sink —
3143/// reaches the substrate primitive through one trait dispatch rather
3144/// than open-coding the two-hop `restart.as_str().as_bytes()`
3145/// composition at every call site. Routed byte-for-byte through the
3146/// [`RestartPolicy::as_str`] `pub const fn` accessor the paired
3147/// str-view ([`AsRef<str>`], [`std::fmt::Display`],
3148/// [`RestartPolicy::as_str`]) and the five reverse-projection
3149/// (`&'static str`, `String`, `Cow<'static, str>`, `Box<str>`,
3150/// `std::sync::Arc<str>`) return-shape axes already resolve through,
3151/// so any future divergence between the byte-view and str-view axes
3152/// trips at caixa-core test time rather than at a downstream byte-
3153/// consumer's silent split.
3154///
3155/// Peer of the sibling per-supervisor-restart-strategy axis
3156/// [`AsRef<[u8]> for RestartStrategy`] (cd4c4e0, the first M2-OTP-
3157/// shape supervisor slot enum to open this axis) — the sixth
3158/// closed-set fieldless typed enum on the caixa surface to converge
3159/// onto the trait-idiomatic byte-view discipline, and the second (and
3160/// final) M2-OTP-shape sibling to pick it up, closing the byte-view
3161/// axis across the paired `:supervisor :estrategia` +
3162/// `:children :restart` M2 slot pair. Pin load-bearing by the paired
3163/// [`tests::restart_policy_as_ref_bytes_routes_through_as_str_accessor`]
3164/// (fail-before-pass-after byte-parity pin against
3165/// [`RestartPolicy::as_str`] `.as_bytes()` across the three-arm
3166/// [`RestartPolicy::ALL`] emit-set, cross-axis witness against the
3167/// paired str-view [`AsRef<str>`] / [`std::fmt::Display`] /
3168/// [`RestartPolicy::as_str`] axes' `.as_bytes()` byte-tails,
3169/// cross-axis witness against the paired reverse-projection
3170/// `{&'static str, String, Cow<'static, str>, Box<str>,
3171/// std::sync::Arc<str>}` return-shape axes' `.as_bytes()` byte-tails,
3172/// a `<T: AsRef<[u8]>>`-bound-consumer witness that a generic
3173/// byte-input function accepts a [`RestartPolicy`] directly through
3174/// the trait bound, and a `blake3::Hasher::update`-shape byte-input
3175/// surface witness routed through the `<T: AsRef<[u8]>>`-bound
3176/// consumer axis to reach the caixa-lacre compounding target). Any
3177/// future silent detour that routes the byte-view impl off the
3178/// substrate-primitive [`RestartPolicy::as_str`] accessor (a per-arm
3179/// inline `b"Permanent".as_slice()`-shaped re-inlining that opens a
3180/// compile-time link to the un-lifted arm-literal, a swap onto the
3181/// kebab-case [`gen_platform::Discriminant`] catalog identity that
3182/// would collide the wire axis with the dispatcher-catalog axis) trips
3183/// at caixa-core test time rather than at a downstream byte-consumer's
3184/// silent split.
3185impl AsRef<[u8]> for RestartPolicy {
3186 fn as_ref(&self) -> &[u8] {
3187 self.as_str().as_bytes()
3188 }
3189}
3190
3191/// Trait-idiomatic *owned-input, owned-`Vec<u8>` output* byte-owned
3192/// reverse projection on the second (and final) M2 OTP-shape closed-set
3193/// fieldless typed enum peer on the caixa surface ([`RestartPolicy`]) —
3194/// the byte-mirror of the [`From<RestartPolicy> for String`] str-owned
3195/// reverse-projection axis and the owned-`Vec<u8>` reverse-projection
3196/// sibling of the paired [`AsRef<[u8]>`] borrowed byte-view axis
3197/// (98b08fa) lifted on this same enum. Routes byte-for-byte through
3198/// the substrate-primitive [`RestartPolicy::as_str`] `pub const fn`
3199/// accessor via [`str::as_bytes`] + [`slice::to_vec`] so every
3200/// consumer that binds a [`RestartPolicy`] through the standard-
3201/// library `impl From<RestartPolicy> for Vec<u8>` axis
3202/// (equivalently `<T: Into<Vec<u8>>>`) — a future
3203/// [`std::io::Write::write_all`]-shape per-child audit-log byte-sink
3204/// whose input parameter is an owned [`Vec<u8>`] payload, a future
3205/// `bytes::Bytes::from(Vec::<u8>::from(restart))` composer folding
3206/// the per-arm restart-decision-policy byte-tag into the
3207/// [`bytes::Bytes`] framing surface, a future
3208/// `hasher.update(&Vec::<u8>::from(restart))`-shape BLAKE3 content-
3209/// address closure that needs the owned byte-tail buffered before
3210/// folding into the [`crate::Lacre`] closure body, a future per-child
3211/// protobuf/CBOR/msgpack payload composer whose framer takes an owned
3212/// [`Vec<u8>`] rather than a borrowed byte-slice — reaches the
3213/// substrate primitive through one trait dispatch rather than an
3214/// open-coded per-call-site `restart.as_str().as_bytes().to_vec()`
3215/// composition whose type bounds have no compile-time link back to
3216/// the substrate primitive.
3217///
3218/// Closes the substrate-wide trait-idiomatic byte-owned reverse-
3219/// projection axis on the M2-OTP-shape `:supervisor :estrategia` +
3220/// `:children :restart` slot pair the sibling
3221/// [`RestartStrategy`] first-mover (63e5dd0) opened one commit prior,
3222/// matching the discipline the paired [`AsRef<[u8]>`] borrowed byte-
3223/// view axis campaign already carried across the same slot pair
3224/// (cd4c4e0 → 98b08fa). Every future arm addition (an OTP-
3225/// `intrinsic` fourth arm the theory
3226/// [`ABSORPTION-ROADMAP`](https://github.com/pleme-io/theory/blob/main/ABSORPTION-ROADMAP.md)
3227/// might reach for once the three canonical OTP restart policies
3228/// stop covering the substrate's discovered load-shape) grows the
3229/// byte-owned axis through one edit on the substrate-primitive
3230/// [`RestartPolicy::as_str`] accessor.
3231///
3232/// Pinned load-bearing by
3233/// [`tests::restart_policy_from_into_owned_vec_bytes_routes_through_as_str_accessor`]
3234/// (byte-parity pin against [`RestartPolicy::as_str`] across the
3235/// three-arm [`RestartPolicy::ALL`] emit-set binding the byte-owned
3236/// reverse-projection axis against the paired [`AsRef<[u8]>`]
3237/// borrowed byte-view axis and the str-owned reverse-projection
3238/// family (`String`, `Cow<'static, str>`, `Box<str>`,
3239/// `std::sync::Arc<str>`) `.into_bytes()` / `.as_bytes().to_vec()`
3240/// byte-tails, a `<T: Into<Vec<u8>>>`-bound generic-consumer witness,
3241/// and a `std::io::Write::write_all`-shape owned-byte-sink surface
3242/// witness on both owned and borrowed input shapes).
3243impl From<RestartPolicy> for Vec<u8> {
3244 fn from(policy: RestartPolicy) -> Vec<u8> {
3245 policy.as_str().as_bytes().to_vec()
3246 }
3247}
3248
3249/// Trait-idiomatic *borrowed-input, owned-`Vec<u8>` output* byte-
3250/// owned reverse projection on the second (and final) M2 OTP-shape
3251/// closed-set fieldless typed enum peer on the caixa surface
3252/// ([`RestartPolicy`]) — the borrowed-input peer of
3253/// [`From<RestartPolicy> for Vec<u8>`], closing the
3254/// `{Self, &Self} → Vec<u8>` pair on the byte-owned reverse-projection
3255/// axis in one lift. Routes byte-for-byte through the substrate-
3256/// primitive [`RestartPolicy::as_str`] `pub const fn` accessor so
3257/// every consumer that holds a borrowed [`&RestartPolicy`] and needs
3258/// an owned [`Vec<u8>`] — a future
3259/// `.iter().map(Vec::<u8>::from).collect()` pipe over
3260/// `&[RestartPolicy]` (whose iterator yields `&RestartPolicy`,
3261/// not `RestartPolicy`, so the owned-input axis alone forces every
3262/// call site through an explicit `.copied()` / spurious [`Copy`]
3263/// deref restatement rather than the direct trait-idiomatic
3264/// projection), a future admission-webhook rejection body composer
3265/// that walks [`RestartPolicy::ALL`] through an `Into<Vec<u8>>`-
3266/// bound per-arm byte-writer to surface the accepted `:children
3267/// :restart` set — reaches the substrate primitive through one
3268/// trait dispatch rather than a `Vec::<u8>::from(*policy)` spurious-
3269/// [`Copy`]-deref restatement.
3270impl From<&RestartPolicy> for Vec<u8> {
3271 fn from(policy: &RestartPolicy) -> Vec<u8> {
3272 policy.as_str().as_bytes().to_vec()
3273 }
3274}
3275
3276/// Trait-idiomatic *borrowed byte-slice input* reverse projection on the
3277/// second (and final) M2-OTP-shape closed-set fieldless typed enum peer on
3278/// the caixa surface ([`RestartPolicy`]) — the byte-view mirror of the
3279/// str-view reverse-projection axis carried by the paired
3280/// [`TryFrom<&str> for RestartPolicy`] impl (which routes through the
3281/// substrate-primitive [`RestartPolicy::from_wire`] `Option<Self>` accessor
3282/// on the three-arm `PascalCase` accept-set the sibling
3283/// [`RestartPolicy::as_str`] emitter returns). Routes byte-for-byte through
3284/// the standard-library [`std::str::from_utf8`] UTF-8 validator and then
3285/// through [`RestartPolicy::from_wire`] so every consumer that holds a
3286/// borrowed [`&[u8]`] and needs to project it back into a typed
3287/// [`RestartPolicy`] — a future `bytes::Bytes::as_ref()`-fed reader that
3288/// parses a per-child `:restart` `PascalCase` wire scalar from an
3289/// already-borrowed framing byte-tail (a
3290/// `tracing::field::valuable::Value::Bytes` recorder on the future
3291/// wasm-operator's per-child restart-decision diagnostic emission path, a
3292/// future audit-report re-loader binding a prior
3293/// [`RestartPolicy::as_str`] output from a mmap'd byte-slice back through
3294/// the typed enum for cross-run comparison), a future M4
3295/// `mesh.pleme.io/v1alpha1/Supervisor` CR admission-webhook rejection body
3296/// that reads a `spec.children[].restart` field off a raw HTTP body
3297/// byte-slice before UTF-8 validation commits allocation, a future generic
3298/// `<T: for<'a> TryFrom<&'a [u8]>>`-bound loader over any of the
3299/// substrate's closed-set typed enums — reaches the same three-arm
3300/// `PascalCase` wire accept-set the sibling method-named
3301/// [`RestartPolicy::from_wire`] resolver and the paired trait-idiomatic
3302/// [`TryFrom<&str>`] axis already resolve against, rather than an open-
3303/// coded per-call-site
3304/// `std::str::from_utf8(bytes).ok().and_then(RestartPolicy::from_wire)`
3305/// composition or a
3306/// `<RestartPolicy as TryFrom<&str>>::try_from(std::str::from_utf8(bytes)?)`
3307/// two-hop shape whose type bounds have no compile-time link to the
3308/// substrate primitive.
3309///
3310/// Closes the substrate-wide trait-idiomatic *byte-view reverse-projection*
3311/// family on the M2-OTP-shape `:supervisor :estrategia` + `:children
3312/// :restart` slot pair the sibling [`RestartStrategy`] first-mover
3313/// (c699a83) opened one commit prior — extends the family from
3314/// [`crate::CaixaKind`] (18d1940), [`crate::CaixaDialeto`] (d102cb8),
3315/// [`crate::dep::DepList`] (b8f25d5), and [`RestartStrategy`] (c699a83)
3316/// onto the second (and final) M2-OTP-shape closed-set fieldless typed
3317/// enum peer on the caixa surface, matching the trajectory the paired
3318/// byte-owned reverse-projection axis campaign already walked across the
3319/// same slot pair (63e5dd0 → 96a522a). Rust's standard library carries no
3320/// blanket `impl<T: for<'a> TryFrom<&'a str>> TryFrom<&[u8]> for T`, so a
3321/// two-hop composition through [`std::str::from_utf8`] + the paired
3322/// [`TryFrom<&str>`] axis is reachable at every call site but has no
3323/// compile-time link back to the byte-view reverse-projection axis. Every
3324/// remaining closed-set fieldless typed enum peer on the substrate
3325/// ([`crate::aplicacao::PlacementStrategy`],
3326/// [`crate::aplicacao::RateLimitUnit`], [`crate::aplicacao::WitShape`],
3327/// and the outside-`caixa-core` peers `PathShapeViolation`,
3328/// `InvariantKind`, `ArchVerdict`, `Severity`, `FixSafety`, `Semantic`,
3329/// `FerriteRuntime`) is a future target of the campaign.
3330///
3331/// `type Error = ()` matches the sibling [`RestartPolicy::from_wire`]'s
3332/// `Option<Self>` return-shape's deliberate deferral of error typing and
3333/// the paired trait-idiomatic [`TryFrom<&str>`] axis's unit-error shape —
3334/// the caller picks the diagnostic form appropriate for its use site (a
3335/// future `feira supervisor --restart …` arg-parse composes its own
3336/// per-verb "unknown restart policy: <arg> — accepted: {…}" message
3337/// enumerating [`RestartPolicy::WIRE_NAMES`]; a future admission-webhook
3338/// rejection body wraps the `Err(())` outcome with the accepted-set
3339/// enumeration for operator diagnostics; a `Result::map_err` at the call
3340/// site lifts the unit-error to a per-verb error type). Two rejection
3341/// paths route through the single unit-error: an invalid UTF-8
3342/// byte-sequence ([`std::str::from_utf8`] returns `Err`) and a valid UTF-8
3343/// byte-string that falls outside the three-arm `PascalCase` accept-set
3344/// ([`RestartPolicy::from_wire`] returns `None`) — both collapse onto
3345/// `Err(())` so the trait signature stays consistent with the sibling
3346/// str-view reverse axis, and a caller that needs to distinguish the two
3347/// failure modes composes [`std::str::from_utf8`] +
3348/// [`RestartPolicy::from_wire`] explicitly.
3349///
3350/// Pinned load-bearing by
3351/// [`tests::restart_policy_try_from_bytes_routes_through_from_wire_accessor`]
3352/// (byte-parity pin against [`RestartPolicy::from_wire`] across the
3353/// three-arm [`RestartPolicy::ALL`] accept-set on the borrowed byte-slice
3354/// surface, plus a cross-axis witness that the byte-view reverse
3355/// projection agrees with the paired [`TryFrom<&str>`] str-view reverse
3356/// axis on every accepted arm, and a forward/reverse byte-view cross-axis
3357/// witness that feeding the paired [`AsRef<[u8]>`] byte-tail back through
3358/// the new impl round-trips to the originating arm) and
3359/// [`tests::restart_policy_try_from_bytes_rejects_unknown_and_non_utf8_bytes`]
3360/// (rejection witness against silent accept-set widening on both the
3361/// non-UTF-8 byte-sequence rejection path and the unknown-wire-vocabulary
3362/// rejection path — the latter includes the sibling kebab-case
3363/// dispatcher-catalog byte-strings on the two-axis wire/catalog split so
3364/// a caller that confuses the two axes trips here rather than at a
3365/// downstream K8s-CR round-trip miss).
3366impl TryFrom<&[u8]> for RestartPolicy {
3367 type Error = ();
3368
3369 fn try_from(bytes: &[u8]) -> Result<Self, Self::Error> {
3370 std::str::from_utf8(bytes)
3371 .ok()
3372 .and_then(Self::from_wire)
3373 .ok_or(())
3374 }
3375}
3376
3377/// Trait-idiomatic *owned byte-vec input* reverse projection on the second
3378/// (and final) M2-OTP-shape supervisor-slot closed-set fieldless typed enum
3379/// peer on the caixa surface ([`RestartPolicy`]) — the owned-input peer of
3380/// [`TryFrom<&[u8]> for RestartPolicy`], closing the byte-view reverse-
3381/// projection *square* ({owned-input, borrowed-input} × {owned-output
3382/// byte-vec, borrowed-output byte-slice}) on the M2-OTP-shape
3383/// `:supervisor :estrategia` + `:children :restart` slot pair the sibling
3384/// [`RestartStrategy`] first-mover (34951fe) opened on the byte-owned
3385/// reverse-input axis one commit-window prior. Routes byte-for-byte through
3386/// [`<Self as TryFrom<&[u8]>>::try_from`] on the [`Vec<u8>::as_slice`]
3387/// borrow so the owned-input surface reaches the same
3388/// [`std::str::from_utf8`] + [`RestartPolicy::from_wire`] resolution chain
3389/// the borrowed-input peer already carries — one substrate-primitive
3390/// accessor, one trait dispatch, no per-consumer detour.
3391///
3392/// Rust's standard library carries no blanket
3393/// `impl<T: for<'a> TryFrom<&'a [u8]>> TryFrom<Vec<u8>> for T`, so a
3394/// consumer that holds an owned [`Vec<u8>`] and needs a typed
3395/// [`RestartPolicy`] otherwise picks between (a) an open-coded
3396/// `<RestartPolicy as TryFrom<&[u8]>>::try_from(bytes.as_slice())` at every
3397/// call site (whose type bounds have no compile-time link to the byte-
3398/// owned reverse-projection axis), (b) a two-hop
3399/// `String::from_utf8(bytes)` + [`RestartPolicy::from_wire`] composition
3400/// whose error surface leaks the standard-library
3401/// [`std::string::FromUtf8Error`] (widening the sibling [`TryFrom<&[u8]>`]
3402/// axis's unit-error) and silently allocates a [`String`] on inputs that
3403/// will never make it past the wire vocabulary, or (c) an intermediate
3404/// `<RestartPolicy as TryFrom<&str>>::try_from(std::str::from_utf8(&bytes)?)`
3405/// three-hop shape. This impl closes the owned-byte-vec reverse-projection
3406/// axis at the substrate-primitive [`RestartPolicy::from_wire`] accessor so
3407/// every future `<T: TryFrom<Vec<u8>>>`-bound owned-byte-vec consumer — a
3408/// future M4 `mesh.pleme.io/v1alpha1/Supervisor` CR admission-webhook body
3409/// reader that hands the `spec.children[].restart` byte-tail off as a
3410/// [`Vec<u8>`] before UTF-8 validation commits allocation, a
3411/// `bytes::Bytes::to_vec()`-shape wire-body composer walking a prior
3412/// audit's per-child rejection payload back to the typed enum, a
3413/// `std::io::Read::read_to_end`-shape audit-log source whose framing yields
3414/// an owned byte-vec per per-policy scalar, an
3415/// `<T: TryFrom<Vec<u8>>>`-bound generic loader over any of the
3416/// substrate's closed-set typed enums — reaches the same three-arm
3417/// `PascalCase` wire accept-set through one trait dispatch.
3418///
3419/// Extends the substrate-wide trait-idiomatic *byte-owned reverse-
3420/// projection* family — opened on the structurally most fundamental
3421/// closed-set fieldless typed enum peer ([`crate::CaixaKind`], commit
3422/// 99c2849), extended onto the second caixa-core-internal peer
3423/// ([`crate::CaixaDialeto`], commit 83a1526), the third
3424/// ([`crate::dep::DepList`], commit 42091cb), and the first M2-OTP-shape
3425/// supervisor-slot peer ([`RestartStrategy`], commit 34951fe) — onto the
3426/// second (and final) M2-OTP-shape supervisor-slot closed-set fieldless
3427/// typed enum peer, tracking the "delegate through `TryFrom<&[u8]>` on the
3428/// `Vec<u8>::as_slice` borrow" discipline the first-mover established.
3429/// Every remaining closed-set fieldless typed enum peer on the substrate
3430/// ([`crate::aplicacao::PlacementStrategy`],
3431/// [`crate::aplicacao::RateLimitUnit`], [`crate::aplicacao::WitShape`],
3432/// [`crate::render::PathShapeViolation`], and the outside-`caixa-core`
3433/// peers `InvariantKind`, `ArchVerdict`, `Severity`, `FixSafety`,
3434/// `Semantic`, `FerriteRuntime`) is a future target of the campaign,
3435/// mirroring the trajectory the closed byte-view reverse-projection
3436/// family (`TryFrom<&[u8]>`) and the closed byte-owned forward-projection
3437/// family (`From<{Self, &Self}> for Vec<u8>`) already walked across the
3438/// same slot pair.
3439///
3440/// `type Error = ()` matches the sibling [`TryFrom<&[u8]> for
3441/// RestartPolicy`] unit-error shape, preserving the trait-family
3442/// consistency across the borrowed-and-owned byte-view reverse-projection
3443/// pair. The owned [`Vec<u8>`] input is dropped on the error path (the
3444/// standard-library `String::from_utf8` convention of returning the input
3445/// in the error deliberately declined — a caller that needs the bytes back
3446/// holds a clone before the call, and the closed-set-enum use site rarely
3447/// wants the raw bytes back past a "did you mean" diagnostic that operates
3448/// on the wire vocabulary rather than the input).
3449///
3450/// Pinned load-bearing by
3451/// [`tests::restart_policy_try_from_vec_bytes_routes_through_borrowed_byte_view_axis`]
3452/// (byte-parity pin against the paired borrowed [`TryFrom<&[u8]>`] axis
3453/// across the three-arm [`RestartPolicy::ALL`] accept-set on the owned
3454/// byte-vec surface, cross-axis witness that the byte-owned reverse
3455/// projection agrees with the paired str-view reverse-projection axis
3456/// ([`TryFrom<&str>`]) on every accepted arm through the shared substrate-
3457/// primitive [`RestartPolicy::from_wire`] accessor, and a four-corner
3458/// {owned-input, borrowed-input} × {`From<Self>` → `Vec<u8>`,
3459/// `From<&Self>` → `Vec<u8>`} round-trip witness available on this enum
3460/// because [`RestartPolicy::as_str`] and [`RestartPolicy::from_wire`]
3461/// share one `PascalCase` byte-vocabulary — like the sibling
3462/// [`RestartStrategy`] and unlike the sibling [`crate::CaixaKind`] which
3463/// its peer test deliberately declines the four-corner witness on because
3464/// the wire/diagnostic split makes the forward and reverse pairs speak
3465/// different byte-strings) and
3466/// [`tests::restart_policy_try_from_vec_bytes_rejects_unknown_and_non_utf8_bytes`]
3467/// (rejection witness against silent accept-set widening on both the
3468/// non-UTF-8 byte-sequence rejection path and the unknown-wire-vocabulary
3469/// rejection path — the latter includes the sibling kebab-case
3470/// dispatcher-catalog byte-strings on the two-axis wire/catalog split so
3471/// a caller that confuses the two axes trips here rather than at a
3472/// downstream K8s-CR round-trip miss, plus a cross-axis witness that the
3473/// owned byte-vec reverse-projection axis agrees with the borrowed byte-
3474/// slice reverse-projection axis on every rejected input).
3475impl TryFrom<Vec<u8>> for RestartPolicy {
3476 type Error = ();
3477
3478 fn try_from(bytes: Vec<u8>) -> Result<Self, Self::Error> {
3479 <Self as TryFrom<&[u8]>>::try_from(bytes.as_slice())
3480 }
3481}
3482
3483/// Trait-idiomatic *owned-`String` input, `Result<Self, ()>` output*
3484/// string-owned reverse projection on the second (and final) M2-OTP-shape
3485/// supervisor-slot closed-set fieldless typed enum peer on the caixa
3486/// surface ([`RestartPolicy`]) — the owned-input peer of the paired
3487/// [`TryFrom<&str> for RestartPolicy`] str-view reverse-projection axis,
3488/// and the string-owned reverse companion of the pre-existing string-owned
3489/// *forward* pair ([`From<RestartPolicy> for String`],
3490/// [`From<&RestartPolicy> for String`]) already lifted on this same enum.
3491/// Routes owned [`String`] input through the paired borrowed-input
3492/// [`TryFrom<&str>`] axis via [`String::as_str`] so every consumer that
3493/// holds an owned `String` — a future M4 `mesh.pleme.io/v1alpha1/Supervisor`
3494/// CR admission-webhook body reader that hands the
3495/// `spec.children[].restart` `PascalCase` scalar off as an owned [`String`]
3496/// after UTF-8 validation, a `serde_yaml::from_str` / `serde_json::from_str`
3497/// de-serialize round-trip whose composer surfaces the `:children :restart`
3498/// scalar as an owned [`String`] typed field, a
3499/// `feira supervisor --restart <Permanent|Temporary|Transient>`
3500/// `clap`-derived arg-parse whose owned-`String` positional lands the
3501/// canonical arm at the typed dispatch, a per-`:children`-slot overlay
3502/// resolver reading an owned [`String`] out of a `ConfigMap`
3503/// `data.children-restart` scalar, an `<T: TryFrom<String>>`-bound generic
3504/// loader over any of the substrate's closed-set typed enums — reaches the
3505/// same three-arm `PascalCase` accept-set through one trait dispatch.
3506///
3507/// Extends the substrate-wide trait-idiomatic *string-owned reverse-
3508/// projection* family — opened on the compound M3-mesh
3509/// `:politicas :rate-limit` primitive [`crate::aplicacao::RateLimit`]
3510/// (a2e6f02), lifted onto the first closed-set fieldless typed-enum peer
3511/// [`crate::aplicacao::WitShape`] (e6aac29), extended onto the second
3512/// closed-set fieldless typed-enum peer [`crate::aplicacao::RateLimitUnit`]
3513/// (94a9c5e), extended onto the third closed-set fieldless typed-enum peer
3514/// [`crate::aplicacao::PlacementStrategy`] (d81a70a), extended onto the
3515/// first M2-OTP-shape supervisor-slot closed-set fieldless typed-enum peer
3516/// [`RestartStrategy`] (78fe8c8) — onto the second (and final) M2-OTP-shape
3517/// supervisor-slot closed-set fieldless typed-enum peer, the per-`:children`
3518/// restart-decision-policy discriminator. This closes the string-owned
3519/// reverse-projection axis on the M2-OTP-shape `:supervisor :estrategia` +
3520/// `:children :restart` slot pair, mirroring the trajectory the byte-view
3521/// / byte-owned / str-view reverse-projection families already walked
3522/// across the same slot pair. The peers [`crate::CaixaKind`],
3523/// [`crate::CaixaDialeto`], and [`crate::dep::DepList`] remain the next
3524/// targets of the campaign.
3525///
3526/// Rust's standard library carries no blanket
3527/// `impl<T: for<'a> TryFrom<&'a str>> TryFrom<String> for T`, so a consumer
3528/// that holds an owned [`String`] and needs a typed [`RestartPolicy`]
3529/// otherwise picks between (a) an open-coded
3530/// `<RestartPolicy as TryFrom<&str>>::try_from(s.as_str())` at every call
3531/// site whose type bounds have no compile-time link back to the string-
3532/// owned reverse-projection axis, (b) a `let s: &str = &s;
3533/// RestartPolicy::try_from(s)` two-step whose borrow arithmetic leaks a
3534/// per-call-site lifetime dance rather than a single trait dispatch, or
3535/// (c) a `String::into_bytes` + [`TryFrom<Vec<u8>>`] detour that reaches
3536/// the substrate-primitive `from_wire` accessor through a UTF-8 re-
3537/// validation hop the owned-`String` axis already knows to skip. This
3538/// impl closes the string-owned reverse-projection axis at the substrate-
3539/// primitive [`RestartPolicy::from_wire`] accessor so every future
3540/// `<T: TryFrom<String>>`-bound owned-string consumer reaches the same
3541/// three-arm `PascalCase` accept-set through one trait dispatch.
3542///
3543/// `type Error = ()` matches the sibling [`TryFrom<&str> for
3544/// RestartPolicy`], [`TryFrom<&[u8]> for RestartPolicy`], and
3545/// [`TryFrom<Vec<u8>> for RestartPolicy`] unit-error shapes, preserving
3546/// the trait-family consistency across the {str-view, byte-view, byte-
3547/// owned, string-owned} reverse-projection square. The owned [`String`]
3548/// input is dropped on the error path (the standard-library
3549/// `String::from_utf8` convention of returning the input in the error
3550/// deliberately declined — a caller that needs the string back holds a
3551/// clone before the call, and the closed-set-enum use site rarely wants
3552/// the raw string back past a "did you mean" diagnostic that operates on
3553/// the wire vocabulary rather than the input).
3554///
3555/// Pinned load-bearing by
3556/// [`tests::restart_policy_try_from_owned_string_routes_through_borrowed_str_view_axis`]
3557/// (byte-parity pin against the paired borrowed [`TryFrom<&str>`] axis
3558/// across the three-arm [`RestartPolicy::ALL`] accept-set on the owned-
3559/// `String` surface, cross-axis witness that the string-owned reverse
3560/// projection agrees with the sibling byte-view / byte-owned reverse-
3561/// projection axes on every accepted arm through the shared substrate-
3562/// primitive [`RestartPolicy::from_wire`] accessor, and a closed-cycle
3563/// witness against the paired string-owned forward-projection pair —
3564/// `Self → String → TryFrom<String> → Self` round-trips to the
3565/// originating arm on every canonical `PascalCase` scalar) and
3566/// [`tests::restart_policy_try_from_owned_string_rejects_unknown_wire_strings`]
3567/// (rejection witness against silent accept-set widening — mirrors the
3568/// corpus the paired [`TryFrom<&str>`] rejection witness already pins,
3569/// including empty / whitespace-only inputs, the sibling kebab-case
3570/// dispatcher-catalog byte-strings on the two-axis wire/catalog split so
3571/// a caller that confuses the two axes trips here rather than at a
3572/// downstream K8s-CR round-trip miss, case-fold rebrand candidates,
3573/// whitespace-padded / trailing-newline / quote-wrapped forms, and
3574/// English-rebrand candidates, with per-input cross-axis parity against
3575/// the borrowed [`TryFrom<&str>`] reverse-projection axis).
3576impl TryFrom<String> for RestartPolicy {
3577 type Error = ();
3578
3579 fn try_from(s: String) -> Result<Self, Self::Error> {
3580 <Self as TryFrom<&str>>::try_from(s.as_str())
3581 }
3582}
3583
3584// Fleet-wide dispatcher-catalog registrations for caixa's OTP
3585// supervisor surface — two more typed shadows over Erlang/OTP
3586// primitives the substrate now mechanically tracks (see
3587// theory/UNIFIED-COMPUTING-MODEL.md §VI for the roadmap +
3588// theory/TYPED-ABSORPTION.md for the absorption arc).
3589gen_platform::register_dispatcher!("caixa.restart-strategy", RestartStrategy);
3590gen_platform::register_dispatcher!("caixa.restart-policy", RestartPolicy);
3591
3592/// One child entry in the supervisor's `:children` list.
3593///
3594/// Every child references another caixa by `:caixa <nome>` + version
3595/// constraint. The supervisor materializes one ComputeUnit per entry.
3596#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq)]
3597#[serde(rename_all = "camelCase")]
3598pub struct ChildSpec {
3599 /// The child caixa's `:nome`. Must resolve via the same dependency
3600 /// resolution path as `:deps` (caixa-resolver).
3601 pub caixa: String,
3602
3603 /// Semver constraint (`"^0.1"`, `"~0.1.2"`, etc.) — same shape as
3604 /// [`crate::dep::Dep::versao`].
3605 pub versao: String,
3606
3607 /// Restart policy — an author-omitted slot degrades onto the
3608 /// substrate-canonical [`SUPERVISOR_CHILD_RESTART_DEFAULT`]
3609 /// (`permanent`, the Erlang/OTP worker-child default) through the
3610 /// [`Default for RestartPolicy`] impl this `#[serde(default)]` routes
3611 /// to.
3612 #[serde(default)]
3613 pub restart: RestartPolicy,
3614}
3615
3616impl ChildSpec {
3617 /// Substrate-canonical per-`:children` child-caixa `:nome` scalar
3618 /// accessor every consumer that reads the OTP-shape supervised
3619 /// child's identity keys off — returns the author-declared
3620 /// `:children :caixa` byte-string verbatim as a `&str`, borrowed
3621 /// from the typed slot's own [`String`] storage.
3622 ///
3623 /// The `:children :caixa` slot carries the DNS-1123 label — the
3624 /// child caixa's `:nome` — that every emitted cluster artifact
3625 /// derives its `metadata.name` from verbatim: the rendered
3626 /// `wasm.pleme.io/v1alpha1/ComputeUnit.metadata.name` per child, the
3627 /// [`crate::LABEL_PROGRAM`] label value on every child's pod
3628 /// identity, and the per-child K8s Service `metadata.name` the
3629 /// future wasm-operator (M3) provisions for inter-child supervision-
3630 /// tree wiring. Every downstream consumer that fans on the child's
3631 /// caixa-name keys off this scalar (the [`SupervisorSpec::validate`]
3632 /// per-child DNS-1123 gate at
3633 /// `require_valid_dns_1123_label(child.nome(), …)`, the per-child
3634 /// duplicate-detection [`crate::render::insert_first_seen`] key, the
3635 /// [`validate_no_self_supervision`] cross-slot equality check
3636 /// against the parent's `:nome`, every `SupervisorError` variant
3637 /// carrying the offending child caixa verbatim for `feira lint`
3638 /// rendering, the future wasm-operator's hierarchical reconciliation
3639 /// scheduler's per-child ComputeUnit-name projection, the future M4
3640 /// `mesh.pleme.io/v1alpha1/Supervisor` CR materializer's per-child
3641 /// admission webhook).
3642 ///
3643 /// Prior to this lift the `.caixa` byte-string was accessed inline
3644 /// at seven sites in `supervisor.rs` — the DNS-1123 gate's
3645 /// `&child.caixa`, the four `SupervisorError::{ChildCaixaInvalid,
3646 /// EmptyChildVersion, ChildVersaoInvalid, DuplicateChildCaixa}`
3647 /// carriers' `child.caixa.clone()`, the dedup key's
3648 /// `child.caixa.as_str()`, and the [`validate_no_self_supervision`]
3649 /// `child.caixa == parent_nome` cross-slot check — seven open-coded
3650 /// field-accesses that expressed no compile-time link back to the
3651 /// typed slot. A future extension of the `:children :caixa` axis to
3652 /// a richer author surface (a per-cluster alias table the operator
3653 /// pins through a future `:placement`-scoped slot on the supervisor
3654 /// tree, a namespace-qualified rewrite the M4 CR materializer
3655 /// applies per-CR, a per-child overlay from the future `:children
3656 /// :nome-suffix` slot the MESH-COMPOSITION §III.2 roadmap
3657 /// acknowledges) would have had to be threaded through every
3658 /// open-coded copy in lockstep or one consumer would silently
3659 /// disagree with the peers on which caixa a given child resolves to
3660 /// — a child-set lookup that treated the name as `"cart-worker"`
3661 /// while the peer duplicate-detector treated it as
3662 /// `"tenant-a/cart-worker"` would silently split the
3663 /// `DuplicateChildCaixa` membership-lookup diagnostic from the
3664 /// self-supervision detector's parent-equality check, a two-consumer
3665 /// split at the validator far from the source `caixa.lisp` with no
3666 /// field naming the identity-drift root cause. Lifting the resolution
3667 /// rule to a typed method on the substrate primitive means every
3668 /// downstream consumer of the Supervisor's per-`:children` identity
3669 /// surface reaches for exactly one typed dispatch — the resolver's
3670 /// accept-set migrates as a unit on any future axis addition.
3671 ///
3672 /// Sibling of the peer per-`:membros` [`crate::Membro::nome`]
3673 /// (4a32abf) member-caixa `:nome` scalar accessor on the M3
3674 /// mesh-slot surface — same "one typed dispatch on the substrate
3675 /// primitive, thin projections at each consumer" discipline extended
3676 /// onto the M2 supervisor-tree per-`:children` child-identity axis.
3677 /// The two typed axes (`Membro::nome` on the M3 Aplicacao side,
3678 /// `ChildSpec::nome` on the M2 Supervisor side) now share one
3679 /// accessor discipline for the shared substrate concept "another
3680 /// caixa referenced by `:nome`". Peer of the second M2 slot scalar
3681 /// accessor [`crate::UpgradeFromEntry::prior_versao`] (75d27a8) on
3682 /// the sibling per-`:upgrade-from :from` OTP-appup axis — the M2
3683 /// slot family's typed-accessor discipline now spans both the
3684 /// upgrade axis (`:upgrade-from`) and the supervision axis
3685 /// (`:children`), matching the closed M3 mesh-slot accessor family's
3686 /// shape. Named `nome()` to match the tatara-lisp author-surface
3687 /// term the field's docstring already reaches for ("The child
3688 /// caixa's `:nome`") and the peer [`crate::Membro::nome`] /
3689 /// [`crate::Caixa::nome`] / [`crate::dep::Dep::nome`] field-name
3690 /// discipline the substrate already carries — the accessor's name
3691 /// maps directly onto the canonical caixa-identity vocabulary rather
3692 /// than shadowing the field's storage-side `caixa` label.
3693 #[must_use]
3694 pub const fn nome(&self) -> &str {
3695 self.caixa.as_str()
3696 }
3697
3698 /// Substrate-canonical per-`:children` child-caixa `:versao` semver-
3699 /// requirement scalar accessor every consumer that reads the OTP-shape
3700 /// supervised child's version pin keys off — returns the author-declared
3701 /// `:children :versao` byte-string verbatim as a `&str`, borrowed from
3702 /// the typed slot's own [`String`] storage.
3703 ///
3704 /// The `:children :versao` slot carries the Cargo-shaped semver
3705 /// requirement string (`"^0.1"`, `"~0.1.2"`, `"0.1.0"`, `"*"`) that pins
3706 /// which release of the supervised child caixa the OTP-shape supervisor
3707 /// tree materializes against — the same requirement grammar the peer
3708 /// `:deps :versao` / `:membros :versao` axes carry, resolved through the
3709 /// shared [`crate::render::require_valid_versao_requirement`] cascade
3710 /// and the shared [`crate::version::parse_requirement`] parser. Every
3711 /// downstream consumer that fans on the child's version pin keys off
3712 /// this scalar (the [`SupervisorSpec::validate`] per-child requirement
3713 /// gate at `require_valid_versao_requirement(child.versao_requirement(),
3714 /// …)`, the [`SupervisorError::ChildVersaoInvalid`] variant's carrier
3715 /// for `feira lint` rendering, every future per-cluster version-lock
3716 /// overlay the caixa-operator's hierarchical reconciliation scheduler
3717 /// pins through a future `:placement`-scoped supervisor-tree slot, the
3718 /// future M4 `mesh.pleme.io/v1alpha1/Supervisor` CR materializer's
3719 /// per-child version resolver, the future wasm-operator's per-child
3720 /// lacre BLAKE3-closure lookup at `ComputeUnit` materialization time).
3721 ///
3722 /// Prior to this lift the `.versao` byte-string was accessed inline at
3723 /// two `&str`-shaped sites in `caixa-core/src/supervisor.rs` — the
3724 /// [`SupervisorSpec::validate`] requirement-gate call
3725 /// `require_valid_versao_requirement(&child.versao, …)` and the
3726 /// [`SupervisorError::ChildVersaoInvalid`] carrier at
3727 /// `versao: child.versao.clone()` — two open-coded field-accesses that
3728 /// expressed no compile-time link back to the typed slot. A future
3729 /// extension of the `:children :versao` axis to a richer author surface
3730 /// (a per-cluster version-pin overlay per MESH-COMPOSITION §III.2 canary
3731 /// flow, a lacre-projected concrete-version rewrite the operator
3732 /// materializes at CR-admission time, a future `:children :versao-lock`
3733 /// per-cluster override slot the wasm-operator's hierarchical
3734 /// reconciliation scheduler authors per-CR) would have had to be
3735 /// threaded through both open-coded copies in lockstep or one consumer
3736 /// would silently disagree with the peer on which release constraint a
3737 /// given child resolves to — the requirement-gate call reading
3738 /// `"^0.1"` while the error-body carrier read `"tenant-a-pin/^0.1"`
3739 /// would silently split the `ChildVersaoInvalid` diagnostic quote from
3740 /// the actual gate rejection input, a two-consumer split at the
3741 /// validator far from the source `caixa.lisp` with no field naming the
3742 /// version-pin drift root cause. Lifting the resolution rule to a typed
3743 /// method on the substrate primitive means every downstream
3744 /// requirement-facing consumer of the Supervisor's per-`:children`
3745 /// version-pin surface reaches for exactly one typed dispatch — the
3746 /// resolver's accept-set migrates as a unit on any future axis addition.
3747 ///
3748 /// Sibling of the peer per-`:membros` [`crate::Membro::versao_requirement`]
3749 /// (a40b0e3) member-caixa `:versao` scalar accessor on the M3 mesh-slot
3750 /// surface — same "one typed dispatch on the substrate primitive, thin
3751 /// projections at each consumer" discipline extended onto the M2
3752 /// supervisor-tree per-`:children` child-version-pin axis. The two typed
3753 /// axes (`Membro::versao_requirement` on the M3 Aplicacao side,
3754 /// `ChildSpec::versao_requirement` on the M2 Supervisor side) now share
3755 /// one accessor discipline for the shared substrate concept "another
3756 /// caixa referenced by a Cargo-shaped semver requirement". Peer of the
3757 /// sibling per-`:children` [`ChildSpec::nome`] (57c61d0) child-caixa
3758 /// `:nome` scalar accessor — the pair
3759 /// `(nome(), versao_requirement())` jointly projects the
3760 /// `(caixa, versao)` field pair every OTP-shape supervisor-tree consumer
3761 /// that fans on per-child identity + version pin keys off, closing the
3762 /// last unlifted per-`:children` `String`-carry axis so every downstream
3763 /// per-`:children` reader now routes through a typed dispatch on the
3764 /// substrate primitive. Named `versao_requirement()` rather than
3765 /// `versao()` because the field's storage-side `.versao` label is
3766 /// already the author-surface term (`:versao`); the accessor's name
3767 /// carries the semantic role — the semver *requirement* string the
3768 /// shared [`crate::version::parse_requirement`] entry-point consumes —
3769 /// so a raw field access and a typed dispatch read differently at every
3770 /// consumer site. Matches the peer [`crate::Membro::versao_requirement`]
3771 /// naming discipline verbatim.
3772 #[must_use]
3773 pub const fn versao_requirement(&self) -> &str {
3774 self.versao.as_str()
3775 }
3776
3777 /// Substrate-canonical per-`:children` `:restart` OTP-shaped
3778 /// per-child post-exit restart-decision policy scalar accessor every
3779 /// consumer that dispatches on the supervised child's post-exit
3780 /// reconcile posture keys off — returns the author-declared
3781 /// `:children :restart` variant verbatim as a [`RestartPolicy`],
3782 /// `Copy`-projected from the typed slot's own [`RestartPolicy`]
3783 /// storage.
3784 ///
3785 /// The `:children :restart` slot carries the closed-set OTP-shaped
3786 /// per-child restart-decision policy discriminator
3787 /// ([`RestartPolicy::Permanent`] — always restart, the OTP `permanent`
3788 /// worker-child default; [`RestartPolicy::Transient`] — restart only
3789 /// on abnormal exit, the OTP `transient` clean-completion-aware
3790 /// default; [`RestartPolicy::Temporary`] — never restart, the OTP
3791 /// `temporary` one-shot default) that every downstream consumer of
3792 /// the Supervisor's per-child post-exit reconcile branch keys off.
3793 /// Every future downstream consumer that fans on the per-child
3794 /// restart-decision keys off this scalar (the future `feira app
3795 /// graph` per-child restart column, the future wasm-operator's
3796 /// per-child post-exit restart-decision branch, the future M4
3797 /// `mesh.pleme.io/v1alpha1/Supervisor` CR materializer's per-child
3798 /// admission webhook, the `caixa-operator`'s hierarchical
3799 /// reconciliation scheduler's per-child post-exit reconcile branch,
3800 /// the [`RestartPolicy::as_str`] `Serialize`-derive-pinning path the
3801 /// [`tests::restart_policy_variants_serialize_to_lifted_scalar_values`]
3802 /// pin threads through).
3803 ///
3804 /// Peer of the sibling per-`:supervisor` [`SupervisorSpec::estrategia`]
3805 /// (eafb619) `Copy`-return [`RestartStrategy`] sibling-restart-strategy
3806 /// scalar accessor and the M3 mesh-slot
3807 /// [`crate::Placement::estrategia`] (921fe1b) `Copy`-return
3808 /// [`crate::PlacementStrategy`] distribution-strategy scalar accessor
3809 /// — same "one typed dispatch on the substrate primitive,
3810 /// `Copy`-projected closed-set enum-arm discriminator that partitions
3811 /// the downstream renderer's per-arm fan-out" discipline extended
3812 /// onto the M2 supervisor-slot per-`:children` restart-decision-policy
3813 /// `Copy`-composite-enum scalar axis. Third axis on the per-`:children`
3814 /// [`ChildSpec`] type — companion to the sibling per-`:children`
3815 /// [`ChildSpec::nome`] (57c61d0) child-caixa `:nome` scalar accessor
3816 /// and the per-`:children` [`ChildSpec::versao_requirement`]
3817 /// (2c053c8) child-caixa `:versao` semver-requirement scalar accessor
3818 /// on the sibling `String`-carry axes. The triple
3819 /// `(nome(), versao_requirement(), restart())` jointly projects the
3820 /// `(caixa, versao, restart)` field trio every OTP-shape supervisor-
3821 /// tree consumer that fans on per-child identity + version pin +
3822 /// restart-decision keys off, closing the last unlifted per-`:children`
3823 /// axis so every downstream per-`:children` reader now routes through
3824 /// a typed dispatch on the substrate primitive. Named `restart()` to
3825 /// match the storage field's name and the author-surface
3826 /// `:children :restart` slot term verbatim; the accessor's identity
3827 /// name maps onto the canonical OTP-shape per-child restart-decision-
3828 /// policy vocabulary the [`RestartPolicy`] enum's docstring already
3829 /// carries.
3830 ///
3831 /// Declared `pub const fn` to close the last non-`const`
3832 /// `Copy`-return raw-field-getter posture on the M2
3833 /// per-`:children` [`ChildSpec`] substrate-primitive surface — peer
3834 /// of the sibling M2 per-`:supervisor`
3835 /// [`SupervisorSpec::estrategia`] (converted in this commit)
3836 /// `Copy`-composite-enum accessor, the sibling M2 per-`:supervisor`
3837 /// [`SupervisorSpec::max_restarts`] (b698ec0) `Copy`-`u32` accessor
3838 /// already lifted, and the peer M3 mesh-slot per-`:entrada`
3839 /// [`crate::Entrada::port`] (bafa004) / per-`:placement`
3840 /// [`crate::Placement::estrategia`] (bafa004) `Copy`-return
3841 /// `pub const fn` scalar accessors on the sibling M3 surface. Every
3842 /// downstream substrate-side `const`-context consumer of the
3843 /// per-`:children` restart-decision-policy scalar (a future
3844 /// module-scope `const _:() = assert!(matches!(child.restart(),
3845 /// RestartPolicy::Permanent))` invariant pin on a typed fixture, a
3846 /// future M4 `mesh.pleme.io/v1alpha1/Supervisor` CR materializer
3847 /// admission-webhook `const fn` per-child restart-decision floor
3848 /// over a typed [`ChildSpec`], any future `const fn` supervisor-tree
3849 /// composer over the substrate primitive that fans on the per-child
3850 /// restart-decision policy at compile time) now reaches through the
3851 /// same typed dispatch on the substrate primitive at const-eval
3852 /// time as at runtime. A future non-`Copy`-return promotion of the
3853 /// scalar (an `Option<RestartPolicy>`-shape migration on the
3854 /// per-child restart-decision axis once heterogeneous per-cluster
3855 /// restart-policy overlays land, a per-tenant restart-policy-alias
3856 /// table the M4 CR materializer resolves per-CR) that would drop
3857 /// the `const` qualifier fails the fail-before-pass-after pin
3858 /// [`tests::child_spec_restart_accessor_is_const_fn`] at caixa-core
3859 /// build time rather than surfacing as a downstream consumer
3860 /// regression.
3861 #[must_use]
3862 pub const fn restart(&self) -> RestartPolicy {
3863 self.restart
3864 }
3865}
3866
3867/// Supervisor-typed slots that live alongside the standard Caixa
3868/// fields when `:kind Supervisor`. Held flat in [`crate::Caixa`] so
3869/// the manifest stays a single typed form; this struct exists for
3870/// validation + conversion.
3871#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq)]
3872#[serde(rename_all = "camelCase")]
3873pub struct SupervisorSpec {
3874 /// Restart strategy. Defaults to [`RestartStrategy::OneForOne`].
3875 #[serde(default)]
3876 pub estrategia: RestartStrategy,
3877
3878 /// Max restarts within [`Self::restart_window`] before the
3879 /// supervisor itself terminates (and its parent supervisor decides
3880 /// what to do). Default 5.
3881 #[serde(default = "default_max_restarts")]
3882 pub max_restarts: u32,
3883
3884 /// Sliding window for `max_restarts`. Authored as a duration
3885 /// string (`"60s"`, `"5m"`); absent = "never reset". A `Some(0s)`
3886 /// is rejected by [`Self::validate`] — Erlang/OTP's
3887 /// `MaxIntensity / Period` invariant requires a positive window
3888 /// (a zero-period supervisor either trips on the first failure or
3889 /// never trips, depending on operator interpretation, neither of
3890 /// which is the author's intent). Omit the slot to express "no
3891 /// reset"; carry a positive duration to express the sliding window.
3892 #[serde(
3893 default,
3894 skip_serializing_if = "Option::is_none",
3895 with = "duration_codec"
3896 )]
3897 pub restart_window: Option<Duration>,
3898
3899 /// Static children. Empty for `SimpleOneForOne` (children added
3900 /// dynamically); required for the other three strategies.
3901 #[serde(default)]
3902 pub children: Vec<ChildSpec>,
3903}
3904
3905const fn default_max_restarts() -> u32 {
3906 // Route the private serde-`#[serde(default = "…")]` helper through
3907 // the substrate-canonical [`SUPERVISOR_MAX_RESTARTS_DEFAULT`] typed
3908 // `pub const` rather than the raw `5` literal — one source of truth
3909 // for the Erlang/OTP-canonical `{intensity, 5, 60}` `MaxIntensity`
3910 // default across the two production consumers that currently
3911 // dispatch on it (this helper via `#[serde(default = "…")]` on
3912 // `SupervisorSpec::max_restarts` and the [`Default for SupervisorSpec`]
3913 // impl at line 962). Pinned by
3914 // `default_max_restarts_helper_routes_through_lifted_default` +
3915 // `supervisor_spec_default_max_restarts_routes_through_lifted_default`
3916 // in the tests module; peer of the sibling caixa-core
3917 // [`crate::manifest::Caixa::supervisor_view`] `unwrap_or(…)` fold
3918 // that now routes its author-omitted `:max-restarts` arm through
3919 // the same lifted constant.
3920 SUPERVISOR_MAX_RESTARTS_DEFAULT
3921}
3922
3923/// Substrate-canonical Erlang/OTP-shaped `MaxIntensity` restart-budget-
3924/// count default for the `:supervisor :max-restarts` axis — the
3925/// canonical `{intensity, 5, 60}` `MaxIntensity` half of Learn You Some
3926/// Erlang's worker-supervisor default, extracted as a typed `pub const`
3927/// so every substrate-side consumer that resolves "what
3928/// [`SupervisorSpec::max_restarts`] value does an author-omitted
3929/// `:max-restarts` slot degrade onto?" reaches for exactly one
3930/// substrate-primitive `u32`.
3931///
3932/// The `:max-restarts` default axis has two production consumers on the
3933/// substrate side today (both prior to this lift folded onto raw `5`
3934/// literals with no compile-time link back to a shared truth): the
3935/// serde-`#[serde(default = "default_max_restarts")]` helper on
3936/// [`SupervisorSpec::max_restarts`] that every author-omitted
3937/// `:supervisor :max-restarts` slot lands in past the derive-macro's
3938/// wire-format compose, and the [`crate::manifest::Caixa::supervisor_view`]
3939/// `.max_restarts().unwrap_or(5)` fold that every downstream consumer of
3940/// the composed [`SupervisorSpec`] altitude reaches through
3941/// (`feira app graph`, the future wasm-operator's per-supervisor
3942/// restart-intensity counter, the future M4
3943/// `mesh.pleme.io/v1alpha1/Supervisor` CR materializer's admission
3944/// webhook, the caixa-operator's hierarchical reconciliation scheduler).
3945/// A pair of open-coded `5`s across two files that expressed no
3946/// compile-time link back to the shared OTP-canonical default — a
3947/// future rebrand of the default (a tightening to Elixir's
3948/// `Supervisor.max_restarts: 3`, a widening to a per-cluster overlay
3949/// the operator pins through a future
3950/// `:supervisor :max-restarts-overrides` slot the MESH-COMPOSITION
3951/// §III.2 supervision-canary roadmap acknowledges, a promotion of the
3952/// plain `u32` count to a richer `{MaxR, MaxT}` per-child-cohort
3953/// restart-budget-partition once the INSPIRATIONS §II.2 Erlang/OTP
3954/// per-child-cohort roadmap lands) would have had to be threaded
3955/// through both open-coded copies in lockstep or the wire-format
3956/// author-omitted arm and the view-construction author-omitted arm
3957/// would silently disagree on which restart-budget an omitted
3958/// `:max-restarts` resolves to (an author writing `:supervisor
3959/// (:max-restarts ())` would round-trip through serde with the new
3960/// default while `supervisor_view` silently continued to compose the
3961/// stale `5`, or vice versa), a two-consumer split at the composition
3962/// boundary far from the source `caixa.lisp` with no field naming the
3963/// default-drift root cause. Lifting the resolution rule to a typed
3964/// `pub const` on the substrate primitive means every downstream
3965/// consumer of the per-Supervisor default-restart-budget-count surface
3966/// reaches for exactly one substrate-primitive `u32` — the resolver's
3967/// accepted value migrates as a unit on any future axis change.
3968///
3969/// The `5` value pins Learn You Some Erlang's `{intensity, 5, 60}`
3970/// worker-supervisor default (the closest canonical OTP-shape
3971/// production reference the substrate carries, matching the sibling
3972/// `60s` `Period` default the [`Default for SupervisorSpec`] impl pairs
3973/// this constant with on the paired sliding-window axis). Two orders of
3974/// magnitude below the [`SUPERVISOR_MAX_RESTARTS_MAX`] `1000` ceiling
3975/// (the upper bracket on the same axis, sibling of this lower default;
3976/// both are typed `u32` const bounds on the `:supervisor :max-restarts`
3977/// axis and now share one accessor discipline on the substrate) and
3978/// above the OTP-`supervisor` callback-module `MaxR = 1` minimum-
3979/// restart floor — the "one restart, then escalate" default is
3980/// deliberately loose enough to absorb a short burst of transient
3981/// child failures without escalating past the supervisor's parent
3982/// while remaining tight enough to trip the `MaxIntensity / Period`
3983/// ratio's escalation on a genuinely-stuck child within the sibling
3984/// `60s` sliding window.
3985///
3986/// Lifted as a typed `pub const` so the bound has exactly one source
3987/// of truth — the serde-side wire-format author-omitted arm at
3988/// [`default_max_restarts`], the [`Default for SupervisorSpec`] impl's
3989/// struct-literal default field, and the caixa-core
3990/// [`crate::manifest::Caixa::supervisor_view`] fold's author-omitted
3991/// arm all read from one place. Same shape every other typed default
3992/// in this crate carries (the sibling
3993/// [`SUPERVISOR_MAX_RESTARTS_MAX`] upper cap on the same axis, the
3994/// paired [`SUPERVISOR_RESTART_WINDOW_MAX`] upper cap on the
3995/// sibling `:restart-window` axis, and the peer
3996/// [`crate::render::DEFAULT_NAMESPACE`] / [`crate::render::DEFAULT_LIBRARY_NAME`]
3997/// per-renderer defaults on the caixa-flux / caixa-helm rendering
3998/// axes).
3999pub const SUPERVISOR_MAX_RESTARTS_DEFAULT: u32 = 5;
4000
4001/// Upper-bound ceiling on the `:supervisor :max-restarts` axis — every
4002/// validated [`SupervisorSpec::max_restarts`] past
4003/// [`SupervisorSpec::validate`] lies in `1..=SUPERVISOR_MAX_RESTARTS_MAX`.
4004///
4005/// The typed field is `u32` (the zero-floor arm
4006/// [`SupervisorError::ZeroMaxRestarts`] already brackets the bottom edge),
4007/// so a programmatic struct literal
4008/// (`SupervisorSpec { max_restarts: u32::MAX, .. }`) and the equivalent
4009/// author-surface form (`:max-restarts 4294967295` or any
4010/// `:max-restarts 100000`-shape typo landing in the slot) both round-trip
4011/// cleanly through serde — a structurally unbounded `u32` ceiling. The
4012/// runtime substrate consuming the value (Erlang/OTP's
4013/// `MaxIntensity / Period` ratio, the future wasm-operator's
4014/// per-supervisor restart-intensity counter, the M4
4015/// `mesh.pleme.io/v1alpha1/Supervisor` CR materializer's admission webhook)
4016/// then turned a typed `:max-restarts` policy into a no-op supervisor: the
4017/// escalation threshold is structurally so high that no realistic
4018/// restarts-per-`:restart-window` traffic shape can reach it, the
4019/// supervisor never escalates to its parent, and a bad child can loop
4020/// inside the window indefinitely with the parent supervisor structurally
4021/// never receiving the "this subtree has exceeded its restart budget"
4022/// signal the typed slot is meant to express — the canonical
4023/// "supervisor intensity declared, no escalation" footgun, exactly the
4024/// peer of the [`crate::aplicacao::POLICY_BREAKER_MAX_FAILURES_MAX`] cap
4025/// on the `:politicas :circuit-breaker :max-failures` axis (both are
4026/// "trip the next-higher protection layer after N events in a rolling
4027/// window" counters with identical degenerate-at-the-high-end shape).
4028///
4029/// The `1000` ceiling matches the sibling
4030/// [`crate::aplicacao::POLICY_BREAKER_MAX_FAILURES_MAX`] (the closest
4031/// peer — same "events-per-window trip threshold" semantics, same `u32`
4032/// type, same no-op-at-the-high-end failure mode) so the M4
4033/// `mesh.pleme.io/v1alpha1/Supervisor` / `.../Aplicacao` CR materializers
4034/// and the future wasm-operator's per-supervisor restart-intensity
4035/// counter reach for either field knowing the value is in `1..=1000`
4036/// without re-validating at the reconciler layer. The cap sits two
4037/// orders of magnitude above every documented Erlang/OTP production
4038/// playbook recommendation (Learn You Some Erlang's
4039/// `{intensity, 5, 60}` worker-supervisor default, Elixir's `Supervisor`
4040/// `max_restarts: 3` default, OTP's `supervisor` callback module
4041/// `MaxR = 1` / `MaxT = 5` "minimal-restart" default, Riak Core's
4042/// typical `MaxR ∈ 5..=100`, RabbitMQ's broker-supervisor `MaxR = 5`
4043/// default) and below the clearly-pathological "effectively no
4044/// escalation" floor (`10_000`, `100_000`, `u32::MAX`): a value the
4045/// author can plausibly want at hyperscale (a long-running supervisor
4046/// over a very-flaky pool tolerating thousands of transient restarts
4047/// before escalating), but a hard wall above which the typed policy is
4048/// structurally a no-op carried verbatim on every emitted child-restart
4049/// reconciliation contract.
4050///
4051/// Lifted as a typed `pub const` so the bound has exactly one source of
4052/// truth — the future M4 `mesh.pleme.io/v1alpha1/Supervisor` CR
4053/// materializer's admission webhook and the wasm-operator-side
4054/// per-supervisor restart-intensity reconciler read from one place. Same
4055/// shape every other typed upper bound in this crate carries
4056/// ([`crate::aplicacao::POLICY_BREAKER_MAX_FAILURES_MAX`],
4057/// [`crate::aplicacao::POLICY_RETRIES_MAX`],
4058/// [`crate::aplicacao::POLICY_RATE_LIMIT_MAX`],
4059/// [`crate::LIMITS_MEMORY_WASM32_MAX_BYTES`],
4060/// [`crate::render::DNS_1123_LABEL_MAX_LEN`],
4061/// [`crate::render::NATS_SUBJECT_MAX_LEN`]).
4062pub const SUPERVISOR_MAX_RESTARTS_MAX: u32 = 1000;
4063
4064/// Upper-bound ceiling on the `:supervisor :restart-window` axis —
4065/// every validated `Some(`[`SupervisorSpec::restart_window`]`)` past
4066/// [`SupervisorSpec::validate`] lies in `1ms..=SUPERVISOR_RESTART_WINDOW_MAX`
4067/// (inclusive on both ends, integer-millisecond magnitudes by the
4068/// canonical-form gate immediately preceding).
4069///
4070/// The typed field is `Option<Duration>` (the zero-floor arm
4071/// [`SupervisorError::RestartWindowZero`] already rejects
4072/// `Some(Duration::ZERO)`, and the canonical-form arm
4073/// [`SupervisorError::RestartWindowNotCanonical`] already rejects
4074/// sub-millisecond residue), so a programmatic struct literal
4075/// (`SupervisorSpec { restart_window: Some(Duration::from_secs(86_400)),
4076/// .. }` — 24h) and the equivalent author-surface form
4077/// (`(:supervisor (:restart-window "24h"))` — the shared duration codec
4078/// emits `"<n>h"` for any integer-hour magnitude) both round-trip
4079/// cleanly through serde — a structurally unbounded `Duration` ceiling.
4080/// A `:restart-window` value far above the documented Erlang/OTP
4081/// `MaxIntensity / Period` production-playbook band (Learn You Some
4082/// Erlang's `{intensity, 5, 60}` worker-supervisor `Period = 60s`
4083/// default, Elixir's `Supervisor` `max_seconds: 5` default, OTP's
4084/// `supervisor` callback module `MaxT = 5..=60` typical, Riak Core's
4085/// `MaxT ∈ 10s..=300s`, RabbitMQ broker-supervisor `MaxT = 5s` default)
4086/// degenerates the supervisor's restart-intensity counter into a
4087/// lifetime counter: the rolling failure-counting window is structurally
4088/// so long that transient restarts are never forgotten, so the
4089/// `MaxIntensity / Period` ratio degenerates from "trip the parent
4090/// supervisor when the child has exceeded its restart budget *within
4091/// the recent window*" to "trip the parent when the child has exceeded
4092/// its restart budget *over its lifetime*" — every transient restart
4093/// counts against the budget forever, the supervisor's reset semantic
4094/// never reaches the child, and the typed `:restart-window` slot
4095/// becomes a no-op rolling window carried on every emitted hierarchical
4096/// reconciliation contract. The canonical
4097/// rolling-window-degenerates-to-lifetime-counter footgun the sibling
4098/// [`crate::POLICY_BREAKER_WINDOW_MAX`] cap closes on the peer
4099/// `:politicas :circuit-breaker :window` axis with identical shape (both
4100/// are "rolling failure-counting window with a per-`Period` reset" Duration
4101/// axes whose lifetime-counter degenerate at the high end is the same
4102/// "the reset semantic never fires" CSE invariant violation).
4103///
4104/// The `1h` (3600s = `3_600_000` ms) ceiling matches the largest unit
4105/// the shared duration codec emits (`"<n>h"` for any integer-hour
4106/// magnitude) — every value in the canonical authoring form's
4107/// `<integer><unit>` grammar at or below this cap renders to a clean
4108/// canonical string — and matches the three sibling typed-`Duration`
4109/// caps already lifted to this surface
4110/// ([`crate::LIMITS_WALL_CLOCK_MAX`], [`crate::POLICY_TIMEOUT_MAX`],
4111/// [`crate::POLICY_BREAKER_WINDOW_MAX`]). All four typed-`Duration`
4112/// axes — per-process `:limits :wall-clock`, per-edge `:politicas
4113/// :timeout`, per-breaker `:politicas :circuit-breaker :window`, and
4114/// per-supervisor `:supervisor :restart-window` — now share a single
4115/// uniform top edge at the codec's largest emitted unit so the next
4116/// typed-slot wiring (the future wasm-operator's per-supervisor
4117/// `MaxIntensity / Period` reconciler, the M4
4118/// `mesh.pleme.io/v1alpha1/Supervisor` CR materializer's admission
4119/// webhook, the `caixa-operator`'s hierarchical reconciliation
4120/// scheduler) reaches for any of the four knowing the value is in
4121/// `1ms..=1h` without re-validating at the renderer layer. The cap sits
4122/// two orders of magnitude above every documented Erlang/OTP / Elixir /
4123/// Riak Core / RabbitMQ production-playbook recommendation band
4124/// (`5s..=300s`) and below the clearly-pathological "rolling window
4125/// degenerates to lifetime counter" floor (`24h`, `7d`, `Duration::MAX`):
4126/// a value the author can plausibly want for a very-low-traffic
4127/// long-tail failure-restart window over a hyperscale-flaky child pool,
4128/// but a hard wall above which the rolling-window contract is
4129/// structurally a lifetime-counter contract.
4130///
4131/// Lifted as a typed `pub const` so the bound has exactly one source
4132/// of truth — the future M4 `mesh.pleme.io/v1alpha1/Supervisor` CR
4133/// materializer's admission webhook, the wasm-operator-side
4134/// per-supervisor `MaxIntensity / Period` reconciler, and the
4135/// `caixa-operator`'s hierarchical reconciliation scheduler all read
4136/// from one place. Same shape every other typed upper bound in this
4137/// crate carries ([`SUPERVISOR_MAX_RESTARTS_MAX`],
4138/// [`crate::aplicacao::POLICY_BREAKER_MAX_FAILURES_MAX`],
4139/// [`crate::aplicacao::POLICY_RETRIES_MAX`],
4140/// [`crate::aplicacao::POLICY_RATE_LIMIT_MAX`],
4141/// [`crate::LIMITS_MEMORY_WASM32_MAX_BYTES`],
4142/// [`crate::LIMITS_WALL_CLOCK_MAX`], [`crate::POLICY_TIMEOUT_MAX`],
4143/// [`crate::POLICY_BREAKER_WINDOW_MAX`],
4144/// [`crate::render::DNS_1123_LABEL_MAX_LEN`],
4145/// [`crate::render::NATS_SUBJECT_MAX_LEN`]).
4146pub const SUPERVISOR_RESTART_WINDOW_MAX: Duration = Duration::from_secs(3600);
4147
4148/// Substrate-canonical Erlang/OTP-shaped `Period` sliding-window-duration
4149/// default for the `:supervisor :restart-window` axis — the canonical
4150/// `{intensity, 5, 60}` `Period` half of Learn You Some Erlang's
4151/// worker-supervisor default, extracted as a typed `pub const` so every
4152/// substrate-side consumer that resolves "what
4153/// [`SupervisorSpec::restart_window`] value does an author-omitted
4154/// `:restart-window` slot degrade onto?" reaches for exactly one
4155/// substrate-primitive [`Duration`].
4156///
4157/// The `:restart-window` default axis has one production consumer on the
4158/// substrate side today: the [`Default for SupervisorSpec`] impl's
4159/// struct-literal `restart_window` field, which prior to this lift folded
4160/// onto a raw `Duration::from_secs(60)` literal with no compile-time link
4161/// back to the paired [`SUPERVISOR_MAX_RESTARTS_DEFAULT`] `MaxIntensity`
4162/// half of the same `{intensity, 5, 60}` OTP-canonical default. The
4163/// [`crate::manifest::Caixa::supervisor_view`] fold deliberately does
4164/// *not* fall back to this default on the sibling `:restart-window` axis
4165/// — an author-omitted `:supervisor :restart-window` composes to
4166/// `restart_window: None` (the shared codec's soft-swallow shape),
4167/// keeping author-declared intent ("no reset — never escalate on rolling
4168/// window") distinct from the [`Default for SupervisorSpec`] "canonical
4169/// 60s Period" arm every programmatic `SupervisorSpec::default()` caller
4170/// resolves to. Prior to this lift the paired `{intensity, 5, 60}` OTP
4171/// default was split across two files with no compile-time link between
4172/// the halves: [`SUPERVISOR_MAX_RESTARTS_DEFAULT`] pinned the
4173/// `MaxIntensity` half at the substrate primitive while the `Period`
4174/// half rode as an open-coded literal at the composition site, so a
4175/// future coherent rebrand of the paired canonical (a tightening to
4176/// Elixir's `{max_restarts: 3, max_seconds: 5}`, a widening to a
4177/// per-cluster overlay the operator pins through a future
4178/// `:supervisor :restart-window-overrides` slot the MESH-COMPOSITION
4179/// §III.2 supervision-canary roadmap acknowledges, a promotion of the
4180/// paired constants to a per-child-cohort `{MaxR, MaxT}` restart-budget-
4181/// partition once the INSPIRATIONS §II.2 Erlang/OTP per-child-cohort
4182/// roadmap lands) would have had to migrate the `MaxIntensity` half
4183/// through the lifted constant and the `Period` half through a raw
4184/// literal in lockstep or the two halves of the same OTP-canonical
4185/// default would silently drift out of pairing. Lifting the resolution
4186/// rule to a typed `pub const` on the substrate primitive means the
4187/// paired OTP-canonical default migrates as one unit on any future
4188/// axis change.
4189///
4190/// The `60s` value pins Learn You Some Erlang's `{intensity, 5, 60}`
4191/// worker-supervisor default (the closest canonical OTP-shape
4192/// production reference the substrate carries, matching the paired
4193/// [`SUPERVISOR_MAX_RESTARTS_DEFAULT`] `5` `MaxIntensity` half this
4194/// constant is the `Period` denominator of on the same
4195/// `MaxIntensity / Period` restart-intensity ratio). Two orders of
4196/// magnitude below the [`SUPERVISOR_RESTART_WINDOW_MAX`] `3600s`
4197/// (`1h`) ceiling (the upper bracket on the same axis, sibling of
4198/// this lower default; both are typed [`Duration`] const bounds on the
4199/// `:supervisor :restart-window` axis and now share one accessor
4200/// discipline on the substrate) and above the OTP-`supervisor`
4201/// callback-module `MaxT = 5` seconds "minimal-window" floor — the "60s
4202/// rolling window" default is deliberately loose enough to absorb a
4203/// short burst of transient child failures without escalating past the
4204/// supervisor's parent while remaining tight enough for the paired
4205/// `MaxIntensity / Period` ratio's escalation to trip on a genuinely-
4206/// stuck child within a human-scale observation window.
4207///
4208/// Lifted as a typed `pub const` so the paired OTP-canonical default has
4209/// exactly one source of truth on each half — the sibling
4210/// [`SUPERVISOR_MAX_RESTARTS_DEFAULT`] `MaxIntensity` `5` half and this
4211/// `Period` `60s` half now share the same substrate-primitive lift
4212/// discipline. Same shape every other typed default in this crate
4213/// carries (the sibling [`SUPERVISOR_MAX_RESTARTS_DEFAULT`] paired
4214/// `MaxIntensity` half on the same OTP-canonical `{intensity, 5, 60}`,
4215/// the sibling [`SUPERVISOR_RESTART_WINDOW_MAX`] upper cap on the same
4216/// axis, and the peer [`crate::render::DEFAULT_NAMESPACE`] /
4217/// [`crate::render::DEFAULT_LIBRARY_NAME`] per-renderer defaults on the
4218/// caixa-flux / caixa-helm rendering axes).
4219pub const SUPERVISOR_RESTART_WINDOW_DEFAULT: Duration = Duration::from_secs(60);
4220
4221/// Substrate-canonical Erlang/OTP-shaped sibling-restart-strategy default
4222/// for the `:supervisor :estrategia` axis — the canonical `one_for_one`
4223/// half of Learn You Some Erlang's `{one_for_one, intensity, 5, 60}`
4224/// worker-supervisor default, extracted as a typed `pub const` so every
4225/// substrate-side consumer that resolves "what
4226/// [`SupervisorSpec::estrategia`] variant does an author-omitted
4227/// `:estrategia` slot degrade onto?" reaches for exactly one substrate-
4228/// primitive [`RestartStrategy`].
4229///
4230/// The `:estrategia` default axis has three production consumers on the
4231/// substrate side today: the [`Default for RestartStrategy`] impl's
4232/// return arm, the [`Default for SupervisorSpec`] impl's struct-literal
4233/// `estrategia` field, and the
4234/// [`crate::manifest::Caixa::supervisor_view`] fold's
4235/// `.unwrap_or(SUPERVISOR_ESTRATEGIA_DEFAULT)` `Option<RestartStrategy>`
4236/// collapse arm — three entry points onto the same OTP-canonical
4237/// `one_for_one` value that prior to this lift folded onto a raw
4238/// `Self::OneForOne` arm at the [`Default for RestartStrategy`] impl and
4239/// implicit `RestartStrategy::default()` routes at the sibling consumers,
4240/// with no compile-time link back to the paired
4241/// [`SUPERVISOR_MAX_RESTARTS_DEFAULT`] `MaxIntensity` half + the paired
4242/// [`SUPERVISOR_RESTART_WINDOW_DEFAULT`] `Period` half of the same
4243/// `{one_for_one, intensity, 5, 60}` OTP-canonical default. The paired
4244/// triple was split across three altitudes with no compile-time link
4245/// between the halves: the `MaxIntensity` half rode through the lifted
4246/// [`SUPERVISOR_MAX_RESTARTS_DEFAULT`] constant (b698ec0) and the `Period`
4247/// half rode through the lifted [`SUPERVISOR_RESTART_WINDOW_DEFAULT`]
4248/// constant (f7dcd0e) while the `one_for_one` half rode as an open-coded
4249/// discriminator at the [`Default for RestartStrategy`] impl, so a future
4250/// coherent rebrand of the triple (Elixir's `{:one_for_one,
4251/// max_restarts: 3, max_seconds: 5}` — same strategy, different
4252/// intensity/period; an OTP `rest_for_one` widening once the substrate
4253/// discovers startup-order-coupled child cohorts as the more common
4254/// worker-supervisor default; a per-cluster overlay the operator pins
4255/// through a future `:estrategia-overrides` slot the MESH-COMPOSITION
4256/// §III.2 supervision-canary roadmap acknowledges) would have had to
4257/// migrate the `MaxIntensity` + `Period` halves through the lifted
4258/// constants and the `one_for_one` half through an open-coded arm in
4259/// lockstep or the three halves of the same OTP-canonical default would
4260/// silently drift out of pairing. Lifting the resolution rule to a typed
4261/// `pub const` on the substrate primitive means the paired OTP-canonical
4262/// worker-supervisor default migrates as one unit on any future axis
4263/// change.
4264///
4265/// The [`RestartStrategy::OneForOne`] value pins Learn You Some Erlang's
4266/// `{one_for_one, intensity, 5, 60}` worker-supervisor default (the
4267/// closest canonical OTP-shape production reference the substrate
4268/// carries, matching the paired [`SUPERVISOR_MAX_RESTARTS_DEFAULT`] `5`
4269/// `MaxIntensity` half and the paired [`SUPERVISOR_RESTART_WINDOW_DEFAULT`]
4270/// `60s` `Period` half). The `one_for_one` strategy — restart only the
4271/// failed child, leaving siblings untouched — is the default for tree-of-
4272/// independent-workers use cases the substrate's [`RestartStrategy`]
4273/// discriminator's own docstring already carries as the default arm; it
4274/// composes with the `{5, 60}` restart-intensity ratio to name the same
4275/// substrate-canonical "canonical worker-supervisor" shape the paired
4276/// halves close on their respective axes.
4277///
4278/// Lifted as a typed `pub const` so the paired OTP-canonical default has
4279/// exactly one source of truth on each of its three halves — the sibling
4280/// [`SUPERVISOR_MAX_RESTARTS_DEFAULT`] `MaxIntensity` `5` half, the
4281/// sibling [`SUPERVISOR_RESTART_WINDOW_DEFAULT`] `Period` `60s` half, and
4282/// this `one_for_one` strategy half now share the same substrate-
4283/// primitive lift discipline. Same shape every other typed default in
4284/// this crate carries (the sibling [`SUPERVISOR_MAX_RESTARTS_DEFAULT`] +
4285/// [`SUPERVISOR_RESTART_WINDOW_DEFAULT`] paired halves on the same OTP-
4286/// canonical `{one_for_one, intensity, 5, 60}`, the sibling
4287/// [`SUPERVISOR_MAX_RESTARTS_MAX`] + [`SUPERVISOR_RESTART_WINDOW_MAX`]
4288/// upper caps on the paired sibling axes, and the peer
4289/// [`crate::render::DEFAULT_NAMESPACE`] / [`crate::render::DEFAULT_LIBRARY_NAME`]
4290/// per-renderer defaults on the caixa-flux / caixa-helm rendering axes).
4291pub const SUPERVISOR_ESTRATEGIA_DEFAULT: RestartStrategy = RestartStrategy::OneForOne;
4292
4293/// Substrate-canonical Erlang/OTP-shaped per-child restart-decision-policy
4294/// default for the `:children :restart` axis — the OTP `permanent`
4295/// worker-child default (`{ChildId, StartFunc, permanent, …}` in a
4296/// `supervisor`'s `init/1` child-spec tuple), extracted as a typed
4297/// `pub const` so every substrate-side consumer that resolves "what
4298/// [`ChildSpec::restart`] variant does an author-omitted `:children
4299/// :restart` slot degrade onto?" reaches for exactly one substrate-
4300/// primitive [`RestartPolicy`].
4301///
4302/// Completes the OTP-shape supervisor-tree default set at the substrate
4303/// primitive. The per-`:supervisor` axis already carries all three of its
4304/// halves as lifted typed constants — [`SUPERVISOR_ESTRATEGIA_DEFAULT`]
4305/// (`one_for_one`, 95ffacc), [`SUPERVISOR_MAX_RESTARTS_DEFAULT`]
4306/// (`MaxIntensity` `5`, b698ec0), [`SUPERVISOR_RESTART_WINDOW_DEFAULT`]
4307/// (`Period` `60s`, f7dcd0e) — while the per-`:children` axis's own
4308/// OTP-canonical default rode as an open-coded `Self::Permanent` arm in
4309/// the [`Default for RestartPolicy`] impl, the last un-lifted default on
4310/// the M2 `:supervisor` slot family. The split mattered because the two
4311/// axes resolve *together* on every author-omitted supervisor: a
4312/// `(defcaixa :kind Supervisor :children ((:caixa "worker" :versao
4313/// "^0.1")))` with no `:estrategia` and no per-child `:restart` degrades
4314/// onto `{one_for_one, 5, 60}` through three lifted constants and onto
4315/// `permanent` through an open-coded enum arm, so a future coherent
4316/// rebrand of the OTP-shape default set (an Elixir-shaped
4317/// `{:one_for_one, max_restarts: 3, max_seconds: 5}` tightening, a
4318/// per-cluster overlay the operator pins through the MESH-COMPOSITION
4319/// §III.2 supervision-canary roadmap slots, an OTP-`transient` widening
4320/// once the substrate discovers clean-completion-aware children as the
4321/// more common child shape) would have had to migrate three halves
4322/// through typed constants and the fourth through a raw enum arm in
4323/// lockstep or the supervisor-level and child-level defaults would
4324/// silently drift apart.
4325///
4326/// The `:children :restart` default axis has two production consumers on
4327/// the substrate side today: the [`Default for RestartPolicy`] impl's
4328/// return arm, and the serde-side `#[serde(default)]` on
4329/// [`ChildSpec::restart`] that resolves an author-omitted `:children
4330/// :restart` slot through that same impl. Both now key off this one
4331/// substrate primitive, so the future wasm-operator's per-child post-exit
4332/// restart-decision branch, the future M4
4333/// `mesh.pleme.io/v1alpha1/Supervisor` CR materializer's per-child
4334/// admission webhook, and the `caixa-operator`'s hierarchical
4335/// reconciliation scheduler's per-child fan-out all reach for one typed
4336/// identifier when they resolve an omitted per-child restart posture.
4337///
4338/// The [`RestartPolicy::Permanent`] value pins Erlang/OTP's `permanent`
4339/// worker-child restart type — always restart the child regardless of how
4340/// it died, the canonical posture for long-running services that must
4341/// always be up, matching the sibling [`SUPERVISOR_ESTRATEGIA_DEFAULT`]
4342/// `one_for_one` tree-of-independent-workers strategy this constant pairs
4343/// with under the same `{one_for_one, intensity, 5, 60}` worker-supervisor
4344/// shape. The two alternatives the closed [`RestartPolicy::ALL`] accept-set
4345/// carries ([`RestartPolicy::Transient`] — restart only on abnormal exit;
4346/// [`RestartPolicy::Temporary`] — never restart) express deliberate
4347/// one-shot / clean-completion-aware postures an author declares
4348/// explicitly, never a posture an omitted slot should silently assume.
4349pub const SUPERVISOR_CHILD_RESTART_DEFAULT: RestartPolicy = RestartPolicy::Permanent;
4350
4351/// Route the manually-authored [`Default`] impl on [`SupervisorSpec`]
4352/// through the substrate-canonical [`SupervisorSpec::otp_canonical`]
4353/// `pub const fn` constructor rather than a struct-literal cascade over
4354/// the paired [`SUPERVISOR_ESTRATEGIA_DEFAULT`] /
4355/// [`default_max_restarts`] / [`SUPERVISOR_RESTART_WINDOW_DEFAULT`]
4356/// lifted consts — one source of truth for the Erlang/OTP-canonical
4357/// `{one_for_one, 5, 60}` worker-supervisor baseline across the two
4358/// paths every downstream consumer already reaches through (the
4359/// hand-authored-until-now [`Default::default`] the
4360/// `..SupervisorSpec::default()` struct-update-syntax on every
4361/// one-axis-under-test fixture in this crate's test module rests on,
4362/// and the `pub const fn` [`SupervisorSpec::otp_canonical`] constructor
4363/// every `const`-context consumer reaches through).
4364///
4365/// Extends the [`Default`]-through-const-ctor fold discipline the
4366/// [`crate::LimitsSpec`] [`Default`]-through-[`crate::LimitsSpec::empty`]
4367/// (abd52c2), [`crate::aplicacao::MeshPolicy`]
4368/// [`Default`]-through-[`crate::aplicacao::MeshPolicy::empty`] (91641a4),
4369/// and [`crate::BehaviorSpec`]
4370/// [`Default`]-through-[`crate::BehaviorSpec::empty`] (0c1752c) folds
4371/// closed on the M2 / M3 `Option`-only "canonical unset baseline"
4372/// typed-slot spec family — extended here onto the M2 supervisor-slot
4373/// [`SupervisorSpec`] whose canonical baseline is not "everything
4374/// `None`" but the OTP-canonical `{one_for_one, 5, 60}` worker-
4375/// supervisor triple. The `empty()` peer's naming did not fit
4376/// (`SupervisorSpec` carries a discriminator-shaped `estrategia` field
4377/// and a non-zero `max_restarts`/`restart_window` pair whose canonical
4378/// shape is Erlang/OTP-descended, not the "no axis declared" bottom
4379/// the sibling `Option`-only slots fold to), so this peer is named
4380/// [`SupervisorSpec::otp_canonical`] instead — the same phrasing the
4381/// existing per-arm pin tests
4382/// [`tests::supervisor_estrategia_default_pins_otp_canonical_value`] /
4383/// [`tests::supervisor_max_restarts_default_pins_otp_canonical_value`] /
4384/// [`tests::supervisor_restart_window_default_pins_otp_canonical_value`]
4385/// already reach for. Pinned load-bearing by
4386/// [`tests::supervisor_spec_default_routes_through_otp_canonical_ctor`]
4387/// (byte-parity pin against [`SupervisorSpec::otp_canonical`] under
4388/// [`PartialEq`], sharpening the sibling
4389/// `supervisor_spec_default_*_routes_through_lifted_default` per-arm
4390/// pins from a per-field lift into a whole-struct one-source-of-truth
4391/// pin — the derived-until-now [`Default::default`] and the
4392/// [`SupervisorSpec::otp_canonical`] constructor are byte-equal by
4393/// construction, not by coincidence).
4394impl Default for SupervisorSpec {
4395 #[inline]
4396 fn default() -> Self {
4397 Self::otp_canonical()
4398 }
4399}
4400
4401impl SupervisorSpec {
4402 /// `const`-context peer of the [`Default for SupervisorSpec`]
4403 /// impl (which routes through this constructor) — returns the
4404 /// Erlang/OTP-canonical `{one_for_one, 5, 60}` worker-supervisor
4405 /// baseline this crate reaches for in every fixture-builder
4406 /// `..SupervisorSpec::default()` struct-update expression and
4407 /// every downstream `SupervisorSpec::default()` seed.
4408 ///
4409 /// Each field routes through the same substrate-canonical
4410 /// [`SUPERVISOR_ESTRATEGIA_DEFAULT`] / [`default_max_restarts`] /
4411 /// [`SUPERVISOR_RESTART_WINDOW_DEFAULT`] lifted consts the
4412 /// per-arm pin tests
4413 /// [`tests::supervisor_estrategia_default_pins_otp_canonical_value`]
4414 /// / [`tests::supervisor_max_restarts_default_pins_otp_canonical_value`]
4415 /// / [`tests::supervisor_restart_window_default_pins_otp_canonical_value`]
4416 /// already assert, so a future coherent rebrand of the OTP-canonical
4417 /// triple (Elixir's `{max_restarts: 3, max_seconds: 5}`, a per-
4418 /// cluster overlay via a future `:restart-window-overrides` slot, a
4419 /// per-child-cohort promotion the INSPIRATIONS.md §II.2 Erlang/OTP
4420 /// absorption roadmap acknowledges) migrates through three typed
4421 /// constants in lockstep, and the paired [`Default`] impl inherits
4422 /// every future extension by construction.
4423 ///
4424 /// `pub const fn` rather than the derived-style `Default::default`
4425 /// or a `pub const SUPERVISOR_SPEC_DEFAULT: SupervisorSpec` item —
4426 /// [`Default::default`] is not `const` on stable Rust, and
4427 /// `SupervisorSpec` is non-`Copy` so a `pub const` item would force
4428 /// every consumer through a [`Clone::clone`]. The `pub const fn`
4429 /// discipline lets `const`-context callers construct the OTP-
4430 /// canonical baseline at compile time without runtime dispatch on
4431 /// the derived [`Default::default`], the same posture the sibling
4432 /// [`crate::LimitsSpec::empty`] (9739971) /
4433 /// [`crate::aplicacao::MeshPolicy::empty`] (6df969b) /
4434 /// [`crate::BehaviorSpec::empty`] (f9b18e3) `Option`-only typed-slot
4435 /// spec `pub const fn` constructors carry on the sibling
4436 /// "everything `None`" baseline axis.
4437 ///
4438 /// Fourth peer on the M2 / M3 typed-slot-spec "const-context peer
4439 /// of the derived-style [`Default`]" family — sibling of the
4440 /// [`crate::LimitsSpec::empty`] / [`crate::aplicacao::MeshPolicy::empty`]
4441 /// / [`crate::BehaviorSpec::empty`] `Option`-only "canonical unset
4442 /// baseline" trio, extended here onto the M2 supervisor-slot
4443 /// [`SupervisorSpec`] whose canonical baseline is not "everything
4444 /// `None`" but the Erlang/OTP-canonical `{one_for_one, 5, 60}`
4445 /// worker-supervisor triple. Named [`Self::otp_canonical`] rather
4446 /// than `empty()` to name the actual invariant the return value
4447 /// pins — the same phrasing already used in the per-arm pin tests
4448 /// on this file. Pinned load-bearing by
4449 /// [`tests::supervisor_spec_otp_canonical_byte_equals_default`] and
4450 /// [`tests::supervisor_spec_otp_canonical_is_usable_in_const_context`].
4451 #[must_use]
4452 pub const fn otp_canonical() -> Self {
4453 Self {
4454 estrategia: SUPERVISOR_ESTRATEGIA_DEFAULT,
4455 max_restarts: default_max_restarts(),
4456 restart_window: Some(SUPERVISOR_RESTART_WINDOW_DEFAULT),
4457 children: Vec::new(),
4458 }
4459 }
4460
4461 /// Substrate-canonical per-`:supervisor` `:estrategia` OTP-shaped
4462 /// sibling-restart-strategy scalar accessor every consumer that
4463 /// dispatches on the supervisor's per-sibling restart-decision shape
4464 /// keys off — returns the author-declared `:supervisor :estrategia`
4465 /// variant verbatim as a [`RestartStrategy`], `Copy`-projected from
4466 /// the typed slot's own [`RestartStrategy`] storage.
4467 ///
4468 /// The `:supervisor :estrategia` slot carries the closed-set
4469 /// OTP-shaped sibling-restart-strategy discriminator ([`RestartStrategy::OneForOne`]
4470 /// — restart only the failed child, the Erlang/OTP `one_for_one` default;
4471 /// [`RestartStrategy::OneForAll`] — restart every child on any child
4472 /// failure, the Erlang/OTP `one_for_all` shared-state cohort default;
4473 /// [`RestartStrategy::RestForOne`] — restart the failed child and
4474 /// every child started after it, the Erlang/OTP `rest_for_one`
4475 /// startup-order default; [`RestartStrategy::SimpleOneForOne`] —
4476 /// dynamic children of the same shape, the Erlang/OTP
4477 /// `simple_one_for_one` per-session default) that every downstream
4478 /// consumer of the Supervisor's per-sibling restart-decision fan-out
4479 /// shape keys off. Validated by [`SupervisorSpec::validate`] to be
4480 /// paired coherently with the sibling `:children` axis
4481 /// (`SimpleOneForOne ↔ children.is_empty()` — the cross-slot
4482 /// partition the strategy-arm's [`SupervisorError::SimpleOneForOneWithStaticChildren`]
4483 /// / [`SupervisorError::NoChildren`] refusal cascade pins), and every
4484 /// downstream consumer that reads the strategy keys off this scalar
4485 /// (the [`SupervisorSpec::validate`] `SimpleOneForOne ↔ non-SimpleOneForOne`
4486 /// partition-dispatch `match` arm, the non-`SimpleOneForOne`-arm
4487 /// declared-but-empty [`SupervisorError::NoChildren`] error carrier's
4488 /// `estrategia:` field, the future `feira app graph` per-Supervisor
4489 /// strategy print line, the future wasm-operator's per-supervisor
4490 /// sibling-restart-strategy branch, the future M4
4491 /// `mesh.pleme.io/v1alpha1/Supervisor` CR materializer's per-strategy
4492 /// admission-webhook resolver, the `caixa-operator`'s hierarchical
4493 /// reconciliation scheduler's per-strategy fan-out).
4494 ///
4495 /// Prior to this lift the `.estrategia` field was accessed inline at
4496 /// two production sites in `caixa-core/src/supervisor.rs` — the
4497 /// [`SupervisorSpec::validate`] `SimpleOneForOne ↔ non-SimpleOneForOne`
4498 /// `match self.estrategia { … }` partition dispatch, and the
4499 /// non-`SimpleOneForOne`-arm [`SupervisorError::NoChildren`] error
4500 /// carrier at `estrategia: self.estrategia` — two open-coded
4501 /// field-accesses that expressed no compile-time link back to the
4502 /// typed slot. A future extension of the `:supervisor :estrategia`
4503 /// axis to a richer author surface (a per-cluster strategy override
4504 /// the operator pins through a future `:supervisor :estrategia-overrides`
4505 /// slot the MESH-COMPOSITION §III.2 supervision-canary roadmap
4506 /// acknowledges, a per-tenant strategy-alias table the M4 CR
4507 /// materializer resolves per-CR, a per-Supervisor dynamic strategy
4508 /// derivation the future adaptive-supervision engine computes from
4509 /// child-failure-history topology, a per-child-cohort strategy split
4510 /// the future `RestForCohort` extension acknowledged by the
4511 /// INSPIRATIONS.md §II.2 Erlang/OTP absorption roadmap acknowledges)
4512 /// would have had to be threaded through every open-coded copy in
4513 /// lockstep — one consumer reading the raw variant while a peer read
4514 /// the operator-resolved variant would silently split the
4515 /// [`SupervisorError::NoChildren`] diagnostic's quoted strategy from
4516 /// the actual partition-dispatch input the empty-children refusal
4517 /// arm reached under, a two-consumer split at the validator far from
4518 /// the source `caixa.lisp` with no field naming the strategy-drift
4519 /// root cause. Lifting the resolution rule to a typed method on the
4520 /// substrate primitive means every downstream consumer of the
4521 /// Supervisor's per-`:supervisor` sibling-restart-strategy surface
4522 /// reaches for exactly one typed dispatch — the resolver's accept-set
4523 /// migrates as a unit on any future axis addition.
4524 ///
4525 /// Peer of the sibling M3 mesh-slot [`crate::Placement::estrategia`]
4526 /// (921fe1b) `Copy`-return `PlacementStrategy` scalar accessor on the
4527 /// per-`:placement` distribution-strategy axis — same "one typed
4528 /// dispatch on the substrate primitive, thin projections at each
4529 /// consumer" discipline extended onto the M2 supervisor-slot
4530 /// per-`:supervisor` sibling-restart-strategy `Copy`-composite-enum
4531 /// scalar axis. The two typed axes (`Placement::estrategia` on the
4532 /// M3 Aplicacao side, `SupervisorSpec::estrategia` on the M2
4533 /// Supervisor side) now share one accessor discipline for the shared
4534 /// substrate concept "a `Copy`-projected closed-set enum-arm
4535 /// discriminator that partitions the downstream renderer's per-arm
4536 /// fan-out". First `Copy`-return accessor on the M2 supervisor-slot
4537 /// `SupervisorSpec` type — companion to the sibling per-`:children`
4538 /// [`crate::ChildSpec::nome`] (57c61d0) /
4539 /// [`crate::ChildSpec::versao_requirement`] (2c053c8) child-caixa
4540 /// scalar accessors on the sibling per-`:children` `String`-carry
4541 /// axes. Named `estrategia()` to match the storage field's name and
4542 /// the peer [`crate::Placement::estrategia`] method-name discipline
4543 /// verbatim; the accessor's identity name maps onto the canonical
4544 /// OTP-shape supervision vocabulary the [`RestartStrategy`] enum's
4545 /// docstring already carries.
4546 ///
4547 /// Declared `pub const fn` to close the M2 supervisor-slot
4548 /// `Copy`-return raw-field-getter `const`-eval-surface pass —
4549 /// sibling of the peer M2 per-`:children` [`ChildSpec::restart`]
4550 /// (converted in this commit) `Copy`-composite-enum accessor, peer
4551 /// of the sibling M2 per-`:supervisor`
4552 /// [`SupervisorSpec::max_restarts`] (b698ec0) `Copy`-`u32` accessor
4553 /// already lifted, and mirror of the peer M3 mesh-slot
4554 /// per-`:placement` [`crate::Placement::estrategia`] (bafa004)
4555 /// `Copy`-return `pub const fn` scalar accessor whose method-name
4556 /// discipline this accessor was authored to match. Every downstream
4557 /// substrate-side `const`-context consumer of the per-`:supervisor`
4558 /// sibling-restart-strategy scalar (a future module-scope `const
4559 /// _:() = assert!(matches!(sup.estrategia(),
4560 /// RestartStrategy::OneForOne))` invariant pin on a typed fixture,
4561 /// a future M4 `mesh.pleme.io/v1alpha1/Supervisor` CR materializer
4562 /// admission-webhook `const fn` per-supervisor strategy-arm floor
4563 /// over a typed [`SupervisorSpec`], any future `const fn`
4564 /// supervisor-tree composer over the substrate primitive that fans
4565 /// on the sibling-restart-strategy at compile time) now reaches
4566 /// through the same typed dispatch on the substrate primitive at
4567 /// const-eval time as at runtime. A future non-`Copy`-return
4568 /// promotion of the scalar (an `Option<RestartStrategy>`-shape
4569 /// migration once the substrate grows per-cluster strategy overlays
4570 /// the [`SupervisorSpec`] docstring already anticipates, a
4571 /// per-tenant strategy-alias table the M4 CR materializer resolves
4572 /// per-CR) that would drop the `const` qualifier fails the
4573 /// fail-before-pass-after pin
4574 /// [`tests::supervisor_spec_estrategia_accessor_is_const_fn`] at
4575 /// caixa-core build time rather than surfacing as a downstream
4576 /// consumer regression.
4577 #[must_use]
4578 pub const fn estrategia(&self) -> RestartStrategy {
4579 self.estrategia
4580 }
4581
4582 /// Substrate-canonical per-`:supervisor` `:max-restarts` OTP-shaped
4583 /// `MaxIntensity` restart-budget scalar accessor every consumer that
4584 /// reads the supervisor's per-`:restart-window` restart-budget count
4585 /// keys off — returns the author-declared `:supervisor :max-restarts`
4586 /// typed `u32` verbatim, `Copy`-projected from the typed slot's own
4587 /// `u32` storage (`u32` is `Copy`, so the accessor returns by value; no
4588 /// borrow of `&self` past the call). Non-optional (the `u32` field
4589 /// carries the restart-budget count as a required axis with a
4590 /// [`default_max_restarts`]-supplied default; the zero-floor arm
4591 /// [`SupervisorError::ZeroMaxRestarts`] and the cap arm
4592 /// [`SupervisorError::MaxRestartsExceedsCap`] jointly bracket the
4593 /// accept-set to `1..=SUPERVISOR_MAX_RESTARTS_MAX`).
4594 ///
4595 /// The `:supervisor :max-restarts` slot carries the Erlang/OTP
4596 /// `MaxIntensity` restart-budget count that pairs with the sibling
4597 /// `:restart-window` `Period` to form the `MaxIntensity / Period`
4598 /// restart-intensity ratio the supervisor trips its own escalation on
4599 /// (`theory/RUNTIME-PATTERNS.md` §II.2, Learn You Some Erlang's
4600 /// `{intensity, 5, 60}` worker-supervisor default). Every downstream
4601 /// consumer of the Supervisor's per-`:supervisor` restart-budget count
4602 /// keys off this scalar (the [`SupervisorSpec::validate`] zero-floor +
4603 /// upper-cap bracket at
4604 /// `require_positive_bounded_u32(self.max_restarts(), …)`, the future
4605 /// wasm-operator's per-supervisor restart-intensity counter's
4606 /// budget-vs-count comparator, the future M4
4607 /// `mesh.pleme.io/v1alpha1/Supervisor` CR materializer's admission
4608 /// webhook, the `caixa-operator`'s hierarchical reconciliation
4609 /// scheduler's per-supervisor escalation-decision branch, every
4610 /// `SupervisorError::MaxRestartsExceedsCap` variant carrying the
4611 /// offending count verbatim for `feira lint` rendering).
4612 ///
4613 /// Prior to this lift the `.max_restarts` field was accessed inline at
4614 /// one production site in `caixa-core/src/supervisor.rs` — the
4615 /// [`SupervisorSpec::validate`] `require_positive_bounded_u32(self
4616 /// .max_restarts, …)` bracket-gate call — one open-coded field-access
4617 /// that expressed no compile-time link back to the typed slot. A
4618 /// future extension of the `:max-restarts` axis to a richer author
4619 /// surface (a per-cluster restart-budget override the operator pins
4620 /// through a future `:supervisor :max-restarts-overrides` slot the
4621 /// MESH-COMPOSITION §III.2 supervision-canary roadmap acknowledges,
4622 /// a per-tenant restart-budget-alias table the M4 CR materializer
4623 /// resolves per-CR, a per-supervisor dynamic restart-budget derivation
4624 /// the future adaptive-supervision engine computes from child-failure-
4625 /// history topology, a promotion of the plain `u32` count to a richer
4626 /// `{MaxR, MaxT}` tuple once Erlang/OTP's per-child-cohort restart-
4627 /// budget-partition slot comes into scope) would have had to be
4628 /// threaded through every open-coded copy in lockstep or the validate
4629 /// gate and the future M4 emit path would silently disagree on which
4630 /// restart-budget count a given supervisor resolves to — an author's
4631 /// `:max-restarts 5` would satisfy validate while the emit path
4632 /// silently read a drifted other value (a `:max-restarts 10000`
4633 /// no-op supervisor at the emit boundary would carry the author's
4634 /// declared `5` verbatim in `feira lint` output while the future
4635 /// wasm-operator's restart-intensity counter operated under the
4636 /// drifted count), a two-consumer split at the validator far from the
4637 /// source `caixa.lisp` with no field naming the restart-budget-drift
4638 /// root cause. Lifting the resolution rule to a typed method on the
4639 /// substrate primitive means every downstream consumer of the
4640 /// Supervisor's per-`:supervisor` restart-budget-count surface reaches
4641 /// for exactly one typed dispatch — the resolver's accept-set migrates
4642 /// as a unit on any future axis addition.
4643 ///
4644 /// Peer of the sibling M3 mesh-slot [`crate::CircuitBreaker::max_failures`]
4645 /// (3a74062) `Copy`-return `u32` sub-struct required-scalar accessor
4646 /// on the per-`:politicas :circuit-breaker :max-failures` Envoy-
4647 /// outlier-detection trip-threshold axis — same "one typed dispatch on
4648 /// the substrate primitive, thin projections at each consumer"
4649 /// discipline extended onto the M2 supervisor-slot per-`:supervisor`
4650 /// restart-budget-count `Copy`-`u32` scalar axis. The two typed axes
4651 /// (`CircuitBreaker::max_failures` on the M3 Aplicacao side,
4652 /// `SupervisorSpec::max_restarts` on the M2 Supervisor side) now share
4653 /// one accessor discipline for the shared substrate concept "a
4654 /// `Copy`-projected required `u32` count that trips the next-higher
4655 /// protection layer after N events in a rolling window" — both are
4656 /// counters with identical degenerate-at-the-high-end shape and share
4657 /// the paired [`crate::POLICY_BREAKER_MAX_FAILURES_MAX`] /
4658 /// [`SUPERVISOR_MAX_RESTARTS_MAX`] `1000` cap. Second `Copy`-return
4659 /// accessor on the M2 supervisor-slot `SupervisorSpec` type, sibling
4660 /// to the [`SupervisorSpec::estrategia`] (eafb619) `Copy`-composite-
4661 /// enum `RestartStrategy` accessor. Named `max_restarts()` to match
4662 /// the storage field's name verbatim and the peer
4663 /// [`crate::CircuitBreaker::max_failures`] method-name discipline; the
4664 /// accessor's identity maps onto the canonical OTP-shape supervision
4665 /// vocabulary the [`SupervisorSpec::max_restarts`] field's docstring
4666 /// already carries.
4667 #[must_use]
4668 pub const fn max_restarts(&self) -> u32 {
4669 self.max_restarts
4670 }
4671
4672 /// Substrate-canonical per-`:supervisor` `:restart-window` OTP-shaped
4673 /// `Period` sliding-window scalar accessor every consumer of the
4674 /// supervisor's `MaxIntensity / Period` restart-intensity denominator
4675 /// keys off — returns the author-declared `:supervisor :restart-window`
4676 /// typed [`Duration`] verbatim as an `Option<Duration>`, copied out of
4677 /// the typed slot's own `Option<Duration>` storage (`Duration` is
4678 /// `Copy`, so `Option<Duration>` is `Copy` and the accessor returns by
4679 /// value; no borrow of `&self` past the call). `None` when the slot is
4680 /// absent (the canonical "never reset — every restart across the
4681 /// supervisor's lifetime counts against the sibling `:max-restarts`
4682 /// budget" sentinel the field's own docstring names and the peer
4683 /// `validate_accepts_none_restart_window` pin locks in on the
4684 /// [`SupervisorSpec::validate`] entry-side).
4685 ///
4686 /// The `:supervisor :restart-window` slot carries the Erlang/OTP
4687 /// `Period` sliding-observation-interval that pairs with the sibling
4688 /// `:max-restarts` `MaxIntensity` restart-budget count to form the
4689 /// `MaxIntensity / Period` restart-intensity ratio the supervisor
4690 /// trips its own escalation on (`theory/RUNTIME-PATTERNS.md` §II.2,
4691 /// Learn You Some Erlang's `{intensity, 5, 60}` worker-supervisor
4692 /// default). The typed slot's `Option<Duration>` accept-set —
4693 /// zero-floor rejected through [`SupervisorError::RestartWindowZero`]
4694 /// (Erlang/OTP's `MaxIntensity / Period` invariant requires
4695 /// `Period > 0`; a zero period either trips on the first failure or
4696 /// never trips depending on operator interpretation, neither of which
4697 /// is the author's intent — omit the slot to express "no reset";
4698 /// carry a positive duration to express the sliding window),
4699 /// integer-millisecond canonical form enforced through
4700 /// [`SupervisorError::RestartWindowNotCanonical`] (the duration
4701 /// codec's canonical form emits `"1500ms"` not `"1.5s"` and the
4702 /// future wasm-operator's per-supervisor restart-intensity counter
4703 /// quantizes at milliseconds), upper-bounded by
4704 /// [`SUPERVISOR_RESTART_WINDOW_MAX`] (1h — the coarsest per-
4705 /// supervisor rolling window any operationally-reachable supervisor
4706 /// can honor without spanning multiple scheduler epochs the
4707 /// hierarchical-reconciliation scheduler treats as independent) —
4708 /// maps onto the future wasm-operator (M3) per-supervisor
4709 /// restart-intensity counter's rolling-observation-interval, the
4710 /// future M4 `mesh.pleme.io/v1alpha1/Supervisor` CR materializer's
4711 /// per-`spec.restartWindow` admission webhook, and the sibling
4712 /// `duration_codec`-serialized wire scalar every downstream consumer
4713 /// of the supervisor's per-`:supervisor` restart-intensity denominator
4714 /// keys off.
4715 ///
4716 /// Prior to this lift the `.restart_window` field was accessed inline
4717 /// at one production site in `caixa-core/src/supervisor.rs` — the
4718 /// [`SupervisorSpec::validate`] `if let Some(w) = self.restart_window {
4719 /// … }` zero-floor + canonical-form + upper-cap bracket arm — one
4720 /// open-coded field-access that expressed no compile-time link back to
4721 /// the typed slot. A future extension of the `:restart-window` axis to
4722 /// a richer author surface (a per-cluster restart-window override the
4723 /// operator pins through a future `:supervisor :restart-window-overrides`
4724 /// slot the MESH-COMPOSITION §III.2 supervision-canary roadmap
4725 /// acknowledges, a per-tenant restart-window-alias table the M4 CR
4726 /// materializer resolves per-CR, a per-supervisor dynamic
4727 /// restart-window derivation the future adaptive-supervision engine
4728 /// computes from child-failure-history topology, a promotion of the
4729 /// plain `Option<Duration>` window to a richer `{observation, cooldown}`
4730 /// pair once Erlang/OTP's per-child-cohort observation-interval-
4731 /// partition slot comes into scope) would have had to be threaded
4732 /// through every open-coded copy in lockstep or the validate gate and
4733 /// the future M4 emit path would silently disagree on which
4734 /// restart-window a given supervisor resolves to — an author's
4735 /// `:restart-window "60s"` would satisfy validate while the emit path
4736 /// silently read a drifted other value (a `Some(Duration::from_secs(60))`
4737 /// authored slot at the emit boundary would carry the author's
4738 /// declared window verbatim in `feira lint` output while the future
4739 /// wasm-operator's restart-intensity counter operated under a
4740 /// drifted window, or vice versa: an author's `:restart-window ()`
4741 /// would carry the "never reset" sentinel through validate while the
4742 /// emit path silently substituted a default sliding window), a
4743 /// two-consumer split at the validator far from the source
4744 /// `caixa.lisp` with no field naming the restart-window-drift root
4745 /// cause. Lifting the resolution rule to a typed method on the
4746 /// substrate primitive means every downstream consumer of the
4747 /// Supervisor's per-`:supervisor` restart-intensity-denominator
4748 /// surface reaches for exactly one typed dispatch — the resolver's
4749 /// accept-set migrates as a unit on any future axis addition.
4750 ///
4751 /// Third `Copy`-return accessor on the M2 supervisor-slot
4752 /// `SupervisorSpec` type, closing the last unlifted per-`:supervisor`
4753 /// scalar-value axis (`children: Vec<ChildSpec>` carries a `Vec`
4754 /// payload rather than a `Copy`-scalar, and the per-`:children`
4755 /// [`crate::ChildSpec::nome`] (57c61d0) /
4756 /// [`crate::ChildSpec::versao_requirement`] (2c053c8) child-caixa
4757 /// scalar accessors already close the per-element `String`-carry
4758 /// axes). Sibling to the peer M2 [`crate::LimitsSpec::wall_clock`]
4759 /// (8cb717b) `Option<Duration>` accessor on the `:limits` slot's
4760 /// per-outermost-call wall-clock-deadline axis and the peer M3
4761 /// [`crate::MeshPolicy::timeout`] (7073d0f) `Option<Duration>`
4762 /// accessor on the `:politicas` slot's per-call-deadline axis — all
4763 /// three share the shared substrate concept "a `Copy`-projected
4764 /// optional `Duration` that carries a positive integer-millisecond
4765 /// canonical value with a `1ms..=<axis-specific>_MAX` accept-set and
4766 /// the paired zero-floor / non-canonical / above-cap refusal cascade"
4767 /// through the same [`crate::render::require_positive_canonical_bounded_duration`]
4768 /// bracket-helper the three axes each route through. Named
4769 /// `restart_window()` to match the storage field's name verbatim and
4770 /// the peer [`crate::LimitsSpec::wall_clock`] /
4771 /// [`crate::MeshPolicy::timeout`] method-name discipline; the
4772 /// accessor's identity maps onto the canonical OTP-shape supervision
4773 /// vocabulary the [`SupervisorSpec::restart_window`] field's docstring
4774 /// already carries.
4775 #[must_use]
4776 pub const fn restart_window(&self) -> Option<Duration> {
4777 self.restart_window
4778 }
4779
4780 /// Substrate-canonical per-`:supervisor` `:children` OTP-shaped
4781 /// static-child-list slice accessor every consumer that walks the
4782 /// supervisor's declared child set keys off — returns the author-
4783 /// declared `:supervisor :children` `Vec<ChildSpec>` verbatim as a
4784 /// `&[ChildSpec]` slice-view, borrowed from the typed slot's own
4785 /// `Vec<ChildSpec>` storage (a zero-copy slice-view over the same
4786 /// backing buffer the `Serialize`/`Deserialize` derives round-trip
4787 /// through). Non-optional: an empty slice is the load-bearing
4788 /// "author declared `:children ()`" sentinel every consumer of the
4789 /// cross-slot `SimpleOneForOne ↔ children.is_empty()` partition
4790 /// keys off (`SimpleOneForOne` requires the empty slice; the peer
4791 /// three strategies require a non-empty slice — the paired
4792 /// [`SupervisorError::SimpleOneForOneWithStaticChildren`] /
4793 /// [`SupervisorError::NoChildren`] refusal cascade pins the
4794 /// partition on both arms).
4795 ///
4796 /// The `:supervisor :children` slot carries the OTP-shaped static
4797 /// child list the supervisor materializes one ComputeUnit per
4798 /// entry from — the Erlang/OTP `supervisor:init/1`'s
4799 /// `{ok, {SupFlags, ChildSpecs}}` `ChildSpecs` list, projected
4800 /// through the tatara-lisp `:children` author surface onto a typed
4801 /// `Vec<ChildSpec>` whose per-element `(nome(),
4802 /// versao_requirement(), restart)` triple the per-child
4803 /// [`SupervisorSpec::validate`] loop already gates through the
4804 /// lifted [`ChildSpec::nome`] (57c61d0) /
4805 /// [`ChildSpec::versao_requirement`] (2c053c8) scalar accessors.
4806 /// Every downstream consumer that fans on the static child list
4807 /// keys off this slice (the [`SupervisorSpec::validate`]
4808 /// `SimpleOneForOne ↔ non-SimpleOneForOne` partition dispatch's
4809 /// `.is_empty()` probe on both arms, the [`SupervisorSpec::validate`]
4810 /// per-child DNS-1123 / semver-requirement / duplicate-detection
4811 /// fan-out loop, every future wasm-operator (M3) per-supervisor
4812 /// hierarchical-reconciliation scheduler's per-child ComputeUnit
4813 /// materialization loop, the future M4
4814 /// `mesh.pleme.io/v1alpha1/Supervisor` CR materializer's per-child
4815 /// admission-webhook fan-out, the future `feira app graph`
4816 /// per-supervisor tree-print traversal).
4817 ///
4818 /// Prior to this lift the `.children` `Vec<ChildSpec>` was accessed
4819 /// inline at three production sites in `caixa-core/src/supervisor.rs`
4820 /// — the [`SupervisorSpec::validate`] `SimpleOneForOne`-arm
4821 /// `!self.children.is_empty()` cross-slot refusal probe, the peer
4822 /// non-`SimpleOneForOne`-arm `self.children.is_empty()`
4823 /// [`SupervisorError::NoChildren`] refusal probe, and the per-child
4824 /// validate loop's `for child in &self.children` traversal head —
4825 /// three open-coded field-accesses that expressed no compile-time
4826 /// link back to the typed slot. A future extension of the
4827 /// `:supervisor :children` axis to a richer author surface (a
4828 /// per-cluster child-set overlay the operator pins through a future
4829 /// `:supervisor :children-overrides` slot the MESH-COMPOSITION §III.2
4830 /// supervision-canary roadmap acknowledges, a per-tenant
4831 /// child-set-alias table the M4 CR materializer resolves per-CR,
4832 /// a per-supervisor dynamic-child derivation the future adaptive-
4833 /// supervision engine computes from child-failure-history topology,
4834 /// a promotion of the plain `Vec<ChildSpec>` to a richer
4835 /// `{static, dynamic}` partition once Erlang/OTP's
4836 /// `simple_one_for_one` dynamic-child slot comes into typed scope)
4837 /// would have had to be threaded through all three open-coded copies
4838 /// in lockstep or one consumer would silently disagree with the
4839 /// peers on which child-set a given supervisor resolves to — the
4840 /// `SimpleOneForOne`-arm probe reading the raw slot while the peer
4841 /// non-`SimpleOneForOne`-arm probe read an operator-resolved slot
4842 /// would silently split the partition-dispatch's two-arm coherence
4843 /// (a supervisor that satisfies neither arm's precondition, or that
4844 /// satisfies both, at the cost of the paired
4845 /// `SimpleOneForOneWithStaticChildren`/`NoChildren` refusal cascade
4846 /// silently drifting from the per-child validate loop's actual
4847 /// traversal input), a three-consumer split at the validator far
4848 /// from the source `caixa.lisp` with no field naming the
4849 /// child-set-drift root cause. Lifting the resolution rule to a
4850 /// typed method on the substrate primitive means every downstream
4851 /// consumer of the Supervisor's per-`:supervisor` static-child-list
4852 /// surface reaches for exactly one typed dispatch — the resolver's
4853 /// accept-set migrates as a unit on any future axis addition.
4854 ///
4855 /// First slice-return (`&[T]`) accessor on any M2 or M3 typed slot
4856 /// — the seed for the same "one typed dispatch on the substrate
4857 /// primitive, thin projections at each consumer" discipline the
4858 /// closed [`crate::LimitsSpec`] / [`BehaviorSpec`] /
4859 /// [`crate::UpgradeFromEntry`] scalar-accessor families each carry
4860 /// on their `Copy` / `Option<Copy>` / `Option<&str>` axes, extended
4861 /// onto the first `Vec`-carry axis on the substrate. The four peer
4862 /// `Vec`-carry axes still unlifted at the time of this seed —
4863 /// [`crate::Placement::clusters`] (`Vec<String>` per-cluster
4864 /// distribution-target list), [`crate::AplicacaoSpec::membros`]
4865 /// (`Vec<Membro>` per-Aplicacao member list),
4866 /// [`crate::AplicacaoSpec::contratos`] (`Vec<WitContract>`
4867 /// per-Aplicacao WIT-typed edge list),
4868 /// [`crate::UpgradeFromEntry::instructions`]
4869 /// (`Vec<UpgradeInstruction>` per-appup migration-instruction list)
4870 /// — inherit this accessor's discipline as future compounding runs
4871 /// migrate their consumers onto the shared slice-return shape.
4872 /// Fourth (and final) accessor on the M2 supervisor-slot
4873 /// `SupervisorSpec` type, sibling to the three `Copy`-return
4874 /// [`SupervisorSpec::estrategia`] (eafb619) /
4875 /// [`SupervisorSpec::max_restarts`] (7844f4e) /
4876 /// [`SupervisorSpec::restart_window`] (7e7b32f) accessors — closes
4877 /// the last unlifted per-`:supervisor` field axis (the
4878 /// `Vec<ChildSpec>` static-child-list carrier) so every downstream
4879 /// per-`:supervisor` reader now routes through a typed dispatch on
4880 /// the substrate primitive. Named `children()` to match the storage
4881 /// field's name verbatim and the tatara-lisp author-surface term
4882 /// (`:children`) the field's own docstring already carries; the
4883 /// accessor's identity maps onto the canonical OTP-shape
4884 /// supervision vocabulary the [`SupervisorSpec::children`] field's
4885 /// docstring already reaches for ("Static children ..."). Returns
4886 /// `&[ChildSpec]` (not `&Vec<ChildSpec>`) because every downstream
4887 /// consumer of the child list treats it as a read-only sequence —
4888 /// the slice-view is the narrowest borrow that supports every
4889 /// present + roadmapped consumer (`.is_empty()`, `.iter()`,
4890 /// index, `.len()`) without leaking the backing `Vec`'s
4891 /// grow/push/reserve surface that no consumer of the typed view
4892 /// reaches for (the storage-side `Vec` remains reachable through
4893 /// the `pub children` field for the mutation-carrying
4894 /// `Caixa::supervisor_view` fold-in path in
4895 /// `manifest.rs:supervisor_view`).
4896 #[must_use]
4897 pub const fn children(&self) -> &[ChildSpec] {
4898 self.children.as_slice()
4899 }
4900
4901 /// Validate the supervisor's typed shape — strategy ↔ children
4902 /// invariants, max_restarts > 0, restart_window > 0 when set,
4903 /// per-child non-empty + duplicate-free names.
4904 ///
4905 /// Mirrors the value-shape discipline applied to every other
4906 /// typed slot:
4907 ///
4908 /// - `Some(Duration::ZERO)` on a Duration-bearing axis is the
4909 /// same "0 means the opposite of what you think" footgun
4910 /// closed for `:politicas :timeout` (Envoy interprets a zero
4911 /// timeout as `infinite`), `:politicas :circuit-breaker
4912 /// :window`, and `:limits :wall-clock`. The
4913 /// `MaxIntensity / Period` ratio in Erlang/OTP's
4914 /// `supervisor` requires `Period > 0`; a zero period either
4915 /// trips on the first failure or never trips depending on
4916 /// operator interpretation, neither of which is the
4917 /// author's intent. Omit `:restart-window` to express "no
4918 /// reset"; carry a positive duration to express the window.
4919 /// - duplicate `:children` `:caixa` names are the same
4920 /// graph-node-set / multiset distinction closed for
4921 /// `:membros` (4bb3f3d), `:placement :clusters` (c7c7799),
4922 /// and `:entrada :paths` (eb3456d). Two children with the
4923 /// same `:caixa` materialize as two ComputeUnits with the
4924 /// same name in the cluster's HelmRelease values, one
4925 /// silently overwriting the other. Erlang/OTP's
4926 /// `child_spec.id` is required-unique per supervisor;
4927 /// pleme-io enforces the same set-not-multiset shape on
4928 /// `:caixa` (the load-bearing identity in our renderer).
4929 pub fn validate(&self) -> Result<(), SupervisorError> {
4930 // Route the `SimpleOneForOne ↔ non-SimpleOneForOne` partition
4931 // dispatch and the non-`SimpleOneForOne`-arm [`SupervisorError::NoChildren`]
4932 // error carrier's `estrategia:` field through the lifted
4933 // [`SupervisorSpec::estrategia`] accessor rather than the raw
4934 // `self.estrategia` field access — the two production consumers
4935 // of the per-`:supervisor` sibling-restart-strategy scalar now
4936 // key off exactly one typed dispatch on the substrate primitive,
4937 // so any future rebrand on the axis (a per-cluster strategy
4938 // override the operator pins through a future `:supervisor
4939 // :estrategia-overrides` slot, a per-tenant strategy-alias table
4940 // the M4 CR materializer resolves per-CR) migrates as a single
4941 // caixa-core edit rather than a coordinated rewrite of the two
4942 // call sites — sibling of the peer M3 [`crate::Placement::estrategia`]
4943 // (921fe1b) four-consumer migration on the per-`:placement`
4944 // distribution-strategy axis.
4945 // Route the `SimpleOneForOne ↔ non-SimpleOneForOne` partition-
4946 // dispatch's paired `.is_empty()` cross-slot refusal probes
4947 // (the `SimpleOneForOne`-arm
4948 // [`SupervisorError::SimpleOneForOneWithStaticChildren`] refusal
4949 // and the non-`SimpleOneForOne`-arm [`SupervisorError::NoChildren`]
4950 // refusal) through the lifted [`SupervisorSpec::children`]
4951 // slice-return accessor rather than the raw `self.children`
4952 // field access — the two paired production consumers of the
4953 // per-`:supervisor` static-child-list scalar-shape now key off
4954 // exactly one typed dispatch on the substrate primitive, so any
4955 // future rebrand on the axis (a per-cluster child-set overlay
4956 // the operator pins through a future `:supervisor
4957 // :children-overrides` slot, a per-tenant child-set-alias table
4958 // the M4 CR materializer resolves per-CR) migrates as a single
4959 // caixa-core edit rather than a coordinated rewrite of the
4960 // paired arms — first slice-return migration on any typed slot,
4961 // seed for the peer per-`:placement :clusters`,
4962 // per-`:membros`, per-`:contratos`, and per-`:upgrade-from
4963 // :instructions` `Vec`-carry axes.
4964 match self.estrategia() {
4965 RestartStrategy::SimpleOneForOne => {
4966 // SimpleOneForOne: children added at runtime. Static
4967 // list must be empty (one shape declared elsewhere).
4968 if !self.children().is_empty() {
4969 return Err(SupervisorError::SimpleOneForOneWithStaticChildren);
4970 }
4971 }
4972 _ => {
4973 if self.children().is_empty() {
4974 return Err(SupervisorError::no_children(self.estrategia()));
4975 }
4976 }
4977 }
4978 // Zero-floor + upper-cap bracket on the typed `:max-restarts`
4979 // axis. See [`crate::render::require_positive_bounded_u32`] for
4980 // the ordering discipline (zero-floor arm strictly precedes cap
4981 // arm so `0` surfaces the self-locating `ZeroMaxRestarts`
4982 // diagnostic with its counter-axis remediation directly named,
4983 // not the misleading `0 > SUPERVISOR_MAX_RESTARTS_MAX == false`
4984 // cap-arm miss). Until this bracket landed the top edge ran all
4985 // the way to `u32::MAX` and a struct-literal
4986 // `SupervisorSpec { max_restarts: 100_000, .. }` (or the
4987 // equivalent author-surface `:max-restarts 100000` /
4988 // `:max-restarts 4294967295` typo landing in the slot) silently
4989 // passed validate. The runtime substrate consuming the value
4990 // (Erlang/OTP's `MaxIntensity / Period` ratio, the future
4991 // wasm-operator's per-supervisor restart-intensity counter, the
4992 // M4 `mesh.pleme.io/v1alpha1/Supervisor` CR materializer's
4993 // admission webhook) then turned a typed `:max-restarts`
4994 // policy into a no-op supervisor: the escalation threshold is
4995 // structurally so high that no realistic
4996 // restarts-per-`:restart-window` traffic shape can reach it,
4997 // the supervisor never escalates to its parent, and a bad
4998 // child can loop inside the window indefinitely with the
4999 // parent supervisor structurally never receiving the "this
5000 // subtree has exceeded its restart budget" signal the typed
5001 // slot is meant to express. The bracket set is
5002 // `1..=SUPERVISOR_MAX_RESTARTS_MAX`, peer with the
5003 // [`crate::aplicacao::POLICY_BREAKER_MAX_FAILURES_MAX`] cap on
5004 // the sibling `:politicas :circuit-breaker :max-failures` axis:
5005 // both are "trip the next-higher protection layer after N
5006 // events in a rolling window" counters with identical
5007 // degenerate-at-the-high-end shape and now share one canonical
5008 // bracket helper. The bracket precedes the sibling
5009 // `:restart-window` zero-floor / canonical-millisecond arms so
5010 // an over-cap `max_restarts` paired with a structurally invalid
5011 // window surfaces the bracket diagnostic first, mirroring the
5012 // `PolicyBreakerMaxFailuresExceedsCap` / window-axis cross-arm
5013 // ordering on the peer `:politicas :circuit-breaker` slot.
5014 // Route the [`SupervisorSpec::validate`] `:max-restarts` zero-floor +
5015 // upper-cap bracket-gate through the lifted [`SupervisorSpec::max_restarts`]
5016 // accessor rather than the raw `self.max_restarts` field access —
5017 // the one production consumer of the per-`:supervisor`
5018 // restart-budget-count scalar now keys off exactly one typed
5019 // dispatch on the substrate primitive, so any future rebrand on
5020 // the axis (a per-cluster restart-budget override the operator
5021 // pins through a future `:supervisor :max-restarts-overrides`
5022 // slot, a per-tenant restart-budget-alias table the M4 CR
5023 // materializer resolves per-CR) migrates as a single caixa-core
5024 // edit rather than a coordinated rewrite — sibling of the peer M3
5025 // [`crate::CircuitBreaker::max_failures`] (3a74062) migration on
5026 // the per-`:politicas :circuit-breaker :max-failures` axis.
5027 crate::render::require_positive_bounded_u32(
5028 self.max_restarts(),
5029 SUPERVISOR_MAX_RESTARTS_MAX,
5030 || SupervisorError::ZeroMaxRestarts,
5031 SupervisorError::max_restarts_exceeds_cap,
5032 )?;
5033 // Route the [`SupervisorSpec::validate`] `:restart-window`
5034 // zero-floor + integer-millisecond canonical-form + upper-cap
5035 // bracket-gate through the lifted [`SupervisorSpec::restart_window`]
5036 // accessor rather than the raw `self.restart_window` field access —
5037 // the one production consumer of the per-`:supervisor`
5038 // restart-intensity-denominator scalar now keys off exactly one
5039 // typed dispatch on the substrate primitive, so any future rebrand
5040 // on the axis (a per-cluster restart-window override the operator
5041 // pins through a future `:supervisor :restart-window-overrides`
5042 // slot, a per-tenant restart-window-alias table the M4 CR
5043 // materializer resolves per-CR) migrates as a single caixa-core
5044 // edit rather than a coordinated rewrite — sibling of the peer M2
5045 // [`crate::LimitsSpec::wall_clock`] (8cb717b) validate-arm-route
5046 // on the per-`:limits :wall-clock` axis and the peer M3
5047 // [`crate::MeshPolicy::timeout`] (7073d0f) accessor-route on the
5048 // per-`:politicas :timeout` axis.
5049 if let Some(w) = self.restart_window() {
5050 // Zero-floor + integer-millisecond canonical-form +
5051 // upper-cap bracket on the typed `:restart-window` axis.
5052 // See
5053 // [`crate::render::require_positive_canonical_bounded_duration`]
5054 // for the full three-arm ordering discipline (zero-floor
5055 // strictly precedes canonical-form so `Duration::ZERO`
5056 // surfaces the self-locating `RestartWindowZero`
5057 // diagnostic; canonical-form strictly precedes the cap arm
5058 // so a sub-millisecond above-cap value surfaces the more
5059 // fundamental round-trip-shape diagnostic first) and the
5060 // three peer typed-`Duration` sites that share this
5061 // canonical bracket ([`crate::MeshPolicy::timeout`],
5062 // [`crate::CircuitBreaker::window`],
5063 // [`crate::LimitsSpec::wall_clock`]). Every validated
5064 // value lies in `1ms..=SUPERVISOR_RESTART_WINDOW_MAX`
5065 // (1ms..=1h), integer-millisecond granularity.
5066 crate::render::require_positive_canonical_bounded_duration(
5067 w,
5068 SUPERVISOR_RESTART_WINDOW_MAX,
5069 || SupervisorError::RestartWindowZero,
5070 SupervisorError::restart_window_not_canonical,
5071 SupervisorError::restart_window_exceeds_cap,
5072 )?;
5073 }
5074 // Route the per-child DNS-1123 / semver-requirement / duplicate-
5075 // detection fan-out loop through the lifted named per-slot gate
5076 // [`SupervisorSpec::validate_children`] rather than an inline
5077 // three-per-child cascade — every future consumer that wants to
5078 // re-check only the `:children` slot's per-entry axes (the M4
5079 // `mesh.pleme.io/v1alpha1/Supervisor` CR materializer's
5080 // admission webhook re-validating one added/renamed child, the
5081 // future wasm-operator's per-child dynamic-add re-validator on
5082 // the `SimpleOneForOne` runtime-add path once dynamic-children
5083 // graduate to a typed slot, a future partial re-validator on a
5084 // per-`:children`-entry patch) reaches every per-entry axis
5085 // through one dispatch rather than re-inlining the three-arm
5086 // cascade in lockstep with `validate` or paying the peer
5087 // `:estrategia`/`:max-restarts`/`:restart-window` gates to
5088 // reach one entry check. Sibling of the peer M3 mesh-slot
5089 // per-slot gate family (`validate_membros` — the exact peer on
5090 // the M3 side, [`crate::AplicacaoSpec::validate_membros`];
5091 // `validate_contratos` — 906a5c6; `validate_entrada` — 20cd523;
5092 // `validate_placement`; `validate_politicas` routing through
5093 // `MeshPolicy::validate` — f03a154) — the M2 supervisor-slot
5094 // per-slot gate discipline now spans both the M3 mesh-slot
5095 // family and the M2 `:children` per-child-cascade axis on one
5096 // shape: one named per-slot gate per typed per-entry loop.
5097 self.validate_children()?;
5098 Ok(())
5099 }
5100
5101 /// Named per-slot gate on the M2 `:supervisor :children` per-entry
5102 /// axis — folds the per-child DNS-1123 name gate, semver-requirement
5103 /// gate, and duplicate-`:caixa` dedup arm into one call every
5104 /// consumer that wants to re-validate one `:children` entry (or the
5105 /// whole list) against the same accept-set [`SupervisorSpec::validate`]
5106 /// admits reaches through.
5107 ///
5108 /// Peer of the M3 mesh-slot [`crate::AplicacaoSpec::validate_membros`]
5109 /// per-slot gate on the analogous per-entry axis (`:membros`) — same
5110 /// three-per-entry shape (DNS-1123 name + semver-requirement +
5111 /// duplicate-`:caixa` dedup), lifted to one named substrate
5112 /// primitive per slot. The M4 `mesh.pleme.io/v1alpha1/Supervisor` CR
5113 /// materializer's admission webhook re-checking one added or renamed
5114 /// child, the future wasm-operator's per-child dynamic-add
5115 /// re-validator on the `SimpleOneForOne` runtime-add path once
5116 /// dynamic-children graduate to a typed slot, a future partial
5117 /// re-validator on a per-`:children`-entry patch — each reaches the
5118 /// three per-entry axes through this one dispatch rather than
5119 /// re-inlining the three-arm cascade in lockstep with `validate`
5120 /// (the duplication the PRIME DIRECTIVE names as a bug) or paying
5121 /// the peer `:estrategia`/`:max-restarts`/`:restart-window` gates to
5122 /// reach one entry check.
5123 ///
5124 /// Self-contained on `&self` — resolves its own dedup `HashSet`
5125 /// through [`SupervisorSpec::children`] rather than borrowing one
5126 /// threaded down from `validate`, the same posture the peer M3
5127 /// mesh-slot per-slot gates ([`crate::AplicacaoSpec::validate_membros`],
5128 /// [`crate::AplicacaoSpec::validate_contratos`],
5129 /// [`crate::AplicacaoSpec::validate_entrada`],
5130 /// [`crate::AplicacaoSpec::validate_placement`]) each carry, so a
5131 /// consumer that reaches this gate directly (without first calling
5132 /// `validate`) still runs the full per-child cascade — pinned by
5133 /// `validate_children_matches_gate_on_per_axis_refusal_shapes` +
5134 /// `validate_children_matches_gate_on_versao_invalid_and_clean_pass`
5135 /// + `validate_children_is_self_contained_on_children_slot`.
5136 ///
5137 /// The three per-entry arms run in the same canonical order the
5138 /// pre-lift inline cascade encoded (DNS-1123 → semver → dedup), so
5139 /// the diagnostic every author-declared per-`:children` entry surfaces
5140 /// through `validate` is byte-equal to the diagnostic this gate
5141 /// surfaces when called directly — the equivalence-pin pair
5142 /// `validate_children_matches_gate_on_per_axis_refusal_shapes` +
5143 /// `validate_children_matches_gate_on_versao_invalid_and_clean_pass`
5144 /// asserts the two altitudes discriminate the same set on every
5145 /// per-entry-covered input.
5146 pub fn validate_children(&self) -> Result<(), SupervisorError> {
5147 let mut seen = std::collections::HashSet::new();
5148 for child in self.children() {
5149 // Every emitted cluster artifact's `metadata.name` for a
5150 // supervised child derives from this `:children :caixa` value
5151 // verbatim — the rendered `wasm.pleme.io/v1alpha1/ComputeUnit
5152 // .metadata.name` per child, the [`crate::LABEL_PROGRAM`]
5153 // label value on every child's pod identity, and the per-
5154 // child K8s [`Service`][svc] `metadata.name` the future
5155 // wasm-operator (M3) provisions for inter-child supervision
5156 // tree wiring. Each apiserver-side schema on each landing
5157 // site enforces the DNS-1123 label rule on admission; a
5158 // structurally invalid child name (`"Worker"`, `"my_worker"`,
5159 // `"team.worker"`, `"-worker"`, `"worker-"`, the >63-byte
5160 // UUID-shaped mistaken-identity slug) silently passes the
5161 // prior empty-/duplicate-only gate and the failure surfaces
5162 // at `kubectl apply` time as a `metadata.name: Invalid value`
5163 // rejection, far from the source caixa.lisp, with no field
5164 // naming the offending `:children` entry. Lifting the gate
5165 // to caixa-build time mirrors the `:membros :caixa` value-
5166 // shape trajectory (3f9d7a0) and the `:placement :clusters`
5167 // trajectory (6cbb900) onto the third DNS-1123-label-shaped
5168 // identifier axis — the supervisor tree's child names —
5169 // through the lifted
5170 // [`crate::render::require_valid_dns_1123_label`] gate the
5171 // seven peer name axes (`:membros :caixa`, `:placement
5172 // :clusters`, `:placement :affinity`, `:contratos :de`/`:para`,
5173 // `:entrada :para`, `:nome`, `:upgrade-from :module`) each
5174 // route through, so drift between the eight axes' accepted
5175 // DNS-1123-label sets is structurally impossible.
5176 //
5177 // [svc]: https://kubernetes.io/docs/concepts/services-networking/service/
5178 crate::render::require_valid_dns_1123_label(
5179 child.nome(),
5180 || SupervisorError::EmptyChildName,
5181 |reason| SupervisorError::child_caixa_invalid(child.nome(), reason),
5182 )?;
5183 // The author surface for `:children :versao` is the same
5184 // Cargo-shaped semver requirement string `:deps :versao` and
5185 // `:membros :versao` carry — and the lacre pipeline resolves
5186 // all three axes through the same
5187 // [`crate::version::parse_requirement`] entry-point. The
5188 // shared [`crate::render::require_valid_versao_requirement`]
5189 // helper brackets the empty-first + parse cascade both peer
5190 // axes ([`crate::dep::Dep::validate`] on `:deps :versao`,
5191 // [`crate::AplicacaoSpec::validate_membros`] on `:membros
5192 // :versao`) route through, so drift between the three axes'
5193 // accepted requirement sets is structurally impossible and
5194 // the parse-side no-op the empty-first arm closes (semver's
5195 // empty parse yields an implicit `*`) lives in exactly one
5196 // predicate. Every `ChildSpec::versao` past validate is
5197 // round-trippable through [`crate::parse_requirement`]
5198 // without re-checking at the resolver layer, and the three
5199 // `:versao` typed surfaces (`:deps`, `:membros`, `:children`)
5200 // are now structurally equivalent by construction.
5201 crate::render::require_valid_versao_requirement(
5202 child.versao_requirement(),
5203 || SupervisorError::empty_child_version(child.nome()),
5204 |reason| {
5205 SupervisorError::child_versao_invalid(
5206 child.nome(),
5207 child.versao_requirement(),
5208 reason,
5209 )
5210 },
5211 )?;
5212 crate::render::insert_first_seen(&mut seen, child.nome(), || {
5213 SupervisorError::duplicate_child_caixa(child.nome())
5214 })?;
5215 }
5216 Ok(())
5217 }
5218}
5219
5220/// Cross-slot coherence gate on the supervision tree: no
5221/// `:children :caixa` entry may name the supervisor's own `:nome`.
5222///
5223/// A supervisor that lists itself as a child is a degenerate self-parent
5224/// — the supervision tree is a DAG rooted at the supervisor (OTP child
5225/// specs reference *distinct* child processes; a supervisor is never its
5226/// own child), and the wasm-operator's hierarchical reconciliation would
5227/// otherwise be handed a node that is its own parent: a one-node cycle it
5228/// either rejects far from the source `caixa.lisp` or recurses on. Because
5229/// every `:nome` is a globally-unique substrate identity (DNS-1123 label +
5230/// lacre closure root), a child whose `:caixa` equals the supervisor's
5231/// `:nome` *is* the supervisor itself, not a coincidentally-named peer.
5232///
5233/// Lives outside [`SupervisorSpec::validate`] because the typed view
5234/// carries the children but not the parent `:nome`; mirrors the
5235/// cross-slot precedence gate `validate_upgrade_from_against_versao`
5236/// (which likewise reads one slot against another at the
5237/// [`crate::layout`] wire-up site) and the mesh self-edge gate
5238/// `AplicacaoSpec`'s `ContratoSelfLoop` — the same "an edge from a graph
5239/// node to itself is structurally not a tree/mesh edge" discipline, here
5240/// on the supervision-tree axis.
5241pub fn validate_no_self_supervision(
5242 children: &[ChildSpec],
5243 parent_nome: &str,
5244) -> Result<(), SupervisorError> {
5245 for child in children {
5246 if child.nome() == parent_nome {
5247 return Err(SupervisorError::child_supervises_self(parent_nome));
5248 }
5249 }
5250 Ok(())
5251}
5252
5253#[derive(Debug, Error, PartialEq, Eq)]
5254pub enum SupervisorError {
5255 #[error("supervisor :estrategia {estrategia:?} requires at least one :children entry")]
5256 NoChildren { estrategia: RestartStrategy },
5257 #[error(
5258 "SimpleOneForOne supervisors must declare zero static children (children spawn dynamically)"
5259 )]
5260 SimpleOneForOneWithStaticChildren,
5261 #[error(":max-restarts must be > 0")]
5262 ZeroMaxRestarts,
5263 #[error(
5264 ":supervisor :max-restarts ({max_restarts}) exceeds the supervisor-policy ceiling \
5265 (SUPERVISOR_MAX_RESTARTS_MAX = 1000) — a value above this cap turns the typed \
5266 restart-intensity policy into a no-op supervisor: the escalation threshold is \
5267 structurally so high that no realistic restarts-per-:restart-window traffic shape \
5268 can reach it, so the supervisor never escalates to its parent and a bad child can \
5269 loop inside the window indefinitely. Every typed-slot consumer (Erlang/OTP's \
5270 MaxIntensity/Period ratio, the future wasm-operator's per-supervisor \
5271 restart-intensity counter, the M4 mesh.pleme.io/v1alpha1/Supervisor CR \
5272 materializer's admission webhook) emits a `:max-restarts` declaration that is \
5273 structurally never reached. Pin a value in 1..=1000 (Erlang/OTP / Elixir / Riak \
5274 Core / RabbitMQ production playbooks recommend 3..=100; the OTP `supervisor` \
5275 callback module's `MaxR = 1` minimal-restart default sits at the bottom of the \
5276 band) or restructure the supervision tree (split the flaky child into its own \
5277 sub-supervisor with a tighter budget) if you need a higher restart tolerance."
5278 )]
5279 MaxRestartsExceedsCap { max_restarts: u32 },
5280 #[error(
5281 ":restart-window must be > 0 when set — Erlang/OTP's MaxIntensity/Period \
5282 requires Period > 0; a zero window either trips on the first failure or \
5283 never trips depending on operator interpretation. Omit :restart-window to \
5284 express `never reset`; carry a positive duration to express the window."
5285 )]
5286 RestartWindowZero,
5287 #[error(
5288 ":supervisor :restart-window ({window:?}) carries a sub-millisecond residue the shared `duration_codec` cannot round-trip — \
5289 the codec truncates to `as_millis()` before picking the canonical unit, so a value with `subsec_nanos() % 1_000_000 != 0` either \
5290 truncates on first serialize (e.g. `Duration::from_micros(1500)` → \"1ms\" → `Duration::from_millis(1)` ≠ original) or renders \
5291 as \"0s\" the `RestartWindowZero` arm then rejects on re-validate. Pin an integer-millisecond magnitude in the canonical authoring form \
5292 (`<integer><unit>` for unit ∈ {{ms, s, m, h}}, e.g. `\"500ms\"`, `\"30s\"`, `\"2m\"`, `\"1h\"`) or omit the field for `never reset`"
5293 )]
5294 RestartWindowNotCanonical { window: Duration },
5295 #[error(
5296 ":supervisor :restart-window ({window:?}) exceeds the supervisor-policy ceiling \
5297 (SUPERVISOR_RESTART_WINDOW_MAX = 1h = 3600s) — a value above this cap turns the typed \
5298 per-supervisor rolling-window restart-intensity counter into a lifetime counter: the \
5299 failure-counting window is structurally so long that transient restarts are never \
5300 forgotten, the MaxIntensity/Period ratio degenerates from `trip the parent supervisor \
5301 when the child has exceeded its restart budget within the recent window` to `trip the \
5302 parent when the child has exceeded its restart budget over its lifetime`, and the \
5303 supervisor's reset semantic never reaches the child — every typed-slot consumer \
5304 (Erlang/OTP's MaxIntensity/Period reconciler, the future wasm-operator's \
5305 per-supervisor restart-intensity counter, the M4 mesh.pleme.io/v1alpha1/Supervisor CR \
5306 materializer's admission webhook, the caixa-operator's hierarchical reconciliation \
5307 scheduler) emits a `:restart-window` declaration that is structurally a no-op rolling \
5308 window. Pin a value in 1ms..=1h (Learn You Some Erlang's `{{intensity, 5, 60}}` \
5309 worker-supervisor `Period = 60s` default, Elixir's `Supervisor` `max_seconds: 5` \
5310 default, OTP's `supervisor` callback module `MaxT = 5..=60` typical, Riak Core's \
5311 `MaxT ∈ 10s..=300s`, RabbitMQ broker-supervisor `MaxT = 5s` default — every Erlang/OTP \
5312 / Elixir production playbook sits in the 5s..=300s band; the longest documented \
5313 per-supervisor restart-window any pleme-io substrate playbook recommends maxes at \
5314 ~30m) or omit :restart-window to express `never reset` (the supervisor's restart \
5315 budget then becomes a strict lifetime counter by design, not a degenerate one — the \
5316 author surfaces the lifetime-counter semantic explicitly at the slot, rather than \
5317 hiding it behind a rolling-window declaration the cap arm rejects)"
5318 )]
5319 RestartWindowExceedsCap { window: Duration },
5320 #[error("child entry has empty :caixa name")]
5321 EmptyChildName,
5322 #[error(
5323 "child :caixa {caixa:?} is not a valid DNS-1123 label: {reason} \
5324 (the K8s apiserver enforces this rule on every `metadata.name` / Service \
5325 name / label value the child name lands in — the per-child \
5326 `wasm.pleme.io/v1alpha1/ComputeUnit.metadata.name`, the `LABEL_PROGRAM` \
5327 label value, and the future wasm-operator per-child Service `metadata.name` \
5328 — each apiserver-side schema rejects names that don't match; use a \
5329 lowercase alphanumeric + hyphen identifier like `\"worker\"` or `\"cache-v2\"`)"
5330 )]
5331 ChildCaixaInvalid { caixa: String, reason: String },
5332 #[error("child {caixa:?} has empty :versao constraint")]
5333 EmptyChildVersion { caixa: String },
5334 #[error(
5335 "child {caixa:?} :versao {versao:?} is not a valid semver requirement: \
5336 {reason} (use Cargo-shaped forms like `\"^0.1\"`, `\"~0.1.2\"`, \
5337 `\"0.1.0\"`, or `\"*\"` — the same shape `:deps :versao` and \
5338 `:membros :versao` carry; the lacre pipeline resolves all three \
5339 through the same parser)"
5340 )]
5341 ChildVersaoInvalid {
5342 caixa: String,
5343 versao: String,
5344 reason: String,
5345 },
5346 #[error(
5347 "child {caixa:?} appears more than once (Erlang/OTP requires unique \
5348 child_spec.id per supervisor; duplicate children materialize as duplicate \
5349 ComputeUnits in the rendered chart, one silently overwriting the other)"
5350 )]
5351 DuplicateChildCaixa { caixa: String },
5352 #[error(
5353 "supervisor {caixa:?} lists itself as a :children entry — a supervisor is \
5354 never its own child (the supervision tree is a DAG rooted at the supervisor; \
5355 OTP child specs reference distinct child processes). Since every :nome is a \
5356 globally-unique substrate identity, a child naming the supervisor's own :nome \
5357 is a one-node reconciliation cycle, not a coincidentally-named peer; drop the \
5358 self-referential :children entry or rename it to the actual child caixa."
5359 )]
5360 ChildSupervisesSelf { caixa: String },
5361}
5362
5363// Fold the three `SupervisorError::<Variant> { caixa: <&str>.to_string() }`
5364// caixa-only struct-variant wire-up sites at [`SupervisorSpec::validate_children`]
5365// and [`validate_no_self_supervision`] onto one substrate primitive per
5366// typed variant — the sibling on `SupervisorError` of the four uniform-shape
5367// `LayoutError`-envelope constructor families the peer
5368// [`crate::layout::layout_violation_ctors!`] macro closed (131ca0d, 16
5369// variants on `{ caixa, issue }`), the [`crate::layout::layout_slot_kind_ctors!`]
5370// macro closed (0419438, 4 variants on `{ caixa, kind, slots }`), the
5371// [`crate::LayoutError::missing_entry`] one-variant ctor closed (1b09f9d,
5372// on `{ kind, path }`), and the [`crate::layout::layout_nome_only_ctors!`]
5373// macro closed (3fe3dd7, 6 variants on `<Variant>(String)`), plus the
5374// [`crate::AplicacaoError::entrada_host_invalid`] one-variant ctor
5375// (17dd504, `{ host, reason }`), the [`crate::aplicacao::contrato_target_ctors!`]
5376// macro (14b81d5, 2 variants on `{ de, para, wit, expected }`), and the
5377// [`crate::aplicacao::contrato_empty_pair_ctors!`] macro (8580068, 4
5378// variants on `{ de, para }`) already at that discipline on the peer
5379// `AplicacaoError` envelopes.
5380//
5381// Each of the three wire-up sites on this shape (`EmptyChildVersion` at
5382// the per-`:children` semver-requirement empty-first arm, `DuplicateChildCaixa`
5383// at the per-`:children` dedup arm, `ChildSupervisesSelf` at the cross-slot
5384// self-supervision arm) opened the identical
5385// `SupervisorError::<Variant> { caixa: <&str>.to_string() }` struct-literal —
5386// the exact "same block re-inlined at every consumer" shape the PRIME
5387// DIRECTIVE names as a bug, on the same altitude the peer `LayoutError` /
5388// `AplicacaoError` families each closed on their sibling envelopes. The
5389// three variants share one `{ caixa: String }` shape, so the fold routes
5390// each wire-up site through one dispatch per typed variant.
5391//
5392// The macro below generates one static constructor per variant of shape
5393// `fn <slot>(caixa: &str) -> SupervisorError`, so every wire-up site
5394// collapses onto one dispatch:
5395// `SupervisorError::<slot>(<&str>)`, byte-equal to the pre-lift
5396// struct-literal on the same `&str` fixture. The uniform one-field
5397// construction (`caixa: caixa.to_string()`) is spelled once — inside the
5398// macro — rather than at every wire-up site. Every constructor is
5399// `#[must_use]` so a caller who mistakenly discards the constructed error
5400// trips a compile warning at the wire-up site.
5401//
5402// Every future consumer that wants to construct one of these three
5403// variants outside `SupervisorSpec::validate_children` /
5404// `validate_no_self_supervision` — a deferred
5405// `mesh.pleme.io/v1alpha1/Supervisor` CR materializer's admission
5406// webhook re-checking one added/renamed child, a future
5407// `feira validate --supervisor` per-caixa admission verb, a per-child
5408// dynamic-add re-validator on the `SimpleOneForOne` runtime-add path
5409// once dynamic-children graduate to a typed slot, a per-Supervisor
5410// overlay resolver rejecting a duplicate/self-supervising child against
5411// a cluster-local snapshot — now reaches each variant through one call
5412// rather than re-inlining the three-line struct-literal in lockstep
5413// with the three in-crate wire-up sites.
5414macro_rules! supervisor_caixa_only_ctors {
5415 ($($ctor:ident => $variant:ident),* $(,)?) => {
5416 impl SupervisorError {
5417 $(
5418 #[doc = concat!(
5419 "Construct a [`SupervisorError::",
5420 stringify!($variant),
5421 "`] naming the offending `:children :caixa` (or ",
5422 "supervisor `:nome`, on the self-supervision arm). ",
5423 "Folds the uniform `Self::",
5424 stringify!($variant),
5425 " { caixa: caixa.to_string() }` one-field ",
5426 "struct-literal onto one substrate primitive so ",
5427 "every [`SupervisorSpec::validate_children`] / ",
5428 "[`validate_no_self_supervision`] wire-up on this ",
5429 "variant reads through one dispatch rather than the ",
5430 "pre-lift open-coded struct-literal block."
5431 )]
5432 #[must_use]
5433 pub fn $ctor(caixa: &str) -> Self {
5434 Self::$variant { caixa: caixa.to_string() }
5435 }
5436 )*
5437 }
5438 };
5439}
5440
5441supervisor_caixa_only_ctors! {
5442 empty_child_version => EmptyChildVersion,
5443 duplicate_child_caixa => DuplicateChildCaixa,
5444 child_supervises_self => ChildSupervisesSelf,
5445}
5446
5447// Fold the two `SupervisorError::{ChildCaixaInvalid, ChildVersaoInvalid}`
5448// struct-variant wire-up sites at [`SupervisorSpec::validate_children`] onto
5449// one substrate primitive per typed variant — the M2 supervisor-side siblings
5450// of the peer [`crate::AplicacaoError::membro_caixa_invalid`] two-slot ctor
5451// already lifted through the sibling
5452// [`crate::aplicacao::aplicacao_field_reason_ctors!`] macro (981060b) on the
5453// peer `AplicacaoError { caixa: String, reason: String }` envelope. The
5454// `ChildCaixaInvalid` variant carries the same `{ <name>: String, reason:
5455// String }` two-slot shape the peer seven-variant
5456// [`crate::aplicacao::aplicacao_field_reason_ctors!`] fold closed on the
5457// `AplicacaoError` envelope (`MembroCaixaInvalid`, `EntradaParaInvalid`,
5458// `EntradaHostInvalid`, `EntradaPathInvalid`, `PlacementClusterInvalid`,
5459// `PlacementAffinityInvalid`, `ShardKeyInvalid`); the `ChildVersaoInvalid`
5460// variant carries the `{ caixa: String, versao: String, reason: String }`
5461// three-slot shape the sibling `AplicacaoError::MembroVersaoInvalid` axis
5462// carries on the same `:versao` value-shape.
5463//
5464// Each of the two wire-up sites opened the same closure-shaped
5465// `|reason| SupervisorError::<Variant> { caixa: child.nome().to_string(),
5466// [versao: child.versao_requirement().to_string(),] reason }` block inside
5467// the paired [`crate::render::require_valid_dns_1123_label`] and
5468// [`crate::render::require_valid_versao_requirement`] callbacks — the exact
5469// "same block re-inlined at every consumer" shape the PRIME DIRECTIVE names
5470// as a bug, on the same altitude the peer `AplicacaoError` /
5471// `SupervisorError` / `LayoutError` / `DepError` / `LimitsError` ctor
5472// families already closed on their sibling envelopes.
5473//
5474// The two `#[must_use]` inherent constructors below fold each wire-up onto
5475// one dispatch: `SupervisorError::child_caixa_invalid(<name>, <reason>)`
5476// and `SupervisorError::child_versao_invalid(<name>, <versao>, <reason>)`,
5477// byte-equal to the pre-lift struct-literal on the same scalar fixtures.
5478// The uniform per-field `.to_string()` / `.into()` construction is spelled
5479// once — inside each ctor body — rather than at every wire-up site. The
5480// `reason: impl Into<String>` bound accepts both `&str` literals and
5481// `format!(…)` outputs verbatim so no wire-up site changes its per-arm
5482// diagnostic shape at the lift, matching the peer
5483// [`aplicacao_field_reason_ctors!`] and
5484// [`crate::aplicacao::contrato_pair_value_reason_ctors!`] bounds on the
5485// sibling envelopes.
5486//
5487// Every future consumer that wants to construct one of these two variants
5488// outside `SupervisorSpec::validate_children` — a deferred
5489// `mesh.pleme.io/v1alpha1/Supervisor` CR materializer's admission webhook
5490// re-checking one added/renamed child's `:caixa` or `:versao`, a future
5491// `feira validate --supervisor` per-caixa admission verb, a per-child
5492// dynamic-add re-validator on the `SimpleOneForOne` runtime-add path once
5493// dynamic-children graduate to a typed slot, a per-Supervisor overlay
5494// resolver rejecting a shape-invalid child `:caixa`/`:versao` against a
5495// cluster-local snapshot — now reaches each variant through one call rather
5496// than re-inlining the per-shape struct-literal block in lockstep with the
5497// two in-crate wire-up sites.
5498impl SupervisorError {
5499 /// Construct a [`SupervisorError::ChildCaixaInvalid`] naming the
5500 /// offending `:children :caixa` value under the given `reason`. Folds
5501 /// the uniform `Self::ChildCaixaInvalid { caixa: caixa.to_string(),
5502 /// reason: reason.into() }` two-slot struct-literal onto one substrate
5503 /// primitive so every wire-up on this variant reads through one
5504 /// dispatch, matching the peer
5505 /// [`crate::AplicacaoError::membro_caixa_invalid`] ctor's shape on the
5506 /// sibling `AplicacaoError { caixa: String, reason: String }`
5507 /// envelope. `reason` accepts both `&str` literals and `format!(…)`
5508 /// outputs through the `impl Into<String>` bound.
5509 #[must_use]
5510 pub fn child_caixa_invalid(caixa: &str, reason: impl Into<String>) -> Self {
5511 Self::ChildCaixaInvalid {
5512 caixa: caixa.to_string(),
5513 reason: reason.into(),
5514 }
5515 }
5516
5517 /// Construct a [`SupervisorError::ChildVersaoInvalid`] naming the
5518 /// offending `:children :caixa` and its `:versao` requirement under
5519 /// the given `reason`. Folds the uniform `Self::ChildVersaoInvalid {
5520 /// caixa: caixa.to_string(), versao: versao.to_string(), reason:
5521 /// reason.into() }` three-slot struct-literal onto one substrate
5522 /// primitive so every wire-up on this variant reads through one
5523 /// dispatch, matching the sibling `AplicacaoError::MembroVersaoInvalid
5524 /// { caixa, versao, reason }` three-slot axis on the peer
5525 /// `AplicacaoError` envelope. `reason` accepts both `&str` literals
5526 /// and `format!(…)` outputs through the `impl Into<String>` bound.
5527 #[must_use]
5528 pub fn child_versao_invalid(caixa: &str, versao: &str, reason: impl Into<String>) -> Self {
5529 Self::ChildVersaoInvalid {
5530 caixa: caixa.to_string(),
5531 versao: versao.to_string(),
5532 reason: reason.into(),
5533 }
5534 }
5535}
5536
5537// Fold the four `SupervisorError::<Variant> { <field>: <Copy> }` one-field
5538// Copy-scalar struct-variant wire-up sites at [`SupervisorSpec::validate`]'s
5539// three bracket-arms — one struct-literal at the `:children`-empty
5540// non-`SimpleOneForOne` refusal cascade (`NoChildren { estrategia }`) plus
5541// three `impl FnOnce(<ty>) -> SupervisorError` bracket-closures at the
5542// [`crate::render::require_positive_bounded_u32`] `:max-restarts` cap arm
5543// (`MaxRestartsExceedsCap { max_restarts }`) and the paired
5544// [`crate::render::require_positive_canonical_bounded_duration`]
5545// `:restart-window` canonical-form + cap arms (`RestartWindowNotCanonical
5546// { window }`, `RestartWindowExceedsCap { window }`) — onto one substrate
5547// primitive per typed variant, matching the sibling
5548// [`crate::aplicacao::aplicacao_policy_scalar_ctors!`] macro (7ef425e, 8
5549// variants on the same `{ <field>: Duration | u32 }` shape) at that
5550// discipline on the peer `AplicacaoError` envelope's per-`:politicas`
5551// scalar axis. Every variant is a one-field `Copy`-pass-through struct-
5552// literal — `RestartStrategy | u32 | Duration` — so the fold routes each
5553// wire-up site through one dispatch per typed variant without a runtime-
5554// work delta.
5555//
5556// Each of the four wire-up sites opened the identical
5557// `SupervisorError::<Variant> { <field>: <val> }` struct-literal — the
5558// exact "same block re-inlined at every consumer" shape the PRIME
5559// DIRECTIVE names as a bug, on the same altitude the peer
5560// `aplicacao_policy_scalar_ctors!` fold closed on the sibling
5561// `AplicacaoError` envelope's per-`:politicas` per-axis cap / canonical-
5562// form arms. The four variants share one `{ <field>: <Copy> }` shape, so
5563// the fold routes each wire-up site through one dispatch per typed
5564// variant.
5565//
5566// The macro below generates one static constructor per variant of shape
5567// `const fn <ctor>(<field>: <ty>) -> SupervisorError`, so every wire-up
5568// site collapses onto one dispatch: `SupervisorError::<ctor>(<val>)`,
5569// byte-equal to the pre-lift struct-literal on the same `Copy`-`<ty>`
5570// fixture — as a direct call at the [`SupervisorSpec::validate`]
5571// `:children`-empty refusal, or as a bare function pointer in the
5572// `impl FnOnce(<ty>) -> SupervisorError` bracket-closure slot every
5573// [`crate::render::require_positive_bounded_u32`] /
5574// [`crate::render::require_positive_canonical_bounded_duration`] gate
5575// carries — rather than the pre-lift open-coded one-line closure over
5576// the same one-field struct-literal. `const fn` preserves the `Copy`-
5577// pass-through's zero-runtime-work property verbatim. Every constructor
5578// is `#[must_use]` so a caller who mistakenly discards the constructed
5579// error trips a compile warning at the wire-up site.
5580//
5581// Every future consumer that wants to construct one of these four
5582// variants outside `SupervisorSpec::validate` — a deferred
5583// `mesh.pleme.io/v1alpha1/Supervisor` CR materializer's admission
5584// webhook re-checking one edited `:estrategia` / `:max-restarts` /
5585// `:restart-window` slot against the cap + canonical-form cascade, a
5586// future `feira validate --supervisor` per-caixa admission verb re-
5587// running the shape gates on demand, a per-Supervisor overlay resolver
5588// rejecting an author-supplied slot against a cluster-local snapshot —
5589// now reaches each variant through one call rather than re-inlining the
5590// per-shape struct-literal block in lockstep with the four in-crate
5591// wire-up sites.
5592macro_rules! supervisor_scalar_ctors {
5593 ($($ctor:ident => $variant:ident { $field:ident: $ty:ty }),* $(,)?) => {
5594 impl SupervisorError {
5595 $(
5596 #[doc = concat!(
5597 "Construct a [`SupervisorError::",
5598 stringify!($variant),
5599 "`] naming the offending per-`:supervisor` `",
5600 stringify!($field),
5601 "` scalar. Folds the uniform `Self::",
5602 stringify!($variant),
5603 " { ",
5604 stringify!($field),
5605 " }` one-field `Copy`-pass-through struct-literal onto ",
5606 "one substrate primitive so every per-axis wire-up on ",
5607 "this variant reads through one dispatch — as a direct ",
5608 "call (`SupervisorError::",
5609 stringify!($ctor),
5610 "(<val>)`, byte-equal to the pre-lift struct-literal on ",
5611 "the same `Copy`-`",
5612 stringify!($ty),
5613 "` fixture) or as a bare function pointer in the ",
5614 "`impl FnOnce(",
5615 stringify!($ty),
5616 ") -> SupervisorError` bracket-closure slot every ",
5617 "`crate::render::require_positive_bounded_*` / ",
5618 "`crate::render::require_positive_canonical_bounded_*` ",
5619 "gate carries — rather than the pre-lift open-coded ",
5620 "one-line closure over the same one-field struct-",
5621 "literal. `const fn` preserves the `Copy`-pass-through's ",
5622 "zero-runtime-work property verbatim."
5623 )]
5624 #[must_use]
5625 pub const fn $ctor($field: $ty) -> Self {
5626 Self::$variant { $field }
5627 }
5628 )*
5629 }
5630 };
5631}
5632
5633supervisor_scalar_ctors! {
5634 no_children => NoChildren { estrategia: RestartStrategy },
5635 max_restarts_exceeds_cap => MaxRestartsExceedsCap { max_restarts: u32 },
5636 restart_window_not_canonical => RestartWindowNotCanonical { window: Duration },
5637 restart_window_exceeds_cap => RestartWindowExceedsCap { window: Duration },
5638}
5639
5640/// Shared duration string codec for the typed slots that take a
5641/// duration (`restart_window`, `MeshPolicy::timeout`,
5642/// `CircuitBreaker::window`, …). Public so [`crate::aplicacao`] can
5643/// reuse it without duplicating the parser.
5644pub mod duration_codec {
5645 use super::Duration;
5646 use serde::{Deserializer, Serializer};
5647
5648 pub fn serialize<S: Serializer>(v: &Option<Duration>, s: S) -> Result<S::Ok, S::Error> {
5649 // Route through the canonical [`crate::render::serialize_option_via_str`]
5650 // — the substrate-side single-owner primitive for the forward
5651 // arm of the typed-magnitude codec family. See its docstring
5652 // for the full sibling roster.
5653 crate::render::serialize_option_via_str(v, s, render)
5654 }
5655
5656 pub fn deserialize<'de, D: Deserializer<'de>>(d: D) -> Result<Option<Duration>, D::Error> {
5657 // Route through the canonical [`crate::render::deserialize_option_via_str`]
5658 // — the substrate-side single-owner primitive for the reverse
5659 // arm of the typed-magnitude codec family. See its docstring
5660 // for the full sibling roster.
5661 crate::render::deserialize_option_via_str(d, parse)
5662 }
5663
5664 pub(crate) fn parse(s: &str) -> Result<Duration, String> {
5665 // Paired whitespace-rejection arm — same canonical-form
5666 // render-determinism discipline as the peer
5667 // `limits::parse_byte_size` / `limits::parse_duration` /
5668 // `limits::parse_millicores` /
5669 // `aplicacao::rate_limit_codec::parse` sites: the ASCII
5670 // byte-scan closes the WhatWG-conformant whitespace bytes
5671 // (`0x20`, `0x09`, `0x0A`, `0x0C`, `0x0D`), the non-ASCII
5672 // `char::is_whitespace` scan closes the strictly-complementary
5673 // Unicode `White_Space` class (NBSP `\u{00A0}`, LINE SEPARATOR
5674 // `\u{2028}`, EM-SPACE `\u{2003}`, and the peer typography
5675 // codepoints) that `str::trim` at parse entry silently strips.
5676 // Either drift class would round-trip through `render` to a
5677 // *different* canonical form on next emit — breaking the
5678 // THEORY.md Part V render-determinism contract on three typed-
5679 // duration slots at once (`:supervisor :restart-window`,
5680 // `:politicas :timeout`, `:politicas :circuit-breaker :window`)
5681 // via the shared codec.
5682 //
5683 // Routed through the lifted [`crate::render::reject_whitespace`]
5684 // primitive — the substrate-side single-owner paired-arm gate
5685 // every typed-magnitude codec in caixa-core shares.
5686 crate::render::reject_whitespace::<String, _, _>(
5687 s,
5688 |b| {
5689 format!(
5690 "duration: value {s:?} contains whitespace byte 0x{b:02x} — the canonical \
5691 authoring form for the typed duration slots routed through this shared codec \
5692 (`:supervisor :restart-window`, `:politicas :timeout`, \
5693 `:politicas :circuit-breaker :window`) is `<integer><unit>` (e.g. \
5694 `\"30s\"`, `\"500ms\"`, `\"2m\"`, `\"1h\"`) with no whitespace bytes \
5695 anywhere. A whitespace-carrying shape (`\" 30s\"`, `\"30s \"`, `\"30 s\"`, \
5696 `\"\\t30s\"`, `\"30s\\n\"`) round-trips through `render` to a *different* \
5697 canonical form (`\"30s\"`) on first serialize — breaking the THEORY.md \
5698 Part V render-determinism contract every typed slot carries. Strip every \
5699 whitespace byte (write `\"30s\"` verbatim)"
5700 )
5701 },
5702 |ch| {
5703 format!(
5704 "duration: value {s:?} contains non-ASCII Unicode whitespace character \
5705 {ch:?} (U+{cp:04X}) — the canonical authoring form for the typed \
5706 duration slots routed through this shared codec (`:supervisor \
5707 :restart-window`, `:politicas :timeout`, `:politicas :circuit-breaker \
5708 :window`) is `<integer><unit>` (e.g. `\"30s\"`, `\"500ms\"`, `\"2m\"`, \
5709 `\"1h\"`) with no whitespace characters anywhere (ASCII or Unicode). A \
5710 non-ASCII-whitespace-carrying shape (`\"\\u{{00A0}}30s\"`, \
5711 `\"30s\\u{{2028}}\"`, `\"30\\u{{2003}}s\"`) survives the ASCII byte-scan \
5712 but `str::trim` (which uses `char::is_whitespace` — the Unicode \
5713 `White_Space` property, strictly wider than the ASCII byte set) silently \
5714 strips it at parse entry, and the value round-trips through `render` to \
5715 a *different* canonical form (`\"30s\"`) on first serialize — breaking \
5716 the THEORY.md Part V render-determinism contract every typed slot \
5717 carries. Strip every non-ASCII whitespace character (write `\"30s\"` \
5718 verbatim with only ASCII bytes)",
5719 cp = ch as u32
5720 )
5721 },
5722 )?;
5723 let s = s.trim();
5724 // Routed through the lifted
5725 // [`crate::render::split_magnitude_and_alpha_unit`] primitive —
5726 // the single-owner split every ASCII-alphabetic-unit typed-
5727 // magnitude codec in caixa-core (`limits::parse_byte_size` /
5728 // `limits::parse_duration` / this shared duration codec) shares.
5729 // See its docstring for the full sibling roster on the same
5730 // primitive altitude.
5731 let (num_part, unit) = crate::render::split_magnitude_and_alpha_unit(s);
5732 let num_trim = num_part.trim();
5733 // The canonical authoring form for every typed slot routed
5734 // through this shared codec — `:supervisor :restart-window`,
5735 // `:politicas :timeout`, `:politicas :circuit-breaker :window`
5736 // — is `<integer><unit>`. Every magnitude [`render`] emits is a
5737 // non-negative integer with no decimal point and no leading
5738 // sign, so the parser's accepted set must match for
5739 // serialize/deserialize to round-trip without canonical-form
5740 // drift. Until this gate landed the parser accepted any
5741 // `f64`-shaped magnitude (`"1.5s"` → 1500ms, `"1.0s"` → 1s,
5742 // `"0.5m"` → 30s, `"+30s"` → 30s) and serde silently round-
5743 // tripped the value to a *different* canonical string on the
5744 // next emit (`"1.5s"` → 1500ms → `"1500ms"`, `"1.0s"` → 1s →
5745 // `"1s"`, `"0.5m"` → 30s → `"30s"`, `"+30s"` → 30s → `"30s"`)
5746 // — breaking the THEORY.md Part V render-determinism contract
5747 // on three typed slots at once. Same canonical-form discipline
5748 // `crate::limits::parse_duration` (818dd38, the immediate
5749 // predecessor on the peer `:limits :wall-clock` codec) applies;
5750 // this gate lifts the discipline onto the shared codec that
5751 // backs the remaining three typed-duration slots in caixa-core.
5752 //
5753 // Strict canonical form: every byte of the magnitude is an
5754 // ASCII digit (no `.`, no `+`, no `-`). On non-digit-only
5755 // inputs the gate distinguishes "non-canonical-but-numeric"
5756 // (parses as f64 or i64 — surfaced with a self-locating
5757 // diagnostic naming the canonical authoring form, the
5758 // round-trip drift each rejected shape would produce on first
5759 // serialize, and the canonical-form remediation) from
5760 // "garbage" (parses as neither — surfaced with the existing
5761 // narrower "bad duration magnitude" wording so its diagnostic
5762 // shape remains stable for the parser-shape footgun case).
5763 // The pre-existing `num < 0.0` arm is now unreachable — the
5764 // digit-only gate strictly precedes magnitude parsing, and a
5765 // leading `-` is not an ASCII digit, so `"-30s"` lands on the
5766 // non-canonical-but-numeric branch with the `-30` named
5767 // verbatim in the diagnostic rather than the prior
5768 // value-laundered "negative duration in \"-30s\"" wording.
5769 //
5770 // Routed through the lifted
5771 // [`crate::render::is_digit_only_magnitude`] predicate — the
5772 // same source of truth the four peer typed-magnitude codec
5773 // sites share.
5774 let digit_only = crate::render::is_digit_only_magnitude(num_trim);
5775 if !digit_only {
5776 let numeric = num_trim.parse::<f64>().is_ok() || num_trim.parse::<i64>().is_ok();
5777 if numeric {
5778 return Err(format!(
5779 "duration: magnitude {num_trim:?} is not a non-negative integer — the \
5780 canonical authoring form for the typed duration slots routed through \
5781 this shared codec (`:supervisor :restart-window`, `:politicas :timeout`, \
5782 `:politicas :circuit-breaker :window`) is `<integer><unit>` (e.g. \
5783 `\"30s\"`, `\"500ms\"`, `\"2m\"`, `\"1h\"`) with no decimal point and \
5784 no leading `+` / `-` sign. A fractional / decimal-shaped magnitude \
5785 (`\"1.5s\"`, `\"1.0s\"`, `\"0.5m\"`, `\"+30s\"`, `\"-30s\"`) round-trips \
5786 through `render` to a *different* canonical form (`\"1500ms\"`, `\"1s\"`, \
5787 `\"30s\"`, `\"30s\"`, `\"30s\"`) on first serialize — breaking the \
5788 THEORY.md Part V render-determinism contract every typed slot carries. \
5789 Pick an integer magnitude in the unit that divides cleanly (write \
5790 `\"1500ms\"` instead of `\"1.5s\"`; `\"30s\"` instead of `\"0.5m\"`)"
5791 ));
5792 }
5793 return Err(format!("bad duration magnitude in {s:?}"));
5794 }
5795 // Leading-zero arm — peer with the `rate_limit_codec` leading-
5796 // zero arm (4f46830) on the same canonical-form render-
5797 // determinism axis. The digit-only gate accepts `"030s"`,
5798 // `"00s"`, `"01h"`, `"0500ms"` as `u64::from_str` parses them
5799 // losslessly (= 30, 0, 1, 500), but `render` emits the leading-
5800 // zero-stripped form (`"30s"`, `"0s"`, `"1h"`, `"500ms"`) — a
5801 // *different* canonical string on the next emit, breaking the
5802 // THEORY.md Part V render-determinism contract the same way
5803 // `"+30s"` did before the leading-`+` arm landed. The single-
5804 // byte magnitude `"0"` (or `"0s"` / `"0ms"`) round-trips
5805 // losslessly through `render` (`render(Duration::ZERO)` emits
5806 // `"0s"`) — the downstream semantic-zero gates (e.g.
5807 // `SupervisorError::ZeroRestartWindow` on
5808 // `:supervisor :restart-window`,
5809 // `AplicacaoError::PolicyTimeoutZero` /
5810 // `PolicyCircuitBreakerWindowZero` on the typed `:politicas`
5811 // duration slots) refuse zero-magnitude authoring at the typed-
5812 // validate layer above, so the single-byte `"0"` stays in the
5813 // accepted set at this codec layer and the diagnostic
5814 // partitioning between canonical-form drift (this arm) and
5815 // semantic-zero (the downstream gates) remains stable.
5816 // Peer with the future leading-zero arms on the two remaining
5817 // typed-magnitude codecs the trajectory acknowledges:
5818 // `limits::parse_duration` backing `:limits :wall-clock`,
5819 // `limits::parse_byte_size` backing `:limits :memory` — each
5820 // carries the same canonical-form-drift class today; this
5821 // gate lands the discipline on the shared duration codec
5822 // first because the `rate_limit_codec` predecessor on the
5823 // same canonical-form-drift axis is the closest peer on the
5824 // trajectory.
5825 //
5826 // Routed through the lifted
5827 // [`crate::render::is_leading_zero_padded_magnitude`]
5828 // predicate — the same source of truth the four peer
5829 // typed-magnitude codec sites share.
5830 if crate::render::is_leading_zero_padded_magnitude(num_trim) {
5831 return Err(format!(
5832 "duration: magnitude {num_trim:?} has a non-canonical leading zero — the \
5833 canonical authoring form for the typed duration slots routed through \
5834 this shared codec (`:supervisor :restart-window`, `:politicas :timeout`, \
5835 `:politicas :circuit-breaker :window`) is `<integer><unit>` (e.g. \
5836 `\"30s\"`, `\"500ms\"`, `\"2m\"`, `\"1h\"`) with no leading-zero padding \
5837 on the magnitude. A leading-zero magnitude (`\"030s\"`, `\"00s\"`, \
5838 `\"01h\"`, `\"0500ms\"`) round-trips through `render` to a *different* \
5839 canonical form (`\"30s\"`, `\"0s\"`, `\"1h\"`, `\"500ms\"`) on first \
5840 serialize — breaking the THEORY.md Part V render-determinism contract \
5841 every typed slot carries. Strip the leading zeros (write \
5842 `\"30s\"` instead of `\"030s\"`)"
5843 ));
5844 }
5845 // The digit-only gate guarantees every byte is `[0-9]`, and
5846 // the leading-zero arm above guarantees the magnitude is
5847 // either the single byte `"0"` or starts with `[1-9]`, so
5848 // the only way `u64::from_str` can fail here is overflow (the
5849 // magnitude exceeds `u64::MAX`). Surface that with an
5850 // overflow-shaped wording so the diagnostic names the offending
5851 // magnitude verbatim rather than collapsing onto the
5852 // non-canonical arm. The codec now operates on `u64` end-to-end
5853 // — every accepted magnitude is integer-exact; no f64 mantissa
5854 // drift between author-supplied magnitude and the consumer's
5855 // `Duration` value. Same shape `crate::limits::parse_duration`
5856 // (818dd38) carries on the peer `:limits :wall-clock` axis.
5857 let num: u64 = num_trim.parse::<u64>().map_err(|_| {
5858 format!("bad duration magnitude in {s:?} (digit-only magnitude overflows u64)")
5859 })?;
5860 // Route the `{"ms" | "s" | "" | "m" | "h"} → Duration`
5861 // unit-arm dispatch through the canonical
5862 // [`crate::render::duration_from_integer_magnitude_and_unit`]
5863 // primitive — the substrate-side single-owner unit-dispatch
5864 // table every typed-duration codec in caixa-core routes
5865 // through (peer: `crate::limits::parse_duration` backing
5866 // `:limits :wall-clock`). Every unit conversion is integer-
5867 // exact for an integer magnitude; overflow surfaces via the
5868 // typed `DurationUnitError::Overflow { multiplier }`
5869 // discriminant so this arm reconstructs the pre-lift
5870 // `"duration <num><unit> overflows u64 (magnitude × 60 …)"`
5871 // wording verbatim from `num` / `unit_trim` / the returned
5872 // `multiplier`, and the unknown-unit arm reconstructs the
5873 // pre-lift `"unknown duration unit \"<other>\""` wording from
5874 // the caller-scoped `unit_trim`. Load-bearing pinned by
5875 // `crate::render::tests::duration_from_integer_magnitude_and_unit_matches_pre_lift_unit_dispatch_table`.
5876 let unit_trim = unit.trim();
5877 let dur = crate::render::duration_from_integer_magnitude_and_unit(num, unit_trim).map_err(
5878 |e| match e {
5879 crate::render::DurationUnitError::Overflow { multiplier } => format!(
5880 "duration {num}{unit_trim} overflows u64 (magnitude × {multiplier} > 2^64-1)"
5881 ),
5882 crate::render::DurationUnitError::UnknownUnit => {
5883 format!("unknown duration unit {unit_trim:?}")
5884 }
5885 },
5886 )?;
5887 Ok(dur)
5888 }
5889
5890 /// Render a [`Duration`] in the canonical pleme-io duration string
5891 /// form (`"30s"`, `"1m"`, `"1h"`, `"500ms"`). The same form every
5892 /// caixa typed-duration slot serializes to and the same form K8s
5893 /// Gateway API HTTPRoute `timeouts` / `backendRequest` and Cilium
5894 /// EnvoyConfig per-route timeouts both expect (an integer
5895 /// followed by `s`/`m`/`h`/`ms`, no fractional values, no leading
5896 /// `+`). Lifted to `pub` so caixa-side renderers
5897 /// (`caixa-mesh::gateway_routes`'s :politicas :timeout overlay,
5898 /// the future per-:politicas `CiliumClusterwideEnvoyConfig`
5899 /// emitter, the future caixa-otel collector pipeline emitter) can
5900 /// consume the same canonical formatter without re-inlining the
5901 /// magnitude/unit decision tree (and inheriting the same drift
5902 /// footguns: a subtly different `300ms` vs `0.3s` rendering breaks
5903 /// downstream apply-time parsing in non-obvious ways).
5904 pub fn render(d: Duration) -> String {
5905 let total_ms = d.as_millis();
5906 if total_ms == 0 {
5907 return "0s".into();
5908 }
5909 if total_ms.is_multiple_of(3600 * 1000) {
5910 return format!("{}h", total_ms / (3600 * 1000));
5911 }
5912 if total_ms.is_multiple_of(60 * 1000) {
5913 return format!("{}m", total_ms / (60 * 1000));
5914 }
5915 if total_ms.is_multiple_of(1000) {
5916 return format!("{}s", total_ms / 1000);
5917 }
5918 format!("{total_ms}ms")
5919 }
5920
5921 /// True iff `d` round-trips losslessly through [`render`] + [`parse`].
5922 ///
5923 /// [`render`] truncates a `Duration` to `as_millis()` before picking the
5924 /// largest divisor unit, so any sub-millisecond residue
5925 /// (`d.subsec_nanos() % 1_000_000 != 0`) silently breaks the THEORY.md
5926 /// §V.2.7 render-determinism contract:
5927 ///
5928 /// - `Duration::from_micros(1500)` (= `1_500_000` ns) → `as_millis() == 1`
5929 /// → renders `"1ms"` → parses back to `Duration::from_millis(1)` =
5930 /// `1_000_000` ns ≠ original `1_500_000` ns;
5931 /// - `Duration::from_nanos(1)` (= 1 ns) → `as_millis() == 0` →
5932 /// renders the literal `"0s"`, which the per-axis zero-floor gate
5933 /// on every typed-`Duration` slot then rejects on re-validate.
5934 ///
5935 /// Lifted to a `pub` predicate next to the [`render`] / [`parse`] pair so
5936 /// the codec's round-trippable accepted set lives in exactly one place —
5937 /// every typed-`Duration` slot that routes through this shared codec
5938 /// (`SupervisorSpec::restart_window` via [`super::duration_codec`],
5939 /// [`crate::MeshPolicy::timeout`] / [`crate::CircuitBreaker::window`] via
5940 /// `supervisor::duration_codec` + [`super::duration_codec_required`]) and
5941 /// every typed-`Duration` slot whose own codec shares the same
5942 /// `as_millis()`-truncation shape ([`crate::LimitsSpec::wall_clock`] via
5943 /// [`crate::limits`]'s in-module `parse_duration` / `render_duration`
5944 /// pair) calls this predicate from its `validate()` to bracket the
5945 /// accepted set against the codec's accepted set, structurally. Drift
5946 /// between the codec's granularity and any typed slot's accepted set is
5947 /// then a single-source-of-truth edit at this predicate rather than a
5948 /// silent round-trip break the next consumer discovers at apply time.
5949 ///
5950 /// Peer of [`crate::aplicacao::POLICY_RETRIES_MAX`] /
5951 /// [`crate::LIMITS_MEMORY_WASM32_MAX_BYTES`] and the
5952 /// `is_dns_1123_label` / `is_canonical_rate_limit_window` predicate
5953 /// family — same "typed-slot's valid set matches its codec's accepted
5954 /// set, structurally" discipline carried at the codec layer.
5955 #[must_use]
5956 pub fn is_integer_millisecond_duration(d: Duration) -> bool {
5957 d.subsec_nanos().is_multiple_of(1_000_000)
5958 }
5959}
5960
5961/// Required-Duration variant for fields that aren't Option<Duration>.
5962pub mod duration_codec_required {
5963 use super::Duration;
5964 use serde::{Deserialize, Deserializer, Serializer};
5965
5966 pub fn serialize<S: Serializer>(v: &Duration, s: S) -> Result<S::Ok, S::Error> {
5967 s.serialize_str(&super::duration_codec::render(*v))
5968 }
5969
5970 pub fn deserialize<'de, D: Deserializer<'de>>(d: D) -> Result<Duration, D::Error> {
5971 let s = String::deserialize(d)?;
5972 super::duration_codec::parse(&s).map_err(serde::de::Error::custom)
5973 }
5974}
5975
5976#[cfg(test)]
5977mod tests {
5978 use super::*;
5979
5980 fn child(name: &str, ver: &str, restart: RestartPolicy) -> ChildSpec {
5981 ChildSpec {
5982 caixa: name.into(),
5983 versao: ver.into(),
5984 restart,
5985 }
5986 }
5987
5988 #[test]
5989 fn child_spec_string_scalar_accessor_pair_is_const_fn() {
5990 // Fail-before-pass-after pin on [`ChildSpec::nome`] +
5991 // [`ChildSpec::versao_requirement`]'s `const`-eval-surface
5992 // posture. Each accessor projects the per-`:children :caixa`
5993 // / per-`:children :versao` [`String`] storage through the
5994 // `pub const fn` [`String::as_str`] (const-stable since Rust
5995 // 1.87, well within the workspace MSRV) — any future
5996 // accidental downgrade to non-`const` fails the corresponding
5997 // `<name>_via_const_fn` wrapper at caixa-core build time with
5998 // E0015 (`cannot call non-const method`), strictly stronger
5999 // than a runtime `assert!`. Sibling of the peer
6000 // per-M2/M3/universal-axis `String → &str` scalar-accessor
6001 // family pins on the sibling `const`-eval-surface passes
6002 // ([`crate::Caixa::nome`] / [`crate::Caixa::versao`] at the
6003 // top-level manifest, [`crate::CaixaVersion::as_str`] at the
6004 // typed-newtype wrapper, [`crate::aplicacao::Membro::nome`] /
6005 // [`crate::aplicacao::Membro::versao_requirement`] at the M3
6006 // membership axis, [`crate::aplicacao::Entrada::hostname`] /
6007 // [`crate::aplicacao::Entrada::destination`] at the M3
6008 // ingress axis,
6009 // [`crate::upgrade::UpgradeFromEntry::prior_versao`] at the
6010 // M2 upgrade axis, [`crate::dep::Dep::nome`] /
6011 // [`crate::dep::Dep::versao_requirement`] at the dep-graph
6012 // axis, and the per-`:contratos`
6013 // [`crate::aplicacao::WitContract::source`] /
6014 // [`crate::aplicacao::WitContract::destination`] /
6015 // [`crate::aplicacao::WitContract::world_ref`] trio the
6016 // sibling pin at 279823b already anchors).
6017 const fn nome_via_const_fn(c: &ChildSpec) -> &str {
6018 c.nome()
6019 }
6020 const fn versao_via_const_fn(c: &ChildSpec) -> &str {
6021 c.versao_requirement()
6022 }
6023 for (caixa, versao) in [
6024 ("worker-a", "^0.1"),
6025 ("worker-b", "~0.2.3"),
6026 ("collector", "*"),
6027 ] {
6028 let c = child(caixa, versao, RestartPolicy::Permanent);
6029 assert_eq!(nome_via_const_fn(&c), c.nome());
6030 assert_eq!(versao_via_const_fn(&c), c.versao_requirement());
6031 assert_eq!(c.nome(), caixa);
6032 assert_eq!(c.versao_requirement(), versao);
6033 }
6034 }
6035
6036 #[test]
6037 fn supervisor_children_slice_return_accessor_is_const_fn() {
6038 // Fail-before-pass-after pin on [`SupervisorSpec::children`]'s
6039 // `const`-eval-surface posture. The accessor destructures the
6040 // per-`:children` `Vec<ChildSpec>` storage through the
6041 // `pub const fn` [`Vec::as_slice`] (const-stable since Rust
6042 // 1.66, well within the workspace MSRV) — any future
6043 // accidental downgrade to non-`const` fails
6044 // `children_via_const_fn` at caixa-core build time with E0015
6045 // (`cannot call non-const method`), strictly stronger than a
6046 // runtime `assert!`. Sibling of the peer per-M3-mesh-slot
6047 // `Vec → &[T]` slice-return accessor family pin
6048 // [`crate::aplicacao::tests::m3_reference_return_accessor_family_is_const_fn`]
6049 // on the M3 mesh-slot per-`:clusters` / per-`:paths` /
6050 // per-`:membros` / per-`:contratos` slice-return axes, and of
6051 // the peer M2 upgrade-appup axis pin
6052 // [`crate::upgrade::tests::upgrade_from_entry_instructions_slice_return_accessor_is_const_fn`]
6053 // on the per-`:upgrade-from :instructions` slice-return axis.
6054 const fn children_via_const_fn(s: &SupervisorSpec) -> &[ChildSpec] {
6055 s.children()
6056 }
6057 // Sweep both the empty-children (leaf-supervisor with no
6058 // static children — the `SimpleOneForOne` dynamic-child
6059 // arm's canonical shape) and the populated-children
6060 // (`OneForOne` / `OneForAll` / `RestForOne` static-child
6061 // arm's canonical shape) axes so the accessor carries a
6062 // const-dispatch pin on both arms.
6063 let s_empty = SupervisorSpec {
6064 estrategia: RestartStrategy::SimpleOneForOne,
6065 max_restarts: SUPERVISOR_MAX_RESTARTS_DEFAULT,
6066 restart_window: Some(SUPERVISOR_RESTART_WINDOW_DEFAULT),
6067 children: vec![],
6068 };
6069 assert!(children_via_const_fn(&s_empty).is_empty());
6070 assert_eq!(children_via_const_fn(&s_empty), s_empty.children());
6071 let s_full = SupervisorSpec {
6072 estrategia: RestartStrategy::OneForOne,
6073 max_restarts: SUPERVISOR_MAX_RESTARTS_DEFAULT,
6074 restart_window: Some(SUPERVISOR_RESTART_WINDOW_DEFAULT),
6075 children: vec![
6076 child("worker-a", "^0.1", RestartPolicy::Permanent),
6077 child("worker-b", "~0.2.3", RestartPolicy::Transient),
6078 child("collector", "*", RestartPolicy::Temporary),
6079 ],
6080 };
6081 assert_eq!(children_via_const_fn(&s_full).len(), 3);
6082 assert_eq!(children_via_const_fn(&s_full), s_full.children());
6083 }
6084
6085 #[test]
6086 fn default_has_one_for_one_and_5_restarts_in_60s() {
6087 let s = SupervisorSpec::default();
6088 assert_eq!(s.estrategia, RestartStrategy::OneForOne);
6089 assert_eq!(s.max_restarts, 5);
6090 assert_eq!(s.restart_window, Some(Duration::from_secs(60)));
6091 assert!(s.children.is_empty());
6092 }
6093
6094 #[test]
6095 fn validate_one_for_one_requires_children() {
6096 // Explicit-empty via struct-update rather than `let mut s = default(); s.children = vec![];`
6097 // — the peer `validate_simple_one_for_one_forbids_static_children` below already uses
6098 // struct-update to name the axis under test at construction, and this shape matches
6099 // it. Also keeps the "empty children is the axis under test" intent visible at the
6100 // binding site rather than one line down, and side-steps `clippy::field_reassign_with_default`.
6101 let mut s = SupervisorSpec {
6102 children: vec![],
6103 ..SupervisorSpec::default()
6104 };
6105 assert!(matches!(
6106 s.validate().unwrap_err(),
6107 SupervisorError::NoChildren { .. }
6108 ));
6109 s.children = vec![child("worker", "^0.1", RestartPolicy::Permanent)];
6110 s.validate().unwrap();
6111 }
6112
6113 #[test]
6114 fn validate_simple_one_for_one_forbids_static_children() {
6115 let mut s = SupervisorSpec {
6116 estrategia: RestartStrategy::SimpleOneForOne,
6117 ..SupervisorSpec::default()
6118 };
6119 s.children
6120 .push(child("w", "^0.1", RestartPolicy::Permanent));
6121 assert_eq!(
6122 s.validate().unwrap_err(),
6123 SupervisorError::SimpleOneForOneWithStaticChildren
6124 );
6125 s.children.clear();
6126 s.validate().unwrap();
6127 }
6128
6129 #[test]
6130 fn validate_rejects_zero_max_restarts() {
6131 let s = SupervisorSpec {
6132 max_restarts: 0,
6133 children: vec![child("w", "^0.1", RestartPolicy::Permanent)],
6134 ..SupervisorSpec::default()
6135 };
6136 assert_eq!(s.validate().unwrap_err(), SupervisorError::ZeroMaxRestarts);
6137 }
6138
6139 // ── upper-cap: SUPERVISOR_MAX_RESTARTS_MAX brackets the typed slot ─────
6140 //
6141 // The cap arm lifts the `:politicas :circuit-breaker :max-failures` /
6142 // `POLICY_BREAKER_MAX_FAILURES_MAX` (2b51ace) discipline onto the peer
6143 // `:supervisor :max-restarts` axis — both fields are "trip the
6144 // next-higher protection layer after N events in a rolling window"
6145 // counters with identical degenerate-at-the-high-end shape, so the
6146 // typed-slot's accepted set lies in `1..=1000` on the supervisor side
6147 // exactly as it lies in `1..=1000` on the breaker side.
6148
6149 #[test]
6150 fn validate_rejects_max_restarts_above_cap() {
6151 // The fail-before-pass-after pin: `SUPERVISOR_MAX_RESTARTS_MAX +
6152 // 1` is structurally one past the cap and silently passed
6153 // validate on every pre-gate codebase because the typed slot's
6154 // only check was the zero-floor arm. The no-op-supervisor vector
6155 // only surfaced at the runtime substrate (Erlang/OTP
6156 // MaxIntensity/Period ratio, the future wasm-operator's
6157 // per-supervisor restart-intensity counter) far from the source
6158 // caixa.lisp with no field naming the offending supervisor.
6159 let s = SupervisorSpec {
6160 max_restarts: SUPERVISOR_MAX_RESTARTS_MAX + 1,
6161 children: vec![child("w", "^0.1", RestartPolicy::Permanent)],
6162 ..SupervisorSpec::default()
6163 };
6164 assert_eq!(
6165 s.validate().unwrap_err(),
6166 SupervisorError::MaxRestartsExceedsCap {
6167 max_restarts: SUPERVISOR_MAX_RESTARTS_MAX + 1,
6168 }
6169 );
6170 }
6171
6172 #[test]
6173 fn validate_rejects_max_restarts_far_above_cap() {
6174 // The `u32::MAX` worst case — the four-billion-restart
6175 // threshold a typo (`:max-restarts 4294967295`) or a
6176 // struct-literal copy-paste lands in the slot. Pin the cap
6177 // arm's coverage explicitly across the full `u32` overflow so
6178 // a future relaxation that drops the upper bound surfaces
6179 // here. Same shape every other typed-cap arm on this surface
6180 // carries (POLICY_BREAKER_MAX_FAILURES_MAX,
6181 // POLICY_RETRIES_MAX, POLICY_RATE_LIMIT_MAX).
6182 let s = SupervisorSpec {
6183 max_restarts: u32::MAX,
6184 children: vec![child("w", "^0.1", RestartPolicy::Permanent)],
6185 ..SupervisorSpec::default()
6186 };
6187 assert_eq!(
6188 s.validate().unwrap_err(),
6189 SupervisorError::MaxRestartsExceedsCap {
6190 max_restarts: u32::MAX,
6191 }
6192 );
6193 }
6194
6195 #[test]
6196 fn validate_accepts_max_restarts_at_cap() {
6197 // The boundary value — exactly SUPERVISOR_MAX_RESTARTS_MAX —
6198 // must validate. The cap is inclusive on the top edge,
6199 // matching the POLICY_BREAKER_MAX_FAILURES_MAX /
6200 // POLICY_RETRIES_MAX / LIMITS_MEMORY_WASM32_MAX_BYTES
6201 // discipline on the sibling capped axes. Pin the boundary
6202 // explicitly so a future off-by-one tightening
6203 // (`>= SUPERVISOR_MAX_RESTARTS_MAX` instead of `>`) surfaces
6204 // here as a test failure rather than a silent contract
6205 // narrowing.
6206 let s = SupervisorSpec {
6207 max_restarts: SUPERVISOR_MAX_RESTARTS_MAX,
6208 children: vec![child("w", "^0.1", RestartPolicy::Permanent)],
6209 ..SupervisorSpec::default()
6210 };
6211 s.validate()
6212 .expect("max_restarts == SUPERVISOR_MAX_RESTARTS_MAX must validate");
6213 }
6214
6215 #[test]
6216 fn validate_accepts_max_restarts_typical_values() {
6217 // The documented production-playbook band positive-control
6218 // sweep — every value Erlang/OTP / Elixir / Riak Core /
6219 // RabbitMQ recommend (1..=100) must pass, plus a sweep
6220 // through the hyperscale band (200, 500, 1000) the cap
6221 // accepts. Pin the inclusive validated set explicitly so a
6222 // future tightening of the ceiling surfaces here.
6223 for n in [1u32, 3, 5, 10, 20, 50, 100, 200, 500, 1000] {
6224 let s = SupervisorSpec {
6225 max_restarts: n,
6226 children: vec![child("w", "^0.1", RestartPolicy::Permanent)],
6227 ..SupervisorSpec::default()
6228 };
6229 s.validate()
6230 .unwrap_or_else(|e| panic!("max_restarts={n} must validate; got {e:?}"));
6231 }
6232 }
6233
6234 #[test]
6235 fn zero_max_restarts_takes_precedence_over_cap() {
6236 // The cross-arm ordering pin: `0` is structurally outside
6237 // both `1..` (zero-floor) and `..=SUPERVISOR_MAX_RESTARTS_MAX`
6238 // (cap), but the zero-floor diagnostic is the more
6239 // self-locating one (it directly names the counter-axis
6240 // remediation), so the validate gate must fire on zero first.
6241 // Same shape every other zero-then-shape ordering on this
6242 // surface uses (PolicyRetriesZero then
6243 // PolicyRetriesExceedsCap; PolicyBreakerZeroFailures then
6244 // PolicyBreakerMaxFailuresExceedsCap).
6245 let s = SupervisorSpec {
6246 max_restarts: 0,
6247 children: vec![child("w", "^0.1", RestartPolicy::Permanent)],
6248 ..SupervisorSpec::default()
6249 };
6250 assert_eq!(
6251 s.validate().unwrap_err(),
6252 SupervisorError::ZeroMaxRestarts,
6253 "max_restarts == 0 must surface the zero-floor diagnostic, not the cap diagnostic"
6254 );
6255 }
6256
6257 #[test]
6258 fn max_restarts_cap_takes_precedence_over_restart_window_gates() {
6259 // The cross-arm ordering pin between the cap and the sibling
6260 // `:restart-window` gates (zero-window, canonical-window). A
6261 // supervisor carrying both an over-cap `max_restarts` AND a
6262 // structurally invalid window (zero, sub-ms) must surface the
6263 // cap diagnostic first — the cap arm is wired immediately
6264 // after the zero-restart arm and strictly before the window
6265 // arms, so the offending value the diagnostic names matches
6266 // the order the author would discover the gates by reading
6267 // top-to-bottom through `SupervisorSpec::validate`. Pin the
6268 // order so a future refactor that reorders the arms surfaces
6269 // here as a test failure rather than a silent diagnostic
6270 // regression. Peer of
6271 // `circuit_breaker_max_failures_cap_takes_precedence_over_window_gates`
6272 // on the sibling `:politicas :circuit-breaker` slot.
6273 let s = SupervisorSpec {
6274 max_restarts: SUPERVISOR_MAX_RESTARTS_MAX + 1,
6275 restart_window: Some(Duration::ZERO),
6276 children: vec![child("w", "^0.1", RestartPolicy::Permanent)],
6277 ..SupervisorSpec::default()
6278 };
6279 assert_eq!(
6280 s.validate().unwrap_err(),
6281 SupervisorError::MaxRestartsExceedsCap {
6282 max_restarts: SUPERVISOR_MAX_RESTARTS_MAX + 1,
6283 },
6284 "over-cap max_restarts must surface the cap diagnostic before any window-axis diagnostic"
6285 );
6286 }
6287
6288 #[test]
6289 fn max_restarts_cap_diagnostic_carries_offending_value() {
6290 // The diagnostic-shape pin: the offending `u32` is carried
6291 // verbatim into the `SupervisorError::MaxRestartsExceedsCap`
6292 // variant so the surfaced error message names the value the
6293 // author wrote (`":supervisor :max-restarts (50000) exceeds the
6294 // supervisor-policy ceiling …"`), not just the cap. Same
6295 // self-locating diagnostic shape every other typed-cap arm on
6296 // this surface carries
6297 // (`AplicacaoError::PolicyBreakerMaxFailuresExceedsCap` carries
6298 // the offending failure count verbatim,
6299 // `AplicacaoError::PolicyRetriesExceedsCap` carries the offending
6300 // retries count verbatim).
6301 let s = SupervisorSpec {
6302 max_restarts: 50_000,
6303 children: vec![child("w", "^0.1", RestartPolicy::Permanent)],
6304 ..SupervisorSpec::default()
6305 };
6306 let err = s.validate().unwrap_err();
6307 assert!(
6308 matches!(
6309 err,
6310 SupervisorError::MaxRestartsExceedsCap {
6311 max_restarts: 50_000
6312 }
6313 ),
6314 "got {err:?}"
6315 );
6316 let msg = err.to_string();
6317 assert!(
6318 msg.contains("50000"),
6319 ":supervisor :max-restarts cap diagnostic must carry the offending value verbatim (got: {msg})"
6320 );
6321 }
6322
6323 #[test]
6324 fn supervisor_max_restarts_default_pins_otp_canonical_value() {
6325 // Pin [`SUPERVISOR_MAX_RESTARTS_DEFAULT`] at `5` — the
6326 // Erlang/OTP-canonical `{intensity, 5, 60}` `MaxIntensity`
6327 // half of Learn You Some Erlang's worker-supervisor default,
6328 // sibling of the `60s` `Period` half that the paired
6329 // [`Default for SupervisorSpec`] impl already pins on the
6330 // sibling `restart_window` axis. Pinning the literal here
6331 // surfaces a future rebrand (a tightening to Elixir's `3`,
6332 // a widening to a per-cluster overlay the operator pins
6333 // through a future `:max-restarts-overrides` slot) as a
6334 // deliberate test edit, not a silent contract migration.
6335 // Peer of the sibling
6336 // [`supervisor_max_restarts_cap_pins_canonical_value`]
6337 // upper-bracket pin on the same axis.
6338 assert_eq!(SUPERVISOR_MAX_RESTARTS_DEFAULT, 5);
6339 }
6340
6341 #[test]
6342 fn default_max_restarts_helper_routes_through_lifted_default() {
6343 // Composition pin: the private `default_max_restarts()`
6344 // serde-`#[serde(default = "…")]` helper on
6345 // [`SupervisorSpec::max_restarts`] must route through the
6346 // substrate-canonical [`SUPERVISOR_MAX_RESTARTS_DEFAULT`]
6347 // typed `pub const` rather than a raw `5` literal. Prior to
6348 // the lift the helper carried an inline `5` with no compile-
6349 // time link back to the shared default, so the wire-format
6350 // author-omitted arm and the caixa-core
6351 // [`crate::manifest::Caixa::supervisor_view`] fold's `unwrap_or(5)`
6352 // arm could silently split on any future default rebrand.
6353 // Byte-parity against the lifted constant closes the split.
6354 assert_eq!(default_max_restarts(), SUPERVISOR_MAX_RESTARTS_DEFAULT);
6355 }
6356
6357 #[test]
6358 fn supervisor_spec_default_max_restarts_routes_through_lifted_default() {
6359 // Composition pin: the [`Default for SupervisorSpec`] impl's
6360 // struct-literal `max_restarts` field must route through the
6361 // substrate-canonical [`SUPERVISOR_MAX_RESTARTS_DEFAULT`]
6362 // typed `pub const` (via the private helper this test's
6363 // sibling `default_max_restarts_helper_routes_through_lifted_default`
6364 // already pins onto the constant). Structurally: every
6365 // `SupervisorSpec::default()` call must yield a
6366 // `max_restarts` field byte-equal to the lifted constant
6367 // (the two paired defaults — the serde-side wire-format arm
6368 // and the struct-literal default arm — cannot silently split
6369 // on any future default rebrand). Peer of the sibling
6370 // `default_has_one_for_one_and_5_restarts_in_60s` shape pin
6371 // — this pin closes the byte-parity arm on the two paired
6372 // altitude entry points onto the shared substrate constant.
6373 assert_eq!(
6374 SupervisorSpec::default().max_restarts(),
6375 SUPERVISOR_MAX_RESTARTS_DEFAULT,
6376 );
6377 }
6378
6379 #[test]
6380 fn supervisor_restart_window_default_pins_otp_canonical_value() {
6381 // Pin [`SUPERVISOR_RESTART_WINDOW_DEFAULT`] at `60s` — the
6382 // Erlang/OTP-canonical `{intensity, 5, 60}` `Period` half of
6383 // Learn You Some Erlang's worker-supervisor default, paired
6384 // with the sibling `SUPERVISOR_MAX_RESTARTS_DEFAULT` `5`
6385 // `MaxIntensity` half this constant is the sliding-window
6386 // denominator of on the same `MaxIntensity / Period`
6387 // restart-intensity ratio. Pinning the literal here surfaces a
6388 // future coherent rebrand of the paired default (Elixir's
6389 // `{max_restarts: 3, max_seconds: 5}`, a per-cluster overlay
6390 // the operator pins through a future
6391 // `:restart-window-overrides` slot) as a deliberate test edit,
6392 // not a silent contract migration. Peer of the sibling
6393 // [`supervisor_max_restarts_default_pins_otp_canonical_value`]
6394 // paired-half pin on the same OTP-canonical default and the
6395 // [`supervisor_restart_window_cap_pins_canonical_value`]
6396 // upper-bracket pin on the same axis.
6397 assert_eq!(SUPERVISOR_RESTART_WINDOW_DEFAULT, Duration::from_secs(60),);
6398 }
6399
6400 #[test]
6401 fn supervisor_spec_default_restart_window_routes_through_lifted_default() {
6402 // Composition pin: the [`Default for SupervisorSpec`] impl's
6403 // struct-literal `restart_window` field must route through the
6404 // substrate-canonical [`SUPERVISOR_RESTART_WINDOW_DEFAULT`]
6405 // typed `pub const` rather than a raw
6406 // `Duration::from_secs(60)` literal. Prior to this lift the
6407 // paired `{intensity, 5, 60}` OTP-canonical default was split
6408 // across two altitudes with no compile-time link between the
6409 // halves — the `MaxIntensity` half rode through the lifted
6410 // [`SUPERVISOR_MAX_RESTARTS_DEFAULT`] constant while the
6411 // `Period` half rode as an open-coded literal at the
6412 // composition site, so a future coherent rebrand of the paired
6413 // canonical would have had to migrate one half through the
6414 // constant and the other through a raw literal in lockstep.
6415 // Byte-parity against the lifted constant on the `Period` half
6416 // closes the split — the paired OTP-canonical default now
6417 // migrates as one unit on any future axis change. Peer of the
6418 // sibling
6419 // [`supervisor_spec_default_max_restarts_routes_through_lifted_default`]
6420 // byte-parity pin on the paired `MaxIntensity` half.
6421 assert_eq!(
6422 SupervisorSpec::default().restart_window(),
6423 Some(SUPERVISOR_RESTART_WINDOW_DEFAULT),
6424 );
6425 }
6426
6427 #[test]
6428 fn supervisor_estrategia_default_pins_otp_canonical_value() {
6429 // Pin [`SUPERVISOR_ESTRATEGIA_DEFAULT`] at [`RestartStrategy::OneForOne`]
6430 // — the Erlang/OTP-canonical `one_for_one` half of Learn You Some
6431 // Erlang's `{one_for_one, intensity, 5, 60}` worker-supervisor
6432 // canonical default, paired with the sibling
6433 // `SUPERVISOR_MAX_RESTARTS_DEFAULT` `5` `MaxIntensity` half and the
6434 // sibling `SUPERVISOR_RESTART_WINDOW_DEFAULT` `60s` `Period` half
6435 // this constant is the strategy discriminator of on the same
6436 // OTP-canonical worker-supervisor default. Pinning the arm here
6437 // surfaces a future coherent rebrand of the paired triple (Elixir's
6438 // `{:one_for_one, max_restarts: 3, max_seconds: 5}` on the sibling
6439 // intensity/period axes leaving this strategy arm untouched, an OTP
6440 // `rest_for_one` widening once the substrate discovers startup-
6441 // order-coupled child cohorts as the more common worker-supervisor
6442 // shape, a per-cluster overlay the operator pins through a future
6443 // `:estrategia-overrides` slot the MESH-COMPOSITION §III.2
6444 // supervision-canary roadmap acknowledges) as a deliberate test
6445 // edit, not a silent contract migration. Peer of the sibling
6446 // [`supervisor_max_restarts_default_pins_otp_canonical_value`] +
6447 // [`supervisor_restart_window_default_pins_otp_canonical_value`]
6448 // paired-half pins on the same OTP-canonical default.
6449 assert_eq!(SUPERVISOR_ESTRATEGIA_DEFAULT, RestartStrategy::OneForOne);
6450 }
6451
6452 #[test]
6453 fn restart_strategy_default_routes_through_lifted_default() {
6454 // Composition pin: the [`Default for RestartStrategy`] impl's
6455 // return arm must route through the substrate-canonical
6456 // [`SUPERVISOR_ESTRATEGIA_DEFAULT`] typed `pub const` rather than
6457 // a raw `Self::OneForOne` arm. Prior to the lift the impl carried
6458 // an inline `Self::OneForOne` with no compile-time link back to
6459 // the shared OTP-canonical `one_for_one` strategy the paired
6460 // [`Default for SupervisorSpec`] impl's struct-literal `estrategia`
6461 // field and the [`crate::manifest::Caixa::supervisor_view`] fold's
6462 // `.unwrap_or_default()` (now
6463 // `.unwrap_or(SUPERVISOR_ESTRATEGIA_DEFAULT)`) arm both key off —
6464 // so a future rebrand of the OTP-canonical strategy default (an
6465 // OTP `rest_for_one` widening once the substrate discovers
6466 // startup-order-coupled child cohorts as the more common worker-
6467 // supervisor shape, a per-cluster overlay the operator pins
6468 // through a future `:estrategia-overrides` slot) would have had to
6469 // be threaded through the `Default` impl and the two peer routes
6470 // in lockstep or the three consumers would silently split. Byte-
6471 // parity against the lifted constant closes the split. Peer of
6472 // the sibling
6473 // [`default_max_restarts_helper_routes_through_lifted_default`] +
6474 // [`supervisor_spec_default_restart_window_routes_through_lifted_default`]
6475 // composition pins on the paired `MaxIntensity` + `Period` halves.
6476 assert_eq!(RestartStrategy::default(), SUPERVISOR_ESTRATEGIA_DEFAULT,);
6477 }
6478
6479 #[test]
6480 fn supervisor_spec_default_estrategia_routes_through_lifted_default() {
6481 // Composition pin: the [`Default for SupervisorSpec`] impl's
6482 // struct-literal `estrategia` field must route through the
6483 // substrate-canonical [`SUPERVISOR_ESTRATEGIA_DEFAULT`] typed
6484 // `pub const` (either directly, or via the
6485 // [`RestartStrategy::default`] impl that the sibling
6486 // `restart_strategy_default_routes_through_lifted_default` pin
6487 // already routes onto the constant). Structurally: every
6488 // `SupervisorSpec::default()` call must yield an `estrategia`
6489 // field byte-equal to the lifted constant (the three paired
6490 // defaults — the [`Default for RestartStrategy`] impl arm, the
6491 // struct-literal default arm here, and the
6492 // [`crate::manifest::Caixa::supervisor_view`] fold arm — cannot
6493 // silently split on any future default rebrand). Peer of the
6494 // sibling
6495 // [`supervisor_spec_default_max_restarts_routes_through_lifted_default`]
6496 // + [`supervisor_spec_default_restart_window_routes_through_lifted_default`]
6497 // byte-parity pins on the paired `MaxIntensity` + `Period` halves
6498 // of the same `SupervisorSpec::default()` composed altitude.
6499 assert_eq!(
6500 SupervisorSpec::default().estrategia(),
6501 SUPERVISOR_ESTRATEGIA_DEFAULT,
6502 );
6503 }
6504
6505 #[test]
6506 fn supervisor_spec_default_routes_through_otp_canonical_ctor() {
6507 // Composition pin: the [`Default for SupervisorSpec`] impl must
6508 // route through the substrate-canonical
6509 // [`SupervisorSpec::otp_canonical`] `pub const fn` constructor
6510 // rather than a re-hand-authored struct-literal cascade. Sharpens
6511 // the sibling per-arm
6512 // `supervisor_spec_default_*_routes_through_lifted_default` pins
6513 // from a per-field lift into a whole-struct one-source-of-truth
6514 // pin — the derived-until-now [`Default::default`] and the
6515 // [`SupervisorSpec::otp_canonical`] constructor are byte-equal by
6516 // construction, not by coincidence.
6517 //
6518 // A future extension of the OTP-canonical baseline (a fifth
6519 // `restart_intensity` field the Erlang/OTP `#supervisor` record
6520 // grows, a per-child-cohort split of the `restart_window` /
6521 // `max_restarts` pair, an M4 `mesh.pleme.io/v1alpha1/Supervisor`
6522 // CR materializer's admission-time overlay pass) reaches both
6523 // paths through exactly one edit on
6524 // [`SupervisorSpec::otp_canonical`] — the derived path could
6525 // silently disagree with the constructor's shape on any new
6526 // field whose [`Default::default`] resolves to a different arm
6527 // than the OTP-canonical baseline the constructor names, while
6528 // this delegated impl reaches the constructor directly and
6529 // picks up every future extension by construction.
6530 //
6531 // Fourth peer on the M2 / M3 typed-slot-spec
6532 // [`Default`]-through-const-ctor fold family — sibling of the
6533 // [`crate::LimitsSpec`] [`Default`]-through-[`crate::LimitsSpec::empty`]
6534 // (abd52c2), [`crate::aplicacao::MeshPolicy`]
6535 // [`Default`]-through-[`crate::aplicacao::MeshPolicy::empty`]
6536 // (91641a4), and [`crate::BehaviorSpec`]
6537 // [`Default`]-through-[`crate::BehaviorSpec::empty`] (0c1752c)
6538 // per-`Option`-only-typed-slot folds — extended here onto the
6539 // M2 supervisor-slot [`SupervisorSpec`] whose canonical baseline
6540 // is not "everything `None`" but the Erlang/OTP-canonical
6541 // `{one_for_one, 5, 60}` worker-supervisor triple.
6542 assert_eq!(SupervisorSpec::default(), SupervisorSpec::otp_canonical());
6543 }
6544
6545 #[test]
6546 fn supervisor_spec_otp_canonical_byte_equals_default() {
6547 // Value pin: [`SupervisorSpec::otp_canonical`] must byte-equal
6548 // the hand-authored `{one_for_one, 5, 60, []}` OTP-canonical
6549 // baseline the sibling `default_has_one_for_one_and_5_restarts_in_60s`
6550 // pin already asserts against the [`Default::default`] path.
6551 // Sharpens the pair-invariant into a per-constructor pin so a
6552 // future extension of [`SupervisorSpec`] with a fifth field
6553 // whose OTP-canonical shape is non-`Default::default`-equivalent
6554 // trips at caixa-core test time rather than at a downstream
6555 // consumer that composed [`SupervisorSpec::otp_canonical`] with
6556 // [`SupervisorSpec::validate`] as its "canonical baseline
6557 // seed".
6558 let canonical = SupervisorSpec::otp_canonical();
6559 assert_eq!(canonical.estrategia, RestartStrategy::OneForOne);
6560 assert_eq!(canonical.max_restarts, 5);
6561 assert_eq!(canonical.restart_window, Some(Duration::from_secs(60)));
6562 assert!(canonical.children.is_empty());
6563 }
6564
6565 #[test]
6566 fn supervisor_spec_otp_canonical_is_usable_in_const_context() {
6567 // Const-context pin: [`SupervisorSpec::otp_canonical`] must
6568 // remain callable from a `const`-bound position so downstream
6569 // `const`-context callers wanting a canonical OTP-baseline seed
6570 // can construct one at compile time without runtime dispatch on
6571 // the derived [`Default::default`]. Peer of the sibling
6572 // `pub const fn` [`crate::LimitsSpec::empty`] /
6573 // [`crate::aplicacao::MeshPolicy::empty`] /
6574 // [`crate::BehaviorSpec::empty`] constructors on the sibling
6575 // typed-slot-spec `pub const fn` axis. If a future edit breaks
6576 // the `const`-eligibility of [`SupervisorSpec::otp_canonical`]
6577 // (a non-`const` field-default helper, a non-`const`-stable
6578 // container type promotion), this evaluation fails at
6579 // build time on this file rather than at a downstream
6580 // `const`-context call site.
6581 const CANONICAL: SupervisorSpec = SupervisorSpec::otp_canonical();
6582 assert_eq!(CANONICAL.estrategia, SUPERVISOR_ESTRATEGIA_DEFAULT);
6583 assert_eq!(CANONICAL.max_restarts, SUPERVISOR_MAX_RESTARTS_DEFAULT);
6584 assert_eq!(
6585 CANONICAL.restart_window,
6586 Some(SUPERVISOR_RESTART_WINDOW_DEFAULT),
6587 );
6588 assert!(CANONICAL.children.is_empty());
6589 }
6590
6591 #[test]
6592 fn supervisor_child_restart_default_pins_otp_canonical_value() {
6593 // Pin [`SUPERVISOR_CHILD_RESTART_DEFAULT`] at
6594 // [`RestartPolicy::Permanent`] — Erlang/OTP's `permanent`
6595 // worker-child restart type (`{ChildId, StartFunc, permanent, …}`
6596 // in a `supervisor`'s `init/1` child-spec tuple), the per-child
6597 // half of the same OTP-shape supervisor-tree default set whose
6598 // per-`:supervisor` halves the sibling
6599 // [`SUPERVISOR_ESTRATEGIA_DEFAULT`] /
6600 // [`SUPERVISOR_MAX_RESTARTS_DEFAULT`] /
6601 // [`SUPERVISOR_RESTART_WINDOW_DEFAULT`] constants pin. Pinning the
6602 // arm here surfaces a future rebrand of the per-child default (an
6603 // OTP-`transient` widening once the substrate discovers clean-
6604 // completion-aware children as the more common child shape, a
6605 // per-cluster overlay the operator pins through a future
6606 // `:restart-overrides` slot the MESH-COMPOSITION §III.2
6607 // supervision-canary roadmap acknowledges) as a deliberate test
6608 // edit, not a silent contract migration. Peer of the sibling
6609 // [`supervisor_estrategia_default_pins_otp_canonical_value`] /
6610 // [`supervisor_max_restarts_default_pins_otp_canonical_value`] /
6611 // [`supervisor_restart_window_default_pins_otp_canonical_value`]
6612 // value pins on the per-`:supervisor` halves.
6613 assert_eq!(SUPERVISOR_CHILD_RESTART_DEFAULT, RestartPolicy::Permanent);
6614 }
6615
6616 #[test]
6617 fn restart_policy_default_routes_through_lifted_default() {
6618 // Composition pin: the [`Default for RestartPolicy`] impl's return
6619 // arm must route through the substrate-canonical
6620 // [`SUPERVISOR_CHILD_RESTART_DEFAULT`] typed `pub const` rather
6621 // than a raw `Self::Permanent` arm. Prior to the lift the impl
6622 // carried an inline `Self::Permanent` with no compile-time link
6623 // back to the OTP-shape supervisor-tree default set whose three
6624 // per-`:supervisor` halves already rode through lifted constants
6625 // — so a future coherent rebrand of the set would have had to
6626 // migrate three halves through typed constants and this fourth
6627 // through a raw enum arm in lockstep or the supervisor-level and
6628 // child-level defaults would silently drift apart. Byte-parity
6629 // against the lifted constant closes the split. Peer of the
6630 // sibling
6631 // [`restart_strategy_default_routes_through_lifted_default`]
6632 // composition pin on the per-`:supervisor` `:estrategia` axis.
6633 assert_eq!(RestartPolicy::default(), SUPERVISOR_CHILD_RESTART_DEFAULT);
6634 }
6635
6636 #[test]
6637 fn child_spec_serde_default_restart_routes_through_lifted_default() {
6638 // Composition pin: the serde-side `#[serde(default)]` on
6639 // [`ChildSpec::restart`] — the wire-format author-omitted
6640 // `:children :restart` arm — must resolve onto the substrate-
6641 // canonical [`SUPERVISOR_CHILD_RESTART_DEFAULT`] typed `pub const`
6642 // (via the [`Default for RestartPolicy`] impl the sibling
6643 // `restart_policy_default_routes_through_lifted_default` pin
6644 // already routes onto the constant). Structurally: a `ChildSpec`
6645 // deserialized from a payload that omits the `restart` key must
6646 // yield a `restart` field byte-equal to the lifted constant, so
6647 // the wire-format author-omitted arm and the
6648 // [`RestartPolicy::default`] impl arm cannot silently split on any
6649 // future default rebrand. Peer of the sibling
6650 // [`supervisor_spec_default_estrategia_routes_through_lifted_default`]
6651 // / [`supervisor_spec_default_max_restarts_routes_through_lifted_default`]
6652 // / [`supervisor_spec_default_restart_window_routes_through_lifted_default`]
6653 // byte-parity pins on the per-`:supervisor` halves of the same
6654 // author-omitted-slot resolution surface.
6655 let omitted: ChildSpec = serde_json::from_str(r#"{"caixa":"worker","versao":"^0.1"}"#)
6656 .expect("ChildSpec must deserialize with the restart key omitted");
6657 assert_eq!(
6658 omitted.restart(),
6659 SUPERVISOR_CHILD_RESTART_DEFAULT,
6660 "an author-omitted :children :restart slot must degrade onto \
6661 the SUPERVISOR_CHILD_RESTART_DEFAULT typed pub const (got \
6662 {:?}, expected {:?})",
6663 omitted.restart(),
6664 SUPERVISOR_CHILD_RESTART_DEFAULT,
6665 );
6666 }
6667
6668 #[test]
6669 fn supervisor_max_restarts_cap_pins_canonical_value() {
6670 // The SUPERVISOR_MAX_RESTARTS_MAX constant pins the value at
6671 // 1000 — the same ceiling the peer
6672 // POLICY_BREAKER_MAX_FAILURES_MAX cap carries on the
6673 // `:politicas :circuit-breaker :max-failures` axis (both are
6674 // "trip the next-higher protection layer after N events in a
6675 // rolling window" counters with identical
6676 // degenerate-at-the-high-end shape; uniform top edge so the
6677 // M4 CR materializers and the wasm-operator reconciler reach
6678 // for either field knowing the value is in `1..=1000`). Two
6679 // orders of magnitude above every documented Erlang/OTP /
6680 // Elixir / Riak Core / RabbitMQ production-playbook
6681 // recommendation band and below the clearly-pathological
6682 // "effectively no escalation" floor (10_000, 100_000,
6683 // u32::MAX). Pinning the literal value here surfaces a future
6684 // drift (a relaxation to 10_000, a tightening to 100) as a
6685 // deliberate test edit, not a silent contract narrowing.
6686 assert_eq!(SUPERVISOR_MAX_RESTARTS_MAX, 1000);
6687 }
6688
6689 #[test]
6690 fn validate_rejects_empty_child_name() {
6691 let s = SupervisorSpec {
6692 children: vec![child("", "^0.1", RestartPolicy::Permanent)],
6693 ..SupervisorSpec::default()
6694 };
6695 assert_eq!(s.validate().unwrap_err(), SupervisorError::EmptyChildName);
6696 }
6697
6698 #[test]
6699 fn validate_rejects_empty_child_version() {
6700 let s = SupervisorSpec {
6701 children: vec![child("w", "", RestartPolicy::Permanent)],
6702 ..SupervisorSpec::default()
6703 };
6704 assert!(matches!(
6705 s.validate().unwrap_err(),
6706 SupervisorError::EmptyChildVersion { .. }
6707 ));
6708 }
6709
6710 // ── value-shape: parse-as-VersionReq on :children :versao ─────────────
6711
6712 #[test]
6713 fn validate_rejects_invalid_child_versao_requirement() {
6714 // The fail-before-pass-after pin: a non-empty but malformed
6715 // semver requirement (`"^bad-version"`) silently passed
6716 // `validate()` on every pre-gate codebase because the prior
6717 // shape only refused the empty string. The parse failure
6718 // surfaced far downstream at lacre-resolve time with a
6719 // `semver::Error` that didn't name which `:children` entry
6720 // carried the typo. The new gate moves the check to caixa-build
6721 // time at the source caixa.lisp — the third `:versao` typed
6722 // axis (`:children`) joins `:deps` and `:membros` (9888b13) at
6723 // structural parity.
6724 let s = SupervisorSpec {
6725 children: vec![
6726 child("worker", "^0.1", RestartPolicy::Permanent),
6727 child("cache", "^bad-version", RestartPolicy::Transient),
6728 ],
6729 ..SupervisorSpec::default()
6730 };
6731 let err = s.validate().unwrap_err();
6732 assert!(
6733 matches!(
6734 err,
6735 SupervisorError::ChildVersaoInvalid { ref caixa, ref versao, .. }
6736 if caixa == "cache" && versao == "^bad-version"
6737 ),
6738 "got {err:?}"
6739 );
6740 }
6741
6742 #[test]
6743 fn validate_rejects_child_versao_with_double_caret_typo() {
6744 // `"^^0.1"` is the canonical doubled-caret typo — looks
6745 // Cargo-shaped on first glance but fails the parser because
6746 // semver doesn't accept stacked operators. Pin this
6747 // adjacent-shape footgun explicitly so a future relaxation that
6748 // accepts "looks-canonical-but-isn't" forms surfaces here.
6749 let s = SupervisorSpec {
6750 children: vec![child("worker", "^^0.1", RestartPolicy::Permanent)],
6751 ..SupervisorSpec::default()
6752 };
6753 let err = s.validate().unwrap_err();
6754 assert!(
6755 matches!(
6756 err,
6757 SupervisorError::ChildVersaoInvalid { ref caixa, ref versao, .. }
6758 if caixa == "worker" && versao == "^^0.1"
6759 ),
6760 "got {err:?}"
6761 );
6762 }
6763
6764 #[test]
6765 fn validate_rejects_child_versao_with_v_prefixed_tag() {
6766 // `"v0.1"` is the canonical "git-tag-shape leaking into the
6767 // semver requirement slot" typo — an author copies the
6768 // publish-side git-tag string verbatim into `:versao`, but
6769 // Cargo's semver parser rejects the leading `v`. Same
6770 // adjacent-shape footgun pinned for `:membros :versao`
6771 // (9888b13).
6772 let s = SupervisorSpec {
6773 children: vec![child("worker", "v0.1", RestartPolicy::Permanent)],
6774 ..SupervisorSpec::default()
6775 };
6776 let err = s.validate().unwrap_err();
6777 assert!(
6778 matches!(
6779 err,
6780 SupervisorError::ChildVersaoInvalid { ref caixa, ref versao, .. }
6781 if caixa == "worker" && versao == "v0.1"
6782 ),
6783 "got {err:?}"
6784 );
6785 }
6786
6787 #[test]
6788 fn validate_accepts_canonical_child_versao_forms() {
6789 // The Cargo-shaped requirement forms `:deps :versao` and
6790 // `:membros :versao` already accept via
6791 // `crate::parse_requirement` must pass the children gate
6792 // without re-validating at the resolver layer. Pin every leg so
6793 // a future tightening of the canonical set surfaces here as a
6794 // test failure.
6795 for form in [
6796 "^0.1", // caret — minor-range pin (the most common shape)
6797 "~0.1.2", // tilde — patch-range pin
6798 "0.1.0", // exact — single-version pin
6799 "*", // wildcard — any version (semver::VersionReq::STAR)
6800 ">=0.1, <2", // multi-range — comma-separated comparators
6801 ] {
6802 let s = SupervisorSpec {
6803 children: vec![child("worker", form, RestartPolicy::Permanent)],
6804 ..SupervisorSpec::default()
6805 };
6806 s.validate()
6807 .unwrap_or_else(|e| panic!("canonical form {form:?} must validate, got {e:?}"));
6808 }
6809 }
6810
6811 #[test]
6812 fn child_versao_empty_takes_precedence_over_invalid() {
6813 // Order pin: the existing `EmptyChildVersion` diagnostic (which
6814 // doesn't try to parse) fires before the new
6815 // `ChildVersaoInvalid` parse-side diagnostic, so an empty
6816 // `:versao` keeps its narrower error message —
6817 // `parse_requirement` would also reject `""`, but the
6818 // empty-string arm is the more self-locating diagnostic for the
6819 // author. Same ordering discipline as
6820 // `membro_versao_empty_takes_precedence_over_invalid` in
6821 // aplicacao.rs.
6822 let s = SupervisorSpec {
6823 children: vec![child("worker", "", RestartPolicy::Permanent)],
6824 ..SupervisorSpec::default()
6825 };
6826 let err = s.validate().unwrap_err();
6827 assert!(
6828 matches!(err, SupervisorError::EmptyChildVersion { ref caixa } if caixa == "worker"),
6829 "got {err:?}"
6830 );
6831 }
6832
6833 #[test]
6834 fn child_versao_invalid_fires_before_duplicate_check() {
6835 // Order pin: a malformed requirement on a non-duplicate entry
6836 // surfaces *its own* diagnostic (which names the offending
6837 // `:versao` string), even when a later entry would otherwise
6838 // collapse onto an earlier name. The per-entry shape gate runs
6839 // inline before the duplicate-key insert — parallel to
6840 // `membro_versao_invalid_fires_before_duplicate_check` in
6841 // aplicacao.rs and the b0c8389 / c4213a4 ordering discipline.
6842 let s = SupervisorSpec {
6843 children: vec![
6844 child("worker", "^bad", RestartPolicy::Permanent),
6845 child("cache", "^0.1", RestartPolicy::Transient),
6846 child("worker", "^0.2", RestartPolicy::Permanent), // would otherwise raise DuplicateChildCaixa
6847 ],
6848 ..SupervisorSpec::default()
6849 };
6850 let err = s.validate().unwrap_err();
6851 assert!(
6852 matches!(
6853 err,
6854 SupervisorError::ChildVersaoInvalid { ref caixa, .. } if caixa == "worker"
6855 ),
6856 "got {err:?}"
6857 );
6858 }
6859
6860 #[test]
6861 fn child_versao_invalid_diagnostic_carries_offending_versao() {
6862 // The diagnostic-shape pin: the error names the offending
6863 // `:versao` value verbatim so the author can grep their
6864 // caixa.lisp without re-running the build, and carries a
6865 // non-empty `reason` from `semver::VersionReq::parse` so the
6866 // parser's own wording flows through to the diagnostic.
6867 let s = SupervisorSpec {
6868 children: vec![child("worker", "not-a-req", RestartPolicy::Permanent)],
6869 ..SupervisorSpec::default()
6870 };
6871 let err = s.validate().unwrap_err();
6872 let SupervisorError::ChildVersaoInvalid {
6873 caixa,
6874 versao,
6875 reason,
6876 } = err
6877 else {
6878 panic!("expected ChildVersaoInvalid, got other variant");
6879 };
6880 assert_eq!(caixa, "worker");
6881 assert_eq!(versao, "not-a-req");
6882 assert!(
6883 !reason.is_empty(),
6884 "ChildVersaoInvalid `reason` must carry the parser's wording verbatim"
6885 );
6886 }
6887
6888 // ── value-shape: DNS-1123 label rule on :children :caixa ──────────────
6889
6890 #[test]
6891 fn validate_rejects_child_caixa_with_uppercase() {
6892 // The canonical "I copied the Servico's display name verbatim"
6893 // typo — child caixa names are lowercase per K8s DNS-1123 label
6894 // rule. The diagnostic names the offending name and suggests the
6895 // lower-cased fix in one edit, mirroring the
6896 // `rejects_membro_caixa_with_uppercase` gate's shape (3f9d7a0).
6897 let s = SupervisorSpec {
6898 children: vec![child("Worker", "^0.1", RestartPolicy::Permanent)],
6899 ..SupervisorSpec::default()
6900 };
6901 let err = s.validate().unwrap_err();
6902 let SupervisorError::ChildCaixaInvalid { caixa, reason } = err else {
6903 panic!("expected ChildCaixaInvalid, got other variant");
6904 };
6905 assert_eq!(caixa, "Worker");
6906 assert!(
6907 reason.contains("uppercase"),
6908 "diagnostic must name the violation as `uppercase` (got: {reason:?})"
6909 );
6910 assert!(
6911 reason.contains("\"worker\""),
6912 "diagnostic must suggest the lower-cased fix verbatim (got: {reason:?})"
6913 );
6914 }
6915
6916 #[test]
6917 fn validate_rejects_child_caixa_with_underscore() {
6918 // The canonical "I'm thinking of a Python module / Postgres
6919 // table" leak — `_` is forbidden by every DNS-1123 / DNS-1035
6920 // label schema. K8s rejects `metadata.name: my_worker` at
6921 // admission time with an opaque `field is invalid` (no source-
6922 // citing diagnostic). The gate moves it to caixa-build time.
6923 let s = SupervisorSpec {
6924 children: vec![child("my_worker", "^0.1", RestartPolicy::Permanent)],
6925 ..SupervisorSpec::default()
6926 };
6927 let err = s.validate().unwrap_err();
6928 assert!(
6929 matches!(
6930 err,
6931 SupervisorError::ChildCaixaInvalid { ref caixa, ref reason }
6932 if caixa == "my_worker" && reason.contains('_')
6933 ),
6934 "got {err:?}"
6935 );
6936 }
6937
6938 #[test]
6939 fn validate_rejects_child_caixa_with_dot() {
6940 // A `:children :caixa` entry is a single DNS-1123 label, not a
6941 // subdomain. The K8s Service / ComputeUnit `metadata.name` rules
6942 // forbid dots. Same shape as `rejects_membro_caixa_with_dot`
6943 // (3f9d7a0) on the peer name axis.
6944 let s = SupervisorSpec {
6945 children: vec![child("team.worker", "^0.1", RestartPolicy::Permanent)],
6946 ..SupervisorSpec::default()
6947 };
6948 let err = s.validate().unwrap_err();
6949 assert!(
6950 matches!(
6951 err,
6952 SupervisorError::ChildCaixaInvalid { ref caixa, ref reason }
6953 if caixa == "team.worker" && reason.contains('.')
6954 ),
6955 "got {err:?}"
6956 );
6957 }
6958
6959 #[test]
6960 fn validate_rejects_child_caixa_with_leading_hyphen() {
6961 // DNS-1123 / DNS-1035 boundary rule: labels must start and end
6962 // with an alphanumeric. The K8s apiserver rejects `-worker`
6963 // outright; the renderer would emit a `metadata.name: "-worker"`
6964 // that fails admission far from the source caixa.lisp.
6965 let s = SupervisorSpec {
6966 children: vec![child("-worker", "^0.1", RestartPolicy::Permanent)],
6967 ..SupervisorSpec::default()
6968 };
6969 let err = s.validate().unwrap_err();
6970 assert!(
6971 matches!(
6972 err,
6973 SupervisorError::ChildCaixaInvalid { ref caixa, ref reason }
6974 if caixa == "-worker" && reason.contains("start and end")
6975 ),
6976 "got {err:?}"
6977 );
6978 }
6979
6980 #[test]
6981 fn validate_rejects_child_caixa_with_trailing_hyphen() {
6982 // The symmetric arm of the boundary rule. Pin separately so
6983 // both ends of the label are covered against a future relaxation
6984 // that only checks one boundary.
6985 let s = SupervisorSpec {
6986 children: vec![child("worker-", "^0.1", RestartPolicy::Permanent)],
6987 ..SupervisorSpec::default()
6988 };
6989 let err = s.validate().unwrap_err();
6990 assert!(
6991 matches!(
6992 err,
6993 SupervisorError::ChildCaixaInvalid { ref caixa, .. }
6994 if caixa == "worker-"
6995 ),
6996 "got {err:?}"
6997 );
6998 }
6999
7000 #[test]
7001 fn validate_rejects_child_caixa_with_unicode() {
7002 // DNS-1123 is ASCII-only; IDN must be pre-encoded as Punycode
7003 // (`xn--…`) by the author before it reaches K8s. The byte-by-
7004 // byte ASCII validity check rejects multi-byte UTF-8 sequences
7005 // by the first byte that fails the `[a-z0-9-]` predicate.
7006 let s = SupervisorSpec {
7007 children: vec![child("café", "^0.1", RestartPolicy::Permanent)],
7008 ..SupervisorSpec::default()
7009 };
7010 let err = s.validate().unwrap_err();
7011 assert!(
7012 matches!(
7013 err,
7014 SupervisorError::ChildCaixaInvalid { ref caixa, .. }
7015 if caixa == "café"
7016 ),
7017 "got {err:?}"
7018 );
7019 }
7020
7021 #[test]
7022 fn validate_rejects_child_caixa_with_whitespace() {
7023 // Whitespace is the canonical "I pasted from a sketch / doc"
7024 // footgun. The apiserver rejects every `metadata.name` value
7025 // carrying whitespace; pin the gate fires at the right boundary.
7026 let s = SupervisorSpec {
7027 children: vec![child("my worker", "^0.1", RestartPolicy::Permanent)],
7028 ..SupervisorSpec::default()
7029 };
7030 let err = s.validate().unwrap_err();
7031 assert!(
7032 matches!(
7033 err,
7034 SupervisorError::ChildCaixaInvalid { ref caixa, .. }
7035 if caixa == "my worker"
7036 ),
7037 "got {err:?}"
7038 );
7039 }
7040
7041 #[test]
7042 fn validate_rejects_child_caixa_too_long() {
7043 // The 64-byte boundary pin. DNS-1123 / DNS-1035 cap labels at
7044 // 63 bytes; the K8s apiserver rejects every `metadata.name`
7045 // axis over the limit at admission time. The diagnostic names
7046 // both the cap and the actual length so the author can shorten
7047 // in one edit, mirroring `rejects_membro_caixa_too_long`
7048 // (3f9d7a0) and `rejects_placement_cluster_too_long` (6cbb900).
7049 let too_long = "a".repeat(64);
7050 let s = SupervisorSpec {
7051 children: vec![child(&too_long, "^0.1", RestartPolicy::Permanent)],
7052 ..SupervisorSpec::default()
7053 };
7054 let err = s.validate().unwrap_err();
7055 let SupervisorError::ChildCaixaInvalid { caixa, reason } = err else {
7056 panic!("expected ChildCaixaInvalid, got other variant");
7057 };
7058 assert_eq!(caixa, too_long);
7059 assert!(
7060 reason.contains("63"),
7061 "diagnostic must name the 63-byte cap (got: {reason:?})"
7062 );
7063 assert!(
7064 reason.contains("64"),
7065 "diagnostic must name the actual length (got: {reason:?})"
7066 );
7067 }
7068
7069 #[test]
7070 fn child_caixa_max_length_validates() {
7071 // The 63-byte boundary control pin — exactly-at-the-cap is
7072 // accepted, mirroring `membro_caixa_max_length_validates`
7073 // (3f9d7a0) and `placement_cluster_max_length_validates`
7074 // (6cbb900). Pinned separately so a future off-by-one tightening
7075 // surfaces here.
7076 let max_label = "a".repeat(63);
7077 let s = SupervisorSpec {
7078 children: vec![child(&max_label, "^0.1", RestartPolicy::Permanent)],
7079 ..SupervisorSpec::default()
7080 };
7081 s.validate().unwrap();
7082 }
7083
7084 #[test]
7085 fn validate_accepts_canonical_child_caixa_forms() {
7086 // The realistic shapes a supervised child's `:caixa` carries —
7087 // single-word `worker`, version-suffixed `cache-v2`, single-char
7088 // `a`, two-char `db`, digit-start `2-pool`, longer hyphen-joined
7089 // `payment-retry`, all-digit `0`. Pin every leg so a future
7090 // tightening (e.g. requiring a leading lowercase letter) surfaces
7091 // here as a test failure. Mirrors `accepts_canonical_membro_caixa_forms`
7092 // (3f9d7a0) and `accepts_canonical_placement_cluster_forms`
7093 // (6cbb900).
7094 for form in [
7095 "worker",
7096 "cache-v2",
7097 "a",
7098 "db",
7099 "2-pool",
7100 "payment-retry",
7101 "0",
7102 ] {
7103 let s = SupervisorSpec {
7104 children: vec![child(form, "^0.1", RestartPolicy::Permanent)],
7105 ..SupervisorSpec::default()
7106 };
7107 s.validate()
7108 .unwrap_or_else(|e| panic!("canonical form {form:?} must validate, got {e:?}"));
7109 }
7110 }
7111
7112 #[test]
7113 fn child_caixa_empty_takes_precedence_over_invalid() {
7114 // Order pin: the existing `EmptyChildName` diagnostic (which
7115 // doesn't try to parse the DNS-1123 shape) fires before the new
7116 // `ChildCaixaInvalid` per-axis gate, so an empty `:caixa` keeps
7117 // its narrower error message — `is_dns_1123_label` would reject
7118 // the empty string too (boundary check on the first byte), but
7119 // the empty-string arm is the more self-locating diagnostic for
7120 // the author. Same ordering discipline as
7121 // `membro_caixa_empty_takes_precedence_over_invalid` in
7122 // aplicacao.rs.
7123 let s = SupervisorSpec {
7124 children: vec![child("", "^0.1", RestartPolicy::Permanent)],
7125 ..SupervisorSpec::default()
7126 };
7127 let err = s.validate().unwrap_err();
7128 assert_eq!(err, SupervisorError::EmptyChildName);
7129 }
7130
7131 #[test]
7132 fn child_caixa_invalid_fires_before_versao_check() {
7133 // Order pin: the per-axis shape gate runs inline before the
7134 // per-entry versao check, so a malformed `:caixa` on an entry
7135 // whose `:versao` would also fail surfaces the more self-
7136 // locating name-axis diagnostic first. Parallel to
7137 // `membro_versao_invalid_fires_before_duplicate_check` (9888b13)
7138 // and `placement_cluster_invalid_fires_before_duplicate_check`
7139 // (6cbb900).
7140 let s = SupervisorSpec {
7141 children: vec![child("My_Worker", "", RestartPolicy::Permanent)],
7142 ..SupervisorSpec::default()
7143 };
7144 let err = s.validate().unwrap_err();
7145 assert!(
7146 matches!(
7147 err,
7148 SupervisorError::ChildCaixaInvalid { ref caixa, .. } if caixa == "My_Worker"
7149 ),
7150 "got {err:?}"
7151 );
7152 }
7153
7154 #[test]
7155 fn child_caixa_invalid_fires_before_duplicate_check() {
7156 // Order pin: a malformed name on a non-duplicate entry surfaces
7157 // its own diagnostic, even when a later entry would otherwise
7158 // collapse onto an earlier name. The per-entry shape gate runs
7159 // inline before the duplicate-key HashSet insert, mirroring
7160 // `placement_cluster_invalid_fires_before_duplicate_check`
7161 // (6cbb900).
7162 let s = SupervisorSpec {
7163 children: vec![
7164 child("Worker", "^0.1", RestartPolicy::Permanent),
7165 child("cache", "^0.1", RestartPolicy::Transient),
7166 child("worker", "^0.2", RestartPolicy::Permanent), // would otherwise raise DuplicateChildCaixa
7167 ],
7168 ..SupervisorSpec::default()
7169 };
7170 let err = s.validate().unwrap_err();
7171 assert!(
7172 matches!(
7173 err,
7174 SupervisorError::ChildCaixaInvalid { ref caixa, .. } if caixa == "Worker"
7175 ),
7176 "got {err:?}"
7177 );
7178 }
7179
7180 #[test]
7181 fn child_caixa_invalid_diagnostic_carries_offending_caixa() {
7182 // The diagnostic-shape pin: the error names the offending
7183 // `:caixa` verbatim plus a non-empty parser-shaped `reason` so
7184 // the author can grep their caixa.lisp without re-running the
7185 // build. Mirrors the diagnostic-shape sweep on every prior
7186 // value-shape gate (3f9d7a0, 6cbb900, c7d05ec).
7187 let s = SupervisorSpec {
7188 children: vec![child("My_Worker", "^0.1", RestartPolicy::Permanent)],
7189 ..SupervisorSpec::default()
7190 };
7191 let err = s.validate().unwrap_err();
7192 let SupervisorError::ChildCaixaInvalid { caixa, reason } = err else {
7193 panic!("expected ChildCaixaInvalid, got other variant");
7194 };
7195 assert_eq!(caixa, "My_Worker");
7196 assert!(
7197 !reason.is_empty(),
7198 "ChildCaixaInvalid `reason` must carry the parser's wording verbatim"
7199 );
7200 }
7201
7202 // ── value-shape: zero restart_window + duplicate child names ──────────
7203
7204 #[test]
7205 fn validate_accepts_none_restart_window() {
7206 // Omitted `:restart-window` is the "never reset" sentinel —
7207 // valid by design. Mirrors :limits axes where None = unbounded.
7208 let s = SupervisorSpec {
7209 restart_window: None,
7210 children: vec![child("w", "^0.1", RestartPolicy::Permanent)],
7211 ..SupervisorSpec::default()
7212 };
7213 s.validate().unwrap();
7214 }
7215
7216 #[test]
7217 fn validate_rejects_zero_restart_window() {
7218 // Same "0 means the opposite of what you think" footgun closed
7219 // for :politicas :timeout (Envoy treats 0s as infinite) and
7220 // :limits :wall-clock (wasmtime traps before the call starts).
7221 // Erlang/OTP's MaxIntensity/Period requires Period > 0.
7222 let s = SupervisorSpec {
7223 restart_window: Some(Duration::ZERO),
7224 children: vec![child("w", "^0.1", RestartPolicy::Permanent)],
7225 ..SupervisorSpec::default()
7226 };
7227 assert_eq!(
7228 s.validate().unwrap_err(),
7229 SupervisorError::RestartWindowZero
7230 );
7231 }
7232
7233 // ── value-shape: integer-ms canonical-form on :restart-window ─────────
7234 //
7235 // The fourth (and last) typed-`Duration` axis in caixa-core to get
7236 // the integer-millisecond canonical-form gate — peer with
7237 // `:limits :wall-clock` (82fc3ef), `:politicas :timeout` (a4ae535),
7238 // and `:politicas :circuit-breaker :window` (a4ae535). The serde
7239 // path is already gated at the shared codec layer (see
7240 // `restart_window_serde_rejects_fractional_seconds`); this arm
7241 // closes the programmatic-struct-literal path the codec gate can't
7242 // see.
7243
7244 #[test]
7245 fn validate_rejects_sub_millisecond_restart_window() {
7246 // The fail-before-pass-after pin: a programmatic
7247 // `Duration::from_micros(1500)` (= 1_500_000 ns) silently passed
7248 // `validate` on every pre-gate codebase, then truncated to
7249 // `as_millis() == 1` on first serialize — the shared codec
7250 // emits `"1ms"`, parses it back to `Duration::from_millis(1)` =
7251 // 1_000_000 ns, the typed `restart_window` no longer matches
7252 // its rendered form.
7253 let s = SupervisorSpec {
7254 restart_window: Some(Duration::from_micros(1500)),
7255 children: vec![child("w", "^0.1", RestartPolicy::Permanent)],
7256 ..SupervisorSpec::default()
7257 };
7258 match s.validate().unwrap_err() {
7259 SupervisorError::RestartWindowNotCanonical { window } => {
7260 assert_eq!(window, Duration::from_micros(1500));
7261 }
7262 other => panic!("expected RestartWindowNotCanonical, got {other:?}"),
7263 }
7264 }
7265
7266 #[test]
7267 fn validate_rejects_one_nanosecond_restart_window() {
7268 // The far-sub-ms case: `Duration::from_nanos(1)` is non-zero
7269 // (so `RestartWindowZero` doesn't fire) but `as_millis() == 0`,
7270 // so the shared codec emits the literal `"0s"` — the next
7271 // serde round-trip would parse back to `Duration::ZERO`, which
7272 // the `RestartWindowZero` arm then rejects on re-validate. The
7273 // canonical-form gate at this layer surfaces a self-locating
7274 // diagnostic naming the offending Duration verbatim rather
7275 // than a downstream `RestartWindowZero` whose remediation
7276 // points at omitting the slot.
7277 let s = SupervisorSpec {
7278 restart_window: Some(Duration::from_nanos(1)),
7279 children: vec![child("w", "^0.1", RestartPolicy::Permanent)],
7280 ..SupervisorSpec::default()
7281 };
7282 match s.validate().unwrap_err() {
7283 SupervisorError::RestartWindowNotCanonical { window } => {
7284 assert_eq!(window, Duration::from_nanos(1));
7285 }
7286 other => panic!("expected RestartWindowNotCanonical, got {other:?}"),
7287 }
7288 }
7289
7290 #[test]
7291 fn validate_rejects_nanosecond_past_canonical_boundary_restart_window() {
7292 // The 1-ns-past-1ms boundary case: a `Duration` carrying
7293 // 1_000_001 ns is structurally past the integer-ms granularity
7294 // floor — `subsec_nanos() % 1_000_000 == 1`. The codec round-
7295 // trip would truncate to `1ms` and the consumer would observe
7296 // a 1-ns drift on every emit. Same boundary the peer
7297 // `validate_rejects_nanosecond_past_canonical_boundary` test
7298 // in limits.rs pins for the `:limits :wall-clock` axis.
7299 let w = Duration::from_nanos(1_000_001);
7300 let s = SupervisorSpec {
7301 restart_window: Some(w),
7302 children: vec![child("w", "^0.1", RestartPolicy::Permanent)],
7303 ..SupervisorSpec::default()
7304 };
7305 assert_eq!(
7306 s.validate().unwrap_err(),
7307 SupervisorError::RestartWindowNotCanonical { window: w }
7308 );
7309 }
7310
7311 #[test]
7312 fn validate_accepts_integer_millisecond_restart_window_values() {
7313 // The positive-control sweep: every `Duration` the shared
7314 // codec can round-trip losslessly — the canonical
7315 // `<integer>{ms,s,m,h}` set the codec's `render` / `parse`
7316 // pair emits and accepts — passes `validate` without
7317 // surfacing the new canonical-form arm. Mirrors
7318 // `validate_accepts_integer_millisecond_wall_clock_values` on
7319 // the sibling `:limits :wall-clock` axis.
7320 for w in [
7321 Duration::from_millis(1),
7322 Duration::from_millis(500),
7323 Duration::from_millis(1500),
7324 Duration::from_secs(1),
7325 Duration::from_secs(30),
7326 Duration::from_secs(60),
7327 Duration::from_secs(120),
7328 Duration::from_secs(3600),
7329 ] {
7330 let s = SupervisorSpec {
7331 restart_window: Some(w),
7332 children: vec![child("w", "^0.1", RestartPolicy::Permanent)],
7333 ..SupervisorSpec::default()
7334 };
7335 s.validate()
7336 .unwrap_or_else(|e| panic!("integer-ms {w:?} must validate, got {e:?}"));
7337 }
7338 }
7339
7340 #[test]
7341 fn validate_restart_window_zero_takes_precedence_over_canonical_gate() {
7342 // Cross-arm ordering pin: `Duration::ZERO` has
7343 // `subsec_nanos() == 0` and would otherwise pass the
7344 // canonical-form arm — the zero-floor arm must fire first so
7345 // the more self-locating `RestartWindowZero` diagnostic (with
7346 // its omit-axis remediation directly named) leads. Same
7347 // posture every peer zero-then-shape gate uses
7348 // (`WallClockZero` → `WallClockNotCanonical`,
7349 // `PolicyTimeoutZero` → `PolicyTimeoutNotCanonical`,
7350 // `PolicyBreakerZeroWindow` → `PolicyBreakerWindowNotCanonical`).
7351 let s = SupervisorSpec {
7352 restart_window: Some(Duration::ZERO),
7353 children: vec![child("w", "^0.1", RestartPolicy::Permanent)],
7354 ..SupervisorSpec::default()
7355 };
7356 assert_eq!(
7357 s.validate().unwrap_err(),
7358 SupervisorError::RestartWindowZero
7359 );
7360 }
7361
7362 #[test]
7363 fn restart_window_canonical_diagnostic_carries_offending_duration() {
7364 // Diagnostic-shape pin: the canonical-form arm names the
7365 // offending `Duration` verbatim so the author's grep lands on
7366 // the field's value, not a generic "duration not canonical"
7367 // message. Same shape every other typed-canonical-form arm
7368 // on this surface carries (`WallClockNotCanonical` carries
7369 // the offending `Duration` verbatim,
7370 // `PolicyTimeoutNotCanonical` carries the offending
7371 // `Duration` verbatim).
7372 let w = Duration::from_micros(500);
7373 let s = SupervisorSpec {
7374 restart_window: Some(w),
7375 children: vec![child("w", "^0.1", RestartPolicy::Permanent)],
7376 ..SupervisorSpec::default()
7377 };
7378 let err = s.validate().unwrap_err();
7379 let msg = err.to_string();
7380 assert!(
7381 msg.contains("500"),
7382 "diagnostic must carry the offending magnitude verbatim (got {msg:?})"
7383 );
7384 assert!(
7385 msg.contains("sub-millisecond"),
7386 "diagnostic must name the sub-millisecond residue class (got {msg:?})"
7387 );
7388 }
7389
7390 #[test]
7391 fn restart_window_validated_value_round_trips_through_codec() {
7392 // The structural property the canonical-ms gate enforces:
7393 // every `SupervisorSpec::restart_window` past
7394 // `SupervisorSpec::validate` round-trips losslessly through
7395 // the shared duration codec (serialize → string →
7396 // deserialize → equal value). Pin this end-to-end so a future
7397 // change to either side (the validate gate's accepted
7398 // granularity, the codec's parse/render unit set) that breaks
7399 // the alignment surfaces here. Peer of
7400 // `wall_clock_validated_value_round_trips_through_codec` on
7401 // the sibling `:limits :wall-clock` axis.
7402 for w in [
7403 Duration::from_millis(1),
7404 Duration::from_millis(1500),
7405 Duration::from_secs(30),
7406 Duration::from_secs(3600),
7407 ] {
7408 let s = SupervisorSpec {
7409 restart_window: Some(w),
7410 children: vec![child("w", "^0.1", RestartPolicy::Permanent)],
7411 ..SupervisorSpec::default()
7412 };
7413 s.validate().unwrap();
7414 let json = serde_json::to_string(&s).unwrap();
7415 let back: SupervisorSpec = serde_json::from_str(&json).unwrap();
7416 assert_eq!(back.restart_window, Some(w));
7417 }
7418 }
7419
7420 // ── value-shape: upper cap on :restart-window ─────────────────────────
7421 //
7422 // The fourth (and last) typed-`Duration` axis in caixa-core to get
7423 // the 1h upper cap — peer with `:limits :wall-clock` (51e0dbd),
7424 // `:politicas :timeout` (2e8ee7e), and `:politicas
7425 // :circuit-breaker :window` (379a814). Brackets the typed
7426 // `:restart-window` axis structurally: every validated value lies
7427 // in `1ms..=SUPERVISOR_RESTART_WINDOW_MAX`, integer-millisecond
7428 // granularity, closing the
7429 // rolling-window-degenerates-to-lifetime-counter footgun the prior
7430 // zero-floor-and-canonical-form-only checks left open.
7431
7432 #[test]
7433 fn validate_rejects_restart_window_above_cap() {
7434 // The fail-before-pass-after pin: 3601s = 1h + 1s is
7435 // structurally one canonical-tick past the
7436 // [`SUPERVISOR_RESTART_WINDOW_MAX`] ceiling (1h = 3600s) — an
7437 // integer-millisecond magnitude the canonical-form arm above
7438 // accepts cleanly, that the shared duration codec round-trips
7439 // losslessly as `"3601s"`, and that silently passed validate on
7440 // every pre-gate codebase because the typed slot's only checks
7441 // were the zero-floor and canonical-form arms. The runtime
7442 // substrate consuming the value (Erlang/OTP's MaxIntensity/
7443 // Period reconciler, the future wasm-operator's per-supervisor
7444 // restart-intensity counter) reaches for a `Duration` so long
7445 // no realistic restart-recovery pattern resets the counter,
7446 // far from the source caixa.lisp.
7447 let w = SUPERVISOR_RESTART_WINDOW_MAX + Duration::from_secs(1);
7448 let s = SupervisorSpec {
7449 restart_window: Some(w),
7450 children: vec![child("w", "^0.1", RestartPolicy::Permanent)],
7451 ..SupervisorSpec::default()
7452 };
7453 assert_eq!(
7454 s.validate().unwrap_err(),
7455 SupervisorError::RestartWindowExceedsCap { window: w }
7456 );
7457 }
7458
7459 #[test]
7460 fn validate_rejects_restart_window_one_millisecond_above_cap() {
7461 // Boundary case: exactly 1ms past the cap (the granularity the
7462 // canonical-form gate enforces). Catches a future "strictly
7463 // less than" half-measure and pins the diagnostic to name the
7464 // offending `Duration` verbatim. Peer of
7465 // `validate_rejects_wall_clock_one_millisecond_above_cap` /
7466 // `rejects_policy_timeout_one_millisecond_above_cap` /
7467 // `rejects_circuit_breaker_window_one_millisecond_above_cap`
7468 // on the sibling typed-`Duration` axes' top edges.
7469 let w = SUPERVISOR_RESTART_WINDOW_MAX + Duration::from_millis(1);
7470 let s = SupervisorSpec {
7471 restart_window: Some(w),
7472 children: vec![child("w", "^0.1", RestartPolicy::Permanent)],
7473 ..SupervisorSpec::default()
7474 };
7475 assert_eq!(
7476 s.validate().unwrap_err(),
7477 SupervisorError::RestartWindowExceedsCap { window: w }
7478 );
7479 }
7480
7481 #[test]
7482 fn validate_rejects_restart_window_far_above_cap() {
7483 // The "obvious authoring footgun" case: a `(:restart-window "24h")`,
7484 // `(:restart-window "7d")`, or any "I want a lifetime counter
7485 // but wrote a `<integer>h` magnitude anyway" typo — values the
7486 // canonical-form arm accepts as integer-millisecond magnitudes,
7487 // the codec round-trips losslessly through serde, but the
7488 // operator's `MaxIntensity / Period` reconciler cannot honor
7489 // as a meaningful rolling window. Until this gate landed
7490 // validate accepted them. Pin the common above-cap values (24h,
7491 // 7d, ~11.5d) so a future relaxation that drops the upper bound
7492 // surfaces here.
7493 for w in [
7494 Duration::from_secs(86_400), // 24h
7495 Duration::from_secs(604_800), // 7d
7496 Duration::from_secs(1_000_000), // ~11.5 days
7497 ] {
7498 let s = SupervisorSpec {
7499 restart_window: Some(w),
7500 children: vec![child("w", "^0.1", RestartPolicy::Permanent)],
7501 ..SupervisorSpec::default()
7502 };
7503 assert_eq!(
7504 s.validate().unwrap_err(),
7505 SupervisorError::RestartWindowExceedsCap { window: w }
7506 );
7507 }
7508 }
7509
7510 #[test]
7511 fn validate_accepts_restart_window_at_cap() {
7512 // The boundary value — exactly [`SUPERVISOR_RESTART_WINDOW_MAX`]
7513 // (1h) — must validate. The cap is inclusive on the top edge,
7514 // matching the [`crate::LIMITS_WALL_CLOCK_MAX`] /
7515 // [`crate::POLICY_TIMEOUT_MAX`] /
7516 // [`crate::POLICY_BREAKER_WINDOW_MAX`] discipline on the sibling
7517 // capped axes. Pin the boundary explicitly so a future
7518 // off-by-one tightening (`>= SUPERVISOR_RESTART_WINDOW_MAX`
7519 // instead of `>`) surfaces here as a test failure rather than a
7520 // silent contract narrowing.
7521 let s = SupervisorSpec {
7522 restart_window: Some(SUPERVISOR_RESTART_WINDOW_MAX),
7523 children: vec![child("w", "^0.1", RestartPolicy::Permanent)],
7524 ..SupervisorSpec::default()
7525 };
7526 s.validate()
7527 .expect("restart_window == SUPERVISOR_RESTART_WINDOW_MAX must validate");
7528 }
7529
7530 #[test]
7531 fn validate_accepts_restart_window_typical_values() {
7532 // The documented Erlang/OTP / Elixir / Riak Core / RabbitMQ
7533 // per-supervisor production-playbook band positive-control
7534 // sweep — every value Learn You Some Erlang's `{intensity, 5,
7535 // 60}` worker-supervisor `Period = 60s` default, Elixir's
7536 // `Supervisor` `max_seconds: 5` default, OTP's `supervisor`
7537 // callback module `MaxT = 5..=60` typical, Riak Core's `MaxT ∈
7538 // 10s..=300s`, and RabbitMQ broker-supervisor `MaxT = 5s`
7539 // default recommend (5s..=300s) must pass, plus a sweep
7540 // through the long-tail-flaky-pool band (5m, 15m, 30m, 1h) the
7541 // cap accepts. Mirrors `validate_accepts_wall_clock_typical_values`
7542 // on the sibling `:limits :wall-clock` axis.
7543 for w in [
7544 Duration::from_millis(1),
7545 Duration::from_millis(500),
7546 Duration::from_secs(1),
7547 Duration::from_secs(5), // RabbitMQ broker-supervisor default
7548 Duration::from_secs(10), // Riak Core lower
7549 Duration::from_secs(30),
7550 Duration::from_secs(60), // Learn You Some Erlang default
7551 Duration::from_secs(120), // OTP supervisor MaxT typical
7552 Duration::from_secs(300), // Riak Core upper
7553 Duration::from_secs(900), // 15m
7554 Duration::from_secs(1800),
7555 Duration::from_secs(3600), // exactly 1h, the cap
7556 ] {
7557 let s = SupervisorSpec {
7558 restart_window: Some(w),
7559 children: vec![child("w", "^0.1", RestartPolicy::Permanent)],
7560 ..SupervisorSpec::default()
7561 };
7562 s.validate()
7563 .unwrap_or_else(|e| panic!("restart_window={w:?} must validate; got {e:?}"));
7564 }
7565 }
7566
7567 #[test]
7568 fn restart_window_zero_takes_precedence_over_cap() {
7569 // The cross-arm ordering pin: `Duration::ZERO` is structurally
7570 // outside both `>= 1ms` (zero-floor) and `<=
7571 // SUPERVISOR_RESTART_WINDOW_MAX` (cap), but the zero-floor
7572 // diagnostic is the more self-locating one (it directly names
7573 // the omit-axis remediation), so the validate gate must fire
7574 // on zero first. Same shape every other zero-then-cap ordering
7575 // on this surface uses (`WallClockZero` then
7576 // `WallClockExceedsCap`, `PolicyTimeoutZero` then
7577 // `PolicyTimeoutExceedsCap`, `PolicyBreakerZeroWindow` then
7578 // `PolicyBreakerWindowExceedsCap`).
7579 let s = SupervisorSpec {
7580 restart_window: Some(Duration::ZERO),
7581 children: vec![child("w", "^0.1", RestartPolicy::Permanent)],
7582 ..SupervisorSpec::default()
7583 };
7584 assert_eq!(
7585 s.validate().unwrap_err(),
7586 SupervisorError::RestartWindowZero,
7587 "Duration::ZERO must surface the zero-floor diagnostic, not the cap diagnostic"
7588 );
7589 }
7590
7591 #[test]
7592 fn restart_window_canonical_takes_precedence_over_cap() {
7593 // The cross-arm ordering pin: a `Duration` that is *both*
7594 // sub-millisecond (non-canonical-form) and structurally above
7595 // the cap surfaces the canonical-form diagnostic first,
7596 // because the round-trip-shape break is the more fundamental
7597 // issue (the value can't even round-trip through the codec,
7598 // so the cap diagnostic naming `1ms..=1h` would be misleading
7599 // — there's no integer-ms form of the offending value). Pin
7600 // the order so a future refactor that reorders the arms
7601 // surfaces here as a test failure rather than a silent
7602 // diagnostic regression. Peer of
7603 // `wall_clock_canonical_takes_precedence_over_cap` /
7604 // `policy_timeout_canonical_takes_precedence_over_cap`.
7605 let w = SUPERVISOR_RESTART_WINDOW_MAX + Duration::from_nanos(1);
7606 let s = SupervisorSpec {
7607 restart_window: Some(w),
7608 children: vec![child("w", "^0.1", RestartPolicy::Permanent)],
7609 ..SupervisorSpec::default()
7610 };
7611 assert_eq!(
7612 s.validate().unwrap_err(),
7613 SupervisorError::RestartWindowNotCanonical { window: w },
7614 "sub-ms above-cap value must surface the canonical-form diagnostic, not the cap diagnostic"
7615 );
7616 }
7617
7618 #[test]
7619 fn max_restarts_cap_takes_precedence_over_restart_window_cap() {
7620 // The cross-arm ordering pin between the `:max-restarts` cap
7621 // and the sibling `:restart-window` cap. A supervisor carrying
7622 // both an over-cap `max_restarts` AND an over-cap window must
7623 // surface the `MaxRestartsExceedsCap` diagnostic first — the
7624 // cap arm is wired immediately after the zero-restart arm and
7625 // strictly before every window-axis arm (zero / canonical /
7626 // cap), so the offending value the diagnostic names matches
7627 // the order the author would discover the gates by reading
7628 // top-to-bottom through `SupervisorSpec::validate`. Pin the
7629 // order so a future refactor that reorders the arms surfaces
7630 // here as a test failure rather than a silent diagnostic
7631 // regression. Peer of
7632 // `max_restarts_cap_takes_precedence_over_restart_window_gates`
7633 // on the sibling zero / canonical window arms.
7634 let w = SUPERVISOR_RESTART_WINDOW_MAX + Duration::from_secs(1);
7635 let s = SupervisorSpec {
7636 max_restarts: SUPERVISOR_MAX_RESTARTS_MAX + 1,
7637 restart_window: Some(w),
7638 children: vec![child("w", "^0.1", RestartPolicy::Permanent)],
7639 ..SupervisorSpec::default()
7640 };
7641 assert_eq!(
7642 s.validate().unwrap_err(),
7643 SupervisorError::MaxRestartsExceedsCap {
7644 max_restarts: SUPERVISOR_MAX_RESTARTS_MAX + 1,
7645 },
7646 "over-cap max_restarts must surface the cap diagnostic before any window-axis diagnostic"
7647 );
7648 }
7649
7650 #[test]
7651 fn restart_window_cap_diagnostic_carries_offending_value() {
7652 // The diagnostic-shape pin: the offending `Duration` is
7653 // carried verbatim into the
7654 // [`SupervisorError::RestartWindowExceedsCap`] variant so the
7655 // surfaced error message names the value the author wrote,
7656 // not just the cap. Same self-locating diagnostic shape every
7657 // other typed-cap arm on this surface carries
7658 // (`WallClockExceedsCap` carries the offending `Duration`
7659 // verbatim, `PolicyTimeoutExceedsCap` carries the offending
7660 // `Duration` verbatim, `PolicyBreakerWindowExceedsCap` carries
7661 // the offending `Duration` verbatim).
7662 let w = Duration::from_secs(7200); // 2h
7663 let s = SupervisorSpec {
7664 restart_window: Some(w),
7665 children: vec![child("w", "^0.1", RestartPolicy::Permanent)],
7666 ..SupervisorSpec::default()
7667 };
7668 let err = s.validate().unwrap_err();
7669 assert!(
7670 matches!(err, SupervisorError::RestartWindowExceedsCap { window } if window == w),
7671 "got {err:?}"
7672 );
7673 let msg = err.to_string();
7674 assert!(
7675 msg.contains("7200"),
7676 ":supervisor :restart-window cap diagnostic must carry the offending value verbatim (got: {msg})"
7677 );
7678 }
7679
7680 #[test]
7681 fn supervisor_restart_window_cap_pins_canonical_value() {
7682 // The SUPERVISOR_RESTART_WINDOW_MAX constant pins the value at
7683 // exactly 1 hour (3600s = 3_600_000ms) — the largest unit the
7684 // shared duration codec emits as a clean canonical string
7685 // (`"<n>h"`). Pinning the literal value here surfaces a future
7686 // drift (a relaxation to 24h, a tightening to 5m) as a
7687 // deliberate test edit, not a silent contract narrowing.
7688 //
7689 // The four typed-`Duration` caps on the validation surface
7690 // (`LIMITS_WALL_CLOCK_MAX` per-process, `POLICY_TIMEOUT_MAX`
7691 // per-edge, `POLICY_BREAKER_WINDOW_MAX` per-breaker,
7692 // `SUPERVISOR_RESTART_WINDOW_MAX` per-supervisor) share a
7693 // single uniform top edge at the codec's largest emitted unit
7694 // — a structural-property invariant the equality assertions
7695 // here enshrine, so a future drift on any of the four
7696 // surfaces as a deliberate test edit. Same shape every other
7697 // typed-cap value pin uses
7698 // (`wall_clock_cap_pins_canonical_value`,
7699 // `policy_timeout_cap_pins_canonical_value`,
7700 // `circuit_breaker_window_cap_pins_canonical_value`).
7701 assert_eq!(SUPERVISOR_RESTART_WINDOW_MAX, Duration::from_secs(3600));
7702 assert_eq!(SUPERVISOR_RESTART_WINDOW_MAX.as_millis(), 3_600_000);
7703 assert_eq!(SUPERVISOR_RESTART_WINDOW_MAX, crate::LIMITS_WALL_CLOCK_MAX);
7704 assert_eq!(SUPERVISOR_RESTART_WINDOW_MAX, crate::POLICY_TIMEOUT_MAX);
7705 assert_eq!(
7706 SUPERVISOR_RESTART_WINDOW_MAX,
7707 crate::POLICY_BREAKER_WINDOW_MAX
7708 );
7709 }
7710
7711 #[test]
7712 fn restart_window_cap_value_round_trips_through_codec() {
7713 // The codec round-trip property the cap arm preserves: the
7714 // [`SUPERVISOR_RESTART_WINDOW_MAX`] constant itself round-trips
7715 // through the shared duration codec — every value at the cap
7716 // serializes to the canonical `"1h"` form and parses back
7717 // identically. Pin the round-trip so a future change to the
7718 // codec's unit set or to the cap's magnitude that breaks the
7719 // round-trip property surfaces here. Peer of
7720 // `wall_clock_cap_value_round_trips_through_codec` on the
7721 // sibling `:limits :wall-clock` axis.
7722 let s = SupervisorSpec {
7723 restart_window: Some(SUPERVISOR_RESTART_WINDOW_MAX),
7724 children: vec![child("w", "^0.1", RestartPolicy::Permanent)],
7725 ..SupervisorSpec::default()
7726 };
7727 s.validate().unwrap();
7728 let json = serde_json::to_string(&s).unwrap();
7729 assert!(
7730 json.contains("\"1h\""),
7731 "SUPERVISOR_RESTART_WINDOW_MAX must serialize to the canonical `\"1h\"` form (got {json})"
7732 );
7733 let back: SupervisorSpec = serde_json::from_str(&json).unwrap();
7734 assert_eq!(back.restart_window, Some(SUPERVISOR_RESTART_WINDOW_MAX));
7735 }
7736
7737 #[test]
7738 fn validate_rejects_duplicate_child_caixa() {
7739 // Two children with the same :caixa render to two ComputeUnits
7740 // with the same name in the cluster's HelmRelease values —
7741 // one silently overwrites the other. Erlang/OTP's child_spec.id
7742 // is required-unique per supervisor; same set-not-multiset
7743 // discipline applied here as for :membros / :placement
7744 // :clusters / :entrada :paths.
7745 let s = SupervisorSpec {
7746 children: vec![
7747 child("worker", "^0.1", RestartPolicy::Permanent),
7748 child("cache", "^0.1", RestartPolicy::Transient),
7749 child("worker", "^0.2", RestartPolicy::Permanent),
7750 ],
7751 ..SupervisorSpec::default()
7752 };
7753 let err = s.validate().unwrap_err();
7754 assert!(
7755 matches!(err, SupervisorError::DuplicateChildCaixa { ref caixa } if caixa == "worker"),
7756 "got {err:?}"
7757 );
7758 }
7759
7760 #[test]
7761 fn validate_duplicate_child_diagnostic_names_first_collision() {
7762 // Iteration walks the :children list in declaration order —
7763 // the diagnostic names the first repeat, deterministically,
7764 // even when multiple names duplicate.
7765 let s = SupervisorSpec {
7766 children: vec![
7767 child("a", "^0.1", RestartPolicy::Permanent),
7768 child("b", "^0.1", RestartPolicy::Permanent),
7769 child("a", "^0.1", RestartPolicy::Permanent),
7770 child("b", "^0.1", RestartPolicy::Permanent),
7771 ],
7772 ..SupervisorSpec::default()
7773 };
7774 let err = s.validate().unwrap_err();
7775 assert!(
7776 matches!(err, SupervisorError::DuplicateChildCaixa { ref caixa } if caixa == "a"),
7777 "got {err:?}"
7778 );
7779 }
7780
7781 // ── self-supervision cross-slot gate ──────────────────────────
7782
7783 #[test]
7784 fn validate_no_self_supervision_rejects_self_referential_child() {
7785 // A supervisor whose `:children` lists its own `:nome` is a
7786 // one-node reconciliation cycle — rejected, naming the parent.
7787 let children = vec![
7788 child("worker", "^0.1", RestartPolicy::Permanent),
7789 child("orquestra", "^0.1", RestartPolicy::Permanent),
7790 ];
7791 let err = validate_no_self_supervision(&children, "orquestra").unwrap_err();
7792 assert!(
7793 matches!(err, SupervisorError::ChildSupervisesSelf { ref caixa } if caixa == "orquestra"),
7794 "got {err:?}"
7795 );
7796 }
7797
7798 #[test]
7799 fn validate_no_self_supervision_accepts_distinct_children() {
7800 // Positive control: distinct child names (including a child that
7801 // is itself a supervisor — nested trees are valid OTP) pass.
7802 let children = vec![
7803 child("worker", "^0.1", RestartPolicy::Permanent),
7804 child("sub-tree", "^0.1", RestartPolicy::Permanent),
7805 ];
7806 validate_no_self_supervision(&children, "orquestra").unwrap();
7807 }
7808
7809 #[test]
7810 fn validate_no_self_supervision_empty_children_is_ok() {
7811 // SimpleOneForOne / no-static-children supervisors have nothing
7812 // to self-reference — the gate is vacuously satisfied.
7813 validate_no_self_supervision(&[], "orquestra").unwrap();
7814 }
7815
7816 #[test]
7817 fn validate_simple_one_for_one_skips_uniqueness_check() {
7818 // SimpleOneForOne supervisors carry no static children — the
7819 // duplicate-child loop never runs. A zero-window declaration
7820 // on a SimpleOneForOne supervisor still trips the window check
7821 // (window applies to dynamic children too).
7822 let s = SupervisorSpec {
7823 estrategia: RestartStrategy::SimpleOneForOne,
7824 restart_window: None,
7825 children: vec![],
7826 ..SupervisorSpec::default()
7827 };
7828 s.validate().unwrap();
7829 let s_zero = SupervisorSpec {
7830 estrategia: RestartStrategy::SimpleOneForOne,
7831 restart_window: Some(Duration::ZERO),
7832 children: vec![],
7833 ..SupervisorSpec::default()
7834 };
7835 assert_eq!(
7836 s_zero.validate().unwrap_err(),
7837 SupervisorError::RestartWindowZero
7838 );
7839 }
7840
7841 #[test]
7842 fn validate_zero_window_runs_after_max_restarts_check() {
7843 // Pin the order: max_restarts == 0 fires before
7844 // restart_window == 0s, so an author with both wrong sees the
7845 // counter-axis diagnostic first (matches the order in the
7846 // struct and in the doc comment).
7847 let s = SupervisorSpec {
7848 max_restarts: 0,
7849 restart_window: Some(Duration::ZERO),
7850 children: vec![child("w", "^0.1", RestartPolicy::Permanent)],
7851 ..SupervisorSpec::default()
7852 };
7853 assert_eq!(s.validate().unwrap_err(), SupervisorError::ZeroMaxRestarts);
7854 }
7855
7856 #[test]
7857 fn round_trip_all_strategies() {
7858 for &strat in RestartStrategy::ALL {
7859 // Route the `SimpleOneForOne ↔ non-SimpleOneForOne` fixture-
7860 // shape partition through the [`gen_platform::IsVariant`]
7861 // derive-generated [`RestartStrategy::is_simple_one_for_one`]
7862 // predicate rather than the raw
7863 // `matches!(strat, RestartStrategy::SimpleOneForOne)`
7864 // open-coded pattern-match — same closed-set-typed-enum
7865 // arm-discriminator dispatch discipline the sibling
7866 // [`crate::upgrade::UpgradeInstruction::is_restart`] convergence
7867 // (915a934) extended onto its two paired positive / negated
7868 // `matches!` filter sites, and the sibling
7869 // [`crate::aplicacao::PlacementStrategy`] `IsVariant`-derived
7870 // predicate convergence (766ec63) extended onto the M3 mesh-
7871 // slot per-`:placement` distribution-strategy `matches!`
7872 // discriminator axis. See the sibling
7873 // `supervisor_spec_estrategia_returns_estrategia_verbatim_across_permutations`
7874 // fixture and the peer `manifest::tests::
7875 // caixa_estrategia_and_supervisor_view_reads_through_lifted_estrategia_accessor`
7876 // fixture — all three sites (the last unlifted
7877 // `matches!`-based arm-discriminator axis on the OTP-shape
7878 // supervisor sibling-restart-strategy closed-set typed enum,
7879 // acknowledged in 915a934's Prior-commits footnote as the
7880 // outstanding follow-up) now consult one typed dispatch on
7881 // the substrate primitive.
7882 let s = SupervisorSpec {
7883 estrategia: strat,
7884 children: if strat.is_simple_one_for_one() {
7885 vec![]
7886 } else {
7887 vec![child("w", "^0.1", RestartPolicy::Permanent)]
7888 },
7889 ..SupervisorSpec::default()
7890 };
7891 let json = serde_json::to_string(&s).unwrap();
7892 let back: SupervisorSpec = serde_json::from_str(&json).unwrap();
7893 assert_eq!(s, back);
7894 }
7895 }
7896
7897 #[test]
7898 fn round_trip_all_restart_policies() {
7899 for policy in [
7900 RestartPolicy::Permanent,
7901 RestartPolicy::Temporary,
7902 RestartPolicy::Transient,
7903 ] {
7904 let c = child("w", "^0.1", policy);
7905 let json = serde_json::to_string(&c).unwrap();
7906 let back: ChildSpec = serde_json::from_str(&json).unwrap();
7907 assert_eq!(c, back);
7908 }
7909 }
7910
7911 #[test]
7912 fn restart_strategy_is_simple_one_for_one_predicate_partitions_the_arm_set() {
7913 // The fail-before-pass-after pin on the `gen_platform::IsVariant`
7914 // derive's [`RestartStrategy::is_simple_one_for_one`] arm-
7915 // discriminator predicate: [`RestartStrategy::SimpleOneForOne`]
7916 // is the only variant that satisfies `.is_simple_one_for_one()`;
7917 // every static-children-bearing arm (`OneForOne` / `OneForAll`
7918 // / `RestForOne`) returns `false`. This pin makes the partition
7919 // invariant load-bearing at caixa-core test time so a future
7920 // derive regression (a hole that returns `false` for
7921 // `SimpleOneForOne` too, or a byte-collision that flips a second
7922 // variant to `true`) trips here rather than laundering the arm
7923 // at the three test-fixture builder sites (a hole flips the
7924 // `SimpleOneForOne` fixture to carry a non-empty children list
7925 // and the subsequent `SupervisorSpec::validate` would refuse the
7926 // fixture with [`SupervisorError::SimpleOneForOneWithStaticChildren`];
7927 // a collision flips a peer strategy's fixture to carry an empty
7928 // children list and the subsequent `validate` would refuse with
7929 // [`SupervisorError::NoChildren`] — either way, the pin fires
7930 // here, at the derive site, rather than at the fixture-refusal
7931 // site far away). Peer of the sibling
7932 // [`crate::upgrade::tests::upgrade_instruction_is_restart_predicate_partitions_the_arm_set`]
7933 // (915a934) pin on the M2 OTP-appup axis and the sibling
7934 // [`crate::kind::tests::caixa_kind_is_variant_predicates_partition_the_arm_set`]
7935 // pin on the M0 `:kind` axis.
7936 let cases: &[(RestartStrategy, bool)] = &[
7937 (RestartStrategy::OneForOne, false),
7938 (RestartStrategy::OneForAll, false),
7939 (RestartStrategy::RestForOne, false),
7940 (RestartStrategy::SimpleOneForOne, true),
7941 ];
7942 for (variant, expected) in cases {
7943 assert_eq!(
7944 variant.is_simple_one_for_one(),
7945 *expected,
7946 "RestartStrategy::{variant:?}.is_simple_one_for_one() must \
7947 return {expected} (partition invariant on the \
7948 IsVariant-derived arm-discriminator predicate — every \
7949 test-fixture site that partitions the `:children` slot \
7950 shape on `SimpleOneForOne ↔ non-SimpleOneForOne` keys \
7951 off this typed dispatch, so a derive regression must \
7952 surface here rather than at the fixture-refusal site)"
7953 );
7954 }
7955 }
7956
7957 #[test]
7958 fn restart_strategy_fixture_partition_routes_through_is_simple_one_for_one_predicate() {
7959 // Byte-identity pin on the `SimpleOneForOne ↔ non-SimpleOneForOne`
7960 // fixture-shape partition against the pre-lift
7961 // `matches!(strat, RestartStrategy::SimpleOneForOne)` open-coded
7962 // pattern-match every test-fixture builder site previously
7963 // coupled to inline. Asserts the two projections agree byte-for-
7964 // byte on every arm of the enum, so a future derive regression
7965 // that flipped either predicate's arm-set would surface here at
7966 // caixa-core test time rather than at the three fixture-builder
7967 // sites (`supervisor::tests::round_trip_all_strategies`,
7968 // `supervisor::tests::supervisor_spec_estrategia_returns_estrategia_verbatim_across_permutations`,
7969 // `manifest::tests::caixa_estrategia_and_supervisor_view_reads_through_lifted_estrategia_accessor`)
7970 // far from the derive site. Same peer-shape byte-identity pin
7971 // every sibling `IsVariant`-derive-routed convergence carries on
7972 // the substrate's closed-set typed-enum surface (peer of
7973 // [`crate::upgrade::tests::validate_restart_exclusive_routes_through_is_restart_predicate`]
7974 // on the M2 OTP-appup axis).
7975 for &strat in RestartStrategy::ALL {
7976 let via_predicate = strat.is_simple_one_for_one();
7977 let via_matches = matches!(strat, RestartStrategy::SimpleOneForOne);
7978 assert_eq!(
7979 via_predicate, via_matches,
7980 "RestartStrategy::{strat:?}: is_simple_one_for_one() must \
7981 byte-equal matches!(_, RestartStrategy::SimpleOneForOne) — \
7982 the pre-lift open-coded pattern and the \
7983 IsVariant-derived predicate are the same axis, \
7984 one typed dispatch"
7985 );
7986 }
7987 }
7988
7989 #[test]
7990 fn duration_codec_round_trip_canonical_units() {
7991 // Note the canonical-form rule: durations serialize to the
7992 // *largest* unit that divides cleanly, so 60s ↔ "1m" and not
7993 // "60s" — but the round-trip preserves the underlying Duration.
7994 let cases = [
7995 ("30s", Duration::from_secs(30)),
7996 ("5m", Duration::from_secs(300)),
7997 ("1h", Duration::from_secs(3600)),
7998 ("500ms", Duration::from_millis(500)),
7999 ];
8000 for (lit, dur) in cases {
8001 let s = SupervisorSpec {
8002 children: vec![child("w", "^0.1", RestartPolicy::Permanent)],
8003 restart_window: Some(dur),
8004 ..SupervisorSpec::default()
8005 };
8006 let json = serde_json::to_string(&s).unwrap();
8007 assert!(
8008 json.contains(&format!("\"{lit}\"")),
8009 "expected \"{lit}\" in {json}"
8010 );
8011 let back: SupervisorSpec = serde_json::from_str(&json).unwrap();
8012 assert_eq!(back.restart_window, Some(dur));
8013 }
8014 }
8015
8016 #[test]
8017 fn duration_canonicalizes_to_largest_unit() {
8018 // 60 seconds → "1m" (largest cleanly-divisible unit), but the
8019 // typed Duration still equals 60s on the way back.
8020 let s = SupervisorSpec {
8021 children: vec![child("w", "^0.1", RestartPolicy::Permanent)],
8022 restart_window: Some(Duration::from_secs(60)),
8023 ..SupervisorSpec::default()
8024 };
8025 let json = serde_json::to_string(&s).unwrap();
8026 assert!(json.contains("\"1m\""), "{json}");
8027 let back: SupervisorSpec = serde_json::from_str(&json).unwrap();
8028 assert_eq!(back.restart_window, Some(Duration::from_secs(60)));
8029 }
8030
8031 #[test]
8032 fn three_child_one_for_one_validates() {
8033 let s = SupervisorSpec {
8034 estrategia: RestartStrategy::OneForOne,
8035 max_restarts: 5,
8036 restart_window: Some(Duration::from_secs(60)),
8037 children: vec![
8038 child("worker", "^0.1", RestartPolicy::Permanent),
8039 child("cache", "^0.1", RestartPolicy::Transient),
8040 child("scratch", "^0.1", RestartPolicy::Temporary),
8041 ],
8042 };
8043 s.validate().unwrap();
8044 }
8045
8046 #[test]
8047 fn json_uses_pascal_case_for_strategy_and_policy() {
8048 // Variant names are PascalCase by default in serde, matching
8049 // tatara-lisp's enum convention (`:estrategia OneForOne`).
8050 let c = child("w", "^0.1", RestartPolicy::Permanent);
8051 let json = serde_json::to_string(&c).unwrap();
8052 assert!(json.contains("\"Permanent\""));
8053 assert!(!json.contains("\"permanent\""));
8054
8055 let s = SupervisorSpec {
8056 estrategia: RestartStrategy::OneForOne,
8057 children: vec![c],
8058 ..SupervisorSpec::default()
8059 };
8060 let json = serde_json::to_string(&s).unwrap();
8061 assert!(json.contains("\"estrategia\":\"OneForOne\""));
8062 }
8063
8064 // ── shared duration codec: integer-magnitude canonical-form gate ──
8065 //
8066 // The gate lifts the discipline `crate::limits::parse_duration`
8067 // (818dd38) carries on the peer `:limits :wall-clock` codec onto
8068 // the shared codec backing the remaining three typed-duration
8069 // slots: `:supervisor :restart-window`, `:politicas :timeout`, and
8070 // `:politicas :circuit-breaker :window`. Every magnitude `render`
8071 // emits is a non-negative integer with no decimal point and no
8072 // leading sign, so the codec's accepted set must match for
8073 // serialize/deserialize to round-trip without canonical-form
8074 // drift.
8075
8076 #[test]
8077 fn parse_accepts_integer_canonical_units() {
8078 // Pin the happy-path: every canonical author shape `render`
8079 // ever emits parses to the same `Duration` value, so the
8080 // codec's accepted set is at least a superset of its emitted
8081 // set on the canonical-unit axis.
8082 for (lit, dur) in [
8083 ("30s", Duration::from_secs(30)),
8084 ("500ms", Duration::from_millis(500)),
8085 ("2m", Duration::from_secs(120)),
8086 ("1h", Duration::from_secs(3600)),
8087 ("0s", Duration::ZERO),
8088 ] {
8089 assert_eq!(
8090 duration_codec::parse(lit).unwrap(),
8091 dur,
8092 "parse({lit:?}) should be {dur:?}"
8093 );
8094 }
8095 }
8096
8097 #[test]
8098 fn parse_accepts_bare_integer_as_seconds() {
8099 // The `"s" | ""` arm: a bare integer with no unit is read as
8100 // seconds. Pin this so the unit-empty form keeps parsing (it
8101 // renders to `"<n>s"` on serialize — that's a unit-choice
8102 // drift the integer-magnitude gate does NOT close, matching
8103 // the `parse_byte_size` `"1024"` → `"1KiB"` scope decision in
8104 // the peer `:limits :memory` codec).
8105 assert_eq!(
8106 duration_codec::parse("30").unwrap(),
8107 Duration::from_secs(30)
8108 );
8109 }
8110
8111 #[test]
8112 fn parse_rejects_fractional_seconds_with_canonical_form_diagnostic() {
8113 // `"1.5s"` parses as f64 to 1.5 → renders back as `"1500ms"`
8114 // on first serialize — DRIFT. The integer-magnitude gate names
8115 // the offending `"1.5"` verbatim and points at the canonical
8116 // remediation `"1500ms"`.
8117 let err = duration_codec::parse("1.5s").unwrap_err();
8118 assert!(err.contains("\"1.5\""), "missing magnitude in {err:?}");
8119 assert!(
8120 err.contains("not a non-negative integer"),
8121 "missing canonical-form reason in {err:?}"
8122 );
8123 assert!(
8124 err.contains("\"1500ms\""),
8125 "missing canonical-form remediation in {err:?}"
8126 );
8127 }
8128
8129 #[test]
8130 fn parse_rejects_decimal_shaped_integer_seconds() {
8131 // `"1.0s"` is the trickiest drift class: numerically `1.0s` is
8132 // `1s` exactly, so the round-trip looks correct — but the
8133 // emitted canonical form is `"1s"`, not `"1.0s"`. Gate the
8134 // decimal-shape-with-integer-value form so author intent is
8135 // never silently rewritten.
8136 let err = duration_codec::parse("1.0s").unwrap_err();
8137 assert!(err.contains("\"1.0\""), "missing magnitude in {err:?}");
8138 assert!(
8139 err.contains("not a non-negative integer"),
8140 "missing canonical-form reason in {err:?}"
8141 );
8142 }
8143
8144 #[test]
8145 fn parse_rejects_half_unit_minute() {
8146 // `"0.5m"` is the unit-fraction footgun — author writes a
8147 // human-readable half-minute, serde silently rewrites to
8148 // `"30s"` on next emit. The gate names the offending
8149 // magnitude `"0.5"` and points at the integer-in-smaller-unit
8150 // form.
8151 let err = duration_codec::parse("0.5m").unwrap_err();
8152 assert!(err.contains("\"0.5\""), "missing magnitude in {err:?}");
8153 assert!(
8154 err.contains("\"30s\""),
8155 "missing canonical-form remediation in {err:?}"
8156 );
8157 }
8158
8159 #[test]
8160 fn parse_rejects_leading_plus_sign() {
8161 // `u64::from_str` rejects `"+30"` but `f64::from_str` accepts
8162 // it as `30.0` — the prior parser used f64 so `"+30s"` parsed
8163 // cleanly to 30s and round-tripped to `"30s"` on next emit
8164 // (DRIFT). The digit-only gate closes the leading-sign class
8165 // first; the diagnostic names `"+30"` verbatim.
8166 let err = duration_codec::parse("+30s").unwrap_err();
8167 assert!(err.contains("\"+30\""), "missing magnitude in {err:?}");
8168 assert!(
8169 err.contains("not a non-negative integer"),
8170 "missing canonical-form reason in {err:?}"
8171 );
8172 }
8173
8174 #[test]
8175 fn parse_rejects_leading_minus_sign() {
8176 // The former `num < 0.0` arm: `"-30s"` parsed as f64 to -30,
8177 // rejected with `"negative duration in \"-30s\""`. Under the
8178 // integer-magnitude gate the diagnostic is unified — `-30` is
8179 // non-digit-only, f64-numeric, and surfaces with the canonical-
8180 // form reason (no leading `+` / `-` sign) naming the offending
8181 // `"-30"` verbatim. Same diagnostic shape as every other
8182 // rejected non-integer magnitude.
8183 let err = duration_codec::parse("-30s").unwrap_err();
8184 assert!(err.contains("\"-30\""), "missing magnitude in {err:?}");
8185 assert!(
8186 err.contains("not a non-negative integer"),
8187 "missing canonical-form reason in {err:?}"
8188 );
8189 }
8190
8191 #[test]
8192 fn parse_garbage_still_falls_through_to_bad_magnitude() {
8193 // Non-digit-only AND non-numeric (`"--1s"`, `"abc"`) falls
8194 // through to the narrower "bad duration magnitude" arm — the
8195 // canonical-form diagnostic is reserved for the parser-shape
8196 // footgun case, not the "not a number at all" case. Same
8197 // shape `parse_byte_size`'s `BadByteMagnitude` arm carries on
8198 // the peer `:limits :memory` codec.
8199 let err = duration_codec::parse("--1s").unwrap_err();
8200 assert!(
8201 err.contains("bad duration magnitude"),
8202 "expected bad-magnitude wording in {err:?}"
8203 );
8204 }
8205
8206 #[test]
8207 fn parse_digit_only_magnitude_carries_zero_f64_drift() {
8208 // The accepted set is now closed under `u64`-exact integer
8209 // arithmetic: `"500ms"` → `Duration::from_millis(500)` exactly,
8210 // `"3600s"` → `Duration::from_secs(3600)` exactly, `"1h"` →
8211 // `Duration::from_secs(3600)` exactly, no f64 mantissa drift
8212 // possible. Pin the integer-exact arms across the four unit
8213 // suffixes so a future refactor that reaches back for f64
8214 // (`from_secs_f64`, `mul_f64`) surfaces here.
8215 assert_eq!(
8216 duration_codec::parse("3600s").unwrap(),
8217 Duration::from_secs(3600)
8218 );
8219 assert_eq!(
8220 duration_codec::parse("60m").unwrap(),
8221 Duration::from_secs(3600)
8222 );
8223 assert_eq!(
8224 duration_codec::parse("1h").unwrap(),
8225 Duration::from_secs(3600)
8226 );
8227 assert_eq!(
8228 duration_codec::parse("999ms").unwrap(),
8229 Duration::from_millis(999)
8230 );
8231 }
8232
8233 #[test]
8234 fn restart_window_serde_rejects_fractional_seconds() {
8235 // The shared codec backs `SupervisorSpec::restart_window`
8236 // (`with = "duration_codec"`) — so the gate applies on serde
8237 // deserialize for the typed Supervisor slot. A
8238 // `{"restartWindow":"1.5s"}` payload that previously round-
8239 // tripped to a different canonical string on next serialize
8240 // is now refused at deserialize with the integer-magnitude
8241 // diagnostic.
8242 let payload = r#"{"estrategia":"OneForOne","maxRestarts":5,
8243 "restartWindow":"1.5s",
8244 "children":[{"caixa":"w","versao":"^0.1","restart":"Permanent"}]}"#;
8245 let err = serde_json::from_str::<SupervisorSpec>(payload).unwrap_err();
8246 let msg = err.to_string();
8247 assert!(
8248 msg.contains("not a non-negative integer"),
8249 "expected integer-magnitude diagnostic in {msg:?}"
8250 );
8251 assert!(msg.contains("\"1.5\""), "missing magnitude in {msg:?}");
8252 }
8253
8254 #[test]
8255 fn restart_window_serde_rejects_leading_plus() {
8256 // The `u64::from_str` leading-`+` permissiveness gap that
8257 // motivated the digit-only gate (the `f64`-side accepted
8258 // `"+30"`, the prior parser silently round-tripped to `"30s"`)
8259 // is now closed on the shared codec — surfaces as a structured
8260 // diagnostic at the serde layer for every typed-duration slot.
8261 let payload = r#"{"estrategia":"OneForOne","maxRestarts":5,
8262 "restartWindow":"+30s",
8263 "children":[{"caixa":"w","versao":"^0.1","restart":"Permanent"}]}"#;
8264 let err = serde_json::from_str::<SupervisorSpec>(payload).unwrap_err();
8265 let msg = err.to_string();
8266 assert!(msg.contains("\"+30\""), "missing magnitude in {msg:?}");
8267 assert!(
8268 msg.contains("not a non-negative integer"),
8269 "missing canonical-form reason in {msg:?}"
8270 );
8271 }
8272
8273 #[test]
8274 fn parse_rejects_leading_zero_magnitude() {
8275 // `"030s"` is digit-only, so the existing non-digit-only / sign
8276 // / fractional arm doesn't catch it — `u64::from_str("030")`
8277 // returns `Ok(30)`, so before this gate `"030s"` parsed to
8278 // `Duration::from_secs(30)` and round-tripped through `render`
8279 // to `"30s"` — a *different* canonical string on the next emit,
8280 // breaking the THEORY.md Part V render-determinism contract
8281 // exactly the way `"+30s"` did before the leading-`+` arm
8282 // landed. Peer with the `rate_limit_codec` leading-zero arm
8283 // (4f46830) on the same canonical-form-drift axis.
8284 let err = duration_codec::parse("030s").unwrap_err();
8285 assert!(
8286 err.contains("non-canonical leading zero"),
8287 "expected leading-zero diagnostic in {err:?}"
8288 );
8289 assert!(err.contains("\"030\""), "missing magnitude in {err:?}");
8290 assert!(
8291 err.contains("\"30s\""),
8292 "missing canonical-form remediation in {err:?}"
8293 );
8294 assert!(
8295 err.contains("THEORY.md"),
8296 "missing render-determinism citation in {err:?}"
8297 );
8298 }
8299
8300 #[test]
8301 fn parse_rejects_multi_digit_zero_magnitude() {
8302 // `"00s"` and `"00ms"` are the all-zero leading-zero footgun —
8303 // digit-only, parse losslessly to `Duration::ZERO`, but render
8304 // back to `"0s"` (the single-byte canonical form) on the next
8305 // emit. The leading-zero arm refuses the drift class at the
8306 // codec layer; the semantic-zero gate downstream
8307 // (`SupervisorError::ZeroRestartWindow`, etc.) would refuse
8308 // the single-byte canonical form `"0s"` separately on the
8309 // typed-validate layer.
8310 let err = duration_codec::parse("00s").unwrap_err();
8311 assert!(
8312 err.contains("non-canonical leading zero"),
8313 "expected leading-zero diagnostic in {err:?}"
8314 );
8315 assert!(err.contains("\"00\""), "missing magnitude in {err:?}");
8316 }
8317
8318 #[test]
8319 fn parse_rejects_leading_zero_per_hour_window() {
8320 // `"01h"` is the per-hour-window footgun — multi-byte magnitude
8321 // starting with `0`, parses losslessly to `Duration::from_secs(3600)`,
8322 // renders to `"1h"` (DRIFT). The arm is unit-agnostic: every
8323 // canonical unit suffix the codec accepts (`ms` / `s` / `m` /
8324 // `h` / bare-integer-as-seconds) inherits the same gate.
8325 let err = duration_codec::parse("01h").unwrap_err();
8326 assert!(
8327 err.contains("non-canonical leading zero"),
8328 "expected leading-zero diagnostic in {err:?}"
8329 );
8330 assert!(err.contains("\"01\""), "missing magnitude in {err:?}");
8331 }
8332
8333 #[test]
8334 fn parse_rejects_leading_zero_bare_integer_as_seconds() {
8335 // The `parse_accepts_bare_integer_as_seconds` happy-path
8336 // (`"30"` → 30s) inherits the leading-zero arm: `"030"` is
8337 // multi-byte starts-with-`0`, parses losslessly to
8338 // `Duration::from_secs(30)`, renders to `"30s"` (DRIFT). The
8339 // bare-integer surface accepts permissive unit-empty
8340 // shorthand but still must reject leading-zero padding.
8341 let err = duration_codec::parse("030").unwrap_err();
8342 assert!(
8343 err.contains("non-canonical leading zero"),
8344 "expected leading-zero diagnostic in {err:?}"
8345 );
8346 assert!(err.contains("\"030\""), "missing magnitude in {err:?}");
8347 }
8348
8349 #[test]
8350 fn parse_accepts_single_zero_magnitude_at_codec_layer() {
8351 // The codec-layer / typed-validate-layer boundary: `"0s"` /
8352 // `"0ms"` / `"0"` are the single-byte canonical-zero forms —
8353 // each round-trips losslessly through `render`
8354 // (`render(Duration::ZERO)` → `"0s"`), so the codec layer
8355 // accepts them. The downstream semantic-zero gates
8356 // (`SupervisorError::ZeroRestartWindow`,
8357 // `AplicacaoError::PolicyTimeoutZero`,
8358 // `AplicacaoError::PolicyCircuitBreakerWindowZero`) refuse
8359 // zero-magnitude authoring at the typed-validate layer above,
8360 // peer with the `rate_limit_codec` codec-layer / typed-
8361 // validate-layer partition for `"0/s"`.
8362 assert_eq!(duration_codec::parse("0s").unwrap(), Duration::ZERO);
8363 assert_eq!(duration_codec::parse("0ms").unwrap(), Duration::ZERO);
8364 assert_eq!(duration_codec::parse("0").unwrap(), Duration::ZERO);
8365 }
8366
8367 #[test]
8368 fn parse_accepts_canonical_magnitude_with_leading_one() {
8369 // The complementary boundary: a future tightening cannot
8370 // drift into rejecting valid canonical magnitudes that
8371 // happen to start with `1` (or any digit `[1-9]`). Pin
8372 // every canonical-unit suffix so the leading-zero arm
8373 // remains strictly narrower than the digit-only arm.
8374 assert_eq!(
8375 duration_codec::parse("100ms").unwrap(),
8376 Duration::from_millis(100)
8377 );
8378 assert_eq!(
8379 duration_codec::parse("100s").unwrap(),
8380 Duration::from_secs(100)
8381 );
8382 assert_eq!(
8383 duration_codec::parse("10m").unwrap(),
8384 Duration::from_secs(600)
8385 );
8386 assert_eq!(
8387 duration_codec::parse("10h").unwrap(),
8388 Duration::from_secs(36_000)
8389 );
8390 }
8391
8392 #[test]
8393 fn restart_window_serde_rejects_leading_zero() {
8394 // The shared codec backs `SupervisorSpec::restart_window`
8395 // (`with = "duration_codec"`) — so the leading-zero arm
8396 // applies on serde deserialize for the typed Supervisor slot.
8397 // A `{"restartWindow":"030s"}` payload that previously round-
8398 // tripped to a different canonical string on next serialize
8399 // is now refused at deserialize with the leading-zero
8400 // diagnostic. Peer with `restart_window_serde_rejects_leading_plus`
8401 // / `restart_window_serde_rejects_fractional_seconds` on the
8402 // same canonical-form-drift axis.
8403 let payload = r#"{"estrategia":"OneForOne","maxRestarts":5,
8404 "restartWindow":"030s",
8405 "children":[{"caixa":"w","versao":"^0.1","restart":"Permanent"}]}"#;
8406 let err = serde_json::from_str::<SupervisorSpec>(payload).unwrap_err();
8407 let msg = err.to_string();
8408 assert!(
8409 msg.contains("non-canonical leading zero"),
8410 "expected leading-zero diagnostic in {msg:?}"
8411 );
8412 assert!(msg.contains("\"030\""), "missing magnitude in {msg:?}");
8413 }
8414
8415 #[test]
8416 fn parse_rejects_leading_whitespace() {
8417 // `" 30s"` — the canonical paste-from-aligned-doc /
8418 // paste-from-YAML-quoted-plain-scalar footgun. Before this
8419 // gate the top-level `s.trim()` at parse entry silently ate
8420 // the leading space and parsed the value to
8421 // `Duration::from_secs(30)`, which then round-tripped through
8422 // `render` to `"30s"` (a *different* canonical string on the
8423 // next emit) — the exact canonical-form-drift class the
8424 // leading-`+` / leading-zero arms already close, extended
8425 // to the whitespace-byte class. Peer with the sibling
8426 // `rate_limit_codec` whitespace-rejection arm (1ad7755) on
8427 // the M3 `:politicas` axis.
8428 let err = duration_codec::parse(" 30s").unwrap_err();
8429 assert!(
8430 err.contains("contains whitespace byte"),
8431 "expected whitespace diagnostic in {err:?}"
8432 );
8433 assert!(err.contains("0x20"), "missing offending byte in {err:?}");
8434 assert!(
8435 err.contains("THEORY.md"),
8436 "missing render-determinism contract citation in {err:?}"
8437 );
8438 }
8439
8440 #[test]
8441 fn parse_rejects_trailing_whitespace() {
8442 // `"30s "` — the canonical shell-history / trailing-space
8443 // paste footgun. Before this gate the top-level `s.trim()`
8444 // silently ate the trailing space and parsed to
8445 // `Duration::from_secs(30)`, round-tripping to `"30s"` on the
8446 // next emit — same canonical-form drift as the leading-space
8447 // sibling, closed on the same whitespace-byte arm.
8448 let err = duration_codec::parse("30s ").unwrap_err();
8449 assert!(
8450 err.contains("contains whitespace byte"),
8451 "expected whitespace diagnostic in {err:?}"
8452 );
8453 assert!(err.contains("0x20"), "missing offending byte in {err:?}");
8454 }
8455
8456 #[test]
8457 fn parse_rejects_internal_whitespace_between_magnitude_and_unit() {
8458 // `"30 s"` — the canonical typographically-spaced author
8459 // shape (the same idiom every prose reference to a duration
8460 // renders as, mistakenly retained when the value is pasted
8461 // into a codec-shaped slot). Before this gate the per-part
8462 // `num_part.trim()` / `unit.trim()` calls silently ate the
8463 // whitespace between the magnitude and the unit and parsed
8464 // the value to `Duration::from_secs(30)`, round-tripping to
8465 // `"30s"` — the codec's *internal* whitespace-tolerance
8466 // vector, orthogonal to the leading / trailing surface but
8467 // the same canonical-form-drift class. Pins the arm as
8468 // strictly stronger than the pre-existing top-level
8469 // `s.trim()` behavior: it fires on whitespace anywhere in
8470 // the value, not just at the string boundary.
8471 let err = duration_codec::parse("30 s").unwrap_err();
8472 assert!(
8473 err.contains("contains whitespace byte"),
8474 "expected whitespace diagnostic in {err:?}"
8475 );
8476 assert!(err.contains("0x20"), "missing offending byte in {err:?}");
8477 }
8478
8479 #[test]
8480 fn parse_rejects_tab_byte() {
8481 // `"\t30s"` — the canonical paste-from-indented-doc /
8482 // paste-from-YAML-block-scalar footgun where a tab byte leads
8483 // the magnitude. Pins that the gate covers tab (`0x09`) as
8484 // well as space (`0x20`) — both are `u8::is_ascii_whitespace`
8485 // members and both would be silently swallowed by `s.trim()`
8486 // pre-gate. The `is_ascii_whitespace` coverage extends beyond
8487 // space alone to the full ASCII-whitespace set (space `0x20`,
8488 // tab `0x09`, LF `0x0A`, FF `0x0C`, CR `0x0D`); this test pins
8489 // the tab arm as a representative of the non-space members.
8490 let err = duration_codec::parse("\t30s").unwrap_err();
8491 assert!(
8492 err.contains("contains whitespace byte"),
8493 "expected whitespace diagnostic in {err:?}"
8494 );
8495 assert!(
8496 err.contains("0x09"),
8497 "missing offending tab byte in {err:?}"
8498 );
8499 }
8500
8501 #[test]
8502 fn restart_window_serde_rejects_whitespace() {
8503 // The shared codec backs `SupervisorSpec::restart_window`
8504 // (`with = "duration_codec"`) — so the whitespace arm
8505 // applies on serde deserialize for the typed Supervisor slot.
8506 // A `{"restartWindow":" 30s"}` payload that previously round-
8507 // tripped to a different canonical string on next serialize
8508 // is now refused at deserialize with the whitespace-byte
8509 // diagnostic. Peer with `restart_window_serde_rejects_leading_zero`
8510 // / `restart_window_serde_rejects_leading_plus` /
8511 // `restart_window_serde_rejects_fractional_seconds` on the
8512 // same canonical-form-drift axis.
8513 let payload = r#"{"estrategia":"OneForOne","maxRestarts":5,
8514 "restartWindow":" 30s",
8515 "children":[{"caixa":"w","versao":"^0.1","restart":"Permanent"}]}"#;
8516 let err = serde_json::from_str::<SupervisorSpec>(payload).unwrap_err();
8517 let msg = err.to_string();
8518 assert!(
8519 msg.contains("contains whitespace byte"),
8520 "expected whitespace diagnostic in {msg:?}"
8521 );
8522 assert!(msg.contains("0x20"), "missing offending byte in {msg:?}");
8523 }
8524
8525 // ── canonical-form: non-ASCII Unicode `White_Space` duration gate ─────
8526 //
8527 // Successor to the ASCII-whitespace arm (a7ae622) on the shared
8528 // duration codec — closes the strictly-complementary class the
8529 // byte-scan cannot see, through the lifted
8530 // [`crate::render::find_non_ascii_whitespace_char`] predicate.
8531 // Applies to `:supervisor :restart-window`, `:politicas :timeout`,
8532 // and `:politicas :circuit-breaker :window` simultaneously via
8533 // this shared codec.
8534
8535 #[test]
8536 fn duration_codec_parse_rejects_leading_nbsp() {
8537 // NBSP prefix — the strictly-complementary drift class the
8538 // ASCII byte-scan cannot see. `str::trim` strips it silently
8539 // and the value drifts to `"30s"` on next serialize.
8540 let err = duration_codec::parse("\u{00A0}30s").unwrap_err();
8541 assert!(
8542 err.contains("non-ASCII Unicode whitespace character"),
8543 "expected non-ASCII whitespace diagnostic in {err:?}"
8544 );
8545 assert!(err.contains("U+00A0"), "missing codepoint in {err:?}");
8546 }
8547
8548 #[test]
8549 fn duration_codec_parse_rejects_trailing_line_separator() {
8550 // LINE SEPARATOR (`\u{2028}`) trailing — paste-from-web-doc
8551 // footgun.
8552 let err = duration_codec::parse("30s\u{2028}").unwrap_err();
8553 assert!(
8554 err.contains("non-ASCII Unicode whitespace character"),
8555 "expected non-ASCII whitespace diagnostic in {err:?}"
8556 );
8557 assert!(err.contains("U+2028"), "missing codepoint in {err:?}");
8558 }
8559
8560 #[test]
8561 fn duration_codec_parse_accepts_ascii_only_forms_after_unicode_arm() {
8562 // Positive-control pin: every ASCII-only canonical form the
8563 // renderer emits stays accepted through the new arm.
8564 assert_eq!(
8565 duration_codec::parse("30s").unwrap(),
8566 Duration::from_secs(30)
8567 );
8568 assert_eq!(
8569 duration_codec::parse("500ms").unwrap(),
8570 Duration::from_millis(500)
8571 );
8572 assert_eq!(
8573 duration_codec::parse("1h").unwrap(),
8574 Duration::from_secs(3600)
8575 );
8576 }
8577
8578 #[test]
8579 fn restart_window_serde_rejects_non_ascii_whitespace() {
8580 // The shared codec backs `SupervisorSpec::restart_window` — so
8581 // the new non-ASCII Unicode whitespace arm applies on serde
8582 // deserialize for the typed Supervisor slot. A
8583 // `{"restartWindow":" 30s"}` payload that previously
8584 // survived the ASCII byte-scan (only ASCII whitespace was
8585 // refused) is now refused at deserialize with the
8586 // non-ASCII-whitespace-and-codepoint diagnostic.
8587 let payload = "{\"estrategia\":\"OneForOne\",\"maxRestarts\":5,\
8588 \"restartWindow\":\"\u{00A0}30s\",\
8589 \"children\":[{\"caixa\":\"w\",\"versao\":\"^0.1\",\"restart\":\"Permanent\"}]}";
8590 let err = serde_json::from_str::<SupervisorSpec>(payload).unwrap_err();
8591 let msg = err.to_string();
8592 assert!(
8593 msg.contains("non-ASCII Unicode whitespace character"),
8594 "expected non-ASCII whitespace diagnostic in {msg:?}"
8595 );
8596 assert!(msg.contains("U+00A0"), "missing codepoint in {msg:?}");
8597 }
8598
8599 // ── drift-detection: serde-derive-to-SUPERVISOR_KEY_* identity ────────
8600
8601 #[test]
8602 fn supervisor_spec_serde_keys_match_lifted_supervisor_key_consts() {
8603 // Load-bearing invariant: the four `SUPERVISOR_KEY_*` consts
8604 // (`SUPERVISOR_KEY_ESTRATEGIA` / `SUPERVISOR_KEY_MAX_RESTARTS` /
8605 // `SUPERVISOR_KEY_RESTART_WINDOW` / `SUPERVISOR_KEY_CHILDREN`)
8606 // name the exact camelCase JSON keys the
8607 // `#[serde(rename_all = "camelCase")]` attribute on
8608 // `SupervisorSpec` emits. Serialize a fully-populated spec (each
8609 // field carries `Some(_)` / non-empty) and pin that each canonical
8610 // byte-sequence appears verbatim in the JSON — a future accidental
8611 // `rename_all = "snake_case"` / `"kebab-case"` / verbatim-field-
8612 // name flip at the derive attribute (any of which would silently
8613 // break every downstream JSON consumer that reaches for one of the
8614 // four consts via `Value::get(...)`) surfaces here as a build-time
8615 // test failure at `supervisor.rs`, not as an apply-time
8616 // `.get(<stale-canonical-const>)` returning `None` far from the
8617 // derive-attr drift's commit. Peer with the sibling
8618 // `limits_spec_serde_keys_match_lifted_m2_limits_key_consts`
8619 // (d8b8b4f) pin on the M2 `:limits` axis — same discipline the
8620 // M2 typed-slot family established, extended here to close the
8621 // top-level Supervisor axis.
8622 let spec = SupervisorSpec {
8623 estrategia: RestartStrategy::OneForOne,
8624 max_restarts: 5,
8625 restart_window: Some(Duration::from_secs(60)),
8626 children: vec![ChildSpec {
8627 caixa: "w".into(),
8628 versao: "^0.1".into(),
8629 restart: RestartPolicy::Permanent,
8630 }],
8631 };
8632 let json = serde_json::to_string(&spec).unwrap();
8633 for key in [
8634 crate::render::SUPERVISOR_KEY_ESTRATEGIA,
8635 crate::render::SUPERVISOR_KEY_MAX_RESTARTS,
8636 crate::render::SUPERVISOR_KEY_RESTART_WINDOW,
8637 crate::render::SUPERVISOR_KEY_CHILDREN,
8638 ] {
8639 let quoted = format!("\"{key}\"");
8640 assert!(
8641 json.contains("ed),
8642 "serialized SupervisorSpec must carry the lifted \
8643 SUPERVISOR_KEY_* byte-sequence {quoted} verbatim in \
8644 the JSON emission (got: {json})",
8645 );
8646 }
8647 }
8648
8649 #[test]
8650 fn supervisor_key_consts_are_pairwise_distinct() {
8651 // Cross-axis drift-detection pin: a future collapse of two
8652 // canonical top-level byte-strings onto the same value (e.g. an
8653 // accidental copy-paste flip of `SUPERVISOR_KEY_CHILDREN` to
8654 // also read `"estrategia"`) would silently reroute every
8655 // downstream probe on one axis onto the sibling axis's overlay
8656 // entry and pass every propagation-probe test that expected only
8657 // the stale axis's value. Peer of the sibling four-way distinct
8658 // pin on the `M2_LIMITS_KEY_*` tetrad (d8b8b4f).
8659 let all = [
8660 crate::render::SUPERVISOR_KEY_ESTRATEGIA,
8661 crate::render::SUPERVISOR_KEY_MAX_RESTARTS,
8662 crate::render::SUPERVISOR_KEY_RESTART_WINDOW,
8663 crate::render::SUPERVISOR_KEY_CHILDREN,
8664 ];
8665 for (i, a) in all.iter().enumerate() {
8666 for b in all.iter().skip(i + 1) {
8667 assert_ne!(
8668 a, b,
8669 "SUPERVISOR_KEY_* consts must be pairwise-distinct \
8670 canonical byte-sequences — got `{a}` == `{b}`",
8671 );
8672 }
8673 }
8674 }
8675
8676 #[test]
8677 fn supervisor_key_consts_are_lower_camel_case_shape() {
8678 // Shape-pin: every `SUPERVISOR_KEY_*` const must be a
8679 // lowerCamelCase byte-sequence (no `snake_case` underscores, no
8680 // `kebab-case` hyphens, no leading colon, no `PascalCase` leading
8681 // capital, no whitespace / dots) — the canonical shape the
8682 // `#[serde(rename_all = "camelCase")]` derive produces on
8683 // `SupervisorSpec`. A future flip to a non-camelCase attribute
8684 // at the derive surfaces both here (this test fails on the
8685 // stale-constant shape) and at
8686 // `supervisor_spec_serde_keys_match_lifted_supervisor_key_consts`
8687 // (that test fails on the mismatch between const and derive).
8688 // Peer with `m2_limits_key_consts_are_lower_camel_case_shape`
8689 // (d8b8b4f) on the sibling M2 `:limits` axis.
8690 for key in [
8691 crate::render::SUPERVISOR_KEY_ESTRATEGIA,
8692 crate::render::SUPERVISOR_KEY_MAX_RESTARTS,
8693 crate::render::SUPERVISOR_KEY_RESTART_WINDOW,
8694 crate::render::SUPERVISOR_KEY_CHILDREN,
8695 ] {
8696 assert!(
8697 !key.is_empty(),
8698 "SUPERVISOR_KEY_* must be non-empty (got {key:?})"
8699 );
8700 let first = key.chars().next().unwrap();
8701 assert!(
8702 first.is_ascii_lowercase(),
8703 "SUPERVISOR_KEY_* must lead with an ASCII-lowercase byte \
8704 (got {key:?}, leads with {first:?})",
8705 );
8706 assert!(
8707 key.chars().all(|c| c.is_ascii_alphanumeric()),
8708 "SUPERVISOR_KEY_* must be ASCII-alphanumeric only \
8709 — no `_` / `-` / `:` / `.` / whitespace (got {key:?})",
8710 );
8711 }
8712 }
8713
8714 #[test]
8715 fn supervisor_key_consts_are_byte_distinct_from_supervisor_author_key_peers() {
8716 // Cross-axis drift pin: the four `SUPERVISOR_KEY_*` consts
8717 // (camelCase JSON keys, no leading colon) must never collide
8718 // byte-for-byte with the four peer `SUPERVISOR_AUTHOR_KEY_*`
8719 // consts (kebab-case author-facing labels with leading colon)
8720 // that sit next to them at `caixa_core::render`. Both families
8721 // cover the same four typed Supervisor slots on two distinct
8722 // axes (author-side kebab vs renderer-side camelCase);
8723 // collapsing either family onto the other's byte-shape would
8724 // silently reroute the render-side probe onto the author-facing
8725 // surface, or vice versa. Peer of the byte-distinctness
8726 // discipline the `M3_PLACEMENT_KEY_ESTRATEGIA` docstring names
8727 // against the peer `M3_AUTHOR_KEY_PLACEMENT`.
8728 let pairs = [
8729 (
8730 crate::render::SUPERVISOR_KEY_ESTRATEGIA,
8731 crate::render::SUPERVISOR_AUTHOR_KEY_ESTRATEGIA,
8732 ),
8733 (
8734 crate::render::SUPERVISOR_KEY_MAX_RESTARTS,
8735 crate::render::SUPERVISOR_AUTHOR_KEY_MAX_RESTARTS,
8736 ),
8737 (
8738 crate::render::SUPERVISOR_KEY_RESTART_WINDOW,
8739 crate::render::SUPERVISOR_AUTHOR_KEY_RESTART_WINDOW,
8740 ),
8741 (
8742 crate::render::SUPERVISOR_KEY_CHILDREN,
8743 crate::render::SUPERVISOR_AUTHOR_KEY_CHILDREN,
8744 ),
8745 ];
8746 for (json_key, author_key) in pairs {
8747 assert_ne!(
8748 json_key, author_key,
8749 "SUPERVISOR_KEY_* (JSON side) must differ byte-for-byte \
8750 from the peer SUPERVISOR_AUTHOR_KEY_* (author side); \
8751 got JSON `{json_key}` == author `{author_key}`",
8752 );
8753 }
8754 }
8755
8756 // ── drift-detection: serde-derive-to-SUPERVISOR_CHILD_KEY_* identity ──
8757
8758 #[test]
8759 fn child_spec_serde_keys_match_lifted_supervisor_child_key_consts() {
8760 // Load-bearing invariant: the three `SUPERVISOR_CHILD_KEY_*` consts
8761 // (`SUPERVISOR_CHILD_KEY_CAIXA` / `SUPERVISOR_CHILD_KEY_VERSAO` /
8762 // `SUPERVISOR_CHILD_KEY_RESTART`) name the exact camelCase JSON
8763 // keys the `#[serde(rename_all = "camelCase")]` attribute on
8764 // `ChildSpec` emits. Serialize a fully-populated `ChildSpec` and
8765 // pin that each canonical byte-sequence appears verbatim in the
8766 // JSON — a future accidental `rename_all = "snake_case"` /
8767 // `"kebab-case"` / verbatim-field-name flip at the derive
8768 // attribute (any of which would silently break every downstream
8769 // JSON consumer that reaches for one of the three consts via
8770 // `Value::get(...)`) surfaces here as a build-time test failure at
8771 // `supervisor.rs`, not as an apply-time
8772 // `.get(<stale-canonical-const>)` returning `None` far from the
8773 // derive-attr drift's commit. Peer with the enclosing
8774 // `supervisor_spec_serde_keys_match_lifted_supervisor_key_consts`
8775 // (40cc4e5) pin on the M2 supervision-tree top-level axis — same
8776 // discipline the SupervisorSpec top-level lift established,
8777 // extended here to the sibling per-`:children` entry `ChildSpec`
8778 // derive so the last M2 typed-struct sub-block
8779 // `#[serde(rename_all = "camelCase")]` axis on the Supervisor
8780 // surface without a lifted serde-key peer joins the substrate's
8781 // "one canonical byte-string per typed serialized-key axis"
8782 // discipline.
8783 let c = ChildSpec {
8784 caixa: "worker".into(),
8785 versao: "^0.1".into(),
8786 restart: RestartPolicy::Permanent,
8787 };
8788 let json = serde_json::to_string(&c).unwrap();
8789 for key in [
8790 crate::render::SUPERVISOR_CHILD_KEY_CAIXA,
8791 crate::render::SUPERVISOR_CHILD_KEY_VERSAO,
8792 crate::render::SUPERVISOR_CHILD_KEY_RESTART,
8793 ] {
8794 let quoted = format!("\"{key}\"");
8795 assert!(
8796 json.contains("ed),
8797 "serialized ChildSpec must carry the lifted \
8798 SUPERVISOR_CHILD_KEY_* byte-sequence {quoted} verbatim \
8799 in the JSON emission (got: {json})",
8800 );
8801 }
8802 }
8803
8804 #[test]
8805 fn supervisor_child_key_consts_are_pairwise_distinct() {
8806 // Cross-axis drift-detection pin: a future collapse of two
8807 // canonical `ChildSpec` per-entry byte-strings onto the same
8808 // value (e.g. an accidental copy-paste flip of
8809 // `SUPERVISOR_CHILD_KEY_RESTART` to also read `"caixa"`) would
8810 // silently reroute every downstream probe on one axis onto the
8811 // sibling axis's overlay entry and pass every propagation-probe
8812 // test that expected only the stale axis's value. Peer of the
8813 // sibling three-way distinct pin on the `CONTRATO_KEY_*` triad
8814 // (ca463a4) and the two-way distinct pin on the `MEMBRO_KEY_*`
8815 // pair (ce80ca0).
8816 let all = [
8817 crate::render::SUPERVISOR_CHILD_KEY_CAIXA,
8818 crate::render::SUPERVISOR_CHILD_KEY_VERSAO,
8819 crate::render::SUPERVISOR_CHILD_KEY_RESTART,
8820 ];
8821 for (i, a) in all.iter().enumerate() {
8822 for b in all.iter().skip(i + 1) {
8823 assert_ne!(
8824 a, b,
8825 "SUPERVISOR_CHILD_KEY_* consts must be pairwise-\
8826 distinct canonical byte-sequences — got `{a}` == `{b}`",
8827 );
8828 }
8829 }
8830 }
8831
8832 #[test]
8833 fn supervisor_child_key_consts_are_lower_camel_case_shape() {
8834 // Shape-pin: every `SUPERVISOR_CHILD_KEY_*` const must be a
8835 // lowerCamelCase byte-sequence (no `snake_case` underscores, no
8836 // `kebab-case` hyphens, no leading colon, no `PascalCase` leading
8837 // capital, no whitespace / dots) — the canonical shape the
8838 // `#[serde(rename_all = "camelCase")]` derive produces on
8839 // `ChildSpec`. A future flip to a non-camelCase attribute at the
8840 // derive surfaces both here (this test fails on the
8841 // stale-constant shape) and at
8842 // `child_spec_serde_keys_match_lifted_supervisor_child_key_consts`
8843 // (that test fails on the mismatch between const and derive).
8844 // Peer with `supervisor_key_consts_are_lower_camel_case_shape`
8845 // (40cc4e5) on the sibling `SupervisorSpec` top-level axis.
8846 for key in [
8847 crate::render::SUPERVISOR_CHILD_KEY_CAIXA,
8848 crate::render::SUPERVISOR_CHILD_KEY_VERSAO,
8849 crate::render::SUPERVISOR_CHILD_KEY_RESTART,
8850 ] {
8851 assert!(
8852 !key.is_empty(),
8853 "SUPERVISOR_CHILD_KEY_* must be non-empty (got {key:?})"
8854 );
8855 let first = key.chars().next().unwrap();
8856 assert!(
8857 first.is_ascii_lowercase(),
8858 "SUPERVISOR_CHILD_KEY_* must lead with an ASCII-lowercase \
8859 byte (got {key:?}, leads with {first:?})",
8860 );
8861 assert!(
8862 key.chars().all(|c| c.is_ascii_alphanumeric()),
8863 "SUPERVISOR_CHILD_KEY_* must be ASCII-alphanumeric only \
8864 — no `_` / `-` / `:` / `.` / whitespace (got {key:?})",
8865 );
8866 }
8867 }
8868
8869 // ── drift-detection: serde-derive-to-SUPERVISOR_ESTRATEGIA_* identity ────
8870
8871 #[test]
8872 fn restart_strategy_variants_serialize_to_lifted_scalar_values() {
8873 // The fail-before-pass-after pin: pre-lift there was no
8874 // single-source binding between the [`RestartStrategy`] variant
8875 // name the un-`rename`d `Serialize` derive emits under
8876 // [`crate::render::SUPERVISOR_KEY_ESTRATEGIA`] and the byte-string
8877 // every downstream cluster-side dispatcher (the future
8878 // wasm-operator's per-supervisor sibling-restart branch, the
8879 // future M4 `mesh.pleme.io/v1alpha1/Supervisor` CR materializer's
8880 // admission-time enum-arm bind, the `caixa-operator`'s
8881 // hierarchical reconciliation scheduler's per-strategy fan-out)
8882 // probes verbatim. A future `#[serde(rename_all = "kebab-case")]`
8883 // attribute on the enum — or a per-variant `#[serde(rename = "…")]`
8884 // override, or a variant rename in the source — would silently
8885 // rebrand the emitted scalar under one spelling while every
8886 // downstream dispatcher still probed the other, with the failure
8887 // surfacing at the operator's reconcile posture (subtrees coming
8888 // up under the `default()` `OneForOne` arm rather than the typed
8889 // slot's declared strategy — a bad child would then only take
8890 // itself down instead of the sibling set the author intended, so
8891 // shared-state children fall out of sync) far from the source
8892 // rebrand commit and with no field naming the drift. Pinning the
8893 // two paths (the `Serialize` derive's serialized string AND the
8894 // [`RestartStrategy::as_str`] helper) to the same four lifted
8895 // [`crate::render::SUPERVISOR_ESTRATEGIA_ONE_FOR_ONE`] /
8896 // [`crate::render::SUPERVISOR_ESTRATEGIA_ONE_FOR_ALL`] /
8897 // [`crate::render::SUPERVISOR_ESTRATEGIA_REST_FOR_ONE`] /
8898 // [`crate::render::SUPERVISOR_ESTRATEGIA_SIMPLE_ONE_FOR_ONE`]
8899 // byte-strings makes any future drift on either endpoint fail
8900 // here at caixa-core build time. Peer of the M3
8901 // `placement_strategy_variants_serialize_to_lifted_scalar_values`
8902 // (3f0e21c) on the sibling `PlacementStrategy` axis — same
8903 // three-path-convergence discipline, extended to close the
8904 // OTP-shaped per-supervisor sibling-restart axis.
8905 for (variant, expected) in [
8906 (
8907 RestartStrategy::OneForOne,
8908 crate::render::SUPERVISOR_ESTRATEGIA_ONE_FOR_ONE,
8909 ),
8910 (
8911 RestartStrategy::OneForAll,
8912 crate::render::SUPERVISOR_ESTRATEGIA_ONE_FOR_ALL,
8913 ),
8914 (
8915 RestartStrategy::RestForOne,
8916 crate::render::SUPERVISOR_ESTRATEGIA_REST_FOR_ONE,
8917 ),
8918 (
8919 RestartStrategy::SimpleOneForOne,
8920 crate::render::SUPERVISOR_ESTRATEGIA_SIMPLE_ONE_FOR_ONE,
8921 ),
8922 ] {
8923 let json = serde_json::to_string(&variant).unwrap();
8924 assert_eq!(
8925 json,
8926 format!("\"{expected}\""),
8927 "RestartStrategy::{variant:?} must serialize to {expected:?}"
8928 );
8929 assert_eq!(
8930 variant.as_str(),
8931 expected,
8932 "RestartStrategy::{variant:?}.as_str() must return the lifted \
8933 SUPERVISOR_ESTRATEGIA_* constant"
8934 );
8935 }
8936 }
8937
8938 #[test]
8939 fn supervisor_estrategia_consts_are_pairwise_distinct() {
8940 // Cross-arm drift-detection pin: a future collapse of two
8941 // canonical variant byte-strings onto the same value (e.g. an
8942 // accidental copy-paste flip of `SUPERVISOR_ESTRATEGIA_REST_FOR_ONE`
8943 // to also read `"OneForOne"`) would silently reroute every
8944 // downstream operator's per-strategy dispatch onto the sibling
8945 // arm's reconcile branch and pass every propagation-probe test
8946 // that expected only the stale arm's value — the mis-strategied
8947 // subtree would come up with the wrong sibling-restart posture
8948 // on every subsequent failure. Peer of the sibling four-way
8949 // distinct pin `supervisor_key_consts_are_pairwise_distinct`
8950 // (40cc4e5) on the top-level `SUPERVISOR_KEY_*` axis.
8951 let all = [
8952 crate::render::SUPERVISOR_ESTRATEGIA_ONE_FOR_ONE,
8953 crate::render::SUPERVISOR_ESTRATEGIA_ONE_FOR_ALL,
8954 crate::render::SUPERVISOR_ESTRATEGIA_REST_FOR_ONE,
8955 crate::render::SUPERVISOR_ESTRATEGIA_SIMPLE_ONE_FOR_ONE,
8956 ];
8957 for (i, a) in all.iter().enumerate() {
8958 for (j, b) in all.iter().enumerate() {
8959 if i != j {
8960 assert_ne!(
8961 a, b,
8962 "SUPERVISOR_ESTRATEGIA_* consts must be pairwise distinct \
8963 — got duplicate {a:?} at indices {i} and {j}",
8964 );
8965 }
8966 }
8967 }
8968 }
8969
8970 #[test]
8971 fn restart_strategy_display_routes_through_as_str_helper() {
8972 // The fail-before-pass-after pin on the first half of the
8973 // three-path convergence: pre-convergence the sibling
8974 // OTP-shape typed enum [`RestartStrategy`] carried a
8975 // [`std::fmt::Display`] surface via its
8976 // `#[discriminant(also_display)]` gen-platform derive route,
8977 // which arrived kebab-case as `"one-for-one"` /
8978 // `"one-for-all"` / `"rest-for-one"` /
8979 // `"simple-one-for-one"` while the wire format ran as
8980 // PascalCase `"OneForOne"` / `"OneForAll"` / `"RestForOne"` /
8981 // `"SimpleOneForOne"` through the un-`rename`d serde derive.
8982 // Every consumer reaching for a strategy byte-string past the
8983 // wire format had to pick between three paths
8984 // ([`RestartStrategy::as_str`], the `Serialize` derive's
8985 // serialized string, or `format!("{v}")` on the
8986 // discriminant-Display route), any two of which a future
8987 // variant rename or `#[serde(rename_all = "kebab-case")]`
8988 // attribute would silently desynchronize. Wiring
8989 // [`std::fmt::Display`] through [`RestartStrategy::as_str`]
8990 // closes the third path: every `format!("{v}")` call reaches
8991 // the same lifted [`crate::render::SUPERVISOR_ESTRATEGIA_*`]
8992 // const the wire format and the [`RestartStrategy::as_str`]
8993 // helper already route through, so a future variant rename
8994 // lands at exactly one place. Pin the routing here so a future
8995 // `impl std::fmt::Display for RestartStrategy`
8996 // reimplementation that hand-rolls the arms instead of
8997 // delegating to [`RestartStrategy::as_str`] fails at
8998 // caixa-core build time. Peer of the M3
8999 // `placement_strategy_display_routes_through_as_str_helper`
9000 // (cc8f749) which the M3 axis converged first.
9001 for &variant in RestartStrategy::ALL {
9002 assert_eq!(
9003 variant.to_string(),
9004 variant.as_str(),
9005 "RestartStrategy::{variant:?} Display must route through \
9006 RestartStrategy::as_str (single source of truth: the lifted \
9007 SUPERVISOR_ESTRATEGIA_* const the wire format also emits)"
9008 );
9009 }
9010 }
9011
9012 #[test]
9013 fn restart_strategy_display_matches_serialized_wire_byte_string() {
9014 // The fail-before-pass-after pin on the second half of the
9015 // three-path convergence: `Display` (user-facing text) agrees
9016 // byte-for-byte with the `Serialize` derive's wire format
9017 // (canonical camelCase-schema `SUPERVISOR_KEY_ESTRATEGIA`
9018 // scalar) on every variant. Pre-convergence the two paths
9019 // were structurally independent — a future
9020 // `#[serde(rename_all = "kebab-case")]` attribute on the
9021 // enum would silently rebrand the emitted wire scalar
9022 // (`one-for-one`, `one-for-all`, `rest-for-one`,
9023 // `simple-one-for-one`) while every consumer that
9024 // pretty-prints the strategy (the future wasm-operator's
9025 // per-supervisor sibling-restart-strategy diagnostic line,
9026 // the future `feira app graph` per-supervisor strategy line,
9027 // the future M4 `mesh.pleme.io/v1alpha1/Supervisor` CR
9028 // materializer's admission-webhook rejection body) would
9029 // still emit the PascalCase form the `as_str` / `Display`
9030 // route returns, with the mismatch surfacing at consumer
9031 // parse time / operator dispatch time far from the source
9032 // rebrand commit. Pin the two paths byte-for-byte here so any
9033 // future serde-attribute or variant-rename drift is a
9034 // caixa-core-build-time test failure at this call, not a
9035 // silent per-consumer dispatch miss. Peer of the M3
9036 // `placement_strategy_display_matches_serialized_wire_byte_string`
9037 // (cc8f749) which the M3 axis converged first.
9038 for &variant in RestartStrategy::ALL {
9039 let wire = serde_json::to_string(&variant).unwrap();
9040 let unquoted = wire
9041 .strip_prefix('"')
9042 .and_then(|s| s.strip_suffix('"'))
9043 .expect("serialized RestartStrategy is a JSON string");
9044 assert_eq!(
9045 variant.to_string(),
9046 unquoted,
9047 "RestartStrategy::{variant:?} Display byte-string must match the \
9048 Serialize derive's wire byte-string (three-path convergence: \
9049 Display + as_str + Serialize all resolve to the same \
9050 SUPERVISOR_ESTRATEGIA_* const)"
9051 );
9052 }
9053 }
9054
9055 #[test]
9056 fn restart_strategy_as_ref_str_routes_through_as_str_accessor() {
9057 // Fail-before-pass-after byte-parity pin on the lifted
9058 // `impl AsRef<str> for RestartStrategy` — asserts the
9059 // standard-library trait impl and the substrate-primitive
9060 // [`RestartStrategy::as_str`] `pub const fn` accessor resolve
9061 // to the same `&str` per instance across the four-arm
9062 // closed set, so any future silent detour that routes the
9063 // impl through a divergent projection (a per-arm inline
9064 // `match self { RestartStrategy::OneForOne => "OneForOne", … }`
9065 // re-inlining that opens a compile-time link to the un-lifted
9066 // arm-literal, a swap onto the kebab-case
9067 // [`gen_platform::Discriminant`] catalog identity that would
9068 // collide the wire axis with the dispatcher-catalog axis) trips
9069 // at caixa-core test time under `PartialEq` rather than at a
9070 // downstream `impl AsRef<str>`-bound consumer's silent split.
9071 // Sweeps every one of the four arms
9072 // [`RestartStrategy::ALL`] carries so no arm's projection is
9073 // covered only by the sibling wire-format `Serialize` derive
9074 // path. Peer of the sibling
9075 // [`crate::version::tests::caixa_version_as_ref_str_routes_through_as_str_accessor`]
9076 // (16d5c7e) `AsRef<str>`-byte-parity pin on the paired
9077 // top-level `:versao` typed newtype — the two pins together
9078 // cover the substrate primitive's `AsRef<str>` projection axis
9079 // on the paired newtype + closed-set-typed-enum surface.
9080 for &variant in RestartStrategy::ALL {
9081 assert_eq!(
9082 <RestartStrategy as AsRef<str>>::as_ref(&variant),
9083 variant.as_str(),
9084 "AsRef<str> impl on RestartStrategy::{variant:?} must \
9085 byte-equal RestartStrategy::as_str on the same instance \
9086 — divergence signals a silent detour off the substrate-\
9087 primitive accessor"
9088 );
9089 }
9090 }
9091
9092 #[test]
9093 fn restart_strategy_as_ref_str_routes_through_display_via_shared_accessor() {
9094 // Fail-before-pass-after byte-parity pin on the three-path
9095 // convergence discipline the M2 sibling-restart primitive now
9096 // carries on the `&str`-projection axis:
9097 // `<RestartStrategy as AsRef<str>>::as_ref(&s)` (the newly
9098 // lifted impl), `format!("{s}")` (the pre-existing
9099 // [`fmt::Display`] impl), and `s.as_str()` (the substrate-
9100 // primitive `pub const fn` accessor both trait impls delegate
9101 // through) must resolve to the same byte-string on every
9102 // instance across the four-arm closed set. Refuses any future
9103 // divergence between the two trait impls (a stray
9104 // [`fmt::Display::fmt`] rewrite that hand-rolls the arms
9105 // rather than delegating through the shared accessor; a
9106 // hypothetical `AsRef<str>` rewrite that inlines a per-arm
9107 // literal cascade) that would silently split the two
9108 // projection paths of the same closed-set typed enum. Mirrors
9109 // the sibling three-path-convergence discipline the peer
9110 // [`crate::CaixaVersion`] typed newtype carries on its
9111 // `AsRef<str>` / `Display` / `as_str` triple
9112 // (version.rs pin
9113 // `caixa_version_as_ref_str_routes_through_display_via_shared_accessor`,
9114 // 16d5c7e).
9115 for &variant in RestartStrategy::ALL {
9116 let via_as_ref: &str = <RestartStrategy as AsRef<str>>::as_ref(&variant);
9117 let via_display: String = format!("{variant}");
9118 let via_accessor: &str = variant.as_str();
9119 assert_eq!(via_as_ref, via_accessor);
9120 assert_eq!(via_display, via_accessor);
9121 assert_eq!(via_as_ref, via_display.as_str());
9122 }
9123 }
9124
9125 #[test]
9126 fn restart_strategy_all_enumerates_every_variant_exactly_once() {
9127 // Fail-before-pass-after pin on the [`RestartStrategy::ALL`]
9128 // exhaustive-iteration surface: every variant appears exactly
9129 // once, and the slice length matches the arm count of the
9130 // closed set. Every consumer that walks the accepted-strategy
9131 // set (a future `feira supervisor --estrategia …` CLI-side
9132 // arg-parse's "did you mean" hint, a future M4 admission-
9133 // webhook's rejection body naming the accepted-`:estrategia`
9134 // list, the [`RestartStrategy::from_wire`] reverse-projection
9135 // consumers that iterate the accept-set for diagnostic
9136 // rendering) reads through this slice, so a future arm addition
9137 // that grows the enum but forgets to grow [`Self::ALL`]
9138 // silently truncates every downstream consumer's accept-set at
9139 // the same pre-addition boundary — this pin fails at caixa-core
9140 // build time on the pairwise-distinct + arm-count invariants.
9141 //
9142 // Peer of the sibling [`crate::CaixaKind::ALL`] (6b1f4fb) /
9143 // [`crate::aplicacao::PlacementStrategy::ALL`] (18c7342) /
9144 // [`crate::aplicacao::RateLimitUnit::ALL`] (6bce03d) /
9145 // [`crate::dep::DepList::ALL`] (45ee563) exhaustive-iteration
9146 // pins on the peer closed-set typed-enum axes.
9147 let all: &[RestartStrategy] = RestartStrategy::ALL;
9148 assert_eq!(
9149 all.len(),
9150 4,
9151 "RestartStrategy::ALL must enumerate every variant of the \
9152 four-arm closed set (OneForOne, OneForAll, RestForOne, \
9153 SimpleOneForOne); got {all:?}"
9154 );
9155 for (i, a) in all.iter().enumerate() {
9156 for (j, b) in all.iter().enumerate() {
9157 if i != j {
9158 assert_ne!(
9159 a, b,
9160 "RestartStrategy::ALL must carry every variant exactly \
9161 once — got duplicate {a:?} at indices {i} and {j}"
9162 );
9163 }
9164 }
9165 }
9166 for variant in [
9167 RestartStrategy::OneForOne,
9168 RestartStrategy::OneForAll,
9169 RestartStrategy::RestForOne,
9170 RestartStrategy::SimpleOneForOne,
9171 ] {
9172 assert!(
9173 all.contains(&variant),
9174 "RestartStrategy::ALL must contain {variant:?} — a future arm \
9175 addition that grows the enum but forgets to grow the ALL slice \
9176 silently truncates every downstream consumer's accept-set at \
9177 the pre-addition boundary"
9178 );
9179 }
9180 }
9181
9182 #[test]
9183 fn restart_strategy_wire_names_covers_every_arm() {
9184 // Load-bearing pin on the substrate-canonical
9185 // [`RestartStrategy::WIRE_NAMES`] exhaustive accept-set roster
9186 // on the `PascalCase` wire byte-string axis: every variant of
9187 // the sibling [`RestartStrategy::ALL`] exhaustive-iteration
9188 // surface must project through [`RestartStrategy::as_str`] onto
9189 // an entry the [`RestartStrategy::WIRE_NAMES`] roster carries,
9190 // and the roster's length must byte-equal
9191 // `RestartStrategy::ALL.len()` so a silent skew between the
9192 // [`RestartStrategy::as_str`] match's arm-set and the roster's
9193 // arm-set trips here at caixa-core test time rather than at a
9194 // downstream M4 `mesh.pleme.io/v1alpha1/Supervisor` CR
9195 // admission-webhook rejection body's wire-form `:estrategia`
9196 // accepted-set enumeration miss / a `feira supervisor
9197 // --estrategia …` "did you mean" hint drift / a future
9198 // wasm-operator per-reconcile-step diagnostic log line's
9199 // accepted-wire-form enumeration miss. A future arm addition
9200 // (an OTP-`rest_for_all` arm the theory
9201 // [`ABSORPTION-ROADMAP`](https://github.com/pleme-io/theory/blob/main/ABSORPTION-ROADMAP.md)
9202 // might reach for once the four canonical OTP strategies stop
9203 // covering the substrate's discovered load-shape) extends
9204 // [`RestartStrategy::ALL`] as a single edit and this pin
9205 // sweeps the new arm by iteration; the paired
9206 // [`RestartStrategy::WIRE_NAMES`] roster must grow in lockstep
9207 // or this assertion trips. Every entry is further pinned to
9208 // open with an ASCII uppercase byte so a silent collapse of
9209 // the wire-form axis with the peer kebab-case
9210 // dispatcher-catalog axis (an entry byte-identical to a
9211 // sibling [`Self::discriminant`] kebab byte-string that would
9212 // let a wire-axis consumer accept the dispatcher-catalog
9213 // vocabulary) trips here rather than at a downstream K8s-CR
9214 // round-trip miss.
9215 //
9216 // Peer of the sibling
9217 // [`crate::kind::tests::caixa_kind_wire_names_covers_every_arm`]
9218 // (bd708bd) pin on the top-level typed-kind discriminator's
9219 // `PascalCase` wire byte-string axis, and of the sibling
9220 // [`crate::upgrade::tests::upgrade_instruction_wire_forms_covers_every_arm`]
9221 // (cc42c0e) /
9222 // [`crate::upgrade::tests::upgrade_instruction_lisp_forms_covers_every_arm`]
9223 // (1898d77) pins on the OTP-appup discriminator's two-axis
9224 // roster split — the same closed-set exhaustive-roster
9225 // coverage discipline extended here onto the first M2
9226 // OTP-shape sibling-restart closed-set typed enum.
9227 //
9228 // Fail-before-pass-after locally verified by mutating one arm
9229 // of the paired [`crate::render::SUPERVISOR_ESTRATEGIA_*`]
9230 // const family (e.g. dropping the trailing `e` from
9231 // `"OneForOne"` → `"OneForOn"`) — the length pin still passes
9232 // but the `contains` check fires on the mutated arm; and by
9233 // shortening the roster to three entries — the length pin
9234 // fires first.
9235 assert_eq!(
9236 RestartStrategy::WIRE_NAMES.len(),
9237 RestartStrategy::ALL.len(),
9238 "RestartStrategy::WIRE_NAMES.len() must byte-equal \
9239 RestartStrategy::ALL.len() — a mismatch means the roster \
9240 and the enum's arm-set have drifted; downstream consumers \
9241 that fan through both will silently disagree on the \
9242 accepted arm-set"
9243 );
9244 for &variant in RestartStrategy::ALL {
9245 let wire = variant.as_str();
9246 assert!(
9247 RestartStrategy::WIRE_NAMES.contains(&wire),
9248 "RestartStrategy::{variant:?}.as_str() = {wire:?} must \
9249 be a member of RestartStrategy::WIRE_NAMES — the \
9250 emitter and the roster have drifted out of lockstep"
9251 );
9252 }
9253 for tag in RestartStrategy::WIRE_NAMES {
9254 let first = tag.chars().next().unwrap_or_else(|| {
9255 panic!(
9256 "RestartStrategy::WIRE_NAMES entry {tag:?} must be \
9257 a non-empty PascalCase byte-string"
9258 )
9259 });
9260 assert!(
9261 first.is_ascii_uppercase(),
9262 "RestartStrategy::WIRE_NAMES entry {tag:?} must open \
9263 with an ASCII uppercase byte (PascalCase wire form) — \
9264 a lowercase entry would collide the wire-form axis \
9265 with the peer kebab-case dispatcher-catalog axis \
9266 [`RestartStrategy::discriminant`] serves"
9267 );
9268 }
9269 }
9270
9271 #[test]
9272 fn restart_strategy_from_wire_accepts_every_lifted_constant() {
9273 // Fail-before-pass-after pin on the forward accept-set of the
9274 // [`RestartStrategy::from_wire`] reverse projection: every
9275 // canonical [`crate::render::SUPERVISOR_ESTRATEGIA_*`]
9276 // constant the [`RestartStrategy::as_str`] emitter walks parses
9277 // back to its paired variant. Any future arm addition that
9278 // grows the emitter's `as_str` match but forgets to grow the
9279 // parser's `from_wire` match silently splits the two halves of
9280 // the round-trip — the wire byte-string one non-serde consumer
9281 // parses from the one the emitter wrote — with the failure
9282 // surfacing at parse time far from the rebrand commit. Pinning
9283 // the four-arm accept-set here catches the drift at caixa-core
9284 // build time.
9285 //
9286 // Peer of the sibling [`crate::CaixaKind::from_wire`] (2aa6d23)
9287 // + [`crate::aplicacao::PlacementStrategy::from_wire`] (18c7342)
9288 // accept-set pins on the peer closed-set typed-enum `str → Self`
9289 // axes.
9290 for (wire, expected) in [
9291 (
9292 crate::render::SUPERVISOR_ESTRATEGIA_ONE_FOR_ONE,
9293 RestartStrategy::OneForOne,
9294 ),
9295 (
9296 crate::render::SUPERVISOR_ESTRATEGIA_ONE_FOR_ALL,
9297 RestartStrategy::OneForAll,
9298 ),
9299 (
9300 crate::render::SUPERVISOR_ESTRATEGIA_REST_FOR_ONE,
9301 RestartStrategy::RestForOne,
9302 ),
9303 (
9304 crate::render::SUPERVISOR_ESTRATEGIA_SIMPLE_ONE_FOR_ONE,
9305 RestartStrategy::SimpleOneForOne,
9306 ),
9307 ] {
9308 let parsed = RestartStrategy::from_wire(wire).unwrap_or_else(|| {
9309 panic!(
9310 "RestartStrategy::from_wire({wire:?}) must accept every \
9311 SUPERVISOR_ESTRATEGIA_* constant — got None for the \
9312 lifted canonical byte-string that RestartStrategy::{expected:?} \
9313 serializes as under SUPERVISOR_KEY_ESTRATEGIA"
9314 )
9315 });
9316 assert_eq!(
9317 parsed, expected,
9318 "RestartStrategy::from_wire({wire:?}) must return \
9319 RestartStrategy::{expected:?}; got RestartStrategy::{parsed:?}"
9320 );
9321 }
9322 }
9323
9324 #[test]
9325 fn restart_strategy_from_wire_round_trips_through_as_str() {
9326 // Fail-before-pass-after pin on the closed round-trip between
9327 // the forward [`RestartStrategy::as_str`] emitter and the
9328 // reverse [`RestartStrategy::from_wire`] parser: for every
9329 // variant in [`RestartStrategy::ALL`], parsing the emitter's
9330 // output must return exactly the same variant. Any per-arm
9331 // divergence — a future arm added to `as_str` but not
9332 // `from_wire`, an accidental copy-paste flip in one but not
9333 // the other — silently splits the emit and parse halves and
9334 // the failure surfaces at consumer parse time far from the
9335 // drift site. The `ALL`-iterating shape means a future arm
9336 // addition picks up the coverage by construction.
9337 //
9338 // Peer of the sibling
9339 // [`crate::aplicacao::tests::placement_strategy_from_wire_round_trips_through_as_str`]
9340 // (18c7342) round-trip pin on
9341 // [`crate::aplicacao::PlacementStrategy::from_wire`] and
9342 // [`crate::kind::tests::caixa_kind_wire_round_trips_through_from_wire`]
9343 // (6b1f4fb) round-trip pin on [`crate::CaixaKind::from_wire`].
9344 for &variant in RestartStrategy::ALL {
9345 let wire = variant.as_str();
9346 let parsed = RestartStrategy::from_wire(wire).unwrap_or_else(|| {
9347 panic!(
9348 "RestartStrategy::from_wire(RestartStrategy::{variant:?}.as_str()) \
9349 must be Some({variant:?}) — the two halves of the round-trip \
9350 dispatch on the same lifted SUPERVISOR_ESTRATEGIA_* consts; \
9351 got None on wire byte-string {wire:?}"
9352 )
9353 });
9354 assert_eq!(
9355 parsed, variant,
9356 "RestartStrategy::from_wire(RestartStrategy::{variant:?}.as_str()) \
9357 must round-trip to the same variant; got {parsed:?}"
9358 );
9359 }
9360 }
9361
9362 #[test]
9363 fn restart_strategy_from_wire_rejects_unknown_byte_strings() {
9364 // Fail-before-pass-after pin on the closed-set refusal
9365 // discipline of [`RestartStrategy::from_wire`]: every
9366 // byte-string outside the four-arm accept-set returns `None`
9367 // rather than silently collapsing onto the [`Default`]
9368 // (`OneForOne`) arm or an arbitrary neighbor. The refusal set
9369 // exercised here sweeps the load-bearing drift shapes: the
9370 // empty string (a stripped serde-attribute drift), all-
9371 // whitespace strings (the canonical text-editor accidental
9372 // padding shape), the kebab-case dispatcher-catalog identities
9373 // (`"one-for-one"` / `"one-for-all"` / `"rest-for-one"` /
9374 // `"simple-one-for-one"` — the [`gen_platform::FromStrKind`]-
9375 // derived [`std::str::FromStr`] accept-set, which parses the
9376 // *other* axis of this enum's two-axis split and must not leak
9377 // into the `from_wire` PascalCase-wire accept-set), the
9378 // lowercased single-word forms (`"oneforone"`), the padded
9379 // canonical scalar (`" OneForOne "`), the trailing-newline
9380 // shapes (`"OneForOne\n"`), and neighboring-but-unknown arms
9381 // (`"AllForOne"` — the canonical typo direction).
9382 //
9383 // Peer of the sibling
9384 // [`crate::kind::tests::caixa_kind_from_wire_rejects_unknown_byte_strings`]
9385 // (2aa6d23) +
9386 // [`crate::aplicacao::tests::placement_strategy_from_wire_rejects_unknown_byte_strings`]
9387 // (18c7342) refusal pins on the peer closed-set typed-enum
9388 // axes.
9389 for bad in [
9390 "",
9391 " ",
9392 "\n",
9393 "\t",
9394 "one-for-one",
9395 "one-for-all",
9396 "rest-for-one",
9397 "simple-one-for-one",
9398 "oneforone",
9399 "OneForOnes",
9400 "one_for_one",
9401 "one for one",
9402 "ONEFORONE",
9403 "OneForOne ",
9404 " OneForOne",
9405 " SimpleOneForOne ",
9406 "OneForOne\n",
9407 "restforone",
9408 "REST_FOR_ONE",
9409 "AllForOne",
9410 "Simple",
9411 "?",
9412 ] {
9413 assert!(
9414 RestartStrategy::from_wire(bad).is_none(),
9415 "RestartStrategy::from_wire({bad:?}) must return None — the \
9416 parser's accept-set is exactly the four RestartStrategy::as_str \
9417 outputs (OneForOne, OneForAll, RestForOne, SimpleOneForOne), \
9418 and this byte-string is outside that closed set"
9419 );
9420 }
9421 }
9422
9423 #[test]
9424 fn restart_strategy_from_wire_matches_serialize_derive_wire_byte_string() {
9425 // Fail-before-pass-after pin on the fourth path of the four-path
9426 // convergence: `from_wire` (the reverse projection) inverts the
9427 // `Serialize` derive's wire byte-string on every variant.
9428 // Together with the pre-existing three-path convergence
9429 // (`Display` + `as_str` + `Serialize` all resolve to the same
9430 // lifted [`crate::render::SUPERVISOR_ESTRATEGIA_*`] const,
9431 // pinned by
9432 // [`restart_strategy_display_matches_serialized_wire_byte_string`])
9433 // this closes the round-trip: the wire byte-string the
9434 // `Serialize` derive emits parses back to the same variant
9435 // through `from_wire`, so any future serde-attribute or variant-
9436 // rename drift on the emit half now surfaces as a matched drift
9437 // on the parse half at caixa-core build time — the two halves
9438 // migrate as a unit through the lifted consts on any future
9439 // rename, and the round-trip cannot silently split.
9440 //
9441 // Peer of the sibling
9442 // [`crate::aplicacao::tests::placement_strategy_from_wire_matches_serialize_derive_wire_byte_string`]
9443 // (18c7342) wire-format pin on
9444 // [`crate::aplicacao::PlacementStrategy::from_wire`].
9445 for &variant in RestartStrategy::ALL {
9446 let wire = serde_json::to_string(&variant).unwrap();
9447 let unquoted = wire
9448 .strip_prefix('"')
9449 .and_then(|s| s.strip_suffix('"'))
9450 .expect("serialized RestartStrategy is a JSON string");
9451 let parsed = RestartStrategy::from_wire(unquoted).unwrap_or_else(|| {
9452 panic!(
9453 "RestartStrategy::from_wire({unquoted:?}) must accept the \
9454 Serialize derive's wire byte-string for \
9455 RestartStrategy::{variant:?} — the four-path convergence \
9456 (Display + as_str + Serialize + from_wire) resolves through \
9457 the same lifted SUPERVISOR_ESTRATEGIA_* const; got None"
9458 )
9459 });
9460 assert_eq!(
9461 parsed, variant,
9462 "RestartStrategy::from_wire of the Serialize derive's wire \
9463 byte-string for RestartStrategy::{variant:?} must round-trip \
9464 to the same variant; got {parsed:?}"
9465 );
9466 }
9467 }
9468
9469 #[test]
9470 fn restart_strategy_try_from_str_routes_through_from_wire_accessor() {
9471 // Fail-before-pass-after byte-parity pin on the newly lifted
9472 // `impl TryFrom<&str> for RestartStrategy` — asserts the standard-
9473 // library trait impl and the substrate-primitive
9474 // [`RestartStrategy::from_wire`] `Option<Self>` accessor resolve to
9475 // the same four-arm accept-set across every arm the exhaustive
9476 // [`RestartStrategy::ALL`] slice enumerates. Any future silent
9477 // detour that routes the trait impl through a divergent projection
9478 // (a per-arm inline `match s { "OneForOne" => Ok(Self::OneForOne),
9479 // … }` re-inlining that opens a compile-time link to the un-
9480 // lifted arm-literal, a hypothetical `#[serde(rename_all = "…")]`
9481 // attribute drift that silently splits the wire byte-string from
9482 // every consumer that reaches for this typed dispatch, an
9483 // accidental swap onto the kebab-case dispatcher-catalog axis the
9484 // pre-existing [`std::str::FromStr`] impl parses through and which
9485 // would collide the two-axis wire/catalog split the sibling
9486 // [`RestartStrategy::from_wire`] doc block makes load-bearing)
9487 // trips at caixa-core test time under `assert_eq!` rather than at
9488 // a downstream `impl TryFrom<&str>`-bound consumer's silent split.
9489 // Sweeps every one of the four arms [`RestartStrategy::ALL`]
9490 // carries so no arm's projection is covered only by the sibling
9491 // method-named `from_wire` path. Peer of the sibling
9492 // [`crate::kind::tests::caixa_kind_try_from_str_routes_through_from_wire_accessor`]
9493 // (3c83606),
9494 // [`crate::dialeto::tests::caixa_dialeto_try_from_str_routes_through_from_wire_accessor`]
9495 // (bf33136), and the M3
9496 // [`crate::aplicacao::tests::placement_strategy_try_from_str_routes_through_from_wire_accessor`]
9497 // (6fd00cd) — extends the trait-idiomatic reverse-projection axis
9498 // onto the first M2-OTP-shape closed-set typed enum on the caixa
9499 // surface.
9500 for &variant in RestartStrategy::ALL {
9501 let wire = variant.as_str();
9502 assert_eq!(
9503 <RestartStrategy as TryFrom<&str>>::try_from(wire),
9504 Ok(variant),
9505 "TryFrom<&str> impl on RestartStrategy must round-trip \
9506 RestartStrategy::{variant:?}.as_str() = {wire:?} back to \
9507 Ok(RestartStrategy::{variant:?}) — divergence from \
9508 RestartStrategy::from_wire signals a silent detour off \
9509 the substrate-primitive accessor"
9510 );
9511 assert_eq!(
9512 <RestartStrategy as TryFrom<&str>>::try_from(wire).ok(),
9513 RestartStrategy::from_wire(wire),
9514 "TryFrom<&str> ok()-projection on {wire:?} must byte-equal \
9515 RestartStrategy::from_wire on the same input"
9516 );
9517 }
9518 }
9519
9520 #[test]
9521 fn restart_strategy_try_from_str_rejects_unknown_byte_strings() {
9522 // Rejection witness on the `impl TryFrom<&str> for
9523 // RestartStrategy` — sweeps a candidate set of byte-strings
9524 // outside the four-arm PascalCase wire accept-set the sibling
9525 // [`RestartStrategy::as_str`] emits and asserts every one lands on
9526 // `Err(())`, so a future accidental widening of the trait impl's
9527 // accept-set (a stray additional
9528 // `_ if s.eq_ignore_ascii_case("OneForOne") => Ok(…)` case-fold
9529 // path, a silent inclusion of the kebab-case dispatcher-catalog
9530 // byte-string the pre-existing [`std::str::FromStr`] impl the
9531 // [`gen_platform::FromStrKind`] derive installs parses onto the
9532 // wire axis — which would collide the two-axis
9533 // wire/dispatcher-catalog split the sibling
9534 // [`RestartStrategy::from_wire`] doc block makes load-bearing —
9535 // an English-rebrand or plural-arm silent alias that would
9536 // widen the wire accept-set past the OTP-canonical four) trips at
9537 // caixa-core test time. The candidate set includes the empty
9538 // string, whitespace-only padding, the kebab-case dispatcher-
9539 // catalog byte-strings on the sibling axis (a caller who confuses
9540 // the two axes trips here rather than at a downstream consumer's
9541 // silent reject), a lowercase / uppercase / mixed-case fold of
9542 // each PascalCase arm (a caller who assumes case-fold acceptance
9543 // trips here), leading/trailing whitespace padding, the trailing-
9544 // newline shape, quote-wrapped candidates, and a residual set of
9545 // plausible-but-wrong English rebrand candidates. Peer of the
9546 // sibling
9547 // [`crate::kind::tests::caixa_kind_try_from_str_rejects_unknown_byte_strings`]
9548 // (3c83606) and
9549 // [`crate::aplicacao::tests::placement_strategy_try_from_str_rejects_unknown_byte_strings`]
9550 // (6fd00cd) rejection witnesses.
9551 let rejected: &[&str] = &[
9552 "",
9553 " ",
9554 "\n",
9555 "\t",
9556 "one-for-one",
9557 "one-for-all",
9558 "rest-for-one",
9559 "simple-one-for-one",
9560 "oneforone",
9561 "one_for_one",
9562 "OneForOnes",
9563 "ONEFORONE",
9564 "oneforall",
9565 "restforone",
9566 "simpleoneforone",
9567 "OneForOne ",
9568 " OneForOne",
9569 " OneForAll ",
9570 "OneForOne\n",
9571 "RestForOne\t",
9572 "OneForEach",
9573 "AllForOne",
9574 "one for one",
9575 "\"OneForOne\"",
9576 "?",
9577 ];
9578 for &input in rejected {
9579 assert_eq!(
9580 <RestartStrategy as TryFrom<&str>>::try_from(input),
9581 Err(()),
9582 "TryFrom<&str> impl on RestartStrategy must reject the \
9583 non-wire byte-string {input:?} — silent acceptance signals \
9584 an accept-set widening off the paired \
9585 RestartStrategy::from_wire resolver"
9586 );
9587 }
9588 }
9589
9590 #[test]
9591 fn restart_strategy_try_from_str_and_from_wire_partition_the_accept_set() {
9592 // Cross-axis partition pin: the paired `TryFrom<&str>` and
9593 // `from_wire` reverse projections must resolve identically on
9594 // *every* input, not just the ones [`RestartStrategy::ALL`]
9595 // enumerates. Sweeps a mixed candidate set spanning accepted
9596 // (four-arm PascalCase wire byte-strings) and rejected (kebab-case
9597 // dispatcher-catalog byte-strings, empty, whitespace-padded,
9598 // quoted, English-rebrand candidates) inputs and asserts the
9599 // trait's `Result::ok()` projection byte-equals the method-named
9600 // resolver's `Option<Self>` return-shape on each, locking the two
9601 // paths together by construction so any future detour (a stray
9602 // `try_from` special-case that widens or narrows the accept-set
9603 // outside the paired `from_wire` resolver, an accidental swap
9604 // onto the kebab-case [`std::str::FromStr`] impl the
9605 // [`gen_platform::FromStrKind`] derive installs on the sibling
9606 // dispatcher-catalog axis) trips at caixa-core test time. Peer of
9607 // the sibling
9608 // [`crate::kind::tests::caixa_kind_try_from_str_and_from_wire_partition_the_accept_set`]
9609 // pin — extends the round-trip discipline onto the M2-OTP-shape
9610 // sibling-restart axis.
9611 let candidates: &[&str] = &[
9612 "OneForOne",
9613 "OneForAll",
9614 "RestForOne",
9615 "SimpleOneForOne",
9616 "",
9617 "one-for-one",
9618 "one-for-all",
9619 "rest-for-one",
9620 "simple-one-for-one",
9621 "oneforone",
9622 "unknown",
9623 "OneForOne ",
9624 " OneForOne",
9625 "\"OneForOne\"",
9626 "OneForEach",
9627 "?",
9628 ];
9629 for &input in candidates {
9630 let via_trait: Option<RestartStrategy> =
9631 <RestartStrategy as TryFrom<&str>>::try_from(input).ok();
9632 let via_method: Option<RestartStrategy> = RestartStrategy::from_wire(input);
9633 assert_eq!(
9634 via_trait, via_method,
9635 "TryFrom<&str> and from_wire must resolve identically on \
9636 input {input:?} — divergence signals the two reverse-\
9637 projection paths have drifted onto different accept-sets"
9638 );
9639 }
9640 }
9641
9642 #[test]
9643 fn restart_strategy_from_into_static_str_routes_through_as_str_accessor() {
9644 // Fail-before-pass-after byte-parity pin on the newly lifted
9645 // `impl From<RestartStrategy> for &'static str` — asserts the
9646 // standard-library trait impl and the substrate-primitive
9647 // [`RestartStrategy::as_str`] `pub const fn` accessor resolve to
9648 // the same four-arm emit-set across every arm the exhaustive
9649 // [`RestartStrategy::ALL`] slice enumerates. Any future silent
9650 // detour that routes the trait impl through a divergent
9651 // projection (a per-arm inline `match strategy { OneForOne =>
9652 // "OneForOne", … }` re-inlining that opens a compile-time link to
9653 // the un-lifted arm-literal, an accidental swap onto the sibling
9654 // kebab-case [`Self::discriminant`] dispatcher-catalog axis that
9655 // would collide the two-axis wire/catalog split the sibling
9656 // [`RestartStrategy::from_wire`] doc block makes load-bearing) trips
9657 // at caixa-core test time under `assert_eq!` rather than at a
9658 // downstream `impl Into<&'static str>`-bound consumer's silent
9659 // split. Sweeps every one of the four arms
9660 // [`RestartStrategy::ALL`] carries so no arm's projection is
9661 // covered only by the sibling method-named `as_str` /
9662 // [`std::fmt::Display`] / [`AsRef<str>`] paths. Materializes the
9663 // `<&'static str as From<RestartStrategy>>::from` output in a
9664 // `const`-shape binding to make the `'static` lifetime promise a
9665 // build-time invariant — a future accidental downgrade of any of
9666 // the four arms' [`crate::render::SUPERVISOR_ESTRATEGIA_*`]
9667 // constants to a non-`&'static str` (a `String::leak()`-produced
9668 // return, a `Box::leak`-cast) trips at caixa-core build time
9669 // rather than at a downstream `'static`-bound consumer.
9670 const ONE_FOR_ONE: &str = RestartStrategy::OneForOne.as_str();
9671 const ONE_FOR_ALL: &str = RestartStrategy::OneForAll.as_str();
9672 const REST_FOR_ONE: &str = RestartStrategy::RestForOne.as_str();
9673 const SIMPLE_ONE_FOR_ONE: &str = RestartStrategy::SimpleOneForOne.as_str();
9674 for &variant in RestartStrategy::ALL {
9675 let via_trait: &'static str = <&'static str as From<RestartStrategy>>::from(variant);
9676 let via_method: &'static str = variant.as_str();
9677 assert_eq!(
9678 via_trait, via_method,
9679 "From<RestartStrategy> for &'static str impl must round-trip \
9680 RestartStrategy::{variant:?} to the same lifted \
9681 SUPERVISOR_ESTRATEGIA_* const RestartStrategy::as_str returns — \
9682 divergence signals a silent detour off the substrate-primitive \
9683 accessor"
9684 );
9685 let via_into: &'static str = variant.into();
9686 assert_eq!(
9687 via_into, via_method,
9688 "Into<&'static str>::into on RestartStrategy::{variant:?} must \
9689 byte-equal RestartStrategy::as_str on the same input — the \
9690 blanket-derived Into shape must resolve to the same as_str \
9691 dispatch as the explicit From impl"
9692 );
9693 }
9694 assert_eq!(
9695 [ONE_FOR_ONE, ONE_FOR_ALL, REST_FOR_ONE, SIMPLE_ONE_FOR_ONE],
9696 [
9697 crate::render::SUPERVISOR_ESTRATEGIA_ONE_FOR_ONE,
9698 crate::render::SUPERVISOR_ESTRATEGIA_ONE_FOR_ALL,
9699 crate::render::SUPERVISOR_ESTRATEGIA_REST_FOR_ONE,
9700 crate::render::SUPERVISOR_ESTRATEGIA_SIMPLE_ONE_FOR_ONE,
9701 ],
9702 "const-context RestartStrategy::as_str must resolve to the four \
9703 lifted SUPERVISOR_ESTRATEGIA_* consts — a future accidental \
9704 downgrade of any arm to a non-const or non-static byte-string \
9705 breaks the `&'static str`-lifetime promise the paired \
9706 From<RestartStrategy> for &'static str impl carries by \
9707 construction"
9708 );
9709 }
9710
9711 #[test]
9712 fn restart_strategy_from_into_static_str_and_as_str_partition_the_emit_set() {
9713 // Cross-axis partition pin: the paired trait-idiomatic
9714 // `From<RestartStrategy> for &'static str` forward projection and
9715 // the method-named [`RestartStrategy::as_str`] forward projection
9716 // must resolve identically on *every* arm, not just the ones
9717 // named in the primary byte-parity pin above. Sweeps every
9718 // [`RestartStrategy::ALL`] arm and asserts the trait's `From::from`
9719 // output byte-equals the method-named accessor's return-value on
9720 // each, locking the two forward-projection paths together by
9721 // construction so any future detour (a stray `From` special-case
9722 // that lands on a divergent per-arm literal outside the paired
9723 // `as_str` dispatch, a hypothetical rebrand touching one axis
9724 // without the other) trips at caixa-core test time. Peer of the
9725 // sibling reverse-projection partition pin
9726 // [`restart_strategy_try_from_str_and_from_wire_partition_the_accept_set`]
9727 // — extends the round-trip discipline onto the trait-idiomatic
9728 // *forward* axis, closing the two-way `Self ↔ &'static str`
9729 // round-trip on the trait-idiomatic pair
9730 // (`From<Self> for &'static str` + `TryFrom<&str> for Self`) as
9731 // well as the pre-existing method-named pair
9732 // (`as_str` + `from_wire`).
9733 for &variant in RestartStrategy::ALL {
9734 let via_trait: &'static str = <&'static str as From<RestartStrategy>>::from(variant);
9735 let via_method: &'static str = variant.as_str();
9736 assert_eq!(
9737 via_trait, via_method,
9738 "From<RestartStrategy> for &'static str and \
9739 RestartStrategy::as_str must resolve identically on \
9740 RestartStrategy::{variant:?} — divergence signals the \
9741 two forward-projection paths have drifted onto different \
9742 emit-sets"
9743 );
9744 }
9745 // Round-trip witness: every arm's forward `From` output re-parses
9746 // through the paired trait-idiomatic reverse `TryFrom<&str>` back
9747 // to the original variant. Closes the two-way `RestartStrategy ↔
9748 // &'static str` round-trip on the trait-idiomatic axis pair,
9749 // mirroring the pre-existing method-named `as_str` + `from_wire`
9750 // round-trip on the substrate-primitive axis pair.
9751 for &variant in RestartStrategy::ALL {
9752 let emitted: &'static str = variant.into();
9753 let re_parsed: Result<RestartStrategy, ()> =
9754 <RestartStrategy as TryFrom<&str>>::try_from(emitted);
9755 assert_eq!(
9756 re_parsed,
9757 Ok(variant),
9758 "trait-idiomatic axis pair must round-trip \
9759 RestartStrategy::{variant:?} through `.into::<&'static \
9760 str>()` and back through `TryFrom<&str>` — a break signals \
9761 the forward-emit and reverse-parse axes have drifted onto \
9762 different vocabularies"
9763 );
9764 }
9765 }
9766
9767 #[test]
9768 fn restart_strategy_from_borrowed_into_static_str_routes_through_as_str_accessor() {
9769 // Fail-before-pass-after byte-parity pin on the newly lifted
9770 // `impl From<&RestartStrategy> for &'static str` — asserts the
9771 // borrowed-input standard-library trait impl and the substrate-
9772 // primitive [`RestartStrategy::as_str`] `pub const fn` accessor
9773 // resolve to the same four-arm emit-set across every arm the
9774 // exhaustive [`RestartStrategy::ALL`] slice enumerates. Rust's
9775 // `From` trait does not auto-derive the borrowed-input sibling
9776 // from a paired owned-input impl (no `impl<T, U> From<&T> for U
9777 // where T: Copy, U: From<T>` blanket in `core`), so the
9778 // borrowed-input axis is a distinct trait-idiomatic surface
9779 // that a `.iter().map(Into::into)` shape over
9780 // [`RestartStrategy::ALL`] (whose iterator yields
9781 // `&RestartStrategy`, not `RestartStrategy`) reaches through
9782 // this impl and no other — the paired owned-input
9783 // [`From<RestartStrategy>`] impl requires an explicit
9784 // `.copied()` / dereference before the trait fires.
9785 // Materializes the `<&'static str as
9786 // From<&RestartStrategy>>::from` output in a `const`-shape
9787 // binding to make the `'static` lifetime promise a build-time
9788 // invariant.
9789 const ONE_FOR_ONE: &str = RestartStrategy::OneForOne.as_str();
9790 const ONE_FOR_ALL: &str = RestartStrategy::OneForAll.as_str();
9791 const REST_FOR_ONE: &str = RestartStrategy::RestForOne.as_str();
9792 const SIMPLE_ONE_FOR_ONE: &str = RestartStrategy::SimpleOneForOne.as_str();
9793 for variant in RestartStrategy::ALL {
9794 let via_trait: &'static str = <&'static str as From<&RestartStrategy>>::from(variant);
9795 let via_method: &'static str = variant.as_str();
9796 assert_eq!(
9797 via_trait, via_method,
9798 "From<&RestartStrategy> for &'static str impl must \
9799 round-trip &RestartStrategy::{variant:?} to the same \
9800 lifted SUPERVISOR_ESTRATEGIA_* const \
9801 RestartStrategy::as_str returns — divergence signals a \
9802 silent detour off the substrate-primitive accessor"
9803 );
9804 let via_into: &'static str = variant.into();
9805 assert_eq!(
9806 via_into, via_method,
9807 "Into<&'static str>::into on &RestartStrategy::{variant:?} \
9808 must byte-equal RestartStrategy::as_str on the same input — \
9809 the blanket-derived Into shape must resolve to the same \
9810 as_str dispatch as the explicit From impl"
9811 );
9812 }
9813 assert_eq!(
9814 [ONE_FOR_ONE, ONE_FOR_ALL, REST_FOR_ONE, SIMPLE_ONE_FOR_ONE],
9815 [
9816 crate::render::SUPERVISOR_ESTRATEGIA_ONE_FOR_ONE,
9817 crate::render::SUPERVISOR_ESTRATEGIA_ONE_FOR_ALL,
9818 crate::render::SUPERVISOR_ESTRATEGIA_REST_FOR_ONE,
9819 crate::render::SUPERVISOR_ESTRATEGIA_SIMPLE_ONE_FOR_ONE,
9820 ],
9821 "const-context RestartStrategy::as_str must resolve to the \
9822 four lifted SUPERVISOR_ESTRATEGIA_* consts — the borrowed-\
9823 input From<&RestartStrategy> for &'static str impl inherits \
9824 its `'static` lifetime promise from the same accessor the \
9825 owned-input sibling routes through"
9826 );
9827 }
9828
9829 #[test]
9830 fn restart_strategy_from_owned_and_borrowed_into_static_str_agree_on_every_arm() {
9831 // Cross-axis partition pin: the paired trait-idiomatic
9832 // owned-input `From<RestartStrategy> for &'static str` (523157d
9833 // campaign-shape) and borrowed-input `From<&RestartStrategy> for
9834 // &'static str` (this lift) forward projections must resolve
9835 // identically on every arm, locking the two input-shape paths
9836 // together so any future detour trips at caixa-core test time.
9837 // Then a witness that a `.iter().map(Into::into)` pipe over
9838 // [`RestartStrategy::ALL`] (whose iterator yields
9839 // `&RestartStrategy`) materializes the four-arm accept-set
9840 // through the borrowed-input axis alone — the exact shape a
9841 // future wasm-operator per-supervisor sibling-restart-strategy
9842 // diagnostic line, a future substrate-wide per-arm diagnostic
9843 // column, or a
9844 // `HashMap::<&'static str, RestartStrategy>::from_iter(
9845 // RestartStrategy::ALL.iter().map(|s| (s.into(), *s)))`-style
9846 // per-strategy lookup reaches through — closing the two-way
9847 // owned/borrowed input-shape symmetry on the forward-projection
9848 // trait-idiomatic axis. Peer of the sibling
9849 // [`crate::dep::tests::dep_list_from_owned_and_borrowed_into_static_str_agree_on_every_arm`]
9850 // (64aa742) /
9851 // [`crate::kind::tests::caixa_kind_from_owned_and_borrowed_into_static_str_agree_on_every_arm`]
9852 // (5ab993a) /
9853 // [`crate::dialeto::tests::caixa_dialeto_from_owned_and_borrowed_into_static_str_agree_on_every_arm`]
9854 // (807b0b5) partition pins on the sibling closed-set typed-enum
9855 // discriminator axes — extends the borrowed-input axis
9856 // discipline onto the first M2 OTP-shape sibling-restart
9857 // closed-set typed enum on the caixa surface. Also closes the
9858 // direct two-way `&Self → &'static str → Self` round-trip via
9859 // the paired [`TryFrom<&str>`] axis — unlike the peer
9860 // [`crate::CaixaKind`] axis pair (whose forward `From` emits
9861 // lowercase Portuguese diagnostic bytes while the reverse
9862 // `TryFrom` parses `PascalCase` wire bytes, forcing the round-
9863 // trip through an intermediate wire-vocab hop), the
9864 // [`RestartStrategy::as_str`] emit and
9865 // [`RestartStrategy::from_wire`] parse share the same
9866 // `PascalCase` vocabulary by construction, so the borrowed-
9867 // input forward axis and the reverse axis compose directly.
9868 for &variant in RestartStrategy::ALL {
9869 let owned: &'static str = <&'static str as From<RestartStrategy>>::from(variant);
9870 let borrowed: &'static str = <&'static str as From<&RestartStrategy>>::from(&variant);
9871 assert_eq!(
9872 owned, borrowed,
9873 "From<RestartStrategy> and From<&RestartStrategy> for \
9874 &'static str must resolve identically on \
9875 RestartStrategy::{variant:?} — divergence signals the \
9876 owned-input and borrowed-input forward-projection paths \
9877 have drifted onto different emit-sets"
9878 );
9879 }
9880 let via_iter: Vec<&'static str> = RestartStrategy::ALL.iter().map(Into::into).collect();
9881 let via_method: Vec<&'static str> =
9882 RestartStrategy::ALL.iter().map(|s| s.as_str()).collect();
9883 assert_eq!(
9884 via_iter, via_method,
9885 "`.iter().map(Into::into)` over RestartStrategy::ALL must \
9886 byte-equal `.iter().map(|s| s.as_str())` on every arm — the \
9887 borrowed-input `From<&RestartStrategy> for &'static str` \
9888 axis is what makes the `.iter().map(Into::into)` shape route \
9889 through the substrate-primitive `RestartStrategy::as_str` \
9890 accessor rather than through a per-call-site `.copied()` / \
9891 dereference detour"
9892 );
9893 for variant in RestartStrategy::ALL {
9894 let emitted: &'static str = variant.into();
9895 let re_parsed: Result<RestartStrategy, ()> =
9896 <RestartStrategy as TryFrom<&str>>::try_from(emitted);
9897 assert_eq!(
9898 re_parsed,
9899 Ok(*variant),
9900 "trait-idiomatic borrowed-input forward-projection + \
9901 reverse-projection axis pair must round-trip \
9902 &RestartStrategy::{variant:?} through `.into::<&'static \
9903 str>()` (via the borrowed-input axis) and back through \
9904 `TryFrom<&str>` — a break signals the borrowed-input \
9905 forward-emit and reverse-parse axes have drifted onto \
9906 different vocabularies"
9907 );
9908 }
9909 }
9910
9911 #[test]
9912 fn restart_strategy_from_into_owned_string_routes_through_as_str_accessor() {
9913 // Fail-before-pass-after byte-parity pin on the newly lifted
9914 // `impl From<RestartStrategy> for String` — asserts the
9915 // owned-`String`-returning standard-library trait impl and the
9916 // substrate-primitive [`RestartStrategy::as_str`] `pub const fn`
9917 // accessor resolve to the same four-arm emit-set across every
9918 // arm the exhaustive [`RestartStrategy::ALL`] slice enumerates.
9919 // Rust's standard library does not carry a blanket
9920 // `impl<T: AsRef<str>> From<T> for String` (nor an
9921 // `impl<T: fmt::Display> From<T> for String`), so the
9922 // owned-`String` forward-projection axis is a distinct
9923 // trait-idiomatic surface that a
9924 // `let key: String = strategy.into();`-shaped call site
9925 // reaches through this impl and no other — the paired sibling
9926 // `From<RestartStrategy> for &'static str` impl forces every
9927 // owned-`String` call site through an explicit
9928 // `.to_owned()` / `String::from` restatement.
9929 for &variant in RestartStrategy::ALL {
9930 let via_trait: String = <String as From<RestartStrategy>>::from(variant);
9931 let via_method: &'static str = variant.as_str();
9932 assert_eq!(
9933 via_trait.as_str(),
9934 via_method,
9935 "From<RestartStrategy> for String impl must round-trip \
9936 RestartStrategy::{variant:?} to the same lifted \
9937 SUPERVISOR_ESTRATEGIA_* const RestartStrategy::as_str \
9938 returns — divergence signals a silent detour off the \
9939 substrate-primitive accessor"
9940 );
9941 let via_into: String = variant.into();
9942 assert_eq!(
9943 via_into.as_str(),
9944 via_method,
9945 "Into<String>::into on RestartStrategy::{variant:?} must \
9946 byte-equal RestartStrategy::as_str on the same input — the \
9947 blanket-derived Into shape must resolve to the same as_str \
9948 dispatch as the explicit From impl"
9949 );
9950 }
9951 }
9952
9953 #[test]
9954 fn restart_strategy_from_into_owned_string_and_static_str_agree_on_every_arm() {
9955 // Cross-axis partition pin: the paired trait-idiomatic
9956 // owned-`String` `From<RestartStrategy> for String` (this lift)
9957 // and owned-`&'static str` `From<RestartStrategy> for &'static
9958 // str` (523157d) forward projections must resolve identically
9959 // on every arm, locking the two return-type-shape paths
9960 // together so any future detour trips at caixa-core test time.
9961 // Also byte-parity witness against the sibling
9962 // [`ToString::to_string`] surface routed through
9963 // [`std::fmt::Display`] — the three owned-heap-string paths
9964 // (`.into::<String>()`, `String::from`, `.to_string()`) must
9965 // resolve identically on every arm so a future consumer that
9966 // picks any of the three lands on the same lifted
9967 // SUPERVISOR_ESTRATEGIA_* const. Then a direct round-trip
9968 // witness through the paired trait-idiomatic reverse
9969 // [`TryFrom<&str>`] axis on the owned-`String`'s
9970 // [`String::as_str`] borrow that closes the two-way
9971 // `Self → String → Self` round-trip on the trait-idiomatic
9972 // owned-`String` forward + reverse axis pair.
9973 for &variant in RestartStrategy::ALL {
9974 let owned_string: String = <String as From<RestartStrategy>>::from(variant);
9975 let owned_static: &'static str = <&'static str as From<RestartStrategy>>::from(variant);
9976 assert_eq!(
9977 owned_string.as_str(),
9978 owned_static,
9979 "From<RestartStrategy> for String and From<RestartStrategy> \
9980 for &'static str must resolve identically on \
9981 RestartStrategy::{variant:?} — divergence signals the \
9982 owned-`String` and owned-`&'static str` forward-projection \
9983 return-type-shape paths have drifted onto different \
9984 emit-sets"
9985 );
9986 let via_to_string: String = variant.to_string();
9987 assert_eq!(
9988 owned_string, via_to_string,
9989 "From<RestartStrategy> for String must byte-equal \
9990 RestartStrategy::to_string on RestartStrategy::{variant:?} — \
9991 divergence signals the trait-idiomatic owned-`String` \
9992 forward-projection axis and the ToString-through-Display \
9993 axis have drifted onto different emit-sets"
9994 );
9995 }
9996 let via_iter: Vec<String> = RestartStrategy::ALL
9997 .iter()
9998 .copied()
9999 .map(String::from)
10000 .collect();
10001 let via_method: Vec<String> = RestartStrategy::ALL
10002 .iter()
10003 .map(|s| s.as_str().to_owned())
10004 .collect();
10005 assert_eq!(
10006 via_iter, via_method,
10007 "`.iter().copied().map(String::from)` over RestartStrategy::ALL \
10008 must byte-equal `.iter().map(|s| s.as_str().to_owned())` on \
10009 every arm — the owned-`String` `From<RestartStrategy> for \
10010 String` axis is what makes the `String::from` composition \
10011 route through the substrate-primitive `RestartStrategy::as_str` \
10012 accessor rather than through a per-call-site `.to_owned()` / \
10013 `String::from(strategy.as_str())` detour"
10014 );
10015 for &variant in RestartStrategy::ALL {
10016 let emitted: String = variant.into();
10017 let re_parsed: Result<RestartStrategy, ()> =
10018 <RestartStrategy as TryFrom<&str>>::try_from(emitted.as_str());
10019 assert_eq!(
10020 re_parsed,
10021 Ok(variant),
10022 "trait-idiomatic owned-`String` forward-projection + \
10023 reverse-projection axis pair must round-trip \
10024 RestartStrategy::{variant:?} through `.into::<String>()` \
10025 and back through `TryFrom<&str>` on the owned-`String`'s \
10026 String::as_str borrow — a break signals the owned-`String` \
10027 forward-emit and reverse-parse axes have drifted onto \
10028 different vocabularies"
10029 );
10030 }
10031 }
10032
10033 #[test]
10034 fn restart_strategy_from_into_borrowed_owned_string_routes_through_as_str_accessor() {
10035 // Fail-before-pass-after byte-parity pin on the newly lifted
10036 // `impl From<&RestartStrategy> for String` — asserts the
10037 // borrowed-input owned-`String`-returning standard-library trait
10038 // impl and the substrate-primitive [`RestartStrategy::as_str`]
10039 // `pub const fn` accessor resolve to the same four-arm emit-set
10040 // across every arm the exhaustive [`RestartStrategy::ALL`] slice
10041 // enumerates. Rust's standard library does not carry a blanket
10042 // `impl<T: AsRef<str>> From<&T> for String` (nor an
10043 // `impl<T: fmt::Display> From<&T> for String`), so the
10044 // borrowed-input owned-`String` forward-projection axis is a
10045 // distinct trait-idiomatic surface that a
10046 // `let key: String = (&strategy).into();`-shaped call site
10047 // reaches through this impl and no other — the paired sibling
10048 // `From<RestartStrategy> for String` impl forces every
10049 // borrowed-input call site through an explicit `Copy` deref
10050 // (`String::from(*strategy)`) or an `.as_str().to_owned()` /
10051 // `.to_string()` detour.
10052 for &variant in RestartStrategy::ALL {
10053 let via_trait: String = <String as From<&RestartStrategy>>::from(&variant);
10054 let via_method: &'static str = variant.as_str();
10055 assert_eq!(
10056 via_trait.as_str(),
10057 via_method,
10058 "From<&RestartStrategy> for String impl must round-trip \
10059 &RestartStrategy::{variant:?} to the same lifted \
10060 SUPERVISOR_ESTRATEGIA_* const RestartStrategy::as_str \
10061 returns — divergence signals a silent detour off the \
10062 substrate-primitive accessor"
10063 );
10064 let via_into: String = (&variant).into();
10065 assert_eq!(
10066 via_into.as_str(),
10067 via_method,
10068 "Into<String>::into on &RestartStrategy::{variant:?} must \
10069 byte-equal RestartStrategy::as_str on the same input — the \
10070 blanket-derived Into shape must resolve to the same as_str \
10071 dispatch as the explicit From impl"
10072 );
10073 }
10074 }
10075
10076 #[test]
10077 fn restart_strategy_from_into_borrowed_owned_string_agrees_with_paired_axes_on_every_arm() {
10078 // Cross-axis partition pin: the newly lifted trait-idiomatic
10079 // borrowed-input owned-`String` `From<&RestartStrategy> for
10080 // String` (this lift), the paired owned-input owned-`String`
10081 // `From<RestartStrategy> for String` (7baa18a), the paired
10082 // borrowed-input owned-`&'static str` `From<&RestartStrategy>
10083 // for &'static str` (e941836), and the paired owned-input
10084 // owned-`&'static str` `From<RestartStrategy> for &'static str`
10085 // (523157d) — every corner of the `{Self, &Self} × {&'static
10086 // str, String}` 2×2 trait-idiomatic projection family — must
10087 // resolve identically on every arm, locking the four
10088 // return-shape × input-shape paths together so any future
10089 // detour trips at caixa-core test time. Also byte-parity
10090 // witness against the sibling [`ToString::to_string`] surface
10091 // routed through [`std::fmt::Display`] and a direct round-trip
10092 // witness through the paired trait-idiomatic reverse
10093 // [`TryFrom<&str>`] axis on the owned-`String`'s
10094 // [`String::as_str`] borrow that closes the two-way
10095 // `&Self → String → Self` round-trip on the trait-idiomatic
10096 // borrowed-input owned-`String` forward + reverse axis pair.
10097 for &variant in RestartStrategy::ALL {
10098 let borrowed_string: String = <String as From<&RestartStrategy>>::from(&variant);
10099 let owned_string: String = <String as From<RestartStrategy>>::from(variant);
10100 let borrowed_static: &'static str =
10101 <&'static str as From<&RestartStrategy>>::from(&variant);
10102 let owned_static: &'static str = <&'static str as From<RestartStrategy>>::from(variant);
10103 assert_eq!(
10104 borrowed_string, owned_string,
10105 "From<&RestartStrategy> for String and From<RestartStrategy> \
10106 for String must resolve identically on \
10107 RestartStrategy::{variant:?} — divergence signals the \
10108 borrowed-input and owned-input owned-`String` \
10109 forward-projection input-shape paths have drifted onto \
10110 different emit-sets"
10111 );
10112 assert_eq!(
10113 borrowed_string.as_str(),
10114 borrowed_static,
10115 "From<&RestartStrategy> for String and From<&RestartStrategy> \
10116 for &'static str must resolve identically on \
10117 RestartStrategy::{variant:?} — divergence signals the \
10118 borrowed-input `&'static str` and owned-`String` \
10119 return-shape paths have drifted onto different emit-sets"
10120 );
10121 assert_eq!(
10122 borrowed_string.as_str(),
10123 owned_static,
10124 "From<&RestartStrategy> for String and From<RestartStrategy> \
10125 for &'static str must resolve identically on \
10126 RestartStrategy::{variant:?} — divergence signals a break \
10127 in the diagonal corner of the {{Self, &Self}} × \
10128 {{&'static str, String}} 2×2 trait-idiomatic \
10129 projection family"
10130 );
10131 let via_to_string: String = variant.to_string();
10132 assert_eq!(
10133 borrowed_string, via_to_string,
10134 "From<&RestartStrategy> for String must byte-equal \
10135 RestartStrategy::to_string on RestartStrategy::{variant:?} — \
10136 divergence signals the trait-idiomatic borrowed-input \
10137 owned-`String` forward-projection axis and the \
10138 ToString-through-Display axis have drifted onto different \
10139 emit-sets"
10140 );
10141 }
10142 let via_iter: Vec<String> = RestartStrategy::ALL.iter().map(String::from).collect();
10143 let via_method: Vec<String> = RestartStrategy::ALL
10144 .iter()
10145 .map(|s| s.as_str().to_owned())
10146 .collect();
10147 assert_eq!(
10148 via_iter, via_method,
10149 "`.iter().map(String::from)` over RestartStrategy::ALL — a \
10150 call site whose iteration axis holds `&RestartStrategy` by \
10151 construction — must byte-equal `.iter().map(|s| \
10152 s.as_str().to_owned())` on every arm — the borrowed-input \
10153 owned-`String` `From<&RestartStrategy> for String` axis is \
10154 what makes the `String::from` composition route through the \
10155 substrate-primitive `RestartStrategy::as_str` accessor \
10156 without a spurious `Copy` deref (which would only be \
10157 reachable through the owned-input `From<RestartStrategy> for \
10158 String` axis by first calling `.copied()` on the iterator)"
10159 );
10160 for &variant in RestartStrategy::ALL {
10161 let emitted: String = (&variant).into();
10162 let re_parsed: Result<RestartStrategy, ()> =
10163 <RestartStrategy as TryFrom<&str>>::try_from(emitted.as_str());
10164 assert_eq!(
10165 re_parsed,
10166 Ok(variant),
10167 "trait-idiomatic borrowed-input owned-`String` \
10168 forward-projection + reverse-projection axis pair must \
10169 round-trip &RestartStrategy::{variant:?} through \
10170 `.into::<String>()` on the borrowed-input surface and \
10171 back through `TryFrom<&str>` on the owned-`String`'s \
10172 String::as_str borrow — a break signals the \
10173 borrowed-input owned-`String` forward-emit and \
10174 reverse-parse axes have drifted onto different \
10175 vocabularies"
10176 );
10177 }
10178 }
10179
10180 #[test]
10181 fn restart_strategy_from_into_static_cow_str_routes_through_as_str_accessor() {
10182 // Fail-before-pass-after byte-parity pin on the newly lifted
10183 // `impl From<RestartStrategy> for std::borrow::Cow<'static, str>` —
10184 // asserts the standard-library trait impl and the substrate-
10185 // primitive [`super::RestartStrategy::as_str`] `pub const fn`
10186 // accessor resolve to the same four-arm emit-set across every
10187 // arm the exhaustive [`super::RestartStrategy::ALL`] slice
10188 // enumerates. Rust's standard library does not carry a blanket
10189 // `impl<T: AsRef<str>> From<T> for Cow<'static, str>` (nor an
10190 // `impl<T: fmt::Display> From<T> for Cow<'static, str>`), so
10191 // the `Cow<'static, str>` forward-projection axis is a
10192 // distinct trait-idiomatic surface that a
10193 // `let key: Cow<'static, str> = strategy.into();`-shaped call
10194 // site reaches through this impl and no other — the paired
10195 // sibling `From<RestartStrategy> for &'static str` and
10196 // `From<RestartStrategy> for String` impls force every
10197 // `Cow<'static, str>`-parameterized call site through a
10198 // `Cow::Borrowed(strategy.as_str())` /
10199 // `Cow::Owned(strategy.to_string())` composition whose type
10200 // bounds have no compile-time link back to the substrate
10201 // primitive.
10202 //
10203 // Also asserts the projection lands on the zero-alloc
10204 // [`std::borrow::Cow::Borrowed`] arm (not the
10205 // [`std::borrow::Cow::Owned`] arm) — the substrate-primitive
10206 // [`super::RestartStrategy::as_str`] accessor's `&'static str`
10207 // return lifetime by construction makes the borrowed arm the
10208 // type-correct projection with no runtime allocation. Any
10209 // future silent detour that routes the impl through the owned
10210 // arm (an accidental `Cow::Owned(strategy.to_string())` rewrite
10211 // that would allocate on every call site where the
10212 // `&'static str` return of [`super::RestartStrategy::as_str`]
10213 // makes the zero-alloc borrowed projection type-correct) trips
10214 // at caixa-core test time under the
10215 // [`std::borrow::Cow::Borrowed`] discriminator witness rather
10216 // than at a downstream `Cow<'static, str>`-bound consumer's
10217 // silent allocation.
10218 //
10219 // First peer on the substrate-wide trait-idiomatic
10220 // [`std::borrow::Cow<'static, str>`] forward-projection family
10221 // to extend the axis off the top-level [`super::CaixaKind`]
10222 // enum (99c1735 owned-input, d45c409 borrowed-input) onto the
10223 // first M2 OTP-shape closed-set fieldless typed enum on the
10224 // caixa surface.
10225 for &variant in RestartStrategy::ALL {
10226 let via_trait: std::borrow::Cow<'static, str> =
10227 <std::borrow::Cow<'static, str> as From<RestartStrategy>>::from(variant);
10228 let via_method: &'static str = variant.as_str();
10229 assert_eq!(
10230 via_trait.as_ref(),
10231 via_method,
10232 "From<RestartStrategy> for Cow<'static, str> impl must \
10233 round-trip RestartStrategy::{variant:?} to the same \
10234 lifted SUPERVISOR_ESTRATEGIA_* const \
10235 RestartStrategy::as_str returns — divergence signals a \
10236 silent detour off the substrate-primitive accessor"
10237 );
10238 assert!(
10239 matches!(via_trait, std::borrow::Cow::Borrowed(_)),
10240 "From<RestartStrategy> for Cow<'static, str> impl must \
10241 land on the zero-alloc Cow::Borrowed arm on \
10242 RestartStrategy::{variant:?} — a Cow::Owned outcome \
10243 signals the projection has silently allocated where \
10244 the substrate-primitive RestartStrategy::as_str \
10245 `&'static str` return makes the borrowed arm the \
10246 type-correct projection"
10247 );
10248 let via_into: std::borrow::Cow<'static, str> = variant.into();
10249 assert_eq!(
10250 via_into.as_ref(),
10251 via_method,
10252 "Into<Cow<'static, str>>::into on \
10253 RestartStrategy::{variant:?} must byte-equal \
10254 RestartStrategy::as_str on the same input — the \
10255 blanket-derived Into shape must resolve to the same \
10256 as_str dispatch as the explicit From impl"
10257 );
10258 assert!(
10259 matches!(via_into, std::borrow::Cow::Borrowed(_)),
10260 "Into<Cow<'static, str>>::into on \
10261 RestartStrategy::{variant:?} must land on the \
10262 zero-alloc Cow::Borrowed arm — the blanket-derived \
10263 Into shape must resolve to the same Cow::Borrowed \
10264 dispatch as the explicit From impl"
10265 );
10266 }
10267 }
10268
10269 #[test]
10270 fn restart_strategy_from_into_static_cow_str_agrees_with_paired_axes_on_every_arm() {
10271 // Cross-axis partition pin: the newly lifted trait-idiomatic
10272 // `From<RestartStrategy> for std::borrow::Cow<'static, str>`
10273 // (this lift), the paired owned-input `From<RestartStrategy>
10274 // for &'static str` (523157d), and the paired owned-input
10275 // `From<RestartStrategy> for String` (7baa18a) forward
10276 // projections must resolve identically on every arm, locking
10277 // the three return-shape paths together by construction so any
10278 // future detour trips at caixa-core test time. Also byte-parity
10279 // witness against the sibling [`ToString::to_string`] surface
10280 // routed through [`std::fmt::Display`] — every owned-heap-
10281 // string path (the `Cow::Owned` promotion of this axis's
10282 // `.into_owned()`, `From<RestartStrategy> for String`, and
10283 // `.to_string()`) resolves to the same lifted
10284 // [`crate::render::SUPERVISOR_ESTRATEGIA_*`] const per arm.
10285 //
10286 // Then a `.iter().copied().map(std::borrow::Cow::from)` pipe
10287 // witness over [`super::RestartStrategy::ALL`] that
10288 // materializes the four-arm accept-set through the
10289 // [`std::borrow::Cow<'static, str>`] axis alone — the exact
10290 // shape a future `axum::response::IntoResponse` per-strategy
10291 // rejection-body composer, a future M4 admission-webhook
10292 // per-strategy rejection-reason emitter whose typing rules out
10293 // the sibling [`AsRef<str>`] borrowed return, or a future
10294 // substrate-wide per-strategy diagnostic surface that binds
10295 // through a [`Cow<'static, str>`] boundary reaches through.
10296 // The pipe witness also pins the zero-alloc discipline: every
10297 // element in the collected vector satisfies the
10298 // [`std::borrow::Cow::Borrowed`] arm predicate, so a future
10299 // accidental silent-allocation regression on the pipe's
10300 // iteration axis is a caixa-core-test-time failure.
10301 for &variant in RestartStrategy::ALL {
10302 let via_cow: std::borrow::Cow<'static, str> =
10303 <std::borrow::Cow<'static, str> as From<RestartStrategy>>::from(variant);
10304 let via_static: &'static str = <&'static str as From<RestartStrategy>>::from(variant);
10305 let via_string: String = <String as From<RestartStrategy>>::from(variant);
10306 assert_eq!(
10307 via_cow.as_ref(),
10308 via_static,
10309 "From<RestartStrategy> for Cow<'static, str> and \
10310 From<RestartStrategy> for &'static str must resolve \
10311 identically on RestartStrategy::{variant:?} — \
10312 divergence signals the Cow<'static, str> and \
10313 &'static str return-shape paths have drifted onto \
10314 different emit-sets"
10315 );
10316 assert_eq!(
10317 via_cow.as_ref(),
10318 via_string.as_str(),
10319 "From<RestartStrategy> for Cow<'static, str> and \
10320 From<RestartStrategy> for String must resolve \
10321 identically on RestartStrategy::{variant:?} — \
10322 divergence signals the Cow<'static, str> and String \
10323 return-shape paths have drifted onto different \
10324 emit-sets"
10325 );
10326 let via_to_string: String = variant.to_string();
10327 assert_eq!(
10328 via_cow.as_ref(),
10329 via_to_string.as_str(),
10330 "From<RestartStrategy> for Cow<'static, str> must \
10331 byte-equal RestartStrategy::to_string on \
10332 RestartStrategy::{variant:?} — divergence signals the \
10333 trait-idiomatic Cow<'static, str> forward-projection \
10334 axis and the ToString-through-Display axis have \
10335 drifted onto different emit-sets"
10336 );
10337 }
10338 let via_iter: Vec<std::borrow::Cow<'static, str>> = RestartStrategy::ALL
10339 .iter()
10340 .copied()
10341 .map(std::borrow::Cow::from)
10342 .collect();
10343 let via_method: Vec<std::borrow::Cow<'static, str>> = RestartStrategy::ALL
10344 .iter()
10345 .map(|s| std::borrow::Cow::Borrowed(s.as_str()))
10346 .collect();
10347 assert_eq!(
10348 via_iter, via_method,
10349 "`.iter().copied().map(Cow::from)` over \
10350 RestartStrategy::ALL must byte-equal `.iter().map(|s| \
10351 Cow::Borrowed(s.as_str()))` on every arm — the \
10352 trait-idiomatic `From<RestartStrategy> for Cow<'static, \
10353 str>` axis is what makes the `Cow::from` composition \
10354 route through the substrate-primitive \
10355 `RestartStrategy::as_str` accessor with the zero-alloc \
10356 Cow::Borrowed arm by construction, rather than a \
10357 per-call-site `Cow::Owned(strategy.to_string())` \
10358 allocation"
10359 );
10360 for cow in &via_iter {
10361 assert!(
10362 matches!(cow, std::borrow::Cow::Borrowed(_)),
10363 "every element of the \
10364 .iter().copied().map(Cow::from) pipe over \
10365 RestartStrategy::ALL must land on the zero-alloc \
10366 Cow::Borrowed arm — a Cow::Owned outcome on any arm \
10367 signals the pipe's iteration axis has silently \
10368 allocated where the substrate-primitive \
10369 RestartStrategy::as_str `&'static str` return makes \
10370 the borrowed arm the type-correct projection"
10371 );
10372 }
10373 }
10374
10375 #[test]
10376 fn restart_strategy_from_borrowed_into_static_cow_str_routes_through_as_str_accessor() {
10377 // Fail-before-pass-after byte-parity pin on the newly lifted
10378 // `impl From<&RestartStrategy> for std::borrow::Cow<'static, str>` —
10379 // asserts the borrowed-input standard-library trait impl and
10380 // the substrate-primitive [`super::RestartStrategy::as_str`]
10381 // `pub const fn` accessor resolve to the same four-arm emit-
10382 // set across every arm the exhaustive
10383 // [`super::RestartStrategy::ALL`] slice enumerates. Rust's
10384 // standard library does not carry a blanket
10385 // `impl<T: AsRef<str>> From<&T> for Cow<'static, str>` (nor a
10386 // `Copy`-based `impl<T: Copy, U: From<T>> From<&T> for U`), so
10387 // the borrowed-input `Cow<'static, str>` forward-projection
10388 // axis is a distinct trait-idiomatic surface that a
10389 // `let key: Cow<'static, str> = (&strategy).into();`-shaped
10390 // call site or a
10391 // `RestartStrategy::ALL.iter().map(Cow::from)`-shaped pipe
10392 // reaches through this impl and no other — the paired owned-
10393 // input `From<RestartStrategy> for Cow<'static, str>` impl
10394 // (7dd28b3) forces every borrowed-input call site through an
10395 // explicit `Copy` deref (`Cow::from(*strategy)`) or a
10396 // `Cow::Borrowed(strategy.as_str())` open-code whose type
10397 // bounds have no compile-time link back to the substrate
10398 // primitive.
10399 //
10400 // Also asserts the projection lands on the zero-alloc
10401 // [`std::borrow::Cow::Borrowed`] arm (not the
10402 // [`std::borrow::Cow::Owned`] arm) — the substrate-primitive
10403 // [`super::RestartStrategy::as_str`] accessor's `&'static str`
10404 // return lifetime by construction makes the borrowed arm the
10405 // type-correct projection with no runtime allocation on the
10406 // borrowed-input surface just as on the paired owned-input
10407 // surface.
10408 //
10409 // Second peer on the substrate-wide trait-idiomatic
10410 // [`std::borrow::Cow<'static, str>`] forward-projection family
10411 // on this enum — closes the `{Self, &Self}` input-shape
10412 // corner of the [`Cow<'static, str>`] axis on the first M2
10413 // OTP-shape closed-set fieldless typed enum peer on the caixa
10414 // surface (`:supervisor :estrategia`), exactly as d45c409
10415 // closed it on the top-level [`super::CaixaKind`] one commit
10416 // after the owning half (99c1735) landed. Every future
10417 // closed-set fieldless typed enum peer on the substrate is a
10418 // future target of the campaign.
10419 for &variant in RestartStrategy::ALL {
10420 let via_trait: std::borrow::Cow<'static, str> =
10421 <std::borrow::Cow<'static, str> as From<&RestartStrategy>>::from(&variant);
10422 let via_method: &'static str = variant.as_str();
10423 assert_eq!(
10424 via_trait.as_ref(),
10425 via_method,
10426 "From<&RestartStrategy> for Cow<'static, str> impl must \
10427 round-trip &RestartStrategy::{variant:?} to the same \
10428 lifted SUPERVISOR_ESTRATEGIA_* const \
10429 RestartStrategy::as_str returns — divergence signals a \
10430 silent detour off the substrate-primitive accessor"
10431 );
10432 assert!(
10433 matches!(via_trait, std::borrow::Cow::Borrowed(_)),
10434 "From<&RestartStrategy> for Cow<'static, str> impl must \
10435 land on the zero-alloc Cow::Borrowed arm on \
10436 &RestartStrategy::{variant:?} — a Cow::Owned outcome \
10437 signals the projection has silently allocated where \
10438 the substrate-primitive RestartStrategy::as_str \
10439 `&'static str` return makes the borrowed arm the \
10440 type-correct projection"
10441 );
10442 let via_into: std::borrow::Cow<'static, str> = (&variant).into();
10443 assert_eq!(
10444 via_into.as_ref(),
10445 via_method,
10446 "Into<Cow<'static, str>>::into on \
10447 &RestartStrategy::{variant:?} must byte-equal \
10448 RestartStrategy::as_str on the same input — the \
10449 blanket-derived Into shape must resolve to the same \
10450 as_str dispatch as the explicit From impl"
10451 );
10452 assert!(
10453 matches!(via_into, std::borrow::Cow::Borrowed(_)),
10454 "Into<Cow<'static, str>>::into on \
10455 &RestartStrategy::{variant:?} must land on the \
10456 zero-alloc Cow::Borrowed arm — the blanket-derived \
10457 Into shape must resolve to the same Cow::Borrowed \
10458 dispatch as the explicit From impl"
10459 );
10460 }
10461 }
10462
10463 #[test]
10464 fn restart_strategy_from_borrowed_into_static_cow_str_agrees_with_paired_axes_on_every_arm() {
10465 // Cross-axis partition pin: the newly lifted trait-idiomatic
10466 // borrowed-input `From<&RestartStrategy> for
10467 // std::borrow::Cow<'static, str>` (this lift), the paired
10468 // owned-input `From<RestartStrategy> for
10469 // std::borrow::Cow<'static, str>` (7dd28b3), the paired
10470 // borrowed-input owned-`&'static str` `From<&RestartStrategy>
10471 // for &'static str`, and the paired borrowed-input owned-
10472 // `String` `From<&RestartStrategy> for String` must resolve
10473 // identically on every arm, locking the four
10474 // return-shape × input-shape paths together by construction so
10475 // any future detour trips at caixa-core test time. Also byte-
10476 // parity witness against the sibling [`ToString::to_string`]
10477 // surface routed through [`std::fmt::Display`] — every owned-
10478 // heap-string path (this axis's `.into_owned()` promotion, the
10479 // paired [`From<&RestartStrategy> for String`], and
10480 // `.to_string()`) resolves to the same lifted
10481 // [`crate::render::SUPERVISOR_ESTRATEGIA_*`] const per arm.
10482 //
10483 // Then a `.iter().map(std::borrow::Cow::from)` pipe witness
10484 // over [`super::RestartStrategy::ALL`] — whose iterator yields
10485 // `&RestartStrategy` by construction, so the borrowed-input
10486 // [`Cow<'static, str>`] axis is what routes the pipe through
10487 // the substrate-primitive [`super::RestartStrategy::as_str`]
10488 // accessor without a spurious [`Copy`] deref (which would only
10489 // be reachable through the owned-input
10490 // [`From<RestartStrategy> for Cow<'static, str>`] axis by
10491 // first calling `.copied()` on the iterator). The pipe witness
10492 // also pins the zero-alloc discipline: every element in the
10493 // collected vector satisfies the [`std::borrow::Cow::Borrowed`]
10494 // arm predicate, so a future accidental silent-allocation
10495 // regression on the pipe's iteration axis is a caixa-core-
10496 // test-time failure.
10497 for &strategy in RestartStrategy::ALL {
10498 let borrowed_cow: std::borrow::Cow<'static, str> =
10499 <std::borrow::Cow<'static, str> as From<&RestartStrategy>>::from(&strategy);
10500 let owned_cow: std::borrow::Cow<'static, str> =
10501 <std::borrow::Cow<'static, str> as From<RestartStrategy>>::from(strategy);
10502 let borrowed_static: &'static str =
10503 <&'static str as From<&RestartStrategy>>::from(&strategy);
10504 let borrowed_string: String = <String as From<&RestartStrategy>>::from(&strategy);
10505 assert_eq!(
10506 borrowed_cow, owned_cow,
10507 "From<&RestartStrategy> for Cow<'static, str> and \
10508 From<RestartStrategy> for Cow<'static, str> must \
10509 resolve identically on RestartStrategy::{strategy:?} — \
10510 divergence signals the borrowed-input and owned-input \
10511 Cow<'static, str> forward-projection input-shape \
10512 paths have drifted onto different emit-sets"
10513 );
10514 assert_eq!(
10515 borrowed_cow.as_ref(),
10516 borrowed_static,
10517 "From<&RestartStrategy> for Cow<'static, str> and \
10518 From<&RestartStrategy> for &'static str must resolve \
10519 identically on RestartStrategy::{strategy:?} — \
10520 divergence signals the borrowed-input Cow<'static, \
10521 str> and &'static str return-shape paths have drifted \
10522 onto different emit-sets"
10523 );
10524 assert_eq!(
10525 borrowed_cow.as_ref(),
10526 borrowed_string.as_str(),
10527 "From<&RestartStrategy> for Cow<'static, str> and \
10528 From<&RestartStrategy> for String must resolve \
10529 identically on RestartStrategy::{strategy:?} — \
10530 divergence signals the borrowed-input Cow<'static, \
10531 str> and owned-`String` return-shape paths have \
10532 drifted onto different emit-sets"
10533 );
10534 let via_to_string: String = strategy.to_string();
10535 assert_eq!(
10536 borrowed_cow.as_ref(),
10537 via_to_string.as_str(),
10538 "From<&RestartStrategy> for Cow<'static, str> must \
10539 byte-equal RestartStrategy::to_string on \
10540 RestartStrategy::{strategy:?} — divergence signals \
10541 the trait-idiomatic borrowed-input Cow<'static, str> \
10542 forward-projection axis and the ToString-through-\
10543 Display axis have drifted onto different emit-sets"
10544 );
10545 }
10546 let via_iter: Vec<std::borrow::Cow<'static, str>> = RestartStrategy::ALL
10547 .iter()
10548 .map(std::borrow::Cow::from)
10549 .collect();
10550 let via_method: Vec<std::borrow::Cow<'static, str>> = RestartStrategy::ALL
10551 .iter()
10552 .map(|s| std::borrow::Cow::Borrowed(s.as_str()))
10553 .collect();
10554 assert_eq!(
10555 via_iter, via_method,
10556 "`.iter().map(Cow::from)` over RestartStrategy::ALL — a \
10557 call site whose iteration axis holds `&RestartStrategy` \
10558 by construction — must byte-equal `.iter().map(|s| \
10559 Cow::Borrowed(s.as_str()))` on every arm — the borrowed-\
10560 input Cow<'static, str> `From<&RestartStrategy> for \
10561 Cow<'static, str>` axis is what makes the `Cow::from` \
10562 composition route through the substrate-primitive \
10563 `RestartStrategy::as_str` accessor with the zero-alloc \
10564 Cow::Borrowed arm by construction and without a spurious \
10565 `Copy` deref (which would only be reachable through the \
10566 owned-input `From<RestartStrategy> for Cow<'static, str>` \
10567 axis by first calling `.copied()` on the iterator)"
10568 );
10569 for cow in &via_iter {
10570 assert!(
10571 matches!(cow, std::borrow::Cow::Borrowed(_)),
10572 "every element of the .iter().map(Cow::from) pipe \
10573 over RestartStrategy::ALL must land on the zero-\
10574 alloc Cow::Borrowed arm — a Cow::Owned outcome on \
10575 any arm signals the pipe's iteration axis has \
10576 silently allocated where the substrate-primitive \
10577 RestartStrategy::as_str `&'static str` return makes \
10578 the borrowed arm the type-correct projection"
10579 );
10580 }
10581 }
10582
10583 #[test]
10584 fn restart_strategy_from_into_box_str_routes_through_as_str_accessor() {
10585 // Fail-before-pass-after byte-parity pin on the newly lifted
10586 // `impl From<RestartStrategy> for Box<str>` — asserts the
10587 // owned-input standard-library trait impl and the
10588 // substrate-primitive [`super::RestartStrategy::as_str`]
10589 // `pub const fn` accessor resolve to the same four-arm emit-
10590 // set across every arm the exhaustive
10591 // [`super::RestartStrategy::ALL`] slice enumerates. Opens the
10592 // substrate-wide `Box<str>` forward-projection campaign tier
10593 // on the first M2 OTP-shape closed-set fieldless typed enum
10594 // peer on the caixa surface (`:supervisor :estrategia`),
10595 // immediately after the paired `Cow<'static, str>` axis
10596 // (7dd28b3 / ee577fd) closed the
10597 // `{Self, &Self} × {&'static str, String, Cow<'static, str>}`
10598 // 2×3 corner on this enum. Rust's standard library carries
10599 // `impl From<&str> for Box<str>` and
10600 // `impl From<String> for Box<str>` but no blanket
10601 // `impl<T: AsRef<str>> From<T> for Box<str>`, so this axis is
10602 // a distinct trait-idiomatic surface that a
10603 // `let key: Box<str> = strategy.into();`-shaped call site
10604 // reaches through this impl and no other — a paired
10605 // `Box::from(strategy.as_str())` open-code has no compile-
10606 // time link back to the substrate primitive.
10607 for &variant in RestartStrategy::ALL {
10608 let via_trait: Box<str> = <Box<str> as From<RestartStrategy>>::from(variant);
10609 let via_method: &'static str = variant.as_str();
10610 assert_eq!(
10611 via_trait.as_ref(),
10612 via_method,
10613 "From<RestartStrategy> for Box<str> impl must round-\
10614 trip RestartStrategy::{variant:?} to the same lifted \
10615 SUPERVISOR_ESTRATEGIA_* const RestartStrategy::as_str \
10616 returns — divergence signals a silent detour off the \
10617 substrate-primitive accessor"
10618 );
10619 let via_into: Box<str> = variant.into();
10620 assert_eq!(
10621 via_into.as_ref(),
10622 via_method,
10623 "Into<Box<str>>::into on RestartStrategy::{variant:?} \
10624 must byte-equal RestartStrategy::as_str on the same \
10625 input — the blanket-derived Into shape must resolve \
10626 to the same as_str dispatch as the explicit From impl"
10627 );
10628 }
10629 }
10630
10631 #[test]
10632 fn restart_strategy_from_borrowed_into_box_str_routes_through_as_str_accessor() {
10633 // Fail-before-pass-after byte-parity pin on the newly lifted
10634 // `impl From<&RestartStrategy> for Box<str>` — asserts the
10635 // borrowed-input standard-library trait impl and the
10636 // substrate-primitive [`super::RestartStrategy::as_str`]
10637 // `pub const fn` accessor resolve to the same four-arm emit-
10638 // set across every arm the exhaustive
10639 // [`super::RestartStrategy::ALL`] slice enumerates. Rust's
10640 // standard library does not carry a blanket
10641 // `impl<T: AsRef<str>> From<&T> for Box<str>` (nor a
10642 // `Copy`-based `impl<T: Copy, U: From<T>> From<&T> for U`),
10643 // so the borrowed-input `Box<str>` forward-projection axis
10644 // is a distinct trait-idiomatic surface that a
10645 // `let key: Box<str> = (&strategy).into();`-shaped call site
10646 // or a `RestartStrategy::ALL.iter().map(Box::<str>::from)`-
10647 // shaped pipe reaches through this impl and no other — the
10648 // paired owned-input `From<RestartStrategy> for Box<str>`
10649 // impl (69ef45c) forces every borrowed-input call site
10650 // through an explicit `Copy` deref
10651 // (`Box::<str>::from((*strategy).as_str())`) or a
10652 // `Box::<str>::from(strategy.as_str())` open-code whose
10653 // type bounds have no compile-time link back to the
10654 // substrate primitive.
10655 //
10656 // Second peer on the substrate-wide trait-idiomatic
10657 // [`Box<str>`] forward-projection family on this enum —
10658 // closes the `{Self, &Self}` input-shape corner of the
10659 // [`Box<str>`] axis on the first M2 OTP-shape closed-set
10660 // fieldless typed enum peer on the caixa surface
10661 // (`:supervisor :estrategia`), exactly as ee577fd closed
10662 // the paired [`Cow<'static, str>`] axis one commit after
10663 // its owning half (7dd28b3) landed. Every future closed-
10664 // set fieldless typed enum peer on the substrate is a
10665 // future target of the campaign.
10666 //
10667 // Also byte-parity witness against the paired owned-input
10668 // [`From<RestartStrategy> for Box<str>`] and the sibling
10669 // borrowed-input [`From<&RestartStrategy> for &'static str`],
10670 // [`From<&RestartStrategy> for String`], and
10671 // [`From<&RestartStrategy> for Cow<'static, str>`]
10672 // return-shape axes — locking the four
10673 // return-shape × input-shape paths together by construction
10674 // so any future detour trips at caixa-core test time. Then a
10675 // `.iter().map(Box::<str>::from)` pipe witness over
10676 // [`super::RestartStrategy::ALL`] — whose iterator yields
10677 // `&RestartStrategy` by construction, so the borrowed-input
10678 // [`Box<str>`] axis is what routes the pipe through the
10679 // substrate-primitive [`super::RestartStrategy::as_str`]
10680 // accessor without a spurious [`Copy`] deref (which would
10681 // only be reachable through the owned-input
10682 // [`From<RestartStrategy> for Box<str>`] axis by first
10683 // calling `.copied()` on the iterator).
10684 for &variant in RestartStrategy::ALL {
10685 let via_trait: Box<str> = <Box<str> as From<&RestartStrategy>>::from(&variant);
10686 let via_method: &'static str = variant.as_str();
10687 assert_eq!(
10688 via_trait.as_ref(),
10689 via_method,
10690 "From<&RestartStrategy> for Box<str> impl must \
10691 round-trip &RestartStrategy::{variant:?} to the same \
10692 lifted SUPERVISOR_ESTRATEGIA_* const \
10693 RestartStrategy::as_str returns — divergence signals \
10694 a silent detour off the substrate-primitive accessor"
10695 );
10696 let via_into: Box<str> = (&variant).into();
10697 assert_eq!(
10698 via_into.as_ref(),
10699 via_method,
10700 "Into<Box<str>>::into on &RestartStrategy::{variant:?} \
10701 must byte-equal RestartStrategy::as_str on the same \
10702 input — the blanket-derived Into shape must resolve \
10703 to the same as_str dispatch as the explicit From impl"
10704 );
10705 let owned_box: Box<str> = <Box<str> as From<RestartStrategy>>::from(variant);
10706 assert_eq!(
10707 via_trait, owned_box,
10708 "From<&RestartStrategy> for Box<str> and \
10709 From<RestartStrategy> for Box<str> must resolve \
10710 identically on RestartStrategy::{variant:?} — \
10711 divergence signals the borrowed-input and owned-input \
10712 Box<str> forward-projection input-shape paths have \
10713 drifted onto different emit-sets"
10714 );
10715 let borrowed_static: &'static str =
10716 <&'static str as From<&RestartStrategy>>::from(&variant);
10717 assert_eq!(
10718 via_trait.as_ref(),
10719 borrowed_static,
10720 "From<&RestartStrategy> for Box<str> and \
10721 From<&RestartStrategy> for &'static str must resolve \
10722 identically on RestartStrategy::{variant:?} — \
10723 divergence signals the borrowed-input Box<str> and \
10724 &'static str return-shape paths have drifted onto \
10725 different emit-sets"
10726 );
10727 let borrowed_string: String = <String as From<&RestartStrategy>>::from(&variant);
10728 assert_eq!(
10729 via_trait.as_ref(),
10730 borrowed_string.as_str(),
10731 "From<&RestartStrategy> for Box<str> and \
10732 From<&RestartStrategy> for String must resolve \
10733 identically on RestartStrategy::{variant:?} — \
10734 divergence signals the borrowed-input Box<str> and \
10735 owned-`String` return-shape paths have drifted onto \
10736 different emit-sets"
10737 );
10738 let borrowed_cow: std::borrow::Cow<'static, str> =
10739 <std::borrow::Cow<'static, str> as From<&RestartStrategy>>::from(&variant);
10740 assert_eq!(
10741 via_trait.as_ref(),
10742 borrowed_cow.as_ref(),
10743 "From<&RestartStrategy> for Box<str> and \
10744 From<&RestartStrategy> for Cow<'static, str> must \
10745 resolve identically on RestartStrategy::{variant:?} — \
10746 divergence signals the borrowed-input Box<str> and \
10747 Cow<'static, str> return-shape paths have drifted \
10748 onto different emit-sets"
10749 );
10750 }
10751 let via_iter: Vec<Box<str>> = RestartStrategy::ALL.iter().map(Box::<str>::from).collect();
10752 let via_method: Vec<Box<str>> = RestartStrategy::ALL
10753 .iter()
10754 .map(|s| Box::<str>::from(s.as_str()))
10755 .collect();
10756 assert_eq!(
10757 via_iter, via_method,
10758 "`.iter().map(Box::<str>::from)` over \
10759 RestartStrategy::ALL — a call site whose iteration axis \
10760 holds `&RestartStrategy` by construction — must byte-\
10761 equal `.iter().map(|s| Box::<str>::from(s.as_str()))` \
10762 on every arm — the borrowed-input Box<str> \
10763 `From<&RestartStrategy> for Box<str>` axis is what \
10764 makes the `Box::<str>::from` composition route through \
10765 the substrate-primitive `RestartStrategy::as_str` \
10766 accessor without a spurious `Copy` deref (which would \
10767 only be reachable through the owned-input \
10768 `From<RestartStrategy> for Box<str>` axis by first \
10769 calling `.copied()` on the iterator)"
10770 );
10771 }
10772
10773 #[test]
10774 fn restart_strategy_from_into_arc_str_routes_through_as_str_accessor() {
10775 // Fail-before-pass-after byte-parity pin on the newly lifted
10776 // `impl From<RestartStrategy> for std::sync::Arc<str>` — asserts
10777 // the owned-input standard-library trait impl and the
10778 // substrate-primitive [`super::RestartStrategy::as_str`]
10779 // `pub const fn` accessor resolve to the same four-arm emit-
10780 // set across every arm the exhaustive
10781 // [`super::RestartStrategy::ALL`] slice enumerates. Opens the
10782 // substrate-wide [`std::sync::Arc<str>`] forward-projection
10783 // campaign tier on the first M2 OTP-shape closed-set fieldless
10784 // typed enum peer on the caixa surface
10785 // (`:supervisor :estrategia`), immediately after the paired
10786 // [`Box<str>`] axis (69ef45c / 59ae5dc) closed the
10787 // `{Self, &Self} × {&'static str, String, Cow<'static, str>,
10788 // Box<str>}` 2×4 corner on this enum. Rust's standard library
10789 // carries `impl From<&str> for std::sync::Arc<str>` and
10790 // `impl From<String> for std::sync::Arc<str>` but no blanket
10791 // `impl<T: AsRef<str>> From<T> for std::sync::Arc<str>` (nor
10792 // an `impl<T: fmt::Display> From<T> for std::sync::Arc<str>`),
10793 // so this axis is a distinct trait-idiomatic surface that a
10794 // `let key: std::sync::Arc<str> = strategy.into();`-shaped call
10795 // site reaches through this impl and no other — a paired
10796 // `std::sync::Arc::<str>::from(strategy.as_str())` open-code
10797 // has no compile-time link back to the substrate primitive,
10798 // and a two-step `std::sync::Arc::<str>::from(String::from(
10799 // strategy))` composition through the owned-`String` axis
10800 // allocates twice (once into the intermediate `String`, once
10801 // into the [`Arc<str>`] on the `From<String>` conversion)
10802 // where the single-step trait impl allocates once.
10803 //
10804 // Cross-axis byte-parity witness against the sibling owned-
10805 // input `{&'static str, String, Cow<'static, str>, Box<str>}`
10806 // return-shape axes — locking the five return-shape paths on
10807 // the owned-input surface together by construction so any
10808 // future detour off the substrate-primitive
10809 // [`super::RestartStrategy::as_str`] accessor trips at caixa-
10810 // core test time.
10811 for &variant in RestartStrategy::ALL {
10812 let via_trait: std::sync::Arc<str> =
10813 <std::sync::Arc<str> as From<RestartStrategy>>::from(variant);
10814 let via_method: &'static str = variant.as_str();
10815 assert_eq!(
10816 via_trait.as_ref(),
10817 via_method,
10818 "From<RestartStrategy> for std::sync::Arc<str> impl \
10819 must round-trip RestartStrategy::{variant:?} to the \
10820 same lifted SUPERVISOR_ESTRATEGIA_* const \
10821 RestartStrategy::as_str returns — divergence signals \
10822 a silent detour off the substrate-primitive accessor"
10823 );
10824 let via_into: std::sync::Arc<str> = variant.into();
10825 assert_eq!(
10826 via_into.as_ref(),
10827 via_method,
10828 "Into<std::sync::Arc<str>>::into on \
10829 RestartStrategy::{variant:?} must byte-equal \
10830 RestartStrategy::as_str on the same input — the \
10831 blanket-derived Into shape must resolve to the same \
10832 as_str dispatch as the explicit From impl"
10833 );
10834 let owned_static: &'static str = <&'static str as From<RestartStrategy>>::from(variant);
10835 assert_eq!(
10836 via_trait.as_ref(),
10837 owned_static,
10838 "From<RestartStrategy> for std::sync::Arc<str> and \
10839 From<RestartStrategy> for &'static str must resolve \
10840 identically on RestartStrategy::{variant:?} — \
10841 divergence signals the owned-input std::sync::Arc<str> \
10842 and &'static str return-shape paths have drifted onto \
10843 different emit-sets"
10844 );
10845 let owned_string: String = <String as From<RestartStrategy>>::from(variant);
10846 assert_eq!(
10847 via_trait.as_ref(),
10848 owned_string.as_str(),
10849 "From<RestartStrategy> for std::sync::Arc<str> and \
10850 From<RestartStrategy> for String must resolve \
10851 identically on RestartStrategy::{variant:?} — \
10852 divergence signals the owned-input std::sync::Arc<str> \
10853 and owned-`String` return-shape paths have drifted \
10854 onto different emit-sets"
10855 );
10856 let owned_cow: std::borrow::Cow<'static, str> =
10857 <std::borrow::Cow<'static, str> as From<RestartStrategy>>::from(variant);
10858 assert_eq!(
10859 via_trait.as_ref(),
10860 owned_cow.as_ref(),
10861 "From<RestartStrategy> for std::sync::Arc<str> and \
10862 From<RestartStrategy> for Cow<'static, str> must \
10863 resolve identically on RestartStrategy::{variant:?} — \
10864 divergence signals the owned-input std::sync::Arc<str> \
10865 and Cow<'static, str> return-shape paths have drifted \
10866 onto different emit-sets"
10867 );
10868 let owned_box: Box<str> = <Box<str> as From<RestartStrategy>>::from(variant);
10869 assert_eq!(
10870 via_trait.as_ref(),
10871 owned_box.as_ref(),
10872 "From<RestartStrategy> for std::sync::Arc<str> and \
10873 From<RestartStrategy> for Box<str> must resolve \
10874 identically on RestartStrategy::{variant:?} — \
10875 divergence signals the owned-input std::sync::Arc<str> \
10876 and Box<str> return-shape paths have drifted onto \
10877 different emit-sets"
10878 );
10879 }
10880 }
10881
10882 #[test]
10883 fn restart_strategy_from_borrowed_into_arc_str_routes_through_as_str_accessor() {
10884 // Fail-before-pass-after byte-parity pin on the newly lifted
10885 // `impl From<&RestartStrategy> for std::sync::Arc<str>` —
10886 // asserts the borrowed-input standard-library trait impl and
10887 // the substrate-primitive [`super::RestartStrategy::as_str`]
10888 // `pub const fn` accessor resolve to the same four-arm emit-
10889 // set across every arm the exhaustive
10890 // [`super::RestartStrategy::ALL`] slice enumerates. Rust's
10891 // standard library does not carry a blanket
10892 // `impl<T: AsRef<str>> From<&T> for std::sync::Arc<str>` (nor
10893 // a `Copy`-based `impl<T: Copy, U: From<T>> From<&T> for U`),
10894 // so the borrowed-input [`std::sync::Arc<str>`] forward-
10895 // projection axis is a distinct trait-idiomatic surface that a
10896 // `let key: std::sync::Arc<str> = (&strategy).into();`-shaped
10897 // call site or a
10898 // `RestartStrategy::ALL.iter().map(std::sync::Arc::<str>::from)`-
10899 // shaped pipe reaches through this impl and no other — the
10900 // paired owned-input
10901 // `From<RestartStrategy> for std::sync::Arc<str>` impl
10902 // (bca2ec8) forces every borrowed-input call site through an
10903 // explicit `Copy` deref
10904 // (`std::sync::Arc::<str>::from((*strategy).as_str())`) or a
10905 // `std::sync::Arc::<str>::from(strategy.as_str())` open-code
10906 // whose type bounds have no compile-time link back to the
10907 // substrate primitive.
10908 //
10909 // Second peer on the substrate-wide trait-idiomatic
10910 // [`std::sync::Arc<str>`] forward-projection family on this
10911 // enum — closes the `{Self, &Self}` input-shape corner of
10912 // the [`std::sync::Arc<str>`] axis on the first M2 OTP-shape
10913 // closed-set fieldless typed enum peer on the caixa surface
10914 // (`:supervisor :estrategia`), exactly as 59ae5dc closed the
10915 // paired [`Box<str>`] axis one commit after its owning half
10916 // (69ef45c) landed. Every future closed-set fieldless typed
10917 // enum peer on the substrate is a future target of the
10918 // campaign.
10919 //
10920 // Also byte-parity witness against the paired owned-input
10921 // [`From<RestartStrategy> for std::sync::Arc<str>`] and the
10922 // sibling borrowed-input
10923 // [`From<&RestartStrategy> for &'static str`],
10924 // [`From<&RestartStrategy> for String`],
10925 // [`From<&RestartStrategy> for Cow<'static, str>`], and
10926 // [`From<&RestartStrategy> for Box<str>`] return-shape axes —
10927 // locking the five return-shape × input-shape paths together
10928 // by construction so any future detour trips at caixa-core
10929 // test time. Then a
10930 // `.iter().map(std::sync::Arc::<str>::from)` pipe witness over
10931 // [`super::RestartStrategy::ALL`] — whose iterator yields
10932 // `&RestartStrategy` by construction, so the borrowed-input
10933 // [`std::sync::Arc<str>`] axis is what routes the pipe
10934 // through the substrate-primitive
10935 // [`super::RestartStrategy::as_str`] accessor without a
10936 // spurious [`Copy`] deref (which would only be reachable
10937 // through the owned-input
10938 // [`From<RestartStrategy> for std::sync::Arc<str>`] axis by
10939 // first calling `.copied()` on the iterator).
10940 for &variant in RestartStrategy::ALL {
10941 let via_trait: std::sync::Arc<str> =
10942 <std::sync::Arc<str> as From<&RestartStrategy>>::from(&variant);
10943 let via_method: &'static str = variant.as_str();
10944 assert_eq!(
10945 via_trait.as_ref(),
10946 via_method,
10947 "From<&RestartStrategy> for std::sync::Arc<str> impl \
10948 must round-trip &RestartStrategy::{variant:?} to the \
10949 same lifted SUPERVISOR_ESTRATEGIA_* const \
10950 RestartStrategy::as_str returns — divergence signals \
10951 a silent detour off the substrate-primitive accessor"
10952 );
10953 let via_into: std::sync::Arc<str> = (&variant).into();
10954 assert_eq!(
10955 via_into.as_ref(),
10956 via_method,
10957 "Into<std::sync::Arc<str>>::into on \
10958 &RestartStrategy::{variant:?} must byte-equal \
10959 RestartStrategy::as_str on the same input — the \
10960 blanket-derived Into shape must resolve to the same \
10961 as_str dispatch as the explicit From impl"
10962 );
10963 let owned_arc: std::sync::Arc<str> =
10964 <std::sync::Arc<str> as From<RestartStrategy>>::from(variant);
10965 assert_eq!(
10966 via_trait, owned_arc,
10967 "From<&RestartStrategy> for std::sync::Arc<str> and \
10968 From<RestartStrategy> for std::sync::Arc<str> must \
10969 resolve identically on RestartStrategy::{variant:?} — \
10970 divergence signals the borrowed-input and owned-input \
10971 std::sync::Arc<str> forward-projection input-shape \
10972 paths have drifted onto different emit-sets"
10973 );
10974 let borrowed_static: &'static str =
10975 <&'static str as From<&RestartStrategy>>::from(&variant);
10976 assert_eq!(
10977 via_trait.as_ref(),
10978 borrowed_static,
10979 "From<&RestartStrategy> for std::sync::Arc<str> and \
10980 From<&RestartStrategy> for &'static str must resolve \
10981 identically on RestartStrategy::{variant:?} — \
10982 divergence signals the borrowed-input \
10983 std::sync::Arc<str> and &'static str return-shape \
10984 paths have drifted onto different emit-sets"
10985 );
10986 let borrowed_string: String = <String as From<&RestartStrategy>>::from(&variant);
10987 assert_eq!(
10988 via_trait.as_ref(),
10989 borrowed_string.as_str(),
10990 "From<&RestartStrategy> for std::sync::Arc<str> and \
10991 From<&RestartStrategy> for String must resolve \
10992 identically on RestartStrategy::{variant:?} — \
10993 divergence signals the borrowed-input \
10994 std::sync::Arc<str> and owned-`String` return-shape \
10995 paths have drifted onto different emit-sets"
10996 );
10997 let borrowed_cow: std::borrow::Cow<'static, str> =
10998 <std::borrow::Cow<'static, str> as From<&RestartStrategy>>::from(&variant);
10999 assert_eq!(
11000 via_trait.as_ref(),
11001 borrowed_cow.as_ref(),
11002 "From<&RestartStrategy> for std::sync::Arc<str> and \
11003 From<&RestartStrategy> for Cow<'static, str> must \
11004 resolve identically on RestartStrategy::{variant:?} — \
11005 divergence signals the borrowed-input \
11006 std::sync::Arc<str> and Cow<'static, str> return-shape \
11007 paths have drifted onto different emit-sets"
11008 );
11009 let borrowed_box: Box<str> = <Box<str> as From<&RestartStrategy>>::from(&variant);
11010 assert_eq!(
11011 via_trait.as_ref(),
11012 borrowed_box.as_ref(),
11013 "From<&RestartStrategy> for std::sync::Arc<str> and \
11014 From<&RestartStrategy> for Box<str> must resolve \
11015 identically on RestartStrategy::{variant:?} — \
11016 divergence signals the borrowed-input \
11017 std::sync::Arc<str> and Box<str> return-shape paths \
11018 have drifted onto different emit-sets"
11019 );
11020 }
11021 let via_iter: Vec<std::sync::Arc<str>> = RestartStrategy::ALL
11022 .iter()
11023 .map(std::sync::Arc::<str>::from)
11024 .collect();
11025 let via_method: Vec<std::sync::Arc<str>> = RestartStrategy::ALL
11026 .iter()
11027 .map(|s| std::sync::Arc::<str>::from(s.as_str()))
11028 .collect();
11029 assert_eq!(
11030 via_iter, via_method,
11031 "`.iter().map(std::sync::Arc::<str>::from)` over \
11032 RestartStrategy::ALL — a call site whose iteration axis \
11033 holds `&RestartStrategy` by construction — must byte-\
11034 equal `.iter().map(|s| std::sync::Arc::<str>::from(s.as_str()))` \
11035 on every arm — the borrowed-input std::sync::Arc<str> \
11036 `From<&RestartStrategy> for std::sync::Arc<str>` axis is \
11037 what makes the `std::sync::Arc::<str>::from` composition \
11038 route through the substrate-primitive \
11039 `RestartStrategy::as_str` accessor without a spurious \
11040 `Copy` deref (which would only be reachable through the \
11041 owned-input `From<RestartStrategy> for std::sync::Arc<str>` \
11042 axis by first calling `.copied()` on the iterator)"
11043 );
11044 }
11045
11046 #[test]
11047 #[allow(
11048 clippy::too_many_lines,
11049 reason = "cross-axis partition pin folds the substrate-primitive \
11050 as_str accessor's `.as_bytes()` byte-tail plus the \
11051 paired str-view (AsRef<str>, Display, as_str) and \
11052 reverse-projection ({&'static str, String, Cow<'static, \
11053 str>, Box<str>, std::sync::Arc<str>}) return-shape \
11054 axes' `.as_bytes()` byte-tails plus a <T: AsRef<[u8]>>\
11055 -bound-consumer witness plus a blake3::Hasher::update-\
11056 shape byte-input surface witness into one exhaustive \
11057 round-trip over RestartStrategy::ALL — the accepted \
11058 line-count cost of opening the byte-view axis keyed \
11059 to the substrate-primitive as_str accessor at the \
11060 same test-site"
11061 )]
11062 #[allow(
11063 clippy::needless_borrows_for_generic_args,
11064 reason = "the borrowed-input surface (&variant) is exercised \
11065 deliberately: the `<T: AsRef<[u8]>>`-bound consumer \
11066 and the `blake3::Hasher::update`-shape byte-input \
11067 surface both accept either owned or borrowed input \
11068 through the standard-library blanket \
11069 `impl<T: ?Sized + AsRef<[u8]>> AsRef<[u8]> for &T`, \
11070 and this pin round-trips both input shapes to lock \
11071 the borrowed-input path load-bearing against a \
11072 future silent regression"
11073 )]
11074 fn restart_strategy_as_ref_bytes_routes_through_as_str_accessor() {
11075 // `<T: AsRef<[u8]>>`-bound generic-consumer witness: a byte-input
11076 // function that binds its argument through the standard-library
11077 // [`AsRef<[u8]>`] trait bound accepts a [`super::RestartStrategy`]
11078 // directly, without the caller open-coding the two-hop
11079 // `estrategia.as_str().as_bytes()` composition. Lifted to the top
11080 // of the function per `clippy::items_after_statements`.
11081 fn generic_bytes_sink<T: AsRef<[u8]>>(t: T) -> Vec<u8> {
11082 t.as_ref().to_vec()
11083 }
11084 // `blake3::Hasher::update`-shape byte-input surface mock: mirrors
11085 // `blake3::Hasher::update` / `ring::digest::Context::update` /
11086 // `sha2::Sha256::update`'s `impl AsRef<[u8]>`-bound `update`
11087 // signature so a per-supervisor BLAKE3 content-address closure
11088 // that composes `hasher.update(estrategia)` on the
11089 // [`crate::Lacre`] closure builder reaches the substrate-primitive
11090 // `as_str` accessor through the [`super::RestartStrategy`]
11091 // `AsRef<[u8]>` axis and no other. Lifted to the top of the
11092 // function per `clippy::items_after_statements`.
11093 struct MockHasher(Vec<u8>);
11094 impl MockHasher {
11095 fn new() -> Self {
11096 Self(Vec::new())
11097 }
11098 fn update(&mut self, bytes: impl AsRef<[u8]>) -> &mut Self {
11099 self.0.extend_from_slice(bytes.as_ref());
11100 self
11101 }
11102 fn finalize(self) -> Vec<u8> {
11103 self.0
11104 }
11105 }
11106
11107 // Fail-before-pass-after byte-parity pin on the newly lifted
11108 // `impl AsRef<[u8]> for RestartStrategy` — asserts the trait-
11109 // idiomatic byte-view standard-library impl and the substrate-
11110 // primitive [`super::RestartStrategy::as_str`] `pub const fn`
11111 // accessor's `.as_bytes()` byte-tail resolve to the same four-arm
11112 // `PascalCase` wire byte-string emit-set across every arm the
11113 // exhaustive [`super::RestartStrategy::ALL`] slice enumerates.
11114 // Opens the trait-idiomatic byte-view axis onto the first M2
11115 // OTP-shape closed-set fieldless typed enum peer on the caixa
11116 // surface (`:supervisor :estrategia`), extending the substrate-
11117 // wide byte-view campaign the sibling
11118 // [`super::crate::CaixaKind`] first-mover (69d8d86) opened.
11119 //
11120 // Rust's standard library carries `impl AsRef<[u8]> for str` and
11121 // `impl AsRef<[u8]> for String`, so a two-hop composition
11122 // `estrategia.as_str().as_bytes()` (or the equally two-hop
11123 // `AsRef::<str>::as_ref(&estrategia).as_bytes()`) is reachable
11124 // through the pre-existing str-view axis alone. But that two-hop
11125 // shape has no compile-time link back to the byte-projection
11126 // axis, forces every downstream `<T: AsRef<[u8]>>`-bound
11127 // consumer to open-code the two-hop composition at every call
11128 // site, and admits a silent split whenever a future call site
11129 // takes a sibling reverse-projection axis whose `.as_bytes()`
11130 // byte-tail carries no compile-time byte-view surface. This
11131 // impl closes the byte-view axis at the substrate-primitive
11132 // [`super::RestartStrategy::as_str`] accessor so every future
11133 // `<T: AsRef<[u8]>>`-bound consumer reaches the same lifted
11134 // [`super::crate::render::SUPERVISOR_ESTRATEGIA_*`] const roster
11135 // the paired str-view axes already return through — through one
11136 // trait dispatch.
11137 for &variant in RestartStrategy::ALL {
11138 let via_trait: &[u8] = <RestartStrategy as AsRef<[u8]>>::as_ref(&variant);
11139 let via_method_bytes: &[u8] = variant.as_str().as_bytes();
11140 assert_eq!(
11141 via_trait, via_method_bytes,
11142 "AsRef<[u8]> for RestartStrategy impl must byte-equal \
11143 RestartStrategy::as_str().as_bytes() on \
11144 RestartStrategy::{variant:?} — divergence signals a \
11145 silent detour off the substrate-primitive accessor"
11146 );
11147 // Cross-axis witness against the paired str-view axes'
11148 // `.as_bytes()` byte-tails: [`AsRef<str>`] /
11149 // [`std::fmt::Display`] / [`super::RestartStrategy::as_str`]
11150 // all resolve to the same lifted
11151 // [`super::crate::render::SUPERVISOR_ESTRATEGIA_*`] const
11152 // roster, and the byte-view axis must byte-equal each of
11153 // their `.as_bytes()` byte-tails by construction — locking
11154 // the str-view and byte-view axes together at the
11155 // substrate-primitive accessor.
11156 let str_view_ref: &str = <RestartStrategy as AsRef<str>>::as_ref(&variant);
11157 assert_eq!(
11158 via_trait,
11159 str_view_ref.as_bytes(),
11160 "AsRef<[u8]> for RestartStrategy and AsRef<str> for \
11161 RestartStrategy must resolve to byte-equal byte-tails \
11162 on RestartStrategy::{variant:?} — divergence signals \
11163 the byte-view and str-view axes have drifted off the \
11164 same substrate-primitive as_str accessor"
11165 );
11166 let display_bytes = variant.to_string();
11167 assert_eq!(
11168 via_trait,
11169 display_bytes.as_bytes(),
11170 "AsRef<[u8]> for RestartStrategy and \
11171 <RestartStrategy as std::fmt::Display>::to_string must \
11172 resolve to byte-equal byte-tails on \
11173 RestartStrategy::{variant:?} — divergence signals the \
11174 byte-view axis and the Display formatter axis have \
11175 drifted off the same substrate-primitive as_str \
11176 accessor"
11177 );
11178 // Cross-axis witness against the paired reverse-projection
11179 // axes' `.as_bytes()` byte-tails: every one of `{&'static
11180 // str, String, Cow<'static, str>, Box<str>,
11181 // std::sync::Arc<str>}` allocates (or borrows) the same
11182 // `PascalCase` wire byte-string the substrate-primitive
11183 // accessor emits, so the byte-view axis must byte-equal
11184 // each of their `.as_bytes()` byte-tails by construction.
11185 let owned_static: &'static str = <&'static str as From<RestartStrategy>>::from(variant);
11186 assert_eq!(
11187 via_trait,
11188 owned_static.as_bytes(),
11189 "AsRef<[u8]> for RestartStrategy and From<RestartStrategy> \
11190 for &'static str must resolve to byte-equal byte-tails \
11191 on RestartStrategy::{variant:?}"
11192 );
11193 let owned_string: String = <String as From<RestartStrategy>>::from(variant);
11194 assert_eq!(
11195 via_trait,
11196 owned_string.as_bytes(),
11197 "AsRef<[u8]> for RestartStrategy and From<RestartStrategy> \
11198 for String must resolve to byte-equal byte-tails on \
11199 RestartStrategy::{variant:?}"
11200 );
11201 let owned_cow: std::borrow::Cow<'static, str> =
11202 <std::borrow::Cow<'static, str> as From<RestartStrategy>>::from(variant);
11203 assert_eq!(
11204 via_trait,
11205 owned_cow.as_bytes(),
11206 "AsRef<[u8]> for RestartStrategy and From<RestartStrategy> \
11207 for Cow<'static, str> must resolve to byte-equal byte-\
11208 tails on RestartStrategy::{variant:?}"
11209 );
11210 let owned_box: Box<str> = <Box<str> as From<RestartStrategy>>::from(variant);
11211 assert_eq!(
11212 via_trait,
11213 owned_box.as_bytes(),
11214 "AsRef<[u8]> for RestartStrategy and From<RestartStrategy> \
11215 for Box<str> must resolve to byte-equal byte-tails on \
11216 RestartStrategy::{variant:?}"
11217 );
11218 let owned_arc: std::sync::Arc<str> =
11219 <std::sync::Arc<str> as From<RestartStrategy>>::from(variant);
11220 assert_eq!(
11221 via_trait,
11222 owned_arc.as_bytes(),
11223 "AsRef<[u8]> for RestartStrategy and From<RestartStrategy> \
11224 for std::sync::Arc<str> must resolve to byte-equal byte-\
11225 tails on RestartStrategy::{variant:?}"
11226 );
11227 }
11228 // `<T: AsRef<[u8]>>`-bound-consumer witness: the generic byte-
11229 // input function `generic_bytes_sink` (lifted above per
11230 // `clippy::items_after_statements`) accepts a
11231 // [`super::RestartStrategy`] directly through the trait bound,
11232 // without the caller open-coding the two-hop
11233 // `estrategia.as_str().as_bytes()` composition. This is the
11234 // shape that reaches the caixa-lacre BLAKE3 content-address
11235 // closure's `blake3::Hasher::update(impl AsRef<[u8]>)` byte-
11236 // input surface through this impl and no other.
11237 for &variant in RestartStrategy::ALL {
11238 let via_generic = generic_bytes_sink(variant);
11239 let via_borrowed_generic = generic_bytes_sink(&variant);
11240 let via_method_bytes = variant.as_str().as_bytes().to_vec();
11241 assert_eq!(
11242 via_generic, via_method_bytes,
11243 "generic `<T: AsRef<[u8]>>`-bound consumer on \
11244 RestartStrategy::{variant:?} must yield the same byte-\
11245 tail RestartStrategy::as_str().as_bytes() returns — \
11246 divergence signals the byte-view axis fails to bridge \
11247 a generic byte-input trait bound to the substrate-\
11248 primitive accessor"
11249 );
11250 assert_eq!(
11251 via_borrowed_generic, via_method_bytes,
11252 "generic `<T: AsRef<[u8]>>`-bound consumer on \
11253 &RestartStrategy::{variant:?} must yield the same byte-\
11254 tail RestartStrategy::as_str().as_bytes() returns — \
11255 the borrowed-input surface must resolve to the same \
11256 as_str dispatch"
11257 );
11258 }
11259 // `blake3::Hasher::update`-shape byte-input surface witness on
11260 // the caixa-lacre compounding target: the `MockHasher` (lifted
11261 // above per `clippy::items_after_statements`) mirrors
11262 // `blake3::Hasher::update` / `ring::digest::Context::update` /
11263 // `sha2::Sha256::update`'s `impl AsRef<[u8]>`-bound update
11264 // signature and accepts a [`super::RestartStrategy`] directly,
11265 // routing its byte-tail through the substrate-primitive
11266 // `as_str` accessor — the shape a future per-supervisor BLAKE3
11267 // content-address closure composes to fold an `:estrategia`
11268 // discriminator byte-tag into the [`crate::Lacre`] closure
11269 // body.
11270 for &variant in RestartStrategy::ALL {
11271 let mut owned_hasher = MockHasher::new();
11272 owned_hasher.update(variant);
11273 let owned_folded = owned_hasher.finalize();
11274 assert_eq!(
11275 owned_folded,
11276 variant.as_str().as_bytes(),
11277 "`hasher.update(estrategia)`-shape composition on \
11278 RestartStrategy::{variant:?} must fold the same byte-\
11279 tail RestartStrategy::as_str().as_bytes() returns — \
11280 the shape a future per-supervisor BLAKE3 content-\
11281 address closure composes to fold an `:estrategia` \
11282 discriminator byte-tag into the Lacre closure body"
11283 );
11284 let mut borrowed_hasher = MockHasher::new();
11285 borrowed_hasher.update(&variant);
11286 let borrowed_folded = borrowed_hasher.finalize();
11287 assert_eq!(
11288 borrowed_folded,
11289 variant.as_str().as_bytes(),
11290 "`hasher.update(&estrategia)`-shape composition on \
11291 &RestartStrategy::{variant:?} must fold the same byte-\
11292 tail RestartStrategy::as_str().as_bytes() returns — \
11293 the borrowed-input surface must resolve to the same \
11294 as_str dispatch"
11295 );
11296 }
11297 }
11298
11299 #[test]
11300 #[expect(
11301 clippy::too_many_lines,
11302 reason = "the byte-owned reverse-projection axis is extended \
11303 here onto the first M2-OTP-shape closed-set fieldless \
11304 typed-enum peer, so the pin binds the new impl against \
11305 every paired byte-view and str-owned axis on the same \
11306 enum plus a generic <T: Into<Vec<u8>>>-bound consumer \
11307 witness and a std::io::Write::write_all-shape owned-\
11308 byte-sink surface witness on both owned and borrowed \
11309 input shapes to lock the whole family against a future \
11310 silent regression"
11311 )]
11312 fn restart_strategy_from_into_owned_vec_bytes_routes_through_as_str_accessor() {
11313 // `<T: Into<Vec<u8>>>`-bound-consumer witness helper: a generic
11314 // owned-byte-input function accepts a [`super::RestartStrategy`]
11315 // directly through the trait bound, without the caller open-
11316 // coding the three-hop `strategy.as_str().as_bytes().to_vec()`
11317 // composition. Lifted to the top of the function per
11318 // `clippy::items_after_statements`.
11319 fn generic_owned_bytes_sink<T: Into<Vec<u8>>>(t: T) -> Vec<u8> {
11320 t.into()
11321 }
11322 // `std::io::Write::write_all`-shape owned-byte-sink surface
11323 // mock: mirrors `std::io::Write::write_all` /
11324 // `bytes::BytesMut::extend_from_slice` / any per-arm audit-log
11325 // byte-sink that consumes a `Vec<u8>` payload via
11326 // `Into<Vec<u8>>`, so a future per-supervisor per-`:estrategia`
11327 // audit-log emit reaches the substrate-primitive `as_str`
11328 // accessor through the byte-owned reverse-projection axis and
11329 // no other. Lifted to the top of the function per
11330 // `clippy::items_after_statements`.
11331 struct MockOwnedByteSink(Vec<u8>);
11332 impl MockOwnedByteSink {
11333 fn new() -> Self {
11334 Self(Vec::new())
11335 }
11336 fn write_all(&mut self, bytes: impl Into<Vec<u8>>) -> &mut Self {
11337 self.0.extend_from_slice(&bytes.into());
11338 self
11339 }
11340 fn finalize(self) -> Vec<u8> {
11341 self.0
11342 }
11343 }
11344
11345 // Fail-before-pass-after byte-parity pin on the newly lifted
11346 // `impl From<RestartStrategy> for Vec<u8>` and
11347 // `impl From<&RestartStrategy> for Vec<u8>` — asserts the trait-
11348 // idiomatic byte-owned reverse-projection standard-library
11349 // impls and the substrate-primitive
11350 // [`super::RestartStrategy::as_str`] `pub const fn` accessor's
11351 // `.as_bytes().to_vec()` byte-tail resolve to the same four-arm
11352 // PascalCase wire byte-string emit-set across every arm the
11353 // exhaustive [`super::RestartStrategy::ALL`] slice enumerates.
11354 // Extends the substrate-wide trait-idiomatic byte-owned
11355 // reverse-projection axis onto the first M2-OTP-shape closed-
11356 // set fieldless typed-enum peer on the caixa surface
11357 // (`:supervisor :estrategia`), matching the trajectory the
11358 // first-mover [`super::crate::CaixaKind`] lift (b245fd6), the
11359 // second-mover [`super::crate::dialeto::CaixaDialeto`] lift
11360 // (4cceaf5), and the third-mover
11361 // [`super::crate::dep::DepList`] lift (e974ca2) established
11362 // across the caixa-core-internal tier.
11363 for &variant in RestartStrategy::ALL {
11364 let via_owned_from: Vec<u8> = <Vec<u8> as From<RestartStrategy>>::from(variant);
11365 let via_borrowed_from: Vec<u8> = <Vec<u8> as From<&RestartStrategy>>::from(&variant);
11366 let via_method_bytes: Vec<u8> = variant.as_str().as_bytes().to_vec();
11367 assert_eq!(
11368 via_owned_from, via_method_bytes,
11369 "From<RestartStrategy> for Vec<u8> impl must byte-equal \
11370 RestartStrategy::as_str().as_bytes().to_vec() on \
11371 RestartStrategy::{variant:?} — divergence signals a \
11372 silent detour off the substrate-primitive accessor"
11373 );
11374 assert_eq!(
11375 via_borrowed_from, via_method_bytes,
11376 "From<&RestartStrategy> for Vec<u8> impl must byte-\
11377 equal RestartStrategy::as_str().as_bytes().to_vec() \
11378 on RestartStrategy::{variant:?} — divergence signals \
11379 a silent detour off the substrate-primitive accessor"
11380 );
11381 assert_eq!(
11382 via_owned_from, via_borrowed_from,
11383 "From<RestartStrategy> for Vec<u8> and \
11384 From<&RestartStrategy> for Vec<u8> must byte-equal \
11385 each other on RestartStrategy::{variant:?} — \
11386 divergence signals the owned-input and borrowed-input \
11387 paths have drifted off the same substrate-primitive \
11388 as_str accessor"
11389 );
11390 // Cross-axis witness against the paired [`AsRef<[u8]>`]
11391 // borrowed byte-view axis (cd4c4e0): the byte-owned
11392 // reverse-projection axis must byte-equal the paired
11393 // borrowed byte-view axis by construction — locking the
11394 // byte-view and byte-owned axes together at the substrate-
11395 // primitive accessor.
11396 let borrowed_bytes: &[u8] = <RestartStrategy as AsRef<[u8]>>::as_ref(&variant);
11397 assert_eq!(
11398 via_owned_from,
11399 borrowed_bytes.to_vec(),
11400 "From<RestartStrategy> for Vec<u8> and AsRef<[u8]> \
11401 for RestartStrategy must resolve to byte-equal byte-\
11402 tails on RestartStrategy::{variant:?} — divergence \
11403 signals the byte-owned and byte-view axes have \
11404 drifted off the same substrate-primitive as_str \
11405 accessor"
11406 );
11407 // Cross-axis witness against the str-owned reverse-
11408 // projection family's `.into_bytes()` / `.as_bytes().to_vec()`
11409 // byte-tails: every one of `{String, Cow<'static, str>,
11410 // Box<str>, std::sync::Arc<str>, std::rc::Rc<str>}`
11411 // allocates (or borrows) the same PascalCase wire byte-
11412 // string the substrate-primitive accessor emits, so the
11413 // byte-owned axis must byte-equal each of their owned
11414 // byte-tails by construction.
11415 let owned_string: String = <String as From<RestartStrategy>>::from(variant);
11416 assert_eq!(
11417 via_owned_from,
11418 owned_string.into_bytes(),
11419 "From<RestartStrategy> for Vec<u8> and \
11420 String::from(strategy).into_bytes() must resolve to \
11421 byte-equal byte-tails on RestartStrategy::{variant:?}"
11422 );
11423 let owned_cow: std::borrow::Cow<'static, str> =
11424 <std::borrow::Cow<'static, str> as From<RestartStrategy>>::from(variant);
11425 assert_eq!(
11426 via_owned_from,
11427 owned_cow.as_bytes().to_vec(),
11428 "From<RestartStrategy> for Vec<u8> and \
11429 From<RestartStrategy> for Cow<'static, str> must \
11430 resolve to byte-equal byte-tails on \
11431 RestartStrategy::{variant:?}"
11432 );
11433 let owned_box: Box<str> = <Box<str> as From<RestartStrategy>>::from(variant);
11434 assert_eq!(
11435 via_owned_from,
11436 owned_box.as_bytes().to_vec(),
11437 "From<RestartStrategy> for Vec<u8> and \
11438 From<RestartStrategy> for Box<str> must resolve to \
11439 byte-equal byte-tails on RestartStrategy::{variant:?}"
11440 );
11441 let owned_arc: std::sync::Arc<str> =
11442 <std::sync::Arc<str> as From<RestartStrategy>>::from(variant);
11443 assert_eq!(
11444 via_owned_from,
11445 owned_arc.as_bytes().to_vec(),
11446 "From<RestartStrategy> for Vec<u8> and \
11447 From<RestartStrategy> for std::sync::Arc<str> must \
11448 resolve to byte-equal byte-tails on \
11449 RestartStrategy::{variant:?}"
11450 );
11451 }
11452 // `<T: Into<Vec<u8>>>`-bound-consumer witness on both owned
11453 // and borrowed input shapes: the generic owned-byte-input
11454 // function `generic_owned_bytes_sink` (lifted above per
11455 // `clippy::items_after_statements`) accepts a
11456 // [`super::RestartStrategy`] and a `&RestartStrategy`
11457 // directly through the trait bound, without the caller open-
11458 // coding the three-hop `strategy.as_str().as_bytes().to_vec()`
11459 // composition.
11460 for &variant in RestartStrategy::ALL {
11461 let via_generic_owned = generic_owned_bytes_sink(variant);
11462 // Bind the borrowed-input path through an explicit
11463 // `&RestartStrategy` local so the generic-consumer witness
11464 // routes through `From<&RestartStrategy> for Vec<u8>` (T
11465 // binds to `&RestartStrategy`) rather than clippy-collapsing
11466 // the borrow onto the owned-input peer.
11467 let variant_ref: &RestartStrategy = &variant;
11468 let via_generic_borrowed = generic_owned_bytes_sink(variant_ref);
11469 let via_method_bytes = variant.as_str().as_bytes().to_vec();
11470 assert_eq!(
11471 via_generic_owned, via_method_bytes,
11472 "generic `<T: Into<Vec<u8>>>`-bound consumer on \
11473 RestartStrategy::{variant:?} must yield the same byte-\
11474 tail RestartStrategy::as_str().as_bytes() returns — \
11475 divergence signals the byte-owned axis fails to bridge \
11476 a generic owned-byte-input trait bound to the \
11477 substrate-primitive accessor"
11478 );
11479 assert_eq!(
11480 via_generic_borrowed, via_method_bytes,
11481 "generic `<T: Into<Vec<u8>>>`-bound consumer on \
11482 &RestartStrategy::{variant:?} must yield the same byte-\
11483 tail RestartStrategy::as_str().as_bytes() returns — \
11484 the borrowed-input surface must resolve to the same \
11485 as_str dispatch"
11486 );
11487 }
11488 // `std::io::Write::write_all`-shape owned-byte-sink surface
11489 // witness: the `MockOwnedByteSink` (lifted above per
11490 // `clippy::items_after_statements`) mirrors
11491 // `std::io::Write::write_all` /
11492 // `bytes::BytesMut::extend_from_slice`'s `impl Into<Vec<u8>>`-
11493 // bound owned-byte input signature and accepts a
11494 // [`super::RestartStrategy`] directly on both owned and
11495 // borrowed input shapes, routing its byte-tail through the
11496 // substrate-primitive `as_str` accessor — the shape a future
11497 // per-supervisor per-`:estrategia` audit-log emit composes to
11498 // fold an `:estrategia` discriminator byte-tag into a
11499 // downstream owned-byte-sink surface.
11500 for &variant in RestartStrategy::ALL {
11501 let mut owned_sink = MockOwnedByteSink::new();
11502 owned_sink.write_all(variant);
11503 let owned_folded = owned_sink.finalize();
11504 assert_eq!(
11505 owned_folded,
11506 variant.as_str().as_bytes(),
11507 "`sink.write_all(strategy)`-shape composition on \
11508 RestartStrategy::{variant:?} must fold the same byte-\
11509 tail RestartStrategy::as_str().as_bytes() returns"
11510 );
11511 let mut borrowed_sink = MockOwnedByteSink::new();
11512 let variant_ref: &RestartStrategy = &variant;
11513 borrowed_sink.write_all(variant_ref);
11514 let borrowed_folded = borrowed_sink.finalize();
11515 assert_eq!(
11516 borrowed_folded,
11517 variant.as_str().as_bytes(),
11518 "`sink.write_all(&strategy)`-shape composition on \
11519 &RestartStrategy::{variant:?} must fold the same byte-\
11520 tail RestartStrategy::as_str().as_bytes() returns — \
11521 the borrowed-input surface must resolve to the same \
11522 as_str dispatch"
11523 );
11524 }
11525 }
11526
11527 #[test]
11528 fn restart_policy_try_from_str_routes_through_from_wire_accessor() {
11529 // Fail-before-pass-after byte-parity pin on the newly lifted
11530 // `impl TryFrom<&str> for RestartPolicy` — asserts the standard-
11531 // library trait impl and the substrate-primitive
11532 // [`RestartPolicy::from_wire`] `Option<Self>` accessor resolve to
11533 // the same three-arm accept-set across every arm the exhaustive
11534 // [`RestartPolicy::ALL`] slice enumerates. Any future silent
11535 // detour that routes the trait impl through a divergent
11536 // projection (a per-arm inline `match s { "Permanent" =>
11537 // Ok(Self::Permanent), … }` re-inlining that opens a compile-time
11538 // link to the un-lifted arm-literal, a hypothetical
11539 // `#[serde(rename_all = "…")]` attribute drift that silently
11540 // splits the wire byte-string from every consumer that reaches
11541 // for this typed dispatch, an accidental swap onto the kebab-case
11542 // dispatcher-catalog axis the pre-existing [`std::str::FromStr`]
11543 // impl parses through and which would collide the two-axis
11544 // wire/catalog split the sibling [`RestartPolicy::from_wire`]
11545 // doc block makes load-bearing) trips at caixa-core test time
11546 // under `assert_eq!` rather than at a downstream
11547 // `impl TryFrom<&str>`-bound consumer's silent split. Sweeps
11548 // every one of the three arms [`RestartPolicy::ALL`] carries so
11549 // no arm's projection is covered only by the sibling method-
11550 // named `from_wire` path. Peer of the sibling
11551 // [`restart_strategy_try_from_str_routes_through_from_wire_accessor`]
11552 // (5b828ed) — extends the trait-idiomatic reverse-projection
11553 // axis onto the third and final M2-OTP-shape closed-set typed
11554 // enum on the caixa surface (the paired per-child restart-
11555 // decision-policy sibling on the same M2 `:supervisor` slot).
11556 for &variant in RestartPolicy::ALL {
11557 let wire = variant.as_str();
11558 assert_eq!(
11559 <RestartPolicy as TryFrom<&str>>::try_from(wire),
11560 Ok(variant),
11561 "TryFrom<&str> impl on RestartPolicy must round-trip \
11562 RestartPolicy::{variant:?}.as_str() = {wire:?} back to \
11563 Ok(RestartPolicy::{variant:?}) — divergence from \
11564 RestartPolicy::from_wire signals a silent detour off \
11565 the substrate-primitive accessor"
11566 );
11567 assert_eq!(
11568 <RestartPolicy as TryFrom<&str>>::try_from(wire).ok(),
11569 RestartPolicy::from_wire(wire),
11570 "TryFrom<&str> ok()-projection on {wire:?} must byte-\
11571 equal RestartPolicy::from_wire on the same input"
11572 );
11573 }
11574 }
11575
11576 #[test]
11577 fn restart_policy_try_from_str_rejects_unknown_byte_strings() {
11578 // Rejection witness on the `impl TryFrom<&str> for
11579 // RestartPolicy` — sweeps a candidate set of byte-strings
11580 // outside the three-arm PascalCase wire accept-set the sibling
11581 // [`RestartPolicy::as_str`] emits and asserts every one lands on
11582 // `Err(())`, so a future accidental widening of the trait impl's
11583 // accept-set (a stray additional
11584 // `_ if s.eq_ignore_ascii_case("Permanent") => Ok(…)` case-fold
11585 // path, a silent inclusion of the kebab-case dispatcher-catalog
11586 // byte-string the pre-existing [`std::str::FromStr`] impl the
11587 // [`gen_platform::FromStrKind`] derive installs parses onto the
11588 // wire axis — which would collide the two-axis
11589 // wire/dispatcher-catalog split the sibling
11590 // [`RestartPolicy::from_wire`] doc block makes load-bearing —
11591 // an English-rebrand or plural-arm silent alias that would widen
11592 // the wire accept-set past the OTP-canonical three) trips at
11593 // caixa-core test time. The candidate set includes the empty
11594 // string, whitespace-only padding, the kebab-case dispatcher-
11595 // catalog byte-strings on the sibling axis (a caller who
11596 // confuses the two axes trips here rather than at a downstream
11597 // consumer's silent reject), a lowercase / uppercase / mixed-case
11598 // fold of each PascalCase arm (a caller who assumes case-fold
11599 // acceptance trips here), leading/trailing whitespace padding,
11600 // the trailing-newline shape, quote-wrapped candidates, and a
11601 // residual set of plausible-but-wrong English rebrand
11602 // candidates. Peer of the sibling
11603 // [`restart_strategy_try_from_str_rejects_unknown_byte_strings`]
11604 // (5b828ed) rejection witness.
11605 let rejected: &[&str] = &[
11606 "",
11607 " ",
11608 "\n",
11609 "\t",
11610 "permanent",
11611 "temporary",
11612 "transient",
11613 "PERMANENT",
11614 "TEMPORARY",
11615 "TRANSIENT",
11616 "Permanents",
11617 "Permanent ",
11618 " Permanent",
11619 " Temporary ",
11620 "Permanent\n",
11621 "Transient\t",
11622 "\"Permanent\"",
11623 "Ephemeral",
11624 "Always",
11625 "Never",
11626 "OnAbnormalExit",
11627 "intrinsic",
11628 "?",
11629 ];
11630 for &input in rejected {
11631 assert_eq!(
11632 <RestartPolicy as TryFrom<&str>>::try_from(input),
11633 Err(()),
11634 "TryFrom<&str> impl on RestartPolicy must reject the \
11635 non-wire byte-string {input:?} — silent acceptance \
11636 signals an accept-set widening off the paired \
11637 RestartPolicy::from_wire resolver"
11638 );
11639 }
11640 }
11641
11642 #[test]
11643 fn restart_policy_try_from_str_and_from_wire_partition_the_accept_set() {
11644 // Cross-axis partition pin: the paired `TryFrom<&str>` and
11645 // `from_wire` reverse projections must resolve identically on
11646 // *every* input, not just the ones [`RestartPolicy::ALL`]
11647 // enumerates. Sweeps a mixed candidate set spanning accepted
11648 // (three-arm PascalCase wire byte-strings) and rejected (kebab-
11649 // case dispatcher-catalog byte-strings, empty, whitespace-
11650 // padded, quoted, English-rebrand candidates) inputs and asserts
11651 // the trait's `Result::ok()` projection byte-equals the method-
11652 // named resolver's `Option<Self>` return-shape on each, locking
11653 // the two paths together by construction so any future detour
11654 // (a stray `try_from` special-case that widens or narrows the
11655 // accept-set outside the paired `from_wire` resolver, an
11656 // accidental swap onto the kebab-case [`std::str::FromStr`]
11657 // impl the [`gen_platform::FromStrKind`] derive installs on the
11658 // sibling dispatcher-catalog axis) trips at caixa-core test
11659 // time. Peer of the sibling
11660 // [`restart_strategy_try_from_str_and_from_wire_partition_the_accept_set`]
11661 // pin — extends the round-trip discipline onto the M2-OTP-shape
11662 // per-child restart-policy axis.
11663 let candidates: &[&str] = &[
11664 "Permanent",
11665 "Temporary",
11666 "Transient",
11667 "",
11668 "permanent",
11669 "temporary",
11670 "transient",
11671 "PERMANENT",
11672 "unknown",
11673 "Permanent ",
11674 " Permanent",
11675 "\"Permanent\"",
11676 "Ephemeral",
11677 "OnAbnormalExit",
11678 "?",
11679 ];
11680 for &input in candidates {
11681 let via_trait: Option<RestartPolicy> =
11682 <RestartPolicy as TryFrom<&str>>::try_from(input).ok();
11683 let via_method: Option<RestartPolicy> = RestartPolicy::from_wire(input);
11684 assert_eq!(
11685 via_trait, via_method,
11686 "TryFrom<&str> and from_wire must resolve identically on \
11687 input {input:?} — divergence signals the two reverse-\
11688 projection paths have drifted onto different accept-sets"
11689 );
11690 }
11691 }
11692
11693 #[test]
11694 fn restart_policy_from_into_static_str_routes_through_as_str_accessor() {
11695 // Fail-before-pass-after byte-parity pin on the newly lifted
11696 // `impl From<RestartPolicy> for &'static str` — asserts the
11697 // standard-library trait impl and the substrate-primitive
11698 // [`RestartPolicy::as_str`] `pub const fn` accessor resolve to
11699 // the same three-arm emit-set across every arm the exhaustive
11700 // [`RestartPolicy::ALL`] slice enumerates. Any future silent
11701 // detour that routes the trait impl through a divergent
11702 // projection (a per-arm inline `match policy { Permanent =>
11703 // "Permanent", … }` re-inlining that opens a compile-time link
11704 // to the un-lifted arm-literal, an accidental swap onto the
11705 // sibling kebab-case [`Self::discriminant`] dispatcher-catalog
11706 // axis that would collide the two-axis wire/catalog split the
11707 // sibling [`RestartPolicy::from_wire`] doc block makes
11708 // load-bearing) trips at caixa-core test time under
11709 // `assert_eq!` rather than at a downstream
11710 // `impl Into<&'static str>`-bound consumer's silent split.
11711 // Sweeps every one of the three arms [`RestartPolicy::ALL`]
11712 // carries so no arm's projection is covered only by the sibling
11713 // method-named `as_str` / [`std::fmt::Display`] / [`AsRef<str>`]
11714 // paths. Materializes the `<&'static str as
11715 // From<RestartPolicy>>::from` output in a `const`-shape binding
11716 // to make the `'static` lifetime promise a build-time invariant
11717 // — a future accidental downgrade of any of the three arms'
11718 // [`crate::render::SUPERVISOR_CHILD_RESTART_*`] constants to a
11719 // non-`&'static str` (a `String::leak()`-produced return, a
11720 // `Box::leak`-cast) trips at caixa-core build time rather than
11721 // at a downstream `'static`-bound consumer. Peer of the sibling
11722 // [`restart_strategy_from_into_static_str_routes_through_as_str_accessor`]
11723 // (523157d) — extends the trait-idiomatic forward-projection
11724 // axis onto the second (and second-of-two-in-M2) closed-set
11725 // typed enum on the caixa surface (the paired per-child
11726 // restart-decision-policy sibling on the same M2 `:supervisor`
11727 // slot).
11728 const PERMANENT: &str = RestartPolicy::Permanent.as_str();
11729 const TEMPORARY: &str = RestartPolicy::Temporary.as_str();
11730 const TRANSIENT: &str = RestartPolicy::Transient.as_str();
11731 for &variant in RestartPolicy::ALL {
11732 let via_trait: &'static str = <&'static str as From<RestartPolicy>>::from(variant);
11733 let via_method: &'static str = variant.as_str();
11734 assert_eq!(
11735 via_trait, via_method,
11736 "From<RestartPolicy> for &'static str impl must round-trip \
11737 RestartPolicy::{variant:?} to the same lifted \
11738 SUPERVISOR_CHILD_RESTART_* const RestartPolicy::as_str returns — \
11739 divergence signals a silent detour off the substrate-primitive \
11740 accessor"
11741 );
11742 let via_into: &'static str = variant.into();
11743 assert_eq!(
11744 via_into, via_method,
11745 "Into<&'static str>::into on RestartPolicy::{variant:?} must \
11746 byte-equal RestartPolicy::as_str on the same input — the \
11747 blanket-derived Into shape must resolve to the same as_str \
11748 dispatch as the explicit From impl"
11749 );
11750 }
11751 assert_eq!(
11752 [PERMANENT, TEMPORARY, TRANSIENT],
11753 [
11754 crate::render::SUPERVISOR_CHILD_RESTART_PERMANENT,
11755 crate::render::SUPERVISOR_CHILD_RESTART_TEMPORARY,
11756 crate::render::SUPERVISOR_CHILD_RESTART_TRANSIENT,
11757 ],
11758 "const-context RestartPolicy::as_str must resolve to the three \
11759 lifted SUPERVISOR_CHILD_RESTART_* consts — a future accidental \
11760 downgrade of any arm to a non-const or non-static byte-string \
11761 breaks the `&'static str`-lifetime promise the paired \
11762 From<RestartPolicy> for &'static str impl carries by \
11763 construction"
11764 );
11765 }
11766
11767 #[test]
11768 fn restart_policy_from_into_static_str_and_as_str_partition_the_emit_set() {
11769 // Cross-axis partition pin: the paired trait-idiomatic
11770 // `From<RestartPolicy> for &'static str` forward projection and
11771 // the method-named [`RestartPolicy::as_str`] forward projection
11772 // must resolve identically on *every* arm, not just the ones
11773 // named in the primary byte-parity pin above. Sweeps every
11774 // [`RestartPolicy::ALL`] arm and asserts the trait's `From::from`
11775 // output byte-equals the method-named accessor's return-value on
11776 // each, locking the two forward-projection paths together by
11777 // construction so any future detour (a stray `From` special-case
11778 // that lands on a divergent per-arm literal outside the paired
11779 // `as_str` dispatch, a hypothetical rebrand touching one axis
11780 // without the other) trips at caixa-core test time. Peer of the
11781 // sibling forward-projection partition pin
11782 // [`restart_strategy_from_into_static_str_and_as_str_partition_the_emit_set`]
11783 // (523157d) — extends the round-trip discipline onto the
11784 // second-of-two M2-OTP-shape closed-set typed enum on the caixa
11785 // surface, closing the two-way `Self ↔ &'static str` round-trip
11786 // on the trait-idiomatic pair (`From<Self> for &'static str` +
11787 // `TryFrom<&str> for Self`) as well as the pre-existing method-
11788 // named pair (`as_str` + `from_wire`).
11789 for &variant in RestartPolicy::ALL {
11790 let via_trait: &'static str = <&'static str as From<RestartPolicy>>::from(variant);
11791 let via_method: &'static str = variant.as_str();
11792 assert_eq!(
11793 via_trait, via_method,
11794 "From<RestartPolicy> for &'static str and \
11795 RestartPolicy::as_str must resolve identically on \
11796 RestartPolicy::{variant:?} — divergence signals the \
11797 two forward-projection paths have drifted onto different \
11798 emit-sets"
11799 );
11800 }
11801 // Round-trip witness: every arm's forward `From` output re-parses
11802 // through the paired trait-idiomatic reverse `TryFrom<&str>` back
11803 // to the original variant. Closes the two-way `RestartPolicy ↔
11804 // &'static str` round-trip on the trait-idiomatic axis pair,
11805 // mirroring the pre-existing method-named `as_str` + `from_wire`
11806 // round-trip on the substrate-primitive axis pair.
11807 for &variant in RestartPolicy::ALL {
11808 let emitted: &'static str = variant.into();
11809 let re_parsed: Result<RestartPolicy, ()> =
11810 <RestartPolicy as TryFrom<&str>>::try_from(emitted);
11811 assert_eq!(
11812 re_parsed,
11813 Ok(variant),
11814 "trait-idiomatic axis pair must round-trip \
11815 RestartPolicy::{variant:?} through `.into::<&'static \
11816 str>()` and back through `TryFrom<&str>` — a break signals \
11817 the forward-emit and reverse-parse axes have drifted onto \
11818 different vocabularies"
11819 );
11820 }
11821 }
11822
11823 #[test]
11824 fn restart_policy_from_borrowed_into_static_str_routes_through_as_str_accessor() {
11825 // Fail-before-pass-after byte-parity pin on the newly lifted
11826 // `impl From<&RestartPolicy> for &'static str` — asserts the
11827 // borrowed-input standard-library trait impl and the substrate-
11828 // primitive [`RestartPolicy::as_str`] `pub const fn` accessor
11829 // resolve to the same three-arm emit-set across every arm the
11830 // exhaustive [`RestartPolicy::ALL`] slice enumerates. Rust's
11831 // `From` trait does not auto-derive the borrowed-input sibling
11832 // from a paired owned-input impl (no `impl<T, U> From<&T> for U
11833 // where T: Copy, U: From<T>` blanket in `core`), so the
11834 // borrowed-input axis is a distinct trait-idiomatic surface
11835 // that a `.iter().map(Into::into)` shape over
11836 // [`RestartPolicy::ALL`] (whose iterator yields
11837 // `&RestartPolicy`, not `RestartPolicy`) reaches through this
11838 // impl and no other — the paired owned-input
11839 // [`From<RestartPolicy>`] impl requires an explicit `.copied()`
11840 // / dereference before the trait fires. Materializes the
11841 // `<&'static str as From<&RestartPolicy>>::from` output in a
11842 // `const`-shape binding to make the `'static` lifetime promise
11843 // a build-time invariant.
11844 const PERMANENT: &str = RestartPolicy::Permanent.as_str();
11845 const TEMPORARY: &str = RestartPolicy::Temporary.as_str();
11846 const TRANSIENT: &str = RestartPolicy::Transient.as_str();
11847 for variant in RestartPolicy::ALL {
11848 let via_trait: &'static str = <&'static str as From<&RestartPolicy>>::from(variant);
11849 let via_method: &'static str = variant.as_str();
11850 assert_eq!(
11851 via_trait, via_method,
11852 "From<&RestartPolicy> for &'static str impl must round-trip \
11853 &RestartPolicy::{variant:?} to the same lifted \
11854 SUPERVISOR_CHILD_RESTART_* const RestartPolicy::as_str \
11855 returns — divergence signals a silent detour off the \
11856 substrate-primitive accessor"
11857 );
11858 let via_into: &'static str = variant.into();
11859 assert_eq!(
11860 via_into, via_method,
11861 "Into<&'static str>::into on &RestartPolicy::{variant:?} \
11862 must byte-equal RestartPolicy::as_str on the same input — \
11863 the blanket-derived Into shape must resolve to the same \
11864 as_str dispatch as the explicit From impl"
11865 );
11866 }
11867 assert_eq!(
11868 [PERMANENT, TEMPORARY, TRANSIENT],
11869 [
11870 crate::render::SUPERVISOR_CHILD_RESTART_PERMANENT,
11871 crate::render::SUPERVISOR_CHILD_RESTART_TEMPORARY,
11872 crate::render::SUPERVISOR_CHILD_RESTART_TRANSIENT,
11873 ],
11874 "const-context RestartPolicy::as_str must resolve to the three \
11875 lifted SUPERVISOR_CHILD_RESTART_* consts — the borrowed-input \
11876 From<&RestartPolicy> for &'static str impl inherits its \
11877 `'static` lifetime promise from the same accessor the \
11878 owned-input sibling routes through"
11879 );
11880 }
11881
11882 #[test]
11883 fn restart_policy_from_owned_and_borrowed_into_static_str_agree_on_every_arm() {
11884 // Cross-axis partition pin: the paired trait-idiomatic
11885 // owned-input `From<RestartPolicy> for &'static str` (9fb37d0
11886 // campaign-shape) and borrowed-input `From<&RestartPolicy> for
11887 // &'static str` (this lift) forward projections must resolve
11888 // identically on every arm, locking the two input-shape paths
11889 // together so any future detour trips at caixa-core test time.
11890 // Then a witness that a `.iter().map(Into::into)` pipe over
11891 // [`RestartPolicy::ALL`] (whose iterator yields
11892 // `&RestartPolicy`) materializes the three-arm accept-set
11893 // through the borrowed-input axis alone — the exact shape a
11894 // future wasm-operator per-child post-exit restart-decision
11895 // diagnostic line, a future substrate-wide per-arm diagnostic
11896 // column, or a
11897 // `HashMap::<&'static str, RestartPolicy>::from_iter(
11898 // RestartPolicy::ALL.iter().map(|p| (p.into(), *p)))`-style
11899 // per-policy lookup reaches through — closing the two-way
11900 // owned/borrowed input-shape symmetry on the forward-projection
11901 // trait-idiomatic axis. Peer of the sibling
11902 // [`crate::dep::tests::dep_list_from_owned_and_borrowed_into_static_str_agree_on_every_arm`]
11903 // (64aa742) /
11904 // [`crate::kind::tests::caixa_kind_from_owned_and_borrowed_into_static_str_agree_on_every_arm`]
11905 // (5ab993a) /
11906 // [`crate::dialeto::tests::caixa_dialeto_from_owned_and_borrowed_into_static_str_agree_on_every_arm`]
11907 // (807b0b5) /
11908 // [`restart_strategy_from_owned_and_borrowed_into_static_str_agree_on_every_arm`]
11909 // (e941836) partition pins on the sibling closed-set typed-enum
11910 // discriminator axes — extends the borrowed-input axis
11911 // discipline onto the second-of-two M2 OTP-shape closed-set
11912 // typed enum on the caixa surface (per-child restart-decision
11913 // policy). Also closes the direct two-way `&Self → &'static
11914 // str → Self` round-trip via the paired [`TryFrom<&str>`] axis
11915 // — unlike the peer [`crate::CaixaKind`] axis pair (whose
11916 // forward `From` emits lowercase Portuguese diagnostic bytes
11917 // while the reverse `TryFrom` parses `PascalCase` wire bytes,
11918 // forcing the round-trip through an intermediate wire-vocab
11919 // hop), the [`RestartPolicy::as_str`] emit and
11920 // [`RestartPolicy::from_wire`] parse share the same
11921 // `PascalCase` vocabulary by construction, so the borrowed-
11922 // input forward axis and the reverse axis compose directly.
11923 for &variant in RestartPolicy::ALL {
11924 let owned: &'static str = <&'static str as From<RestartPolicy>>::from(variant);
11925 let borrowed: &'static str = <&'static str as From<&RestartPolicy>>::from(&variant);
11926 assert_eq!(
11927 owned, borrowed,
11928 "From<RestartPolicy> and From<&RestartPolicy> for \
11929 &'static str must resolve identically on \
11930 RestartPolicy::{variant:?} — divergence signals the \
11931 owned-input and borrowed-input forward-projection paths \
11932 have drifted onto different emit-sets"
11933 );
11934 }
11935 let via_iter: Vec<&'static str> = RestartPolicy::ALL.iter().map(Into::into).collect();
11936 let via_method: Vec<&'static str> = RestartPolicy::ALL.iter().map(|p| p.as_str()).collect();
11937 assert_eq!(
11938 via_iter, via_method,
11939 "`.iter().map(Into::into)` over RestartPolicy::ALL must \
11940 byte-equal `.iter().map(|p| p.as_str())` on every arm — the \
11941 borrowed-input `From<&RestartPolicy> for &'static str` axis \
11942 is what makes the `.iter().map(Into::into)` shape route \
11943 through the substrate-primitive `RestartPolicy::as_str` \
11944 accessor rather than through a per-call-site `.copied()` / \
11945 dereference detour"
11946 );
11947 for variant in RestartPolicy::ALL {
11948 let emitted: &'static str = variant.into();
11949 let re_parsed: Result<RestartPolicy, ()> =
11950 <RestartPolicy as TryFrom<&str>>::try_from(emitted);
11951 assert_eq!(
11952 re_parsed,
11953 Ok(*variant),
11954 "trait-idiomatic borrowed-input forward-projection + \
11955 reverse-projection axis pair must round-trip \
11956 &RestartPolicy::{variant:?} through `.into::<&'static \
11957 str>()` (via the borrowed-input axis) and back through \
11958 `TryFrom<&str>` — a break signals the borrowed-input \
11959 forward-emit and reverse-parse axes have drifted onto \
11960 different vocabularies"
11961 );
11962 }
11963 }
11964
11965 #[test]
11966 fn restart_policy_from_into_owned_string_routes_through_as_str_accessor() {
11967 // Fail-before-pass-after byte-parity pin on the newly lifted
11968 // `impl From<RestartPolicy> for String` — asserts the
11969 // owned-`String`-returning standard-library trait impl and the
11970 // substrate-primitive [`RestartPolicy::as_str`] `pub const fn`
11971 // accessor resolve to the same three-arm emit-set across every
11972 // arm the exhaustive [`RestartPolicy::ALL`] slice enumerates.
11973 // Rust's standard library does not carry a blanket
11974 // `impl<T: AsRef<str>> From<T> for String` (nor an
11975 // `impl<T: fmt::Display> From<T> for String`), so the
11976 // owned-`String` forward-projection axis is a distinct
11977 // trait-idiomatic surface that a `let key: String =
11978 // policy.into();`-shaped call site reaches through this impl
11979 // and no other — the paired sibling `From<RestartPolicy> for
11980 // &'static str` impl forces every owned-`String` call site
11981 // through an explicit `.to_owned()` / `String::from`
11982 // restatement. Peer of the first-mover
11983 // [`restart_strategy_from_into_owned_string_routes_through_as_str_accessor`]
11984 // (7baa18a) — extends the trait-idiomatic owned-`String`
11985 // forward-projection axis onto the second-of-two M2 OTP-shape
11986 // closed-set typed enums on the caixa surface (per-child
11987 // restart-decision-policy sibling on the same M2 `:supervisor`
11988 // slot).
11989 for &variant in RestartPolicy::ALL {
11990 let via_trait: String = <String as From<RestartPolicy>>::from(variant);
11991 let via_method: &'static str = variant.as_str();
11992 assert_eq!(
11993 via_trait.as_str(),
11994 via_method,
11995 "From<RestartPolicy> for String impl must round-trip \
11996 RestartPolicy::{variant:?} to the same lifted \
11997 SUPERVISOR_CHILD_RESTART_* const RestartPolicy::as_str \
11998 returns — divergence signals a silent detour off the \
11999 substrate-primitive accessor"
12000 );
12001 let via_into: String = variant.into();
12002 assert_eq!(
12003 via_into.as_str(),
12004 via_method,
12005 "Into<String>::into on RestartPolicy::{variant:?} must \
12006 byte-equal RestartPolicy::as_str on the same input — the \
12007 blanket-derived Into shape must resolve to the same as_str \
12008 dispatch as the explicit From impl"
12009 );
12010 }
12011 }
12012
12013 #[test]
12014 fn restart_policy_from_into_owned_string_and_static_str_agree_on_every_arm() {
12015 // Cross-axis partition pin: the paired trait-idiomatic
12016 // owned-`String` `From<RestartPolicy> for String` (this lift)
12017 // and owned-`&'static str` `From<RestartPolicy> for &'static
12018 // str` (9fb37d0) forward projections must resolve identically
12019 // on every arm, locking the two return-type-shape paths
12020 // together so any future detour trips at caixa-core test time.
12021 // Also byte-parity witness against the sibling
12022 // [`ToString::to_string`] surface routed through
12023 // [`std::fmt::Display`] — the three owned-heap-string paths
12024 // (`.into::<String>()`, `String::from`, `.to_string()`) must
12025 // resolve identically on every arm so a future consumer that
12026 // picks any of the three lands on the same lifted
12027 // SUPERVISOR_CHILD_RESTART_* const. Then a `.iter().copied()
12028 // .map(String::from)` pipe witness over [`RestartPolicy::ALL`]
12029 // that materializes the three-arm accept-set through the
12030 // owned-`String` axis alone — the exact shape a future
12031 // wasm-operator per-child post-exit restart-decision
12032 // diagnostic line composer or a
12033 // `HashMap::<String, RestartPolicy>::from_iter(
12034 // RestartPolicy::ALL.iter().copied().map(|p| (p.into(), p)))`-style
12035 // owned-key per-policy lookup reaches through — closing the
12036 // owned-`String` forward-projection axis's iterator-pipe
12037 // shape. Then a direct round-trip witness through the paired
12038 // trait-idiomatic reverse [`TryFrom<&str>`] axis on the
12039 // owned-`String`'s [`String::as_str`] borrow that closes the
12040 // two-way `Self → String → Self` round-trip on the trait-
12041 // idiomatic owned-`String` forward + reverse axis pair —
12042 // unlike the peer [`crate::CaixaKind`] axis pair (whose
12043 // forward `From` emits lowercase Portuguese diagnostic bytes
12044 // while the reverse `TryFrom` parses `PascalCase` wire bytes,
12045 // forcing the round-trip through an intermediate wire-vocab
12046 // hop), the [`RestartPolicy::as_str`] emit and
12047 // [`RestartPolicy::from_wire`] parse share the same
12048 // `PascalCase` vocabulary by construction, so the owned-
12049 // `String` forward axis and the reverse axis compose directly.
12050 for &variant in RestartPolicy::ALL {
12051 let owned_string: String = <String as From<RestartPolicy>>::from(variant);
12052 let owned_static: &'static str = <&'static str as From<RestartPolicy>>::from(variant);
12053 assert_eq!(
12054 owned_string.as_str(),
12055 owned_static,
12056 "From<RestartPolicy> for String and From<RestartPolicy> \
12057 for &'static str must resolve identically on \
12058 RestartPolicy::{variant:?} — divergence signals the \
12059 owned-`String` and owned-`&'static str` forward-projection \
12060 return-type-shape paths have drifted onto different \
12061 emit-sets"
12062 );
12063 let via_to_string: String = variant.to_string();
12064 assert_eq!(
12065 owned_string, via_to_string,
12066 "From<RestartPolicy> for String must byte-equal \
12067 RestartPolicy::to_string on RestartPolicy::{variant:?} — \
12068 divergence signals the trait-idiomatic owned-`String` \
12069 forward-projection axis and the ToString-through-Display \
12070 axis have drifted onto different emit-sets"
12071 );
12072 }
12073 let via_iter: Vec<String> = RestartPolicy::ALL
12074 .iter()
12075 .copied()
12076 .map(String::from)
12077 .collect();
12078 let via_method: Vec<String> = RestartPolicy::ALL
12079 .iter()
12080 .map(|p| p.as_str().to_owned())
12081 .collect();
12082 assert_eq!(
12083 via_iter, via_method,
12084 "`.iter().copied().map(String::from)` over RestartPolicy::ALL \
12085 must byte-equal `.iter().map(|p| p.as_str().to_owned())` on \
12086 every arm — the owned-`String` `From<RestartPolicy> for \
12087 String` axis is what makes the `String::from` composition \
12088 route through the substrate-primitive `RestartPolicy::as_str` \
12089 accessor rather than through a per-call-site `.to_owned()` / \
12090 `String::from(policy.as_str())` detour"
12091 );
12092 for &variant in RestartPolicy::ALL {
12093 let emitted: String = variant.into();
12094 let re_parsed: Result<RestartPolicy, ()> =
12095 <RestartPolicy as TryFrom<&str>>::try_from(emitted.as_str());
12096 assert_eq!(
12097 re_parsed,
12098 Ok(variant),
12099 "trait-idiomatic owned-`String` forward-projection + \
12100 reverse-projection axis pair must round-trip \
12101 RestartPolicy::{variant:?} through `.into::<String>()` \
12102 and back through `TryFrom<&str>` on the owned-`String`'s \
12103 String::as_str borrow — a break signals the owned-`String` \
12104 forward-emit and reverse-parse axes have drifted onto \
12105 different vocabularies"
12106 );
12107 }
12108 }
12109
12110 #[test]
12111 fn restart_policy_from_into_borrowed_owned_string_routes_through_as_str_accessor() {
12112 // Fail-before-pass-after byte-parity pin on the newly lifted
12113 // `impl From<&RestartPolicy> for String` — asserts the
12114 // borrowed-input owned-`String`-returning standard-library
12115 // trait impl and the substrate-primitive
12116 // [`RestartPolicy::as_str`] `pub const fn` accessor resolve to
12117 // the same three-arm emit-set across every arm the exhaustive
12118 // [`RestartPolicy::ALL`] slice enumerates. Rust's standard
12119 // library does not carry a blanket `impl<T: AsRef<str>>
12120 // From<&T> for String` (nor an `impl<T: fmt::Display> From<&T>
12121 // for String`), so the borrowed-input owned-`String` forward-
12122 // projection axis is a distinct trait-idiomatic surface that a
12123 // `let key: String = (&policy).into();`-shaped call site
12124 // reaches through this impl and no other — the paired sibling
12125 // `From<RestartPolicy> for String` impl forces every borrowed-
12126 // input call site through an explicit `Copy` deref
12127 // (`String::from(*policy)`) or an `.as_str().to_owned()` /
12128 // `.to_string()` detour. Peer of the first-mover
12129 // [`restart_strategy_from_into_borrowed_owned_string_routes_through_as_str_accessor`]
12130 // (579385f) — extends the trait-idiomatic borrowed-input
12131 // owned-`String` forward-projection axis onto the second-of-
12132 // two M2 OTP-shape closed-set typed enums on the caixa surface
12133 // (per-child restart-decision-policy sibling on the same M2
12134 // `:supervisor` slot).
12135 for &variant in RestartPolicy::ALL {
12136 let via_trait: String = <String as From<&RestartPolicy>>::from(&variant);
12137 let via_method: &'static str = variant.as_str();
12138 assert_eq!(
12139 via_trait.as_str(),
12140 via_method,
12141 "From<&RestartPolicy> for String impl must round-trip \
12142 &RestartPolicy::{variant:?} to the same lifted \
12143 SUPERVISOR_CHILD_RESTART_* const RestartPolicy::as_str \
12144 returns — divergence signals a silent detour off the \
12145 substrate-primitive accessor"
12146 );
12147 let via_into: String = (&variant).into();
12148 assert_eq!(
12149 via_into.as_str(),
12150 via_method,
12151 "Into<String>::into on &RestartPolicy::{variant:?} must \
12152 byte-equal RestartPolicy::as_str on the same input — \
12153 the blanket-derived Into shape must resolve to the \
12154 same as_str dispatch as the explicit From impl"
12155 );
12156 }
12157 }
12158
12159 #[test]
12160 fn restart_policy_from_into_borrowed_owned_string_agrees_with_paired_axes_on_every_arm() {
12161 // Cross-axis partition pin: the newly lifted trait-idiomatic
12162 // borrowed-input owned-`String` `From<&RestartPolicy> for
12163 // String` (this lift), the paired owned-input owned-`String`
12164 // `From<RestartPolicy> for String` (7851725), the paired
12165 // borrowed-input owned-`&'static str` `From<&RestartPolicy>
12166 // for &'static str` (842c7f3), and the paired owned-input
12167 // owned-`&'static str` `From<RestartPolicy> for &'static str`
12168 // (9fb37d0) — every corner of the `{Self, &Self} × {&'static
12169 // str, String}` 2×2 trait-idiomatic projection family — must
12170 // resolve identically on every arm, locking the four
12171 // return-shape × input-shape paths together so any future
12172 // detour trips at caixa-core test time. Also byte-parity
12173 // witness against the sibling [`ToString::to_string`] surface
12174 // routed through [`std::fmt::Display`] and a direct round-trip
12175 // witness through the paired trait-idiomatic reverse
12176 // [`TryFrom<&str>`] axis on the owned-`String`'s
12177 // [`String::as_str`] borrow that closes the two-way
12178 // `&Self → String → Self` round-trip on the trait-idiomatic
12179 // borrowed-input owned-`String` forward + reverse axis pair.
12180 // Peer of the first-mover
12181 // [`restart_strategy_from_into_borrowed_owned_string_agrees_with_paired_axes_on_every_arm`]
12182 // (579385f) — closes the whole `{Self, &Self} × {&'static str,
12183 // String}` 2×2 projection corner on both M2 OTP-shape sibling
12184 // peers.
12185 for &variant in RestartPolicy::ALL {
12186 let borrowed_string: String = <String as From<&RestartPolicy>>::from(&variant);
12187 let owned_string: String = <String as From<RestartPolicy>>::from(variant);
12188 let borrowed_static: &'static str =
12189 <&'static str as From<&RestartPolicy>>::from(&variant);
12190 let owned_static: &'static str = <&'static str as From<RestartPolicy>>::from(variant);
12191 assert_eq!(
12192 borrowed_string, owned_string,
12193 "From<&RestartPolicy> for String and From<RestartPolicy> \
12194 for String must resolve identically on \
12195 RestartPolicy::{variant:?} — divergence signals the \
12196 borrowed-input and owned-input owned-`String` \
12197 forward-projection input-shape paths have drifted onto \
12198 different emit-sets"
12199 );
12200 assert_eq!(
12201 borrowed_string.as_str(),
12202 borrowed_static,
12203 "From<&RestartPolicy> for String and From<&RestartPolicy> \
12204 for &'static str must resolve identically on \
12205 RestartPolicy::{variant:?} — divergence signals the \
12206 borrowed-input `&'static str` and owned-`String` \
12207 return-shape paths have drifted onto different \
12208 emit-sets"
12209 );
12210 assert_eq!(
12211 borrowed_string.as_str(),
12212 owned_static,
12213 "From<&RestartPolicy> for String and From<RestartPolicy> \
12214 for &'static str must resolve identically on \
12215 RestartPolicy::{variant:?} — divergence signals a \
12216 break in the diagonal corner of the {{Self, &Self}} × \
12217 {{&'static str, String}} 2×2 trait-idiomatic \
12218 projection family"
12219 );
12220 let via_to_string: String = variant.to_string();
12221 assert_eq!(
12222 borrowed_string, via_to_string,
12223 "From<&RestartPolicy> for String must byte-equal \
12224 RestartPolicy::to_string on RestartPolicy::{variant:?} \
12225 — divergence signals the trait-idiomatic borrowed-input \
12226 owned-`String` forward-projection axis and the \
12227 ToString-through-Display axis have drifted onto \
12228 different emit-sets"
12229 );
12230 }
12231 let via_iter: Vec<String> = RestartPolicy::ALL.iter().map(String::from).collect();
12232 let via_method: Vec<String> = RestartPolicy::ALL
12233 .iter()
12234 .map(|p| p.as_str().to_owned())
12235 .collect();
12236 assert_eq!(
12237 via_iter, via_method,
12238 "`.iter().map(String::from)` over RestartPolicy::ALL — a \
12239 call site whose iteration axis holds `&RestartPolicy` by \
12240 construction — must byte-equal `.iter().map(|p| \
12241 p.as_str().to_owned())` on every arm — the borrowed-input \
12242 owned-`String` `From<&RestartPolicy> for String` axis is \
12243 what makes the `String::from` composition route through \
12244 the substrate-primitive `RestartPolicy::as_str` accessor \
12245 without a spurious `Copy` deref (which would only be \
12246 reachable through the owned-input `From<RestartPolicy> \
12247 for String` axis by first calling `.copied()` on the \
12248 iterator)"
12249 );
12250 for &variant in RestartPolicy::ALL {
12251 let emitted: String = (&variant).into();
12252 let re_parsed: Result<RestartPolicy, ()> =
12253 <RestartPolicy as TryFrom<&str>>::try_from(emitted.as_str());
12254 assert_eq!(
12255 re_parsed,
12256 Ok(variant),
12257 "trait-idiomatic borrowed-input owned-`String` \
12258 forward-projection + reverse-projection axis pair must \
12259 round-trip &RestartPolicy::{variant:?} through \
12260 `.into::<String>()` on the borrowed-input surface and \
12261 back through `TryFrom<&str>` on the owned-`String`'s \
12262 String::as_str borrow — a break signals the \
12263 borrowed-input owned-`String` forward-emit and \
12264 reverse-parse axes have drifted onto different \
12265 vocabularies"
12266 );
12267 }
12268 }
12269
12270 #[test]
12271 fn restart_policy_from_into_static_cow_str_routes_through_as_str_accessor() {
12272 // Fail-before-pass-after byte-parity pin on the newly lifted
12273 // `impl From<RestartPolicy> for std::borrow::Cow<'static, str>` —
12274 // asserts the standard-library trait impl and the substrate-
12275 // primitive [`super::RestartPolicy::as_str`] `pub const fn`
12276 // accessor resolve to the same three-arm emit-set across every
12277 // arm the exhaustive [`super::RestartPolicy::ALL`] slice
12278 // enumerates. Rust's standard library does not carry a blanket
12279 // `impl<T: AsRef<str>> From<T> for Cow<'static, str>` (nor an
12280 // `impl<T: fmt::Display> From<T> for Cow<'static, str>`), so
12281 // the `Cow<'static, str>` forward-projection axis is a
12282 // distinct trait-idiomatic surface that a
12283 // `let key: Cow<'static, str> = policy.into();`-shaped call
12284 // site reaches through this impl and no other — the paired
12285 // sibling `From<RestartPolicy> for &'static str` and
12286 // `From<RestartPolicy> for String` impls force every
12287 // `Cow<'static, str>`-parameterized call site through a
12288 // `Cow::Borrowed(policy.as_str())` /
12289 // `Cow::Owned(policy.to_string())` composition whose type
12290 // bounds have no compile-time link back to the substrate
12291 // primitive.
12292 //
12293 // Also asserts the projection lands on the zero-alloc
12294 // [`std::borrow::Cow::Borrowed`] arm (not the
12295 // [`std::borrow::Cow::Owned`] arm) — the substrate-primitive
12296 // [`super::RestartPolicy::as_str`] accessor's `&'static str`
12297 // return lifetime by construction makes the borrowed arm the
12298 // type-correct projection with no runtime allocation. Any
12299 // future silent detour that routes the impl through the owned
12300 // arm (an accidental `Cow::Owned(policy.to_string())` rewrite
12301 // that would allocate on every call site where the
12302 // `&'static str` return of [`super::RestartPolicy::as_str`]
12303 // makes the zero-alloc borrowed projection type-correct) trips
12304 // at caixa-core test time under the
12305 // [`std::borrow::Cow::Borrowed`] discriminator witness rather
12306 // than at a downstream `Cow<'static, str>`-bound consumer's
12307 // silent allocation.
12308 //
12309 // Second peer on the substrate-wide trait-idiomatic
12310 // [`std::borrow::Cow<'static, str>`] forward-projection family
12311 // to extend the axis off the top-level [`super::CaixaKind`]
12312 // enum (99c1735 owned-input, d45c409 borrowed-input) onto the
12313 // second (and second-of-two-in-M2) M2 OTP-shape closed-set
12314 // fieldless typed enum peer on the caixa surface — closes the
12315 // M2 OTP-shape tier of the campaign on the owned-input axis
12316 // (both sibling peers, `RestartStrategy` and `RestartPolicy`,
12317 // now carry the owned-input Cow<'static, str> forward
12318 // projection).
12319 for &variant in RestartPolicy::ALL {
12320 let via_trait: std::borrow::Cow<'static, str> =
12321 <std::borrow::Cow<'static, str> as From<RestartPolicy>>::from(variant);
12322 let via_method: &'static str = variant.as_str();
12323 assert_eq!(
12324 via_trait.as_ref(),
12325 via_method,
12326 "From<RestartPolicy> for Cow<'static, str> impl must \
12327 round-trip RestartPolicy::{variant:?} to the same \
12328 lifted SUPERVISOR_CHILD_RESTART_* const \
12329 RestartPolicy::as_str returns — divergence signals a \
12330 silent detour off the substrate-primitive accessor"
12331 );
12332 assert!(
12333 matches!(via_trait, std::borrow::Cow::Borrowed(_)),
12334 "From<RestartPolicy> for Cow<'static, str> impl must \
12335 land on the zero-alloc Cow::Borrowed arm on \
12336 RestartPolicy::{variant:?} — a Cow::Owned outcome \
12337 signals the projection has silently allocated where \
12338 the substrate-primitive RestartPolicy::as_str \
12339 `&'static str` return makes the borrowed arm the \
12340 type-correct projection"
12341 );
12342 let via_into: std::borrow::Cow<'static, str> = variant.into();
12343 assert_eq!(
12344 via_into.as_ref(),
12345 via_method,
12346 "Into<Cow<'static, str>>::into on \
12347 RestartPolicy::{variant:?} must byte-equal \
12348 RestartPolicy::as_str on the same input — the \
12349 blanket-derived Into shape must resolve to the same \
12350 as_str dispatch as the explicit From impl"
12351 );
12352 assert!(
12353 matches!(via_into, std::borrow::Cow::Borrowed(_)),
12354 "Into<Cow<'static, str>>::into on \
12355 RestartPolicy::{variant:?} must land on the \
12356 zero-alloc Cow::Borrowed arm — the blanket-derived \
12357 Into shape must resolve to the same Cow::Borrowed \
12358 dispatch as the explicit From impl"
12359 );
12360 }
12361 }
12362
12363 #[test]
12364 fn restart_policy_from_into_static_cow_str_agrees_with_paired_axes_on_every_arm() {
12365 // Cross-axis partition pin: the newly lifted trait-idiomatic
12366 // `From<RestartPolicy> for std::borrow::Cow<'static, str>`
12367 // (this lift), the paired owned-input `From<RestartPolicy>
12368 // for &'static str` (9fb37d0), and the paired owned-input
12369 // `From<RestartPolicy> for String` (7851725) forward
12370 // projections must resolve identically on every arm, locking
12371 // the three return-shape paths together by construction so any
12372 // future detour trips at caixa-core test time. Also byte-parity
12373 // witness against the sibling [`ToString::to_string`] surface
12374 // routed through [`std::fmt::Display`] — every owned-heap-
12375 // string path (the `Cow::Owned` promotion of this axis's
12376 // `.into_owned()`, `From<RestartPolicy> for String`, and
12377 // `.to_string()`) resolves to the same lifted
12378 // [`crate::render::SUPERVISOR_CHILD_RESTART_*`] const per arm.
12379 //
12380 // Then a `.iter().copied().map(std::borrow::Cow::from)` pipe
12381 // witness over [`super::RestartPolicy::ALL`] that
12382 // materializes the three-arm accept-set through the
12383 // [`std::borrow::Cow<'static, str>`] axis alone — the exact
12384 // shape a future `axum::response::IntoResponse` per-policy
12385 // rejection-body composer, a future M4 admission-webhook
12386 // per-policy rejection-reason emitter whose typing rules out
12387 // the sibling [`AsRef<str>`] borrowed return, or a future
12388 // substrate-wide per-policy diagnostic surface that binds
12389 // through a [`Cow<'static, str>`] boundary reaches through.
12390 // The pipe witness also pins the zero-alloc discipline: every
12391 // element in the collected vector satisfies the
12392 // [`std::borrow::Cow::Borrowed`] arm predicate, so a future
12393 // accidental silent-allocation regression on the pipe's
12394 // iteration axis is a caixa-core-test-time failure. Peer of
12395 // the first-mover
12396 // [`restart_strategy_from_into_static_cow_str_agrees_with_paired_axes_on_every_arm`]
12397 // (7dd28b3) on the sibling M2 OTP-shape sibling-restart axis
12398 // — closes the whole owned-input `Cow<'static, str>` +
12399 // paired `{&'static str, String}` cross-axis-parity corner on
12400 // both M2 OTP-shape sibling peers.
12401 for &variant in RestartPolicy::ALL {
12402 let via_cow: std::borrow::Cow<'static, str> =
12403 <std::borrow::Cow<'static, str> as From<RestartPolicy>>::from(variant);
12404 let via_static: &'static str = <&'static str as From<RestartPolicy>>::from(variant);
12405 let via_string: String = <String as From<RestartPolicy>>::from(variant);
12406 assert_eq!(
12407 via_cow.as_ref(),
12408 via_static,
12409 "From<RestartPolicy> for Cow<'static, str> and \
12410 From<RestartPolicy> for &'static str must resolve \
12411 identically on RestartPolicy::{variant:?} — \
12412 divergence signals the Cow<'static, str> and \
12413 &'static str return-shape paths have drifted onto \
12414 different emit-sets"
12415 );
12416 assert_eq!(
12417 via_cow.as_ref(),
12418 via_string.as_str(),
12419 "From<RestartPolicy> for Cow<'static, str> and \
12420 From<RestartPolicy> for String must resolve \
12421 identically on RestartPolicy::{variant:?} — \
12422 divergence signals the Cow<'static, str> and String \
12423 return-shape paths have drifted onto different \
12424 emit-sets"
12425 );
12426 let via_to_string: String = variant.to_string();
12427 assert_eq!(
12428 via_cow.as_ref(),
12429 via_to_string.as_str(),
12430 "From<RestartPolicy> for Cow<'static, str> must \
12431 byte-equal RestartPolicy::to_string on \
12432 RestartPolicy::{variant:?} — divergence signals the \
12433 trait-idiomatic Cow<'static, str> forward-projection \
12434 axis and the ToString-through-Display axis have \
12435 drifted onto different emit-sets"
12436 );
12437 }
12438 let via_iter: Vec<std::borrow::Cow<'static, str>> = RestartPolicy::ALL
12439 .iter()
12440 .copied()
12441 .map(std::borrow::Cow::from)
12442 .collect();
12443 let via_method: Vec<std::borrow::Cow<'static, str>> = RestartPolicy::ALL
12444 .iter()
12445 .map(|p| std::borrow::Cow::Borrowed(p.as_str()))
12446 .collect();
12447 assert_eq!(
12448 via_iter, via_method,
12449 "`.iter().copied().map(Cow::from)` over \
12450 RestartPolicy::ALL must byte-equal `.iter().map(|p| \
12451 Cow::Borrowed(p.as_str()))` on every arm — the \
12452 trait-idiomatic `From<RestartPolicy> for Cow<'static, \
12453 str>` axis is what makes the `Cow::from` composition \
12454 route through the substrate-primitive \
12455 `RestartPolicy::as_str` accessor with the zero-alloc \
12456 Cow::Borrowed arm by construction, rather than a \
12457 per-call-site `Cow::Owned(policy.to_string())` \
12458 allocation"
12459 );
12460 for cow in &via_iter {
12461 assert!(
12462 matches!(cow, std::borrow::Cow::Borrowed(_)),
12463 "every element of the \
12464 .iter().copied().map(Cow::from) pipe over \
12465 RestartPolicy::ALL must land on the zero-alloc \
12466 Cow::Borrowed arm — a Cow::Owned outcome on any arm \
12467 signals the pipe's iteration axis has silently \
12468 allocated where the substrate-primitive \
12469 RestartPolicy::as_str `&'static str` return makes \
12470 the borrowed arm the type-correct projection"
12471 );
12472 }
12473 }
12474
12475 #[test]
12476 fn restart_policy_from_borrowed_into_static_cow_str_routes_through_as_str_accessor() {
12477 // Fail-before-pass-after byte-parity pin on the newly lifted
12478 // `impl From<&RestartPolicy> for std::borrow::Cow<'static, str>` —
12479 // asserts the borrowed-input standard-library trait impl and
12480 // the substrate-primitive [`super::RestartPolicy::as_str`]
12481 // `pub const fn` accessor resolve to the same three-arm emit-
12482 // set across every arm the exhaustive
12483 // [`super::RestartPolicy::ALL`] slice enumerates. Rust's
12484 // standard library does not carry a blanket
12485 // `impl<T: AsRef<str>> From<&T> for Cow<'static, str>` (nor a
12486 // `Copy`-based `impl<T: Copy, U: From<T>> From<&T> for U`), so
12487 // the borrowed-input `Cow<'static, str>` forward-projection
12488 // axis is a distinct trait-idiomatic surface that a
12489 // `let key: Cow<'static, str> = (&policy).into();`-shaped
12490 // call site or a
12491 // `RestartPolicy::ALL.iter().map(Cow::from)`-shaped pipe
12492 // reaches through this impl and no other — the paired owned-
12493 // input `From<RestartPolicy> for Cow<'static, str>` impl
12494 // (0612398) forces every borrowed-input call site through an
12495 // explicit `Copy` deref (`Cow::from(*policy)`) or a
12496 // `Cow::Borrowed(policy.as_str())` open-code whose type
12497 // bounds have no compile-time link back to the substrate
12498 // primitive.
12499 //
12500 // Also asserts the projection lands on the zero-alloc
12501 // [`std::borrow::Cow::Borrowed`] arm (not the
12502 // [`std::borrow::Cow::Owned`] arm) — the substrate-primitive
12503 // [`super::RestartPolicy::as_str`] accessor's `&'static str`
12504 // return lifetime by construction makes the borrowed arm the
12505 // type-correct projection with no runtime allocation on the
12506 // borrowed-input surface just as on the paired owned-input
12507 // surface.
12508 //
12509 // Closes the `{Self, &Self}` input-shape corner on the M2
12510 // OTP-shape per-child-restart [`Cow<'static, str>`] axis on
12511 // the second-of-two-in-M2 closed-set fieldless typed enum peer
12512 // on the caixa surface (`:supervisor :children :restart`),
12513 // exactly as d45c409 closed it on the top-level
12514 // [`super::CaixaKind`] one commit after the owning half
12515 // (99c1735) landed and as 9b3e4b3 closed it on the sibling
12516 // M2 OTP-shape [`super::RestartStrategy`] one commit after
12517 // (7dd28b3) landed. This lift closes the whole M2 OTP-shape
12518 // tier of the substrate-wide Cow<'static, str> forward-
12519 // projection campaign on both input-shape corners
12520 // ({Self, &Self}) of both M2 OTP-shape sibling peers.
12521 for &variant in RestartPolicy::ALL {
12522 let via_trait: std::borrow::Cow<'static, str> =
12523 <std::borrow::Cow<'static, str> as From<&RestartPolicy>>::from(&variant);
12524 let via_method: &'static str = variant.as_str();
12525 assert_eq!(
12526 via_trait.as_ref(),
12527 via_method,
12528 "From<&RestartPolicy> for Cow<'static, str> impl must \
12529 round-trip &RestartPolicy::{variant:?} to the same \
12530 lifted SUPERVISOR_CHILD_RESTART_* const \
12531 RestartPolicy::as_str returns — divergence signals a \
12532 silent detour off the substrate-primitive accessor"
12533 );
12534 assert!(
12535 matches!(via_trait, std::borrow::Cow::Borrowed(_)),
12536 "From<&RestartPolicy> for Cow<'static, str> impl must \
12537 land on the zero-alloc Cow::Borrowed arm on \
12538 &RestartPolicy::{variant:?} — a Cow::Owned outcome \
12539 signals the projection has silently allocated where \
12540 the substrate-primitive RestartPolicy::as_str \
12541 `&'static str` return makes the borrowed arm the \
12542 type-correct projection"
12543 );
12544 let via_into: std::borrow::Cow<'static, str> = (&variant).into();
12545 assert_eq!(
12546 via_into.as_ref(),
12547 via_method,
12548 "Into<Cow<'static, str>>::into on \
12549 &RestartPolicy::{variant:?} must byte-equal \
12550 RestartPolicy::as_str on the same input — the \
12551 blanket-derived Into shape must resolve to the same \
12552 as_str dispatch as the explicit From impl"
12553 );
12554 assert!(
12555 matches!(via_into, std::borrow::Cow::Borrowed(_)),
12556 "Into<Cow<'static, str>>::into on \
12557 &RestartPolicy::{variant:?} must land on the \
12558 zero-alloc Cow::Borrowed arm — the blanket-derived \
12559 Into shape must resolve to the same Cow::Borrowed \
12560 dispatch as the explicit From impl"
12561 );
12562 }
12563 }
12564
12565 #[test]
12566 fn restart_policy_from_borrowed_into_static_cow_str_agrees_with_paired_axes_on_every_arm() {
12567 // Cross-axis partition pin: the newly lifted trait-idiomatic
12568 // borrowed-input `From<&RestartPolicy> for
12569 // std::borrow::Cow<'static, str>` (this lift), the paired
12570 // owned-input `From<RestartPolicy> for
12571 // std::borrow::Cow<'static, str>` (0612398), the paired
12572 // borrowed-input owned-`&'static str` `From<&RestartPolicy>
12573 // for &'static str`, and the paired borrowed-input owned-
12574 // `String` `From<&RestartPolicy> for String` must resolve
12575 // identically on every arm, locking the four
12576 // return-shape × input-shape paths together by construction so
12577 // any future detour trips at caixa-core test time. Also byte-
12578 // parity witness against the sibling [`ToString::to_string`]
12579 // surface routed through [`std::fmt::Display`] — every owned-
12580 // heap-string path (this axis's `.into_owned()` promotion, the
12581 // paired [`From<&RestartPolicy> for String`], and
12582 // `.to_string()`) resolves to the same lifted
12583 // [`crate::render::SUPERVISOR_CHILD_RESTART_*`] const per arm.
12584 //
12585 // Then a `.iter().map(std::borrow::Cow::from)` pipe witness
12586 // over [`super::RestartPolicy::ALL`] — whose iterator yields
12587 // `&RestartPolicy` by construction, so the borrowed-input
12588 // [`Cow<'static, str>`] axis is what routes the pipe through
12589 // the substrate-primitive [`super::RestartPolicy::as_str`]
12590 // accessor without a spurious [`Copy`] deref (which would only
12591 // be reachable through the owned-input
12592 // [`From<RestartPolicy> for Cow<'static, str>`] axis by first
12593 // calling `.copied()` on the iterator). The pipe witness also
12594 // pins the zero-alloc discipline: every element in the
12595 // collected vector satisfies the [`std::borrow::Cow::Borrowed`]
12596 // arm predicate, so a future accidental silent-allocation
12597 // regression on the pipe's iteration axis is a caixa-core-
12598 // test-time failure. Peer of the sibling
12599 // [`restart_strategy_from_borrowed_into_static_cow_str_agrees_with_paired_axes_on_every_arm`]
12600 // (9b3e4b3) on the M2 OTP-shape sibling-restart axis — closes
12601 // the whole borrowed-input `Cow<'static, str>` +
12602 // paired `{&'static str, String}` cross-axis-parity corner on
12603 // both M2 OTP-shape sibling peers.
12604 for &policy in RestartPolicy::ALL {
12605 let borrowed_cow: std::borrow::Cow<'static, str> =
12606 <std::borrow::Cow<'static, str> as From<&RestartPolicy>>::from(&policy);
12607 let owned_cow: std::borrow::Cow<'static, str> =
12608 <std::borrow::Cow<'static, str> as From<RestartPolicy>>::from(policy);
12609 let borrowed_static: &'static str =
12610 <&'static str as From<&RestartPolicy>>::from(&policy);
12611 let borrowed_string: String = <String as From<&RestartPolicy>>::from(&policy);
12612 assert_eq!(
12613 borrowed_cow, owned_cow,
12614 "From<&RestartPolicy> for Cow<'static, str> and \
12615 From<RestartPolicy> for Cow<'static, str> must \
12616 resolve identically on RestartPolicy::{policy:?} — \
12617 divergence signals the borrowed-input and owned-input \
12618 Cow<'static, str> forward-projection input-shape \
12619 paths have drifted onto different emit-sets"
12620 );
12621 assert_eq!(
12622 borrowed_cow.as_ref(),
12623 borrowed_static,
12624 "From<&RestartPolicy> for Cow<'static, str> and \
12625 From<&RestartPolicy> for &'static str must resolve \
12626 identically on RestartPolicy::{policy:?} — \
12627 divergence signals the borrowed-input Cow<'static, \
12628 str> and &'static str return-shape paths have drifted \
12629 onto different emit-sets"
12630 );
12631 assert_eq!(
12632 borrowed_cow.as_ref(),
12633 borrowed_string.as_str(),
12634 "From<&RestartPolicy> for Cow<'static, str> and \
12635 From<&RestartPolicy> for String must resolve \
12636 identically on RestartPolicy::{policy:?} — \
12637 divergence signals the borrowed-input Cow<'static, \
12638 str> and owned-`String` return-shape paths have \
12639 drifted onto different emit-sets"
12640 );
12641 let via_to_string: String = policy.to_string();
12642 assert_eq!(
12643 borrowed_cow.as_ref(),
12644 via_to_string.as_str(),
12645 "From<&RestartPolicy> for Cow<'static, str> must \
12646 byte-equal RestartPolicy::to_string on \
12647 RestartPolicy::{policy:?} — divergence signals \
12648 the trait-idiomatic borrowed-input Cow<'static, str> \
12649 forward-projection axis and the ToString-through-\
12650 Display axis have drifted onto different emit-sets"
12651 );
12652 }
12653 let via_iter: Vec<std::borrow::Cow<'static, str>> = RestartPolicy::ALL
12654 .iter()
12655 .map(std::borrow::Cow::from)
12656 .collect();
12657 let via_method: Vec<std::borrow::Cow<'static, str>> = RestartPolicy::ALL
12658 .iter()
12659 .map(|p| std::borrow::Cow::Borrowed(p.as_str()))
12660 .collect();
12661 assert_eq!(
12662 via_iter, via_method,
12663 "`.iter().map(Cow::from)` over RestartPolicy::ALL — a \
12664 call site whose iteration axis holds `&RestartPolicy` \
12665 by construction — must byte-equal `.iter().map(|p| \
12666 Cow::Borrowed(p.as_str()))` on every arm — the borrowed-\
12667 input Cow<'static, str> `From<&RestartPolicy> for \
12668 Cow<'static, str>` axis is what makes the `Cow::from` \
12669 composition route through the substrate-primitive \
12670 `RestartPolicy::as_str` accessor with the zero-alloc \
12671 Cow::Borrowed arm by construction and without a spurious \
12672 `Copy` deref (which would only be reachable through the \
12673 owned-input `From<RestartPolicy> for Cow<'static, str>` \
12674 axis by first calling `.copied()` on the iterator)"
12675 );
12676 for cow in &via_iter {
12677 assert!(
12678 matches!(cow, std::borrow::Cow::Borrowed(_)),
12679 "every element of the .iter().map(Cow::from) pipe \
12680 over RestartPolicy::ALL must land on the zero-\
12681 alloc Cow::Borrowed arm — a Cow::Owned outcome on \
12682 any arm signals the pipe's iteration axis has \
12683 silently allocated where the substrate-primitive \
12684 RestartPolicy::as_str `&'static str` return makes \
12685 the borrowed arm the type-correct projection"
12686 );
12687 }
12688 }
12689
12690 #[test]
12691 fn restart_policy_from_into_box_str_routes_through_as_str_accessor() {
12692 // Fail-before-pass-after byte-parity pin on the newly lifted
12693 // `impl From<RestartPolicy> for Box<str>` — asserts the
12694 // owned-input standard-library trait impl and the
12695 // substrate-primitive [`super::RestartPolicy::as_str`]
12696 // `pub const fn` accessor resolve to the same three-arm emit-
12697 // set across every arm the exhaustive
12698 // [`super::RestartPolicy::ALL`] slice enumerates. Extends the
12699 // substrate-wide `Box<str>` forward-projection campaign tier
12700 // opened one commit prior (69ef45c) on the paired sibling-
12701 // restart [`RestartStrategy`] onto the second (and third-and-
12702 // final) M2 OTP-shape closed-set fieldless typed enum peer on
12703 // the caixa surface (`:children :restart`), immediately after
12704 // the paired `Cow<'static, str>` axis (0612398 / b4dc55c)
12705 // closed the
12706 // `{Self, &Self} × {&'static str, String, Cow<'static, str>}`
12707 // 2×3 corner on this enum. Rust's standard library carries
12708 // `impl From<&str> for Box<str>` and
12709 // `impl From<String> for Box<str>` but no blanket
12710 // `impl<T: AsRef<str>> From<T> for Box<str>`, so this axis is
12711 // a distinct trait-idiomatic surface that a
12712 // `let key: Box<str> = policy.into();`-shaped call site
12713 // reaches through this impl and no other — a paired
12714 // `Box::from(policy.as_str())` open-code has no compile-time
12715 // link back to the substrate primitive. Peer of the sibling
12716 // [`restart_strategy_from_into_box_str_routes_through_as_str_accessor`]
12717 // (69ef45c) — extends the trait-idiomatic owned-input
12718 // [`Box<str>`] forward-projection axis onto the third and
12719 // final M2-OTP-shape closed-set typed enum on the caixa
12720 // surface.
12721 for &variant in RestartPolicy::ALL {
12722 let via_trait: Box<str> = <Box<str> as From<RestartPolicy>>::from(variant);
12723 let via_method: &'static str = variant.as_str();
12724 assert_eq!(
12725 via_trait.as_ref(),
12726 via_method,
12727 "From<RestartPolicy> for Box<str> impl must round-\
12728 trip RestartPolicy::{variant:?} to the same lifted \
12729 SUPERVISOR_CHILD_RESTART_* const RestartPolicy::as_str \
12730 returns — divergence signals a silent detour off the \
12731 substrate-primitive accessor"
12732 );
12733 let via_into: Box<str> = variant.into();
12734 assert_eq!(
12735 via_into.as_ref(),
12736 via_method,
12737 "Into<Box<str>>::into on RestartPolicy::{variant:?} \
12738 must byte-equal RestartPolicy::as_str on the same \
12739 input — the blanket-derived Into shape must resolve \
12740 to the same as_str dispatch as the explicit From impl"
12741 );
12742 }
12743 }
12744
12745 #[test]
12746 fn restart_policy_from_borrowed_into_box_str_routes_through_as_str_accessor() {
12747 // Fail-before-pass-after byte-parity pin on the newly lifted
12748 // `impl From<&RestartPolicy> for Box<str>` — asserts the
12749 // borrowed-input standard-library trait impl and the
12750 // substrate-primitive [`super::RestartPolicy::as_str`]
12751 // `pub const fn` accessor resolve to the same three-arm emit-
12752 // set across every arm the exhaustive
12753 // [`super::RestartPolicy::ALL`] slice enumerates. Rust's
12754 // standard library does not carry a blanket
12755 // `impl<T: AsRef<str>> From<&T> for Box<str>` (nor a
12756 // `Copy`-based `impl<T: Copy, U: From<T>> From<&T> for U`),
12757 // so the borrowed-input `Box<str>` forward-projection axis
12758 // is a distinct trait-idiomatic surface that a
12759 // `let key: Box<str> = (&policy).into();`-shaped call site
12760 // or a `RestartPolicy::ALL.iter().map(Box::<str>::from)`-
12761 // shaped pipe reaches through this impl and no other — the
12762 // paired owned-input `From<RestartPolicy> for Box<str>`
12763 // impl (0a1b313) forces every borrowed-input call site
12764 // through an explicit `Copy` deref
12765 // (`Box::<str>::from((*policy).as_str())`) or a
12766 // `Box::<str>::from(policy.as_str())` open-code whose
12767 // type bounds have no compile-time link back to the
12768 // substrate primitive.
12769 //
12770 // Fourth (and closing) peer on the substrate-wide trait-
12771 // idiomatic [`Box<str>`] forward-projection family on the
12772 // M2 OTP-shape tier — closes the `{Self, &Self}` input-
12773 // shape corner of the [`Box<str>`] axis on the second (and
12774 // third-and-final) M2 OTP-shape closed-set fieldless typed
12775 // enum peer on the caixa surface (`:children :restart`),
12776 // exactly as b4dc55c closed the paired [`Cow<'static, str>`]
12777 // axis one commit after its owning half (0612398) landed
12778 // on this enum. Every remaining closed-set fieldless typed
12779 // enum peer on the M3 mesh-shape / outside-M3 caixa-core /
12780 // render-side / outside-caixa-core tiers is a future
12781 // target of the campaign.
12782 //
12783 // Also byte-parity witness against the paired owned-input
12784 // [`From<RestartPolicy> for Box<str>`] and the sibling
12785 // borrowed-input [`From<&RestartPolicy> for &'static str`],
12786 // [`From<&RestartPolicy> for String`], and
12787 // [`From<&RestartPolicy> for Cow<'static, str>`]
12788 // return-shape axes — locking the four
12789 // return-shape × input-shape paths together by construction
12790 // so any future detour trips at caixa-core test time. Then a
12791 // `.iter().map(Box::<str>::from)` pipe witness over
12792 // [`super::RestartPolicy::ALL`] — whose iterator yields
12793 // `&RestartPolicy` by construction, so the borrowed-input
12794 // [`Box<str>`] axis is what routes the pipe through the
12795 // substrate-primitive [`super::RestartPolicy::as_str`]
12796 // accessor without a spurious [`Copy`] deref (which would
12797 // only be reachable through the owned-input
12798 // [`From<RestartPolicy> for Box<str>`] axis by first
12799 // calling `.copied()` on the iterator).
12800 for &variant in RestartPolicy::ALL {
12801 let via_trait: Box<str> = <Box<str> as From<&RestartPolicy>>::from(&variant);
12802 let via_method: &'static str = variant.as_str();
12803 assert_eq!(
12804 via_trait.as_ref(),
12805 via_method,
12806 "From<&RestartPolicy> for Box<str> impl must round-\
12807 trip &RestartPolicy::{variant:?} to the same lifted \
12808 SUPERVISOR_CHILD_RESTART_* const RestartPolicy::as_str \
12809 returns — divergence signals a silent detour off the \
12810 substrate-primitive accessor"
12811 );
12812 let via_into: Box<str> = (&variant).into();
12813 assert_eq!(
12814 via_into.as_ref(),
12815 via_method,
12816 "Into<Box<str>>::into on &RestartPolicy::{variant:?} \
12817 must byte-equal RestartPolicy::as_str on the same \
12818 input — the blanket-derived Into shape must resolve \
12819 to the same as_str dispatch as the explicit From impl"
12820 );
12821 let owned_box: Box<str> = <Box<str> as From<RestartPolicy>>::from(variant);
12822 assert_eq!(
12823 via_trait, owned_box,
12824 "From<&RestartPolicy> for Box<str> and \
12825 From<RestartPolicy> for Box<str> must resolve \
12826 identically on RestartPolicy::{variant:?} — \
12827 divergence signals the borrowed-input and owned-input \
12828 Box<str> forward-projection input-shape paths have \
12829 drifted onto different emit-sets"
12830 );
12831 let borrowed_static: &'static str =
12832 <&'static str as From<&RestartPolicy>>::from(&variant);
12833 assert_eq!(
12834 via_trait.as_ref(),
12835 borrowed_static,
12836 "From<&RestartPolicy> for Box<str> and \
12837 From<&RestartPolicy> for &'static str must resolve \
12838 identically on RestartPolicy::{variant:?} — \
12839 divergence signals the borrowed-input Box<str> and \
12840 &'static str return-shape paths have drifted onto \
12841 different emit-sets"
12842 );
12843 let borrowed_string: String = <String as From<&RestartPolicy>>::from(&variant);
12844 assert_eq!(
12845 via_trait.as_ref(),
12846 borrowed_string.as_str(),
12847 "From<&RestartPolicy> for Box<str> and \
12848 From<&RestartPolicy> for String must resolve \
12849 identically on RestartPolicy::{variant:?} — \
12850 divergence signals the borrowed-input Box<str> and \
12851 owned-`String` return-shape paths have drifted onto \
12852 different emit-sets"
12853 );
12854 let borrowed_cow: std::borrow::Cow<'static, str> =
12855 <std::borrow::Cow<'static, str> as From<&RestartPolicy>>::from(&variant);
12856 assert_eq!(
12857 via_trait.as_ref(),
12858 borrowed_cow.as_ref(),
12859 "From<&RestartPolicy> for Box<str> and \
12860 From<&RestartPolicy> for Cow<'static, str> must \
12861 resolve identically on RestartPolicy::{variant:?} — \
12862 divergence signals the borrowed-input Box<str> and \
12863 Cow<'static, str> return-shape paths have drifted \
12864 onto different emit-sets"
12865 );
12866 }
12867 let via_iter: Vec<Box<str>> = RestartPolicy::ALL.iter().map(Box::<str>::from).collect();
12868 let via_method: Vec<Box<str>> = RestartPolicy::ALL
12869 .iter()
12870 .map(|p| Box::<str>::from(p.as_str()))
12871 .collect();
12872 assert_eq!(
12873 via_iter, via_method,
12874 "`.iter().map(Box::<str>::from)` over \
12875 RestartPolicy::ALL — a call site whose iteration axis \
12876 holds `&RestartPolicy` by construction — must byte-\
12877 equal `.iter().map(|p| Box::<str>::from(p.as_str()))` \
12878 on every arm — the borrowed-input Box<str> \
12879 `From<&RestartPolicy> for Box<str>` axis is what \
12880 makes the `Box::<str>::from` composition route through \
12881 the substrate-primitive `RestartPolicy::as_str` \
12882 accessor without a spurious `Copy` deref (which would \
12883 only be reachable through the owned-input \
12884 `From<RestartPolicy> for Box<str>` axis by first \
12885 calling `.copied()` on the iterator)"
12886 );
12887 }
12888
12889 #[test]
12890 fn restart_policy_from_into_arc_str_routes_through_as_str_accessor() {
12891 // Fail-before-pass-after byte-parity pin on the newly lifted
12892 // `impl From<RestartPolicy> for std::sync::Arc<str>` — asserts
12893 // the owned-input standard-library trait impl and the
12894 // substrate-primitive [`super::RestartPolicy::as_str`]
12895 // `pub const fn` accessor resolve to the same three-arm emit-
12896 // set across every arm the exhaustive
12897 // [`super::RestartPolicy::ALL`] slice enumerates. Extends the
12898 // substrate-wide [`std::sync::Arc<str>`] forward-projection
12899 // campaign tier opened one projection tier prior (bca2ec8) on
12900 // the paired sibling-restart [`RestartStrategy`] owned-input
12901 // first-mover onto the second (and third-and-final) M2 OTP-
12902 // shape closed-set fieldless typed enum peer on the caixa
12903 // surface (`:children :restart`), immediately after the paired
12904 // [`Box<str>`] axis (0a1b313 / cb1d068) closed the
12905 // `{Self, &Self} × {&'static str, String, Cow<'static, str>,
12906 // Box<str>}` 2×4 corner on this enum. Rust's standard library
12907 // carries `impl From<&str> for std::sync::Arc<str>` and
12908 // `impl From<String> for std::sync::Arc<str>` but no blanket
12909 // `impl<T: AsRef<str>> From<T> for std::sync::Arc<str>` (nor
12910 // an `impl<T: fmt::Display> From<T> for std::sync::Arc<str>`),
12911 // so this axis is a distinct trait-idiomatic surface that a
12912 // `let key: std::sync::Arc<str> = policy.into();`-shaped call
12913 // site reaches through this impl and no other — a paired
12914 // `std::sync::Arc::<str>::from(policy.as_str())` open-code
12915 // has no compile-time link back to the substrate primitive,
12916 // and a two-step `std::sync::Arc::<str>::from(String::from(
12917 // policy))` composition through the owned-`String` axis
12918 // allocates twice (once into the intermediate `String`, once
12919 // into the [`Arc<str>`] on the `From<String>` conversion)
12920 // where the single-step trait impl allocates once.
12921 //
12922 // Cross-axis byte-parity witness against the sibling owned-
12923 // input `{&'static str, String, Cow<'static, str>, Box<str>}`
12924 // return-shape axes — locking the five return-shape paths on
12925 // the owned-input surface together by construction so any
12926 // future detour off the substrate-primitive
12927 // [`super::RestartPolicy::as_str`] accessor trips at caixa-
12928 // core test time.
12929 for &variant in RestartPolicy::ALL {
12930 let via_trait: std::sync::Arc<str> =
12931 <std::sync::Arc<str> as From<RestartPolicy>>::from(variant);
12932 let via_method: &'static str = variant.as_str();
12933 assert_eq!(
12934 via_trait.as_ref(),
12935 via_method,
12936 "From<RestartPolicy> for std::sync::Arc<str> impl \
12937 must round-trip RestartPolicy::{variant:?} to the \
12938 same lifted SUPERVISOR_CHILD_RESTART_* const \
12939 RestartPolicy::as_str returns — divergence signals \
12940 a silent detour off the substrate-primitive accessor"
12941 );
12942 let via_into: std::sync::Arc<str> = variant.into();
12943 assert_eq!(
12944 via_into.as_ref(),
12945 via_method,
12946 "Into<std::sync::Arc<str>>::into on \
12947 RestartPolicy::{variant:?} must byte-equal \
12948 RestartPolicy::as_str on the same input — the \
12949 blanket-derived Into shape must resolve to the same \
12950 as_str dispatch as the explicit From impl"
12951 );
12952 let owned_static: &'static str = <&'static str as From<RestartPolicy>>::from(variant);
12953 assert_eq!(
12954 via_trait.as_ref(),
12955 owned_static,
12956 "From<RestartPolicy> for std::sync::Arc<str> and \
12957 From<RestartPolicy> for &'static str must resolve \
12958 identically on RestartPolicy::{variant:?} — \
12959 divergence signals the owned-input std::sync::Arc<str> \
12960 and &'static str return-shape paths have drifted onto \
12961 different emit-sets"
12962 );
12963 let owned_string: String = <String as From<RestartPolicy>>::from(variant);
12964 assert_eq!(
12965 via_trait.as_ref(),
12966 owned_string.as_str(),
12967 "From<RestartPolicy> for std::sync::Arc<str> and \
12968 From<RestartPolicy> for String must resolve \
12969 identically on RestartPolicy::{variant:?} — \
12970 divergence signals the owned-input std::sync::Arc<str> \
12971 and owned-`String` return-shape paths have drifted \
12972 onto different emit-sets"
12973 );
12974 let owned_cow: std::borrow::Cow<'static, str> =
12975 <std::borrow::Cow<'static, str> as From<RestartPolicy>>::from(variant);
12976 assert_eq!(
12977 via_trait.as_ref(),
12978 owned_cow.as_ref(),
12979 "From<RestartPolicy> for std::sync::Arc<str> and \
12980 From<RestartPolicy> for Cow<'static, str> must \
12981 resolve identically on RestartPolicy::{variant:?} — \
12982 divergence signals the owned-input std::sync::Arc<str> \
12983 and Cow<'static, str> return-shape paths have drifted \
12984 onto different emit-sets"
12985 );
12986 let owned_box: Box<str> = <Box<str> as From<RestartPolicy>>::from(variant);
12987 assert_eq!(
12988 via_trait.as_ref(),
12989 owned_box.as_ref(),
12990 "From<RestartPolicy> for std::sync::Arc<str> and \
12991 From<RestartPolicy> for Box<str> must resolve \
12992 identically on RestartPolicy::{variant:?} — \
12993 divergence signals the owned-input std::sync::Arc<str> \
12994 and Box<str> return-shape paths have drifted onto \
12995 different emit-sets"
12996 );
12997 }
12998 }
12999
13000 #[test]
13001 fn restart_policy_from_borrowed_into_arc_str_routes_through_as_str_accessor() {
13002 // Fail-before-pass-after byte-parity pin on the newly lifted
13003 // `impl From<&RestartPolicy> for std::sync::Arc<str>` —
13004 // asserts the borrowed-input standard-library trait impl and
13005 // the substrate-primitive [`super::RestartPolicy::as_str`]
13006 // `pub const fn` accessor resolve to the same three-arm
13007 // emit-set across every arm the exhaustive
13008 // [`super::RestartPolicy::ALL`] slice enumerates. Rust's
13009 // standard library carries `impl From<&str> for
13010 // std::sync::Arc<str>` and `impl From<String> for
13011 // std::sync::Arc<str>` but no blanket
13012 // `impl<T: AsRef<str>> From<&T> for std::sync::Arc<str>` (nor
13013 // a `Copy`-based `impl<T: Copy, U: From<T>> From<&T> for U`),
13014 // so the borrowed-input [`std::sync::Arc<str>`] forward-
13015 // projection axis is a distinct trait-idiomatic surface that
13016 // a `let key: std::sync::Arc<str> = (&policy).into();`-shaped
13017 // call site or a
13018 // `RestartPolicy::ALL.iter().map(std::sync::Arc::<str>::from)`-
13019 // shaped pipe reaches through this impl and no other — the
13020 // paired owned-input [`From<RestartPolicy> for
13021 // std::sync::Arc<str>`] impl (b05724e) forces every borrowed-
13022 // input call site through an explicit [`Copy`] deref
13023 // (`std::sync::Arc::<str>::from((*policy).as_str())`) or a
13024 // `std::sync::Arc::<str>::from(policy.as_str())` open-code
13025 // whose type bounds have no compile-time link back to the
13026 // substrate primitive.
13027 //
13028 // Closes the `{Self, &Self}` input-shape corner of the
13029 // substrate-wide trait-idiomatic [`std::sync::Arc<str>`]
13030 // forward-projection family on the second (and third-and-
13031 // final) M2 OTP-shape closed-set fieldless typed enum peer
13032 // on the caixa surface (`:children :restart`), one commit
13033 // after b05724e opened the owned-input half — exactly as
13034 // b3e72d7 closed the paired [`std::sync::Arc<str>`] corner on
13035 // the sibling-restart [`RestartStrategy`] first-mover one
13036 // commit after its owning half (bca2ec8) landed, and as
13037 // cb1d068 closed the paired [`Box<str>`] corner on this
13038 // enum one commit after its owning half (0a1b313) landed.
13039 //
13040 // Also byte-parity witness against the paired owned-input
13041 // [`From<RestartPolicy> for std::sync::Arc<str>`] and the
13042 // sibling borrowed-input [`From<&RestartPolicy> for
13043 // &'static str`], [`From<&RestartPolicy> for String`],
13044 // [`From<&RestartPolicy> for Cow<'static, str>`], and
13045 // [`From<&RestartPolicy> for Box<str>`] return-shape axes —
13046 // locking the five return-shape × input-shape paths together
13047 // by construction so any future detour off the substrate-
13048 // primitive [`super::RestartPolicy::as_str`] accessor trips
13049 // at caixa-core test time. Then a
13050 // `.iter().map(std::sync::Arc::<str>::from)` pipe witness
13051 // over [`super::RestartPolicy::ALL`] — whose iterator yields
13052 // `&RestartPolicy` by construction, so the borrowed-input
13053 // [`std::sync::Arc<str>`] axis is what routes the pipe
13054 // through the substrate-primitive
13055 // [`super::RestartPolicy::as_str`] accessor without a
13056 // spurious [`Copy`] deref (which would only be reachable
13057 // through the owned-input
13058 // [`From<RestartPolicy> for std::sync::Arc<str>`] axis by
13059 // first calling `.copied()` on the iterator).
13060 for &variant in RestartPolicy::ALL {
13061 let via_trait: std::sync::Arc<str> =
13062 <std::sync::Arc<str> as From<&RestartPolicy>>::from(&variant);
13063 let via_method: &'static str = variant.as_str();
13064 assert_eq!(
13065 via_trait.as_ref(),
13066 via_method,
13067 "From<&RestartPolicy> for std::sync::Arc<str> impl \
13068 must round-trip &RestartPolicy::{variant:?} to the \
13069 same lifted SUPERVISOR_CHILD_RESTART_* const \
13070 RestartPolicy::as_str returns — divergence signals \
13071 a silent detour off the substrate-primitive accessor"
13072 );
13073 let via_into: std::sync::Arc<str> = (&variant).into();
13074 assert_eq!(
13075 via_into.as_ref(),
13076 via_method,
13077 "Into<std::sync::Arc<str>>::into on \
13078 &RestartPolicy::{variant:?} must byte-equal \
13079 RestartPolicy::as_str on the same input — the \
13080 blanket-derived Into shape must resolve to the same \
13081 as_str dispatch as the explicit From impl"
13082 );
13083 let owned_arc: std::sync::Arc<str> =
13084 <std::sync::Arc<str> as From<RestartPolicy>>::from(variant);
13085 assert_eq!(
13086 via_trait, owned_arc,
13087 "From<&RestartPolicy> for std::sync::Arc<str> and \
13088 From<RestartPolicy> for std::sync::Arc<str> must \
13089 resolve identically on RestartPolicy::{variant:?} — \
13090 divergence signals the borrowed-input and owned-input \
13091 std::sync::Arc<str> forward-projection input-shape \
13092 paths have drifted onto different emit-sets"
13093 );
13094 let borrowed_static: &'static str =
13095 <&'static str as From<&RestartPolicy>>::from(&variant);
13096 assert_eq!(
13097 via_trait.as_ref(),
13098 borrowed_static,
13099 "From<&RestartPolicy> for std::sync::Arc<str> and \
13100 From<&RestartPolicy> for &'static str must resolve \
13101 identically on RestartPolicy::{variant:?} — \
13102 divergence signals the borrowed-input std::sync::Arc<str> \
13103 and &'static str return-shape paths have drifted onto \
13104 different emit-sets"
13105 );
13106 let borrowed_string: String = <String as From<&RestartPolicy>>::from(&variant);
13107 assert_eq!(
13108 via_trait.as_ref(),
13109 borrowed_string.as_str(),
13110 "From<&RestartPolicy> for std::sync::Arc<str> and \
13111 From<&RestartPolicy> for String must resolve \
13112 identically on RestartPolicy::{variant:?} — \
13113 divergence signals the borrowed-input std::sync::Arc<str> \
13114 and owned-`String` return-shape paths have drifted \
13115 onto different emit-sets"
13116 );
13117 let borrowed_cow: std::borrow::Cow<'static, str> =
13118 <std::borrow::Cow<'static, str> as From<&RestartPolicy>>::from(&variant);
13119 assert_eq!(
13120 via_trait.as_ref(),
13121 borrowed_cow.as_ref(),
13122 "From<&RestartPolicy> for std::sync::Arc<str> and \
13123 From<&RestartPolicy> for Cow<'static, str> must \
13124 resolve identically on RestartPolicy::{variant:?} — \
13125 divergence signals the borrowed-input std::sync::Arc<str> \
13126 and Cow<'static, str> return-shape paths have drifted \
13127 onto different emit-sets"
13128 );
13129 let borrowed_box: Box<str> = <Box<str> as From<&RestartPolicy>>::from(&variant);
13130 assert_eq!(
13131 via_trait.as_ref(),
13132 borrowed_box.as_ref(),
13133 "From<&RestartPolicy> for std::sync::Arc<str> and \
13134 From<&RestartPolicy> for Box<str> must resolve \
13135 identically on RestartPolicy::{variant:?} — \
13136 divergence signals the borrowed-input std::sync::Arc<str> \
13137 and Box<str> return-shape paths have drifted onto \
13138 different emit-sets"
13139 );
13140 }
13141 let via_iter: Vec<std::sync::Arc<str>> = RestartPolicy::ALL
13142 .iter()
13143 .map(std::sync::Arc::<str>::from)
13144 .collect();
13145 let via_method: Vec<std::sync::Arc<str>> = RestartPolicy::ALL
13146 .iter()
13147 .map(|p| std::sync::Arc::<str>::from(p.as_str()))
13148 .collect();
13149 assert_eq!(
13150 via_iter, via_method,
13151 "`.iter().map(std::sync::Arc::<str>::from)` over \
13152 RestartPolicy::ALL — a call site whose iteration axis \
13153 holds `&RestartPolicy` by construction — must byte-\
13154 equal `.iter().map(|p| std::sync::Arc::<str>::from(p.as_str()))` \
13155 on every arm — the borrowed-input std::sync::Arc<str> \
13156 `From<&RestartPolicy> for std::sync::Arc<str>` axis is \
13157 what makes the `std::sync::Arc::<str>::from` composition \
13158 route through the substrate-primitive \
13159 `RestartPolicy::as_str` accessor without a spurious \
13160 `Copy` deref (which would only be reachable through the \
13161 owned-input `From<RestartPolicy> for std::sync::Arc<str>` \
13162 axis by first calling `.copied()` on the iterator)"
13163 );
13164 }
13165
13166 // ── drift-detection: serde-derive-to-SUPERVISOR_CHILD_RESTART_* identity ─
13167
13168 #[test]
13169 fn restart_policy_variants_serialize_to_lifted_scalar_values() {
13170 // The fail-before-pass-after pin: pre-lift there was no
13171 // single-source binding between the [`RestartPolicy`] variant
13172 // name the un-`rename`d `Serialize` derive emits under
13173 // [`crate::render::SUPERVISOR_CHILD_KEY_RESTART`] and the
13174 // byte-string every downstream cluster-side dispatcher (the
13175 // future wasm-operator's per-child post-exit restart-decision
13176 // branch, the future M4 `mesh.pleme.io/v1alpha1/Supervisor` CR
13177 // materializer's admission-time enum-arm bind, the
13178 // `caixa-operator`'s hierarchical reconciliation scheduler's
13179 // per-child-policy fan-out) probes verbatim. A future
13180 // `#[serde(rename_all = "kebab-case")]` attribute on the enum —
13181 // or a per-variant `#[serde(rename = "…")]` override, or a
13182 // variant rename in the source — would silently rebrand the
13183 // emitted scalar under one spelling while every downstream
13184 // dispatcher still probed the other, with the failure surfacing
13185 // at the operator's reconcile posture (children coming up under
13186 // the `default()` `Permanent` arm rather than the typed slot's
13187 // declared policy — a `:temporary` `oneShot` child would be
13188 // restarted on clean exit, treating the successful-completion
13189 // signal as failure and re-running the completion-terminal
13190 // one-shot indefinitely; a `:transient` child that clean-exited
13191 // would be restarted, masking the clean-completion contract)
13192 // far from the source rebrand commit and with no field naming
13193 // the drift. Pinning the two paths (the `Serialize` derive's
13194 // serialized string AND the [`RestartPolicy::as_str`] helper)
13195 // to the same three lifted
13196 // [`crate::render::SUPERVISOR_CHILD_RESTART_PERMANENT`] /
13197 // [`crate::render::SUPERVISOR_CHILD_RESTART_TEMPORARY`] /
13198 // [`crate::render::SUPERVISOR_CHILD_RESTART_TRANSIENT`]
13199 // byte-strings makes any future drift on either endpoint fail
13200 // here at caixa-core build time. Peer of the sibling
13201 // [`restart_strategy_variants_serialize_to_lifted_scalar_values`]
13202 // (09ffb2d) on the per-supervisor sibling-restart-strategy axis
13203 // and the M3
13204 // `placement_strategy_variants_serialize_to_lifted_scalar_values`
13205 // (3f0e21c) on the per-Aplicacao distribution-strategy axis —
13206 // same three-path-convergence discipline, extended to close the
13207 // third OTP-shaped closed-enum discriminator axis on the caixa
13208 // typed surface (per-child restart-decision policy).
13209 for (variant, expected) in [
13210 (
13211 RestartPolicy::Permanent,
13212 crate::render::SUPERVISOR_CHILD_RESTART_PERMANENT,
13213 ),
13214 (
13215 RestartPolicy::Temporary,
13216 crate::render::SUPERVISOR_CHILD_RESTART_TEMPORARY,
13217 ),
13218 (
13219 RestartPolicy::Transient,
13220 crate::render::SUPERVISOR_CHILD_RESTART_TRANSIENT,
13221 ),
13222 ] {
13223 let json = serde_json::to_string(&variant).unwrap();
13224 assert_eq!(
13225 json,
13226 format!("\"{expected}\""),
13227 "RestartPolicy::{variant:?} must serialize to {expected:?}"
13228 );
13229 assert_eq!(
13230 variant.as_str(),
13231 expected,
13232 "RestartPolicy::{variant:?}.as_str() must return the lifted \
13233 SUPERVISOR_CHILD_RESTART_* constant"
13234 );
13235 }
13236 }
13237
13238 #[test]
13239 fn supervisor_child_restart_consts_are_pairwise_distinct() {
13240 // Cross-arm drift-detection pin: a future collapse of two
13241 // canonical variant byte-strings onto the same value (e.g. an
13242 // accidental copy-paste flip of `SUPERVISOR_CHILD_RESTART_TRANSIENT`
13243 // to also read `"Permanent"`) would silently reroute every
13244 // downstream operator's per-child-policy dispatch onto the
13245 // sibling arm's reconcile branch and pass every propagation-probe
13246 // test that expected only the stale arm's value — a `:transient`
13247 // child would come up under the `:permanent` restart-decision
13248 // posture on every subsequent clean exit, so a completion-terminal
13249 // child would be restarted indefinitely against its declared
13250 // policy. Peer of the sibling
13251 // [`supervisor_estrategia_consts_are_pairwise_distinct`]
13252 // (09ffb2d) on the per-supervisor sibling-restart-strategy axis
13253 // and the four-way distinct pin
13254 // `supervisor_key_consts_are_pairwise_distinct` (40cc4e5) on the
13255 // top-level `SUPERVISOR_KEY_*` axis.
13256 let all = [
13257 crate::render::SUPERVISOR_CHILD_RESTART_PERMANENT,
13258 crate::render::SUPERVISOR_CHILD_RESTART_TEMPORARY,
13259 crate::render::SUPERVISOR_CHILD_RESTART_TRANSIENT,
13260 ];
13261 for (i, a) in all.iter().enumerate() {
13262 for (j, b) in all.iter().enumerate() {
13263 if i != j {
13264 assert_ne!(
13265 a, b,
13266 "SUPERVISOR_CHILD_RESTART_* consts must be pairwise distinct \
13267 — got duplicate {a:?} at indices {i} and {j}",
13268 );
13269 }
13270 }
13271 }
13272 }
13273
13274 #[test]
13275 fn restart_policy_display_routes_through_as_str_helper() {
13276 // The fail-before-pass-after pin on the first half of the
13277 // three-path convergence: pre-convergence [`RestartPolicy`]
13278 // carried a [`std::fmt::Display`] surface via its
13279 // `#[discriminant(also_display)]` gen-platform derive route,
13280 // which arrived kebab-case as `"permanent"` / `"temporary"`
13281 // / `"transient"` on this three-arm enum (whose variant
13282 // names each collapse to their own lowercase form under the
13283 // kebab-case transform) while the wire format ran as
13284 // PascalCase `"Permanent"` / `"Temporary"` / `"Transient"`
13285 // through the un-`rename`d serde derive. Every consumer
13286 // reaching for a policy byte-string past the wire format had
13287 // to pick between three paths ([`RestartPolicy::as_str`],
13288 // the `Serialize` derive's serialized string, or
13289 // `format!("{v}")` on the discriminant-Display route), any
13290 // two of which a future variant rename or
13291 // `#[serde(rename_all = "kebab-case")]` attribute would
13292 // silently desynchronize. Wiring [`std::fmt::Display`]
13293 // through [`RestartPolicy::as_str`] closes the third path:
13294 // every `format!("{v}")` call reaches the same lifted
13295 // [`crate::render::SUPERVISOR_CHILD_RESTART_*`] const the
13296 // wire format and the [`RestartPolicy::as_str`] helper
13297 // already route through, so a future variant rename lands at
13298 // exactly one place. Pin the routing here so a future
13299 // `impl std::fmt::Display for RestartPolicy`
13300 // reimplementation that hand-rolls the arms instead of
13301 // delegating to [`RestartPolicy::as_str`] fails at
13302 // caixa-core build time. Peer of the sibling
13303 // [`restart_strategy_display_routes_through_as_str_helper`]
13304 // on the per-supervisor sibling-restart-strategy axis and
13305 // the M3
13306 // `placement_strategy_display_routes_through_as_str_helper`
13307 // (cc8f749) — the third of three OTP-shape closed-enum
13308 // discriminator axes on the caixa typed surface now
13309 // converged onto the same three-path
13310 // (Display → as_str → lifted const) discipline.
13311 for variant in [
13312 RestartPolicy::Permanent,
13313 RestartPolicy::Temporary,
13314 RestartPolicy::Transient,
13315 ] {
13316 assert_eq!(
13317 variant.to_string(),
13318 variant.as_str(),
13319 "RestartPolicy::{variant:?} Display must route through \
13320 RestartPolicy::as_str (single source of truth: the lifted \
13321 SUPERVISOR_CHILD_RESTART_* const the wire format also emits)"
13322 );
13323 }
13324 }
13325
13326 #[test]
13327 fn restart_policy_display_matches_serialized_wire_byte_string() {
13328 // The fail-before-pass-after pin on the second half of the
13329 // three-path convergence: `Display` (user-facing text) agrees
13330 // byte-for-byte with the `Serialize` derive's wire format
13331 // (canonical camelCase-schema `SUPERVISOR_CHILD_KEY_RESTART`
13332 // scalar) on every variant. Pre-convergence the two paths
13333 // were structurally independent — a future
13334 // `#[serde(rename_all = "kebab-case")]` attribute on the
13335 // enum would silently rebrand the emitted wire scalar
13336 // (`permanent`, `temporary`, `transient`) while every
13337 // consumer that pretty-prints the policy (the future
13338 // wasm-operator's per-child post-exit restart-decision
13339 // diagnostic line, the future `feira app graph` per-child
13340 // restart column, the future M4
13341 // `mesh.pleme.io/v1alpha1/Supervisor` CR materializer's
13342 // per-child admission-webhook rejection body) would still
13343 // emit the PascalCase form the `as_str` / `Display` route
13344 // returns, with the mismatch surfacing at consumer parse
13345 // time / operator dispatch time far from the source rebrand
13346 // commit. Pin the two paths byte-for-byte here so any future
13347 // serde-attribute or variant-rename drift is a
13348 // caixa-core-build-time test failure at this call, not a
13349 // silent per-consumer dispatch miss. Peer of the sibling
13350 // [`restart_strategy_display_matches_serialized_wire_byte_string`]
13351 // on the per-supervisor sibling-restart-strategy axis and
13352 // the M3
13353 // `placement_strategy_display_matches_serialized_wire_byte_string`
13354 // (cc8f749).
13355 for variant in [
13356 RestartPolicy::Permanent,
13357 RestartPolicy::Temporary,
13358 RestartPolicy::Transient,
13359 ] {
13360 let wire = serde_json::to_string(&variant).unwrap();
13361 let unquoted = wire
13362 .strip_prefix('"')
13363 .and_then(|s| s.strip_suffix('"'))
13364 .expect("serialized RestartPolicy is a JSON string");
13365 assert_eq!(
13366 variant.to_string(),
13367 unquoted,
13368 "RestartPolicy::{variant:?} Display byte-string must match the \
13369 Serialize derive's wire byte-string (three-path convergence: \
13370 Display + as_str + Serialize all resolve to the same \
13371 SUPERVISOR_CHILD_RESTART_* const)"
13372 );
13373 }
13374 }
13375
13376 #[test]
13377 fn restart_policy_as_ref_str_routes_through_as_str_accessor() {
13378 // Fail-before-pass-after byte-parity pin on the lifted
13379 // `impl AsRef<str> for RestartPolicy` — asserts the
13380 // standard-library trait impl and the substrate-primitive
13381 // [`RestartPolicy::as_str`] `pub const fn` accessor resolve
13382 // to the same `&str` per instance across the three-arm
13383 // closed set, so any future silent detour that routes the
13384 // impl through a divergent projection (a per-arm inline
13385 // `match self { RestartPolicy::Permanent => "Permanent", … }`
13386 // re-inlining that opens a compile-time link to the un-lifted
13387 // arm-literal, a swap onto the kebab-case
13388 // [`gen_platform::Discriminant`] catalog identity that would
13389 // collide the wire axis with the dispatcher-catalog axis) trips
13390 // at caixa-core test time under `PartialEq` rather than at a
13391 // downstream `impl AsRef<str>`-bound consumer's silent split.
13392 // Sweeps every one of the three arms
13393 // [`RestartPolicy::ALL`] carries so no arm's projection is
13394 // covered only by the sibling wire-format `Serialize` derive
13395 // path. Peer of the sibling
13396 // [`restart_strategy_as_ref_str_routes_through_as_str_accessor`]
13397 // (63eb1a4) on the paired per-supervisor sibling-restart-
13398 // strategy axis and the [`crate::CaixaVersion`]
13399 // `AsRef<str>`-byte-parity pin (16d5c7e) on the paired
13400 // top-level `:versao` typed newtype — the three pins together
13401 // cover the substrate primitive's `AsRef<str>` projection axis
13402 // on the paired newtype + M2 closed-set-typed-enum surface.
13403 for &variant in RestartPolicy::ALL {
13404 assert_eq!(
13405 <RestartPolicy as AsRef<str>>::as_ref(&variant),
13406 variant.as_str(),
13407 "AsRef<str> impl on RestartPolicy::{variant:?} must \
13408 byte-equal RestartPolicy::as_str on the same instance \
13409 — divergence signals a silent detour off the substrate-\
13410 primitive accessor"
13411 );
13412 }
13413 }
13414
13415 #[test]
13416 fn restart_policy_as_ref_str_routes_through_display_via_shared_accessor() {
13417 // Fail-before-pass-after byte-parity pin on the three-path
13418 // convergence discipline the M2 per-child-restart-policy
13419 // primitive now carries on the `&str`-projection axis:
13420 // `<RestartPolicy as AsRef<str>>::as_ref(&v)` (the newly
13421 // lifted impl), `format!("{v}")` (the pre-existing
13422 // [`fmt::Display`] impl), and `v.as_str()` (the substrate-
13423 // primitive `pub const fn` accessor both trait impls delegate
13424 // through) must resolve to the same byte-string on every
13425 // instance across the three-arm closed set. Refuses any future
13426 // divergence between the two trait impls (a stray
13427 // [`fmt::Display::fmt`] rewrite that hand-rolls the arms
13428 // rather than delegating through the shared accessor; a
13429 // hypothetical `AsRef<str>` rewrite that inlines a per-arm
13430 // literal cascade) that would silently split the two
13431 // projection paths of the same closed-set typed enum. Mirrors
13432 // the sibling three-path-convergence discipline the peer
13433 // [`RestartStrategy`] typed enum carries on its
13434 // `AsRef<str>` / `Display` / `as_str` triple
13435 // (supervisor.rs pin
13436 // `restart_strategy_as_ref_str_routes_through_display_via_shared_accessor`,
13437 // 63eb1a4) and the [`crate::CaixaVersion`] typed newtype
13438 // carries on the same triple (version.rs pin
13439 // `caixa_version_as_ref_str_routes_through_display_via_shared_accessor`,
13440 // 16d5c7e).
13441 for &variant in RestartPolicy::ALL {
13442 let via_as_ref: &str = <RestartPolicy as AsRef<str>>::as_ref(&variant);
13443 let via_display: String = format!("{variant}");
13444 let via_accessor: &str = variant.as_str();
13445 assert_eq!(via_as_ref, via_accessor);
13446 assert_eq!(via_display, via_accessor);
13447 assert_eq!(via_as_ref, via_display.as_str());
13448 }
13449 }
13450
13451 // The `generic_bytes_sink(&variant)` and `borrowed_hasher.update(&variant)`
13452 // shapes below are the borrowed-input witness half of the by-value +
13453 // by-reference partition the paired witness pair carries: the pair proves
13454 // the trait bound accepts both owned (`variant`) and borrowed (`&variant`)
13455 // shapes through the same substrate-primitive `as_str` accessor, which is
13456 // the shape the caixa-lacre BLAKE3 content-address closure composes.
13457 // `clippy::needless_borrows_for_generic_args` would fold the borrowed half
13458 // into the owned half and collapse the by-value/by-reference partition
13459 // this test load-bears; the `#[allow]` documents that the partition is
13460 // deliberate, not an oversight.
13461 #[allow(clippy::needless_borrows_for_generic_args)]
13462 #[test]
13463 fn restart_policy_as_ref_bytes_routes_through_as_str_accessor() {
13464 // `<T: AsRef<[u8]>>`-bound generic-consumer witness: a byte-input
13465 // function that binds its argument through the standard-library
13466 // [`AsRef<[u8]>`] trait bound accepts a [`super::RestartPolicy`]
13467 // directly, without the caller open-coding the two-hop
13468 // `restart.as_str().as_bytes()` composition. Lifted to the top
13469 // of the function per `clippy::items_after_statements`.
13470 fn generic_bytes_sink<T: AsRef<[u8]>>(t: T) -> Vec<u8> {
13471 t.as_ref().to_vec()
13472 }
13473 // `blake3::Hasher::update`-shape byte-input surface mock: mirrors
13474 // `blake3::Hasher::update` / `ring::digest::Context::update` /
13475 // `sha2::Sha256::update`'s `impl AsRef<[u8]>`-bound `update`
13476 // signature so a per-child BLAKE3 content-address closure that
13477 // composes `hasher.update(restart)` on the [`crate::Lacre`]
13478 // closure builder reaches the substrate-primitive `as_str`
13479 // accessor through the [`super::RestartPolicy`] `AsRef<[u8]>`
13480 // axis and no other. Lifted to the top of the function per
13481 // `clippy::items_after_statements`.
13482 struct MockHasher(Vec<u8>);
13483 impl MockHasher {
13484 fn new() -> Self {
13485 Self(Vec::new())
13486 }
13487 fn update(&mut self, bytes: impl AsRef<[u8]>) -> &mut Self {
13488 self.0.extend_from_slice(bytes.as_ref());
13489 self
13490 }
13491 fn finalize(self) -> Vec<u8> {
13492 self.0
13493 }
13494 }
13495
13496 // Fail-before-pass-after byte-parity pin on the newly lifted
13497 // `impl AsRef<[u8]> for RestartPolicy` — asserts the trait-
13498 // idiomatic byte-view standard-library impl and the substrate-
13499 // primitive [`super::RestartPolicy::as_str`] `pub const fn`
13500 // accessor's `.as_bytes()` byte-tail resolve to the same three-
13501 // arm `PascalCase` wire byte-string emit-set across every arm
13502 // the exhaustive [`super::RestartPolicy::ALL`] slice enumerates.
13503 // Extends the trait-idiomatic byte-view axis onto the second
13504 // (and final) M2 OTP-shape closed-set fieldless typed enum peer
13505 // on the caixa surface (the paired per-child restart-decision
13506 // policy sibling on the same M2 `:supervisor` slot), closing
13507 // the byte-view axis across the `:supervisor :estrategia` +
13508 // `:children :restart` M2 slot pair the sibling
13509 // [`super::RestartStrategy`] first-mover (cd4c4e0) opened.
13510 //
13511 // Rust's standard library carries `impl AsRef<[u8]> for str` and
13512 // `impl AsRef<[u8]> for String`, so a two-hop composition
13513 // `restart.as_str().as_bytes()` (or the equally two-hop
13514 // `AsRef::<str>::as_ref(&restart).as_bytes()`) is reachable
13515 // through the pre-existing str-view axis alone. But that two-hop
13516 // shape has no compile-time link back to the byte-projection
13517 // axis, forces every downstream `<T: AsRef<[u8]>>`-bound
13518 // consumer to open-code the two-hop composition at every call
13519 // site, and admits a silent split whenever a future call site
13520 // takes a sibling reverse-projection axis whose `.as_bytes()`
13521 // byte-tail carries no compile-time byte-view surface. This
13522 // impl closes the byte-view axis at the substrate-primitive
13523 // [`super::RestartPolicy::as_str`] accessor so every future
13524 // `<T: AsRef<[u8]>>`-bound consumer reaches the same lifted
13525 // [`super::crate::render::SUPERVISOR_CHILD_RESTART_*`] const
13526 // roster the paired str-view axes already return through —
13527 // through one trait dispatch.
13528 for &variant in RestartPolicy::ALL {
13529 let via_trait: &[u8] = <RestartPolicy as AsRef<[u8]>>::as_ref(&variant);
13530 let via_method_bytes: &[u8] = variant.as_str().as_bytes();
13531 assert_eq!(
13532 via_trait, via_method_bytes,
13533 "AsRef<[u8]> for RestartPolicy impl must byte-equal \
13534 RestartPolicy::as_str().as_bytes() on \
13535 RestartPolicy::{variant:?} — divergence signals a \
13536 silent detour off the substrate-primitive accessor"
13537 );
13538 // Cross-axis witness against the paired str-view axes'
13539 // `.as_bytes()` byte-tails: [`AsRef<str>`] /
13540 // [`std::fmt::Display`] / [`super::RestartPolicy::as_str`]
13541 // all resolve to the same lifted
13542 // [`super::crate::render::SUPERVISOR_CHILD_RESTART_*`] const
13543 // roster, and the byte-view axis must byte-equal each of
13544 // their `.as_bytes()` byte-tails by construction — locking
13545 // the str-view and byte-view axes together at the
13546 // substrate-primitive accessor.
13547 let str_view_ref: &str = <RestartPolicy as AsRef<str>>::as_ref(&variant);
13548 assert_eq!(
13549 via_trait,
13550 str_view_ref.as_bytes(),
13551 "AsRef<[u8]> for RestartPolicy and AsRef<str> for \
13552 RestartPolicy must resolve to byte-equal byte-tails \
13553 on RestartPolicy::{variant:?} — divergence signals \
13554 the byte-view and str-view axes have drifted off the \
13555 same substrate-primitive as_str accessor"
13556 );
13557 let display_bytes = variant.to_string();
13558 assert_eq!(
13559 via_trait,
13560 display_bytes.as_bytes(),
13561 "AsRef<[u8]> for RestartPolicy and \
13562 <RestartPolicy as std::fmt::Display>::to_string must \
13563 resolve to byte-equal byte-tails on \
13564 RestartPolicy::{variant:?} — divergence signals the \
13565 byte-view axis and the Display formatter axis have \
13566 drifted off the same substrate-primitive as_str \
13567 accessor"
13568 );
13569 // Cross-axis witness against the paired reverse-projection
13570 // axes' `.as_bytes()` byte-tails: every one of `{&'static
13571 // str, String, Cow<'static, str>, Box<str>,
13572 // std::sync::Arc<str>}` allocates (or borrows) the same
13573 // `PascalCase` wire byte-string the substrate-primitive
13574 // accessor emits, so the byte-view axis must byte-equal
13575 // each of their `.as_bytes()` byte-tails by construction.
13576 let owned_static: &'static str = <&'static str as From<RestartPolicy>>::from(variant);
13577 assert_eq!(
13578 via_trait,
13579 owned_static.as_bytes(),
13580 "AsRef<[u8]> for RestartPolicy and From<RestartPolicy> \
13581 for &'static str must resolve to byte-equal byte-tails \
13582 on RestartPolicy::{variant:?}"
13583 );
13584 let owned_string: String = <String as From<RestartPolicy>>::from(variant);
13585 assert_eq!(
13586 via_trait,
13587 owned_string.as_bytes(),
13588 "AsRef<[u8]> for RestartPolicy and From<RestartPolicy> \
13589 for String must resolve to byte-equal byte-tails on \
13590 RestartPolicy::{variant:?}"
13591 );
13592 let owned_cow: std::borrow::Cow<'static, str> =
13593 <std::borrow::Cow<'static, str> as From<RestartPolicy>>::from(variant);
13594 assert_eq!(
13595 via_trait,
13596 owned_cow.as_bytes(),
13597 "AsRef<[u8]> for RestartPolicy and From<RestartPolicy> \
13598 for Cow<'static, str> must resolve to byte-equal byte-\
13599 tails on RestartPolicy::{variant:?}"
13600 );
13601 let owned_box: Box<str> = <Box<str> as From<RestartPolicy>>::from(variant);
13602 assert_eq!(
13603 via_trait,
13604 owned_box.as_bytes(),
13605 "AsRef<[u8]> for RestartPolicy and From<RestartPolicy> \
13606 for Box<str> must resolve to byte-equal byte-tails on \
13607 RestartPolicy::{variant:?}"
13608 );
13609 let owned_arc: std::sync::Arc<str> =
13610 <std::sync::Arc<str> as From<RestartPolicy>>::from(variant);
13611 assert_eq!(
13612 via_trait,
13613 owned_arc.as_bytes(),
13614 "AsRef<[u8]> for RestartPolicy and From<RestartPolicy> \
13615 for std::sync::Arc<str> must resolve to byte-equal \
13616 byte-tails on RestartPolicy::{variant:?}"
13617 );
13618 }
13619 // `<T: AsRef<[u8]>>`-bound-consumer witness: the generic byte-
13620 // input function `generic_bytes_sink` (lifted above per
13621 // `clippy::items_after_statements`) accepts a
13622 // [`super::RestartPolicy`] directly through the trait bound,
13623 // without the caller open-coding the two-hop
13624 // `restart.as_str().as_bytes()` composition. This is the shape
13625 // that reaches the caixa-lacre BLAKE3 content-address closure's
13626 // `blake3::Hasher::update(impl AsRef<[u8]>)` byte-input surface
13627 // through this impl and no other.
13628 for &variant in RestartPolicy::ALL {
13629 let via_generic = generic_bytes_sink(variant);
13630 let via_borrowed_generic = generic_bytes_sink(&variant);
13631 let via_method_bytes = variant.as_str().as_bytes().to_vec();
13632 assert_eq!(
13633 via_generic, via_method_bytes,
13634 "generic `<T: AsRef<[u8]>>`-bound consumer on \
13635 RestartPolicy::{variant:?} must yield the same byte-\
13636 tail RestartPolicy::as_str().as_bytes() returns — \
13637 divergence signals the byte-view axis fails to bridge \
13638 a generic byte-input trait bound to the substrate-\
13639 primitive accessor"
13640 );
13641 assert_eq!(
13642 via_borrowed_generic, via_method_bytes,
13643 "generic `<T: AsRef<[u8]>>`-bound consumer on \
13644 &RestartPolicy::{variant:?} must yield the same byte-\
13645 tail RestartPolicy::as_str().as_bytes() returns — the \
13646 borrowed-input surface must resolve to the same as_str \
13647 dispatch"
13648 );
13649 }
13650 // `blake3::Hasher::update`-shape byte-input surface witness on
13651 // the caixa-lacre compounding target: the `MockHasher` (lifted
13652 // above per `clippy::items_after_statements`) mirrors
13653 // `blake3::Hasher::update` / `ring::digest::Context::update` /
13654 // `sha2::Sha256::update`'s `impl AsRef<[u8]>`-bound update
13655 // signature and accepts a [`super::RestartPolicy`] directly,
13656 // routing its byte-tail through the substrate-primitive
13657 // `as_str` accessor — the shape a future per-child BLAKE3
13658 // content-address closure composes to fold a `:restart`
13659 // discriminator byte-tag into the [`crate::Lacre`] closure
13660 // body.
13661 for &variant in RestartPolicy::ALL {
13662 let mut owned_hasher = MockHasher::new();
13663 owned_hasher.update(variant);
13664 let owned_folded = owned_hasher.finalize();
13665 assert_eq!(
13666 owned_folded,
13667 variant.as_str().as_bytes(),
13668 "`hasher.update(restart)`-shape composition on \
13669 RestartPolicy::{variant:?} must fold the same byte-\
13670 tail RestartPolicy::as_str().as_bytes() returns — the \
13671 shape a future per-child BLAKE3 content-address \
13672 closure composes to fold a `:restart` discriminator \
13673 byte-tag into the Lacre closure body"
13674 );
13675 let mut borrowed_hasher = MockHasher::new();
13676 borrowed_hasher.update(&variant);
13677 let borrowed_folded = borrowed_hasher.finalize();
13678 assert_eq!(
13679 borrowed_folded,
13680 variant.as_str().as_bytes(),
13681 "`hasher.update(&restart)`-shape composition on \
13682 &RestartPolicy::{variant:?} must fold the same byte-\
13683 tail RestartPolicy::as_str().as_bytes() returns — the \
13684 borrowed-input surface must resolve to the same as_str \
13685 dispatch"
13686 );
13687 }
13688 }
13689
13690 #[test]
13691 #[expect(
13692 clippy::too_many_lines,
13693 reason = "the byte-owned reverse-projection axis is closed \
13694 here across the M2-OTP-shape :supervisor slot pair by \
13695 extending onto the second and final M2-OTP-shape \
13696 closed-set fieldless typed-enum peer, so the pin \
13697 binds the new impl against every paired byte-view \
13698 and str-owned axis on the same enum plus a generic \
13699 <T: Into<Vec<u8>>>-bound consumer witness and a \
13700 std::io::Write::write_all-shape owned-byte-sink \
13701 surface witness on both owned and borrowed input \
13702 shapes to lock the whole family against a future \
13703 silent regression"
13704 )]
13705 fn restart_policy_from_into_owned_vec_bytes_routes_through_as_str_accessor() {
13706 // `<T: Into<Vec<u8>>>`-bound-consumer witness helper: a generic
13707 // owned-byte-input function accepts a [`super::RestartPolicy`]
13708 // directly through the trait bound, without the caller open-
13709 // coding the three-hop `restart.as_str().as_bytes().to_vec()`
13710 // composition. Lifted to the top of the function per
13711 // `clippy::items_after_statements`.
13712 fn generic_owned_bytes_sink<T: Into<Vec<u8>>>(t: T) -> Vec<u8> {
13713 t.into()
13714 }
13715 // `std::io::Write::write_all`-shape owned-byte-sink surface
13716 // mock: mirrors `std::io::Write::write_all` /
13717 // `bytes::BytesMut::extend_from_slice` / any per-arm audit-log
13718 // byte-sink that consumes a `Vec<u8>` payload via
13719 // `Into<Vec<u8>>`, so a future per-child per-`:restart` audit-
13720 // log emit reaches the substrate-primitive `as_str` accessor
13721 // through the byte-owned reverse-projection axis and no
13722 // other. Lifted to the top of the function per
13723 // `clippy::items_after_statements`.
13724 struct MockOwnedByteSink(Vec<u8>);
13725 impl MockOwnedByteSink {
13726 fn new() -> Self {
13727 Self(Vec::new())
13728 }
13729 fn write_all(&mut self, bytes: impl Into<Vec<u8>>) -> &mut Self {
13730 self.0.extend(bytes.into());
13731 self
13732 }
13733 fn finalize(self) -> Vec<u8> {
13734 self.0
13735 }
13736 }
13737
13738 // Fail-before-pass-after byte-parity pin on the newly lifted
13739 // `impl From<RestartPolicy> for Vec<u8>` and
13740 // `impl From<&RestartPolicy> for Vec<u8>` — asserts the trait-
13741 // idiomatic byte-owned reverse-projection standard-library
13742 // impls and the substrate-primitive
13743 // [`super::RestartPolicy::as_str`] `pub const fn` accessor's
13744 // `.as_bytes().to_vec()` byte-tail resolve to the same three-
13745 // arm PascalCase wire byte-string emit-set across every arm
13746 // the exhaustive [`super::RestartPolicy::ALL`] slice
13747 // enumerates. Closes the substrate-wide trait-idiomatic byte-
13748 // owned reverse-projection axis on the M2-OTP-shape closed-
13749 // set typed-enum pair the sibling first-mover
13750 // [`super::RestartStrategy`] `From<{Self, &Self}> for Vec<u8>`
13751 // lift (63e5dd0) opened one commit prior, matching the
13752 // trajectory the paired [`AsRef<[u8]>`] borrowed byte-view
13753 // axis campaign already tracked across the same slot pair
13754 // (cd4c4e0 → 98b08fa).
13755 for &variant in RestartPolicy::ALL {
13756 let via_owned_from: Vec<u8> = <Vec<u8> as From<RestartPolicy>>::from(variant);
13757 let via_borrowed_from: Vec<u8> = <Vec<u8> as From<&RestartPolicy>>::from(&variant);
13758 let via_method_bytes: Vec<u8> = variant.as_str().as_bytes().to_vec();
13759 assert_eq!(
13760 via_owned_from, via_method_bytes,
13761 "From<RestartPolicy> for Vec<u8> impl must byte-equal \
13762 RestartPolicy::as_str().as_bytes().to_vec() on \
13763 RestartPolicy::{variant:?} — divergence signals a \
13764 silent detour off the substrate-primitive accessor"
13765 );
13766 assert_eq!(
13767 via_borrowed_from, via_method_bytes,
13768 "From<&RestartPolicy> for Vec<u8> impl must byte-\
13769 equal RestartPolicy::as_str().as_bytes().to_vec() \
13770 on RestartPolicy::{variant:?} — divergence signals \
13771 a silent detour off the substrate-primitive accessor"
13772 );
13773 assert_eq!(
13774 via_owned_from, via_borrowed_from,
13775 "From<RestartPolicy> for Vec<u8> and \
13776 From<&RestartPolicy> for Vec<u8> must byte-equal \
13777 each other on RestartPolicy::{variant:?} — \
13778 divergence signals the owned-input and borrowed-input \
13779 paths have drifted off the same substrate-primitive \
13780 as_str accessor"
13781 );
13782 // Cross-axis witness against the paired [`AsRef<[u8]>`]
13783 // borrowed byte-view axis (98b08fa): the byte-owned
13784 // reverse-projection axis must byte-equal the paired
13785 // borrowed byte-view axis by construction — locking the
13786 // byte-view and byte-owned axes together at the substrate-
13787 // primitive accessor.
13788 let borrowed_bytes: &[u8] = <RestartPolicy as AsRef<[u8]>>::as_ref(&variant);
13789 assert_eq!(
13790 via_owned_from,
13791 borrowed_bytes.to_vec(),
13792 "From<RestartPolicy> for Vec<u8> and AsRef<[u8]> for \
13793 RestartPolicy must resolve to byte-equal byte-tails \
13794 on RestartPolicy::{variant:?} — divergence signals \
13795 the byte-owned and byte-view axes have drifted off \
13796 the same substrate-primitive as_str accessor"
13797 );
13798 // Cross-axis witness against the str-owned reverse-
13799 // projection family's `.into_bytes()` / `.as_bytes().to_vec()`
13800 // byte-tails: every one of `{String, Cow<'static, str>,
13801 // Box<str>, std::sync::Arc<str>}` allocates (or borrows)
13802 // the same PascalCase wire byte-string the substrate-
13803 // primitive accessor emits, so the byte-owned axis must
13804 // byte-equal each of their owned byte-tails by
13805 // construction.
13806 let owned_string: String = <String as From<RestartPolicy>>::from(variant);
13807 assert_eq!(
13808 via_owned_from,
13809 owned_string.into_bytes(),
13810 "From<RestartPolicy> for Vec<u8> and \
13811 String::from(policy).into_bytes() must resolve to \
13812 byte-equal byte-tails on RestartPolicy::{variant:?}"
13813 );
13814 let owned_cow: std::borrow::Cow<'static, str> =
13815 <std::borrow::Cow<'static, str> as From<RestartPolicy>>::from(variant);
13816 assert_eq!(
13817 via_owned_from,
13818 owned_cow.as_bytes().to_vec(),
13819 "From<RestartPolicy> for Vec<u8> and \
13820 From<RestartPolicy> for Cow<'static, str> must \
13821 resolve to byte-equal byte-tails on \
13822 RestartPolicy::{variant:?}"
13823 );
13824 let owned_box: Box<str> = <Box<str> as From<RestartPolicy>>::from(variant);
13825 assert_eq!(
13826 via_owned_from,
13827 owned_box.as_bytes().to_vec(),
13828 "From<RestartPolicy> for Vec<u8> and \
13829 From<RestartPolicy> for Box<str> must resolve to \
13830 byte-equal byte-tails on RestartPolicy::{variant:?}"
13831 );
13832 let owned_arc: std::sync::Arc<str> =
13833 <std::sync::Arc<str> as From<RestartPolicy>>::from(variant);
13834 assert_eq!(
13835 via_owned_from,
13836 owned_arc.as_bytes().to_vec(),
13837 "From<RestartPolicy> for Vec<u8> and \
13838 From<RestartPolicy> for std::sync::Arc<str> must \
13839 resolve to byte-equal byte-tails on \
13840 RestartPolicy::{variant:?}"
13841 );
13842 }
13843 // `<T: Into<Vec<u8>>>`-bound-consumer witness on both owned
13844 // and borrowed input shapes: the generic owned-byte-input
13845 // function `generic_owned_bytes_sink` (lifted above per
13846 // `clippy::items_after_statements`) accepts a
13847 // [`super::RestartPolicy`] and a `&RestartPolicy` directly
13848 // through the trait bound, without the caller open-coding
13849 // the three-hop `restart.as_str().as_bytes().to_vec()`
13850 // composition.
13851 for &variant in RestartPolicy::ALL {
13852 let via_generic_owned = generic_owned_bytes_sink(variant);
13853 // Bind the borrowed-input path through an explicit
13854 // `&RestartPolicy` local so the generic-consumer witness
13855 // routes through `From<&RestartPolicy> for Vec<u8>` (T
13856 // binds to `&RestartPolicy`) rather than clippy-collapsing
13857 // the borrow onto the owned-input peer.
13858 let variant_ref: &RestartPolicy = &variant;
13859 let via_generic_borrowed = generic_owned_bytes_sink(variant_ref);
13860 let via_method_bytes = variant.as_str().as_bytes().to_vec();
13861 assert_eq!(
13862 via_generic_owned, via_method_bytes,
13863 "generic `<T: Into<Vec<u8>>>`-bound consumer on \
13864 RestartPolicy::{variant:?} must yield the same byte-\
13865 tail RestartPolicy::as_str().as_bytes() returns — \
13866 divergence signals the byte-owned axis fails to bridge \
13867 a generic owned-byte-input trait bound to the \
13868 substrate-primitive accessor"
13869 );
13870 assert_eq!(
13871 via_generic_borrowed, via_method_bytes,
13872 "generic `<T: Into<Vec<u8>>>`-bound consumer on \
13873 &RestartPolicy::{variant:?} must yield the same byte-\
13874 tail RestartPolicy::as_str().as_bytes() returns — \
13875 the borrowed-input surface must resolve to the same \
13876 as_str dispatch"
13877 );
13878 }
13879 // `std::io::Write::write_all`-shape owned-byte-sink surface
13880 // witness: the `MockOwnedByteSink` (lifted above per
13881 // `clippy::items_after_statements`) mirrors
13882 // `std::io::Write::write_all` /
13883 // `bytes::BytesMut::extend_from_slice`'s `impl Into<Vec<u8>>`-
13884 // bound owned-byte input signature and accepts a
13885 // [`super::RestartPolicy`] directly on both owned and
13886 // borrowed input shapes, routing its byte-tail through the
13887 // substrate-primitive `as_str` accessor — the shape a future
13888 // per-child per-`:restart` audit-log emit composes to fold a
13889 // `:restart` discriminator byte-tag into a downstream owned-
13890 // byte-sink surface.
13891 for &variant in RestartPolicy::ALL {
13892 let mut owned_sink = MockOwnedByteSink::new();
13893 owned_sink.write_all(variant);
13894 let owned_folded = owned_sink.finalize();
13895 assert_eq!(
13896 owned_folded,
13897 variant.as_str().as_bytes(),
13898 "`sink.write_all(restart)`-shape composition on \
13899 RestartPolicy::{variant:?} must fold the same byte-\
13900 tail RestartPolicy::as_str().as_bytes() returns"
13901 );
13902 let mut borrowed_sink = MockOwnedByteSink::new();
13903 let variant_ref: &RestartPolicy = &variant;
13904 borrowed_sink.write_all(variant_ref);
13905 let borrowed_folded = borrowed_sink.finalize();
13906 assert_eq!(
13907 borrowed_folded,
13908 variant.as_str().as_bytes(),
13909 "`sink.write_all(&restart)`-shape composition on \
13910 &RestartPolicy::{variant:?} must fold the same byte-\
13911 tail RestartPolicy::as_str().as_bytes() returns — \
13912 the borrowed-input surface must resolve to the same \
13913 as_str dispatch"
13914 );
13915 }
13916 }
13917
13918 #[test]
13919 fn restart_policy_all_enumerates_every_variant_exactly_once() {
13920 // Fail-before-pass-after pin on the [`RestartPolicy::ALL`]
13921 // exhaustive-iteration surface: every variant appears exactly
13922 // once, and the slice length matches the arm count of the
13923 // closed set. Every consumer that walks the accepted-policy
13924 // set (a future `feira supervisor --restart …` CLI-side
13925 // arg-parse's "did you mean" hint, a future M4 admission-
13926 // webhook's per-child rejection body naming the accepted-
13927 // `:restart` list, the [`RestartPolicy::from_wire`] reverse-
13928 // projection consumers that iterate the accept-set for
13929 // diagnostic rendering) reads through this slice, so a future
13930 // arm addition that grows the enum but forgets to grow
13931 // [`Self::ALL`] silently truncates every downstream consumer's
13932 // accept-set at the same pre-addition boundary — this pin
13933 // fails at caixa-core build time on the pairwise-distinct +
13934 // arm-count invariants.
13935 //
13936 // Peer of the sibling [`RestartStrategy::ALL`] (4eec29c) /
13937 // [`crate::CaixaKind::ALL`] (6b1f4fb) /
13938 // [`crate::aplicacao::PlacementStrategy::ALL`] (18c7342) /
13939 // [`crate::aplicacao::RateLimitUnit::ALL`] (6bce03d) /
13940 // [`crate::dep::DepList::ALL`] (45ee563) exhaustive-iteration
13941 // pins on the peer closed-set typed-enum axes.
13942 let all: &[RestartPolicy] = RestartPolicy::ALL;
13943 assert_eq!(
13944 all.len(),
13945 3,
13946 "RestartPolicy::ALL must enumerate every variant of the \
13947 three-arm closed set (Permanent, Temporary, Transient); \
13948 got {all:?}"
13949 );
13950 for (i, a) in all.iter().enumerate() {
13951 for (j, b) in all.iter().enumerate() {
13952 if i != j {
13953 assert_ne!(
13954 a, b,
13955 "RestartPolicy::ALL must carry every variant exactly \
13956 once — got duplicate {a:?} at indices {i} and {j}"
13957 );
13958 }
13959 }
13960 }
13961 for variant in [
13962 RestartPolicy::Permanent,
13963 RestartPolicy::Temporary,
13964 RestartPolicy::Transient,
13965 ] {
13966 assert!(
13967 all.contains(&variant),
13968 "RestartPolicy::ALL must contain {variant:?} — a future arm \
13969 addition that grows the enum but forgets to grow the ALL slice \
13970 silently truncates every downstream consumer's accept-set at \
13971 the pre-addition boundary"
13972 );
13973 }
13974 }
13975
13976 #[test]
13977 fn restart_policy_wire_names_covers_every_arm() {
13978 // Load-bearing pin on the substrate-canonical
13979 // [`RestartPolicy::WIRE_NAMES`] exhaustive accept-set roster on
13980 // the `PascalCase` wire byte-string axis: every variant of the
13981 // sibling [`RestartPolicy::ALL`] exhaustive-iteration surface
13982 // must project through [`RestartPolicy::as_str`] onto an entry
13983 // the [`RestartPolicy::WIRE_NAMES`] roster carries, and the
13984 // roster's length must byte-equal `RestartPolicy::ALL.len()` so
13985 // a silent skew between the [`RestartPolicy::as_str`] match's
13986 // arm-set and the roster's arm-set trips here at caixa-core
13987 // test time rather than at a downstream M4
13988 // `mesh.pleme.io/v1alpha1/Supervisor` CR admission-webhook
13989 // rejection body's wire-form `:restart` accepted-set
13990 // enumeration miss / a `feira supervisor --restart …` "did you
13991 // mean" hint drift / a future wasm-operator per-reconcile-step
13992 // diagnostic log line's accepted-wire-form enumeration miss.
13993 // A future arm addition (an OTP-`intrinsic` fourth arm the
13994 // theory
13995 // [`ABSORPTION-ROADMAP`](https://github.com/pleme-io/theory/blob/main/ABSORPTION-ROADMAP.md)
13996 // might reach for once the three canonical OTP restart policies
13997 // stop covering the substrate's discovered load-shape) extends
13998 // [`RestartPolicy::ALL`] as a single edit and this pin sweeps
13999 // the new arm by iteration; the paired
14000 // [`RestartPolicy::WIRE_NAMES`] roster must grow in lockstep or
14001 // this assertion trips. Every entry is further pinned to open
14002 // with an ASCII uppercase byte so a silent collapse of the
14003 // wire-form axis with the peer kebab-case dispatcher-catalog
14004 // axis (an entry byte-identical to a sibling
14005 // [`RestartPolicy::discriminant`] kebab byte-string that would
14006 // let a wire-axis consumer accept the dispatcher-catalog
14007 // vocabulary) trips here rather than at a downstream K8s-CR
14008 // round-trip miss.
14009 //
14010 // Peer of the sibling
14011 // [`restart_strategy_wire_names_covers_every_arm`] (3033f45)
14012 // pin on the first M2 OTP-shape sibling-restart closed-set
14013 // typed enum, the sibling
14014 // [`crate::aplicacao::tests::placement_strategy_wire_names_covers_every_arm`]
14015 // (3e5b194) pin on the first M3 mesh-shape distribution-strategy
14016 // closed-set typed enum, the sibling
14017 // [`crate::kind::tests::caixa_kind_wire_names_covers_every_arm`]
14018 // (bd708bd) pin on the top-level typed-kind discriminator's
14019 // `PascalCase` wire byte-string axis, and the sibling
14020 // [`crate::upgrade::tests::upgrade_instruction_wire_forms_covers_every_arm`]
14021 // (cc42c0e) /
14022 // [`crate::upgrade::tests::upgrade_instruction_lisp_forms_covers_every_arm`]
14023 // (1898d77) pins on the OTP-appup discriminator's two-axis
14024 // roster split — the same closed-set exhaustive-roster coverage
14025 // discipline extended here onto the second and final M2
14026 // OTP-shape sibling-enum on the caixa surface, closing the
14027 // per-child restart-decision-policy axis paired with the peer
14028 // per-supervisor sibling-restart-strategy axis on the same M2
14029 // `:supervisor` slot.
14030 //
14031 // Fail-before-pass-after locally verified by mutating one arm
14032 // of the paired [`crate::render::SUPERVISOR_CHILD_RESTART_*`]
14033 // const family (e.g. dropping the trailing `t` from
14034 // `"Permanent"` → `"Permanen"`) — the length pin still passes
14035 // but the `contains` check fires on the mutated arm; and by
14036 // shortening the roster to two entries — the length pin fires
14037 // first.
14038 assert_eq!(
14039 RestartPolicy::WIRE_NAMES.len(),
14040 RestartPolicy::ALL.len(),
14041 "RestartPolicy::WIRE_NAMES.len() must byte-equal \
14042 RestartPolicy::ALL.len() — a mismatch means the roster \
14043 and the enum's arm-set have drifted; downstream consumers \
14044 that fan through both will silently disagree on the \
14045 accepted arm-set"
14046 );
14047 for &variant in RestartPolicy::ALL {
14048 let wire = variant.as_str();
14049 assert!(
14050 RestartPolicy::WIRE_NAMES.contains(&wire),
14051 "RestartPolicy::{variant:?}.as_str() = {wire:?} must \
14052 be a member of RestartPolicy::WIRE_NAMES — the \
14053 emitter and the roster have drifted out of lockstep"
14054 );
14055 }
14056 for tag in RestartPolicy::WIRE_NAMES {
14057 let first = tag.chars().next().unwrap_or_else(|| {
14058 panic!(
14059 "RestartPolicy::WIRE_NAMES entry {tag:?} must be \
14060 a non-empty PascalCase byte-string"
14061 )
14062 });
14063 assert!(
14064 first.is_ascii_uppercase(),
14065 "RestartPolicy::WIRE_NAMES entry {tag:?} must open \
14066 with an ASCII uppercase byte (PascalCase wire form) — \
14067 a lowercase entry would collide the wire-form axis \
14068 with the peer kebab-case dispatcher-catalog axis \
14069 [`RestartPolicy::discriminant`] serves"
14070 );
14071 }
14072 }
14073
14074 #[test]
14075 fn restart_policy_from_wire_accepts_every_lifted_constant() {
14076 // Fail-before-pass-after pin on the forward accept-set of the
14077 // [`RestartPolicy::from_wire`] reverse projection: every
14078 // canonical [`crate::render::SUPERVISOR_CHILD_RESTART_*`]
14079 // constant the [`RestartPolicy::as_str`] emitter walks parses
14080 // back to its paired variant. Any future arm addition that
14081 // grows the emitter's `as_str` match but forgets to grow the
14082 // parser's `from_wire` match silently splits the two halves of
14083 // the round-trip — the wire byte-string one non-serde consumer
14084 // parses from the one the emitter wrote — with the failure
14085 // surfacing at the operator's reconcile posture (a `:temporary`
14086 // `oneShot` child restarted on clean exit, a `:transient` child
14087 // restarted after clean completion) far from the rebrand
14088 // commit. Pinning the three-arm accept-set here catches the
14089 // drift at caixa-core build time.
14090 //
14091 // Peer of the sibling [`RestartStrategy::from_wire`] (4eec29c)
14092 // + [`crate::CaixaKind::from_wire`] (2aa6d23)
14093 // + [`crate::aplicacao::PlacementStrategy::from_wire`] (18c7342)
14094 // accept-set pins on the peer closed-set typed-enum `str → Self`
14095 // axes.
14096 for (wire, expected) in [
14097 (
14098 crate::render::SUPERVISOR_CHILD_RESTART_PERMANENT,
14099 RestartPolicy::Permanent,
14100 ),
14101 (
14102 crate::render::SUPERVISOR_CHILD_RESTART_TEMPORARY,
14103 RestartPolicy::Temporary,
14104 ),
14105 (
14106 crate::render::SUPERVISOR_CHILD_RESTART_TRANSIENT,
14107 RestartPolicy::Transient,
14108 ),
14109 ] {
14110 let parsed = RestartPolicy::from_wire(wire).unwrap_or_else(|| {
14111 panic!(
14112 "RestartPolicy::from_wire({wire:?}) must accept every \
14113 SUPERVISOR_CHILD_RESTART_* constant — got None for the \
14114 lifted canonical byte-string that RestartPolicy::{expected:?} \
14115 serializes as under SUPERVISOR_CHILD_KEY_RESTART"
14116 )
14117 });
14118 assert_eq!(
14119 parsed, expected,
14120 "RestartPolicy::from_wire({wire:?}) must return \
14121 RestartPolicy::{expected:?}; got RestartPolicy::{parsed:?}"
14122 );
14123 }
14124 }
14125
14126 #[test]
14127 fn restart_policy_from_wire_round_trips_through_as_str() {
14128 // Fail-before-pass-after pin on the closed round-trip between
14129 // the forward [`RestartPolicy::as_str`] emitter and the
14130 // reverse [`RestartPolicy::from_wire`] parser: for every
14131 // variant in [`RestartPolicy::ALL`], parsing the emitter's
14132 // output must return exactly the same variant. Any per-arm
14133 // divergence — a future arm added to `as_str` but not
14134 // `from_wire`, an accidental copy-paste flip in one but not
14135 // the other — silently splits the emit and parse halves and
14136 // the failure surfaces at consumer parse time far from the
14137 // drift site. The `ALL`-iterating shape means a future arm
14138 // addition picks up the coverage by construction.
14139 //
14140 // Peer of the sibling
14141 // [`restart_strategy_from_wire_round_trips_through_as_str`]
14142 // (4eec29c) round-trip pin on
14143 // [`RestartStrategy::from_wire`] and the M3
14144 // [`crate::aplicacao::tests::placement_strategy_from_wire_round_trips_through_as_str`]
14145 // (18c7342) round-trip pin on
14146 // [`crate::aplicacao::PlacementStrategy::from_wire`].
14147 for &variant in RestartPolicy::ALL {
14148 let wire = variant.as_str();
14149 let parsed = RestartPolicy::from_wire(wire).unwrap_or_else(|| {
14150 panic!(
14151 "RestartPolicy::from_wire(RestartPolicy::{variant:?}.as_str()) \
14152 must be Some({variant:?}) — the two halves of the round-trip \
14153 dispatch on the same lifted SUPERVISOR_CHILD_RESTART_* consts; \
14154 got None on wire byte-string {wire:?}"
14155 )
14156 });
14157 assert_eq!(
14158 parsed, variant,
14159 "RestartPolicy::from_wire(RestartPolicy::{variant:?}.as_str()) \
14160 must round-trip to the same variant; got {parsed:?}"
14161 );
14162 }
14163 }
14164
14165 #[test]
14166 fn restart_policy_from_wire_rejects_unknown_byte_strings() {
14167 // Fail-before-pass-after pin on the closed-set refusal
14168 // discipline of [`RestartPolicy::from_wire`]: every
14169 // byte-string outside the three-arm accept-set returns `None`
14170 // rather than silently collapsing onto the [`Default`]
14171 // (`Permanent`) arm or an arbitrary neighbor. The refusal set
14172 // exercised here sweeps the load-bearing drift shapes: the
14173 // empty string (a stripped serde-attribute drift), all-
14174 // whitespace strings (the canonical text-editor accidental
14175 // padding shape), the kebab-case dispatcher-catalog identities
14176 // (`"permanent"` / `"temporary"` / `"transient"` — the
14177 // [`gen_platform::FromStrKind`]-derived [`std::str::FromStr`]
14178 // accept-set, which parses the *other* axis of this enum's
14179 // two-axis split and must not leak into the `from_wire`
14180 // PascalCase-wire accept-set — a lowercase leak here would
14181 // silently accept the operator's kebab-case
14182 // dispatcher-catalog probe under the wire-axis parser and mis-
14183 // route a `:permanent` intent), the padded canonical scalar
14184 // (`" Permanent "`), the trailing-newline shapes
14185 // (`"Permanent\n"`), the uppercase-single-word forms
14186 // (`"PERMANENT"`), and neighboring-but-unknown arms
14187 // (`"Restart"` — the canonical typo direction toward the
14188 // sibling [`RestartStrategy`] enum's own wire-arm namespace).
14189 //
14190 // Peer of the sibling
14191 // [`restart_strategy_from_wire_rejects_unknown_byte_strings`]
14192 // (4eec29c) +
14193 // [`crate::kind::tests::caixa_kind_from_wire_rejects_unknown_byte_strings`]
14194 // (2aa6d23) +
14195 // [`crate::aplicacao::tests::placement_strategy_from_wire_rejects_unknown_byte_strings`]
14196 // (18c7342) refusal pins on the peer closed-set typed-enum
14197 // axes.
14198 for bad in [
14199 "",
14200 " ",
14201 "\n",
14202 "\t",
14203 "permanent",
14204 "temporary",
14205 "transient",
14206 "PERMANENT",
14207 "TEMPORARY",
14208 "TRANSIENT",
14209 "Permanents",
14210 "Permanent ",
14211 " Permanent",
14212 " Transient ",
14213 "Permanent\n",
14214 "perma",
14215 "Trans",
14216 "OneForOne",
14217 "Restart",
14218 "?",
14219 ] {
14220 assert!(
14221 RestartPolicy::from_wire(bad).is_none(),
14222 "RestartPolicy::from_wire({bad:?}) must return None — the \
14223 parser's accept-set is exactly the three RestartPolicy::as_str \
14224 outputs (Permanent, Temporary, Transient), and this \
14225 byte-string is outside that closed set"
14226 );
14227 }
14228 }
14229
14230 #[test]
14231 fn restart_policy_from_wire_matches_serialize_derive_wire_byte_string() {
14232 // Fail-before-pass-after pin on the fourth path of the four-path
14233 // convergence: `from_wire` (the reverse projection) inverts the
14234 // `Serialize` derive's wire byte-string on every variant.
14235 // Together with the pre-existing three-path convergence
14236 // (`Display` + `as_str` + `Serialize` all resolve to the same
14237 // lifted [`crate::render::SUPERVISOR_CHILD_RESTART_*`] const,
14238 // pinned by
14239 // [`restart_policy_display_matches_serialized_wire_byte_string`])
14240 // this closes the round-trip: the wire byte-string the
14241 // `Serialize` derive emits parses back to the same variant
14242 // through `from_wire`, so any future serde-attribute or variant-
14243 // rename drift on the emit half now surfaces as a matched drift
14244 // on the parse half at caixa-core build time — the two halves
14245 // migrate as a unit through the lifted consts on any future
14246 // rename, and the round-trip cannot silently split.
14247 //
14248 // Peer of the sibling
14249 // [`restart_strategy_from_wire_matches_serialize_derive_wire_byte_string`]
14250 // (4eec29c) wire-format pin on
14251 // [`RestartStrategy::from_wire`] and the M3
14252 // [`crate::aplicacao::tests::placement_strategy_from_wire_matches_serialize_derive_wire_byte_string`]
14253 // (18c7342) wire-format pin on
14254 // [`crate::aplicacao::PlacementStrategy::from_wire`].
14255 for &variant in RestartPolicy::ALL {
14256 let wire = serde_json::to_string(&variant).unwrap();
14257 let unquoted = wire
14258 .strip_prefix('"')
14259 .and_then(|s| s.strip_suffix('"'))
14260 .expect("serialized RestartPolicy is a JSON string");
14261 let parsed = RestartPolicy::from_wire(unquoted).unwrap_or_else(|| {
14262 panic!(
14263 "RestartPolicy::from_wire({unquoted:?}) must accept the \
14264 Serialize derive's wire byte-string for \
14265 RestartPolicy::{variant:?} — the four-path convergence \
14266 (Display + as_str + Serialize + from_wire) resolves through \
14267 the same lifted SUPERVISOR_CHILD_RESTART_* const; got None"
14268 )
14269 });
14270 assert_eq!(
14271 parsed, variant,
14272 "RestartPolicy::from_wire of the Serialize derive's wire \
14273 byte-string for RestartPolicy::{variant:?} must round-trip \
14274 to the same variant; got {parsed:?}"
14275 );
14276 }
14277 }
14278
14279 // ── drift-detection: ChildSpec::nome accessor pins ────────────────────
14280 //
14281 // The M2 supervisor-tree sibling of the M3 `Membro::nome` (4a32abf) pin
14282 // pair (`membro_nome_returns_caixa_byte_equal_across_permutations` +
14283 // `membro_nome_borrows_from_caixa_storage`) — extended here to the M2
14284 // per-`:children` child-caixa `:nome` axis, sibling to the first M2
14285 // slot scalar accessor `UpgradeFromEntry::prior_versao` (75d27a8) on
14286 // the peer per-`:upgrade-from :from` axis. The three pins jointly
14287 // brace the accessor against every future silent detour that would
14288 // desynchronize it from the raw `.caixa` field access every consumer
14289 // previously open-coded.
14290
14291 #[test]
14292 fn child_spec_nome_returns_caixa_byte_equal_across_permutations() {
14293 // The canonical per-`:children` child-caixa `:nome`-scalar pin:
14294 // [`ChildSpec::nome`] must return the `:children :caixa` field
14295 // byte-for-byte across every DNS-1123-label value the upstream
14296 // [`crate::render::require_valid_dns_1123_label`] gate at
14297 // `SupervisorSpec::validate` admits. Peer of the sibling
14298 // `membro_nome_returns_caixa_byte_equal_across_permutations`
14299 // (4a32abf) pin on the M3 per-`:membros` axis — same "the
14300 // substrate-primitive accessor must byte-equal the raw field
14301 // access verbatim across every author-declared value" discipline
14302 // extended to the M2 supervisor-tree per-`:children` arm. Pins
14303 // against a future silent detour that re-normalized the child
14304 // identity (an accidental `.to_lowercase()` — every `:children
14305 // :caixa` is validated as a DNS-1123 label upstream, so any
14306 // re-normalization is redundant + a drift surface between the
14307 // validator and the accessor), a namespace-prefix rewrite (an
14308 // accidental `format!("{namespace}/{caixa}")` per-CR
14309 // fully-qualified rewrite that didn't land on the peer axes), or
14310 // a per-cluster alias stamp the future wasm-operator's
14311 // hierarchical reconciliation scheduler authors on one consumer
14312 // without the others. Five values sweep the accept-set the
14313 // DNS-1123 gate upstream admits (short single-word / dashed /
14314 // v-suffixed / mixed-digit child names).
14315 for name in [
14316 "worker",
14317 "cache-server",
14318 "scratch-job",
14319 "orders-v2",
14320 "session-8080",
14321 ] {
14322 let c = ChildSpec {
14323 caixa: name.into(),
14324 versao: "^0.1".into(),
14325 restart: RestartPolicy::Permanent,
14326 };
14327 assert_eq!(
14328 c.nome(),
14329 name,
14330 "ChildSpec::nome must return :children :caixa verbatim \
14331 (got {:?}, expected {name:?})",
14332 c.nome(),
14333 );
14334 assert_eq!(
14335 c.nome(),
14336 c.caixa.as_str(),
14337 "ChildSpec::nome must byte-equal the .caixa field access",
14338 );
14339 }
14340 }
14341
14342 #[test]
14343 fn child_spec_nome_borrows_from_caixa_storage() {
14344 // The borrow-not-copy pin: [`ChildSpec::nome`] must return a
14345 // `&str` slice that borrows from the typed slot's own [`String`]
14346 // storage — same-address invariant with `c.caixa.as_str()`. Pins
14347 // against a future silent detour that allocated a fresh `String`
14348 // (`self.caixa.clone()` in the body would type-check but silently
14349 // drop the borrow, and every downstream consumer that assumed
14350 // the returned slice outlives `&self` would break on a stale-
14351 // reference use-after-free — the [`crate::render::insert_first_seen`]
14352 // dedup key at [`SupervisorSpec::validate`], the
14353 // [`validate_no_self_supervision`] equality check against the
14354 // parent's `:nome` string slice, the DNS-1123 gate's `&str`
14355 // borrow — each would silently misbehave if this accessor
14356 // produced a detached copy). Peer of the sibling
14357 // `membro_nome_borrows_from_caixa_storage` (4a32abf) pin on the
14358 // M3 per-`:membros` axis and the
14359 // `prior_versao_borrows_from_from_storage` (75d27a8) pin on the
14360 // first M2 slot scalar accessor.
14361 let c = ChildSpec {
14362 caixa: "worker".into(),
14363 versao: "^0.1".into(),
14364 restart: RestartPolicy::Permanent,
14365 };
14366 let name = c.nome();
14367 let caixa_slice = c.caixa.as_str();
14368 assert_eq!(
14369 name.as_ptr(),
14370 caixa_slice.as_ptr(),
14371 "ChildSpec::nome must borrow from the .caixa String's backing \
14372 storage — a fresh allocation here means the accessor no \
14373 longer names the substrate-primitive typed dispatch and \
14374 every downstream consumer would silently carry a detached \
14375 copy",
14376 );
14377 assert_eq!(
14378 name.len(),
14379 caixa_slice.len(),
14380 "ChildSpec::nome and .caixa.as_str() must byte-equal in length \
14381 as well as in address",
14382 );
14383 }
14384
14385 #[test]
14386 fn validate_gates_child_nome_through_lifted_accessor() {
14387 // Bilateral coherence pin: every `:children :caixa` that
14388 // [`SupervisorSpec::validate`] accepts is one
14389 // [`crate::render::require_valid_dns_1123_label`] accepts on the
14390 // accessor-projected value, and vice versa on the reject side.
14391 // This closes the "the validator reads through the accessor"
14392 // contract structurally — a future silent detour that made the
14393 // accessor return a different byte-string than the validator
14394 // gates against would surface here as a coverage mismatch, not
14395 // as an apply-time DNS-1123 rejection at
14396 // `metadata.name: Invalid value` far from the caixa.lisp source.
14397 // Peer of the M2 sibling
14398 // `validate_parses_prior_versao_through_lifted_accessor`
14399 // (75d27a8) on the per-`:upgrade-from :from` axis and the M3
14400 // `validate_membros` peer discipline.
14401 //
14402 // Accept-set sweep: five DNS-1123-label values the upstream gate
14403 // admits.
14404 for ok_name in ["a", "worker", "cache-server", "orders-v2", "svc-8080"] {
14405 let s = SupervisorSpec {
14406 children: vec![ChildSpec {
14407 caixa: ok_name.into(),
14408 versao: "^0.1".into(),
14409 restart: RestartPolicy::Permanent,
14410 }],
14411 ..SupervisorSpec::default()
14412 };
14413 s.validate().unwrap_or_else(|e| {
14414 panic!(
14415 "SupervisorSpec::validate must accept :children :caixa {ok_name:?} \
14416 (upstream DNS-1123 gate accepts it): got {e:?}",
14417 );
14418 });
14419 let c = ChildSpec {
14420 caixa: ok_name.into(),
14421 versao: "^0.1".into(),
14422 restart: RestartPolicy::Permanent,
14423 };
14424 crate::render::require_valid_dns_1123_label(c.nome(), || (), |_reason| ())
14425 .unwrap_or_else(|()| {
14426 panic!(
14427 "require_valid_dns_1123_label must accept the accessor-projected \
14428 :children :caixa {ok_name:?}",
14429 );
14430 });
14431 }
14432 // Reject-set sweep: five DNS-1123-label-violating shapes the
14433 // upstream gate refuses (empty / uppercase / underscore / dot /
14434 // leading-hyphen). Every rejection at the validator must
14435 // correspond to a rejection when the accessor's projected value
14436 // is fed back through the shared gate.
14437 for bad_name in ["", "Worker", "my_worker", "team.worker", "-worker"] {
14438 let s = SupervisorSpec {
14439 children: vec![ChildSpec {
14440 caixa: bad_name.into(),
14441 versao: "^0.1".into(),
14442 restart: RestartPolicy::Permanent,
14443 }],
14444 ..SupervisorSpec::default()
14445 };
14446 let err = s.validate().unwrap_err();
14447 assert!(
14448 matches!(
14449 err,
14450 SupervisorError::EmptyChildName | SupervisorError::ChildCaixaInvalid { .. }
14451 ),
14452 "SupervisorSpec::validate must reject :children :caixa {bad_name:?} \
14453 via the DNS-1123 gate: got {err:?}",
14454 );
14455 let c = ChildSpec {
14456 caixa: bad_name.into(),
14457 versao: "^0.1".into(),
14458 restart: RestartPolicy::Permanent,
14459 };
14460 assert!(
14461 crate::render::require_valid_dns_1123_label(c.nome(), || (), |_reason| (),)
14462 .is_err(),
14463 "require_valid_dns_1123_label must reject the accessor-projected \
14464 :children :caixa {bad_name:?}",
14465 );
14466 }
14467 }
14468
14469 // ── drift-detection: ChildSpec::versao_requirement accessor pins ──────
14470 //
14471 // Sibling of the peer per-`:membros` `membro_versao_requirement_*`
14472 // (a40b0e3) pin pair on the M3 mesh-slot surface — extended here to the
14473 // M2 supervisor-tree per-`:children` child-`:versao` axis, sibling to
14474 // the just-landed [`ChildSpec::nome`] (57c61d0) child-`:nome` pin
14475 // trio on the peer per-`:children` `String`-carry axis. The three pins
14476 // jointly brace the accessor against every future silent detour that
14477 // would desynchronize it from the raw `.versao` field access the
14478 // requirement gate + error carrier previously open-coded.
14479 //
14480 // Closes the last unlifted per-`:children` `String`-carry axis: the
14481 // pair (`nome`, `versao_requirement`) now jointly projects the
14482 // (`.caixa`, `.versao`) field pair every OTP-shape supervisor-tree
14483 // consumer that fans on per-child identity + version pin reads,
14484 // matching the peer M3 (`Membro::nome`, `Membro::versao_requirement`)
14485 // pair discipline verbatim.
14486 #[test]
14487 fn child_spec_versao_requirement_returns_versao_byte_equal_across_permutations() {
14488 // The canonical per-`:children` child-`:versao`-scalar pin:
14489 // [`ChildSpec::versao_requirement`] must return the `:children
14490 // :versao` field byte-for-byte across every Cargo-shaped semver
14491 // requirement value the upstream
14492 // [`crate::render::require_valid_versao_requirement`] gate admits.
14493 // Peer of the sibling
14494 // `membro_versao_requirement_returns_versao_byte_equal_across_permutations`
14495 // (a40b0e3) pin on the M3 per-`:membros` axis — same "the
14496 // substrate-primitive accessor must byte-equal the raw field
14497 // access verbatim across every author-declared value" discipline
14498 // extended to the M2 supervisor-tree per-`:children` arm. Pins
14499 // against a future silent detour that re-canonicalized the
14500 // requirement (an accidental `.to_string()` via
14501 // [`crate::version::parse_requirement`] → [`std::fmt::Display`]
14502 // round-trip that collapsed `"^0.1"` to `">=0.1, <0.2"` and
14503 // silently drifted the error carrier's quoted requirement away
14504 // from the source `caixa.lisp`, an accidental whitespace trim on
14505 // `"^ 0.1"` that no consumer ever produced from the field-access
14506 // side, an accidental per-cluster lacre-projected concrete-version
14507 // rewrite that didn't land on the peer requirement-gate call).
14508 // Five values sweep the accept-set the shared
14509 // [`crate::render::require_valid_versao_requirement`] gate admits
14510 // (caret / tilde / exact / wildcard / bare-major).
14511 for req in ["^0.1", "~0.1.2", "0.1.0", "*", "^1"] {
14512 let c = ChildSpec {
14513 caixa: "worker".into(),
14514 versao: req.into(),
14515 restart: RestartPolicy::Permanent,
14516 };
14517 assert_eq!(
14518 c.versao_requirement(),
14519 req,
14520 "ChildSpec::versao_requirement must return :children :versao \
14521 verbatim (got {:?}, expected {req:?})",
14522 c.versao_requirement(),
14523 );
14524 assert_eq!(
14525 c.versao_requirement(),
14526 c.versao.as_str(),
14527 "ChildSpec::versao_requirement must byte-equal the .versao \
14528 field access",
14529 );
14530 }
14531 }
14532
14533 #[test]
14534 fn child_spec_versao_requirement_borrows_from_versao_storage() {
14535 // The borrow-not-copy pin: [`ChildSpec::versao_requirement`] must
14536 // return a `&str` slice that borrows from the typed slot's own
14537 // [`String`] storage — same-address invariant with
14538 // `c.versao.as_str()`. Pins against a future silent detour that
14539 // allocated a fresh `String` (`self.versao.clone()` in the body
14540 // would type-check but silently drop the borrow, and every
14541 // downstream consumer that assumed the returned slice outlives
14542 // `&self` — the [`crate::render::require_valid_versao_requirement`]
14543 // gate's `&str` borrow, the [`SupervisorError::ChildVersaoInvalid`]
14544 // `.to_string()` carrier's byte-length assumption — would silently
14545 // misbehave if this accessor produced a detached copy). Peer of
14546 // the sibling `child_spec_nome_borrows_from_caixa_storage`
14547 // (57c61d0) pin on the per-`:children` `:nome` axis and the M3
14548 // `membro_versao_requirement_borrows_from_versao_storage` (a40b0e3)
14549 // pin on the peer per-`:membros` `:versao` axis.
14550 let c = ChildSpec {
14551 caixa: "worker".into(),
14552 versao: "^0.1".into(),
14553 restart: RestartPolicy::Permanent,
14554 };
14555 let req = c.versao_requirement();
14556 let versao_slice = c.versao.as_str();
14557 assert_eq!(
14558 req.as_ptr(),
14559 versao_slice.as_ptr(),
14560 "ChildSpec::versao_requirement must borrow from the .versao \
14561 String's backing storage — a fresh allocation here means the \
14562 accessor no longer names the substrate-primitive typed \
14563 dispatch and every downstream consumer would silently carry \
14564 a detached copy",
14565 );
14566 assert_eq!(
14567 req.len(),
14568 versao_slice.len(),
14569 "ChildSpec::versao_requirement and .versao.as_str() must \
14570 byte-equal in length as well as in address",
14571 );
14572 }
14573
14574 #[test]
14575 fn validate_gates_child_versao_through_lifted_accessor() {
14576 // Bilateral coherence pin: every `:children :versao` that
14577 // [`SupervisorSpec::validate`] accepts is one
14578 // [`crate::render::require_valid_versao_requirement`] accepts on
14579 // the accessor-projected value, and vice versa on the reject side.
14580 // This closes the "the validator reads through the accessor"
14581 // contract structurally — a future silent detour that made the
14582 // accessor return a different byte-string than the validator gates
14583 // against would surface here as a coverage mismatch, not as a
14584 // resolver-time semver-parse rejection at lacre-closure time far
14585 // from the caixa.lisp source. Peer of the sibling
14586 // `validate_gates_child_nome_through_lifted_accessor` (57c61d0) on
14587 // the per-`:children :caixa` axis and the M2
14588 // `validate_parses_prior_versao_through_lifted_accessor` (75d27a8)
14589 // on the peer per-`:upgrade-from :from` axis.
14590 //
14591 // Accept-set sweep: five Cargo-shaped semver requirement values
14592 // the upstream gate admits (caret / tilde / exact / wildcard /
14593 // bare-major).
14594 for ok_req in ["^0.1", "~0.1.2", "0.1.0", "*", "^1"] {
14595 let s = SupervisorSpec {
14596 children: vec![ChildSpec {
14597 caixa: "worker".into(),
14598 versao: ok_req.into(),
14599 restart: RestartPolicy::Permanent,
14600 }],
14601 ..SupervisorSpec::default()
14602 };
14603 s.validate().unwrap_or_else(|e| {
14604 panic!(
14605 "SupervisorSpec::validate must accept :children :versao {ok_req:?} \
14606 (upstream versao-requirement gate accepts it): got {e:?}",
14607 );
14608 });
14609 let c = ChildSpec {
14610 caixa: "worker".into(),
14611 versao: ok_req.into(),
14612 restart: RestartPolicy::Permanent,
14613 };
14614 crate::render::require_valid_versao_requirement(
14615 c.versao_requirement(),
14616 || (),
14617 |_reason| (),
14618 )
14619 .unwrap_or_else(|()| {
14620 panic!(
14621 "require_valid_versao_requirement must accept the accessor-projected \
14622 :children :versao {ok_req:?}",
14623 );
14624 });
14625 }
14626 // Reject-set sweep: five requirement-violating shapes the upstream
14627 // gate refuses. The empty string closes the empty-first arm of the
14628 // shared [`crate::render::require_valid_versao_requirement`]
14629 // cascade; the four non-empty arms exercise distinct semver-parse
14630 // failure modes the M3 peer per-`:membros` reject-set already pins
14631 // (`rejects_invalid_membro_versao_requirement` on `^bad-version`,
14632 // `rejects_membro_versao_with_double_caret_typo` on `^^0.1`,
14633 // `rejects_membro_versao_with_v_prefixed_tag` on `v0.1`) — the
14634 // shared parser routing means the same reject-set must fail
14635 // identically at the M2 supervisor-tree per-`:children` accessor
14636 // arm here. Every rejection at the validator must correspond to a
14637 // rejection when the accessor's projected value is fed back
14638 // through the shared gate.
14639 //
14640 // (Bare partial magnitudes like `"0.1"` and bare identifiers like
14641 // `"not-a-semver"` are intentionally *not* in the reject-set: the
14642 // semver crate accepts `"0.1"` as an implicit `^0.1` requirement,
14643 // and the identifier-tail arm's grammar admits some non-canonical
14644 // shapes — matching what the M3 peer test suite already documents
14645 // as the shared parser's accept-set edges.)
14646 for bad_req in ["", "v0.1.0", "^bad-version", "^^0.1", "v0.1"] {
14647 let s = SupervisorSpec {
14648 children: vec![ChildSpec {
14649 caixa: "worker".into(),
14650 versao: bad_req.into(),
14651 restart: RestartPolicy::Permanent,
14652 }],
14653 ..SupervisorSpec::default()
14654 };
14655 let err = s.validate().unwrap_err();
14656 assert!(
14657 matches!(
14658 err,
14659 SupervisorError::EmptyChildVersion { .. }
14660 | SupervisorError::ChildVersaoInvalid { .. }
14661 ),
14662 "SupervisorSpec::validate must reject :children :versao {bad_req:?} \
14663 via the versao-requirement gate: got {err:?}",
14664 );
14665 let c = ChildSpec {
14666 caixa: "worker".into(),
14667 versao: bad_req.into(),
14668 restart: RestartPolicy::Permanent,
14669 };
14670 assert!(
14671 crate::render::require_valid_versao_requirement(
14672 c.versao_requirement(),
14673 || (),
14674 |_reason| (),
14675 )
14676 .is_err(),
14677 "require_valid_versao_requirement must reject the accessor-projected \
14678 :children :versao {bad_req:?}",
14679 );
14680 }
14681 }
14682
14683 // ── per-`:children` `:restart` typed-accessor coherence pins ──────────
14684 //
14685 // The [`ChildSpec::restart`] accessor lift closes the last unlifted
14686 // per-`:children` axis (the pair `nome()` + `versao_requirement()`
14687 // already project the `String`-carry `(caixa, versao)` fields; the
14688 // `Copy`-composite-enum `restart` field is the third and final axis).
14689 // Peer of the sibling per-`:supervisor` [`SupervisorSpec::estrategia`]
14690 // (eafb619) `Copy`-return [`RestartStrategy`] sibling-restart-strategy
14691 // scalar accessor and the M3 mesh-slot [`crate::Placement::estrategia`]
14692 // (921fe1b) `Copy`-return [`crate::PlacementStrategy`] distribution-
14693 // strategy scalar accessor — same "one typed dispatch on the substrate
14694 // primitive, `Copy`-projected closed-set enum-arm discriminator" shape
14695 // extended onto the M2 supervisor-slot per-`:children` restart-decision
14696 // axis. The pin below covers the accessor's byte-equal projection
14697 // against the raw field access across every variant in the closed
14698 // accept-set (`Permanent`, `Transient`, `Temporary`).
14699
14700 #[test]
14701 fn child_spec_restart_returns_restart_verbatim_across_permutations() {
14702 // The canonical per-`:children` restart-decision-policy-scalar
14703 // pin: [`ChildSpec::restart`] must return the `:children :restart`
14704 // field verbatim as a [`RestartPolicy`], `Copy`-projected from the
14705 // typed slot's own [`RestartPolicy`] storage across every variant
14706 // in the closed accept-set (`Permanent`, `Transient`, `Temporary`).
14707 // Pins against a future silent detour that re-derived the policy
14708 // from a peer axis (an accidental fallback to
14709 // `if is_supervisor_child { Permanent } else { Temporary }` that
14710 // collapsed the child's kind axis into the restart discriminator),
14711 // a variant remap the operator authors on one consumer without the
14712 // other, or a stale-derive detour that substituted
14713 // [`RestartPolicy::default`] when the field held any explicit
14714 // variant (which would silently collapse the distinction between
14715 // "author explicitly declared `:restart Permanent`" and "author
14716 // omitted the slot and inherited the default" the future
14717 // per-cluster restart-decision override slot depends on).
14718 //
14719 // Peer of the sibling per-`:supervisor`
14720 // `supervisor_spec_estrategia_returns_estrategia_verbatim_across_permutations`
14721 // (eafb619) pin on the M2 supervisor-slot sibling-restart-strategy
14722 // axis and the M3
14723 // `placement_estrategia_returns_estrategia_verbatim_across_permutations`
14724 // (921fe1b) pin on the per-`:placement` distribution-strategy axis
14725 // — same "the substrate-primitive accessor must byte-equal the raw
14726 // field access verbatim across every author-declared value"
14727 // discipline extended onto the M2 supervisor-slot per-`:children`
14728 // restart-decision-policy axis, closing the last unlifted axis on
14729 // the per-`:children` [`ChildSpec`] type.
14730 for restart in [
14731 RestartPolicy::Permanent,
14732 RestartPolicy::Transient,
14733 RestartPolicy::Temporary,
14734 ] {
14735 let c = ChildSpec {
14736 caixa: "worker".into(),
14737 versao: "^0.1".into(),
14738 restart,
14739 };
14740 assert_eq!(
14741 c.restart(),
14742 restart,
14743 "ChildSpec::restart must return :children :restart \
14744 verbatim (got {:?}, expected {restart:?})",
14745 c.restart(),
14746 );
14747 assert_eq!(
14748 c.restart(),
14749 c.restart,
14750 "ChildSpec::restart accessor and .restart field access \
14751 must byte-equal — the accessor is the substrate-primitive \
14752 typed dispatch every downstream per-child restart-\
14753 decision consumer must route through",
14754 );
14755 }
14756 }
14757
14758 // ── per-`:supervisor` `:estrategia` typed-accessor coherence pins ─────
14759 //
14760 // The [`SupervisorSpec::estrategia`] accessor lift extends the peer M3
14761 // [`crate::Placement::estrategia`] (921fe1b) `Copy`-return
14762 // distribution-strategy accessor discipline onto the M2 supervisor-slot
14763 // per-`:supervisor` sibling-restart-strategy `Copy`-composite-enum
14764 // scalar axis. The two pins below cover (1) the accessor's byte-equal
14765 // projection against the raw field access across every variant in the
14766 // closed accept-set, and (2) the two-consumer coherence between the
14767 // [`SupervisorSpec::validate`] partition-dispatch `match` arm and the
14768 // non-`SimpleOneForOne`-arm [`SupervisorError::NoChildren`] error
14769 // carrier's `estrategia:` field — peer of the sibling M3
14770 // `placement_estrategia_returns_estrategia_verbatim_across_permutations`
14771 // / `validate_placement_reads_through_lifted_estrategia_accessor` pin
14772 // pair on the per-`:placement` distribution-strategy axis.
14773
14774 #[test]
14775 fn supervisor_spec_estrategia_returns_estrategia_verbatim_across_permutations() {
14776 // The canonical per-`:supervisor` sibling-restart-strategy-scalar
14777 // pin: [`SupervisorSpec::estrategia`] must return the
14778 // `:supervisor :estrategia` field verbatim as a
14779 // [`RestartStrategy`], `Copy`-projected from the typed slot's own
14780 // [`RestartStrategy`] storage across every variant in the closed
14781 // accept-set (`OneForOne`, `OneForAll`, `RestForOne`,
14782 // `SimpleOneForOne`). Pins against a future silent detour that
14783 // re-derived the strategy from a peer axis (an accidental
14784 // fallback to `if children.is_empty() { SimpleOneForOne } else {
14785 // OneForOne }` collapse that read the children-count axis into
14786 // the strategy discriminator), a variant remap the operator
14787 // authors on one consumer without the other, or a stale-derive
14788 // detour that substituted [`RestartStrategy::default`] when the
14789 // field held any explicit variant (which would silently collapse
14790 // the distinction between "author explicitly declared
14791 // `:estrategia OneForOne`" and "author omitted the slot and
14792 // inherited the default" the future per-cluster strategy override
14793 // slot depends on). Peer of the sibling M3
14794 // `placement_estrategia_returns_estrategia_verbatim_across_permutations`
14795 // (921fe1b) pin on the M3 mesh-slot `Copy`-composite-enum scalar
14796 // axis — same "the substrate-primitive accessor must byte-equal
14797 // the raw field access verbatim across every author-declared
14798 // value" discipline extended onto the M2 supervisor-slot
14799 // per-`:supervisor` sibling-restart-strategy axis.
14800 for &estrategia in RestartStrategy::ALL {
14801 // `SimpleOneForOne` requires `children.is_empty()`; the peer
14802 // three strategies require a non-empty static children list.
14803 // Build each shape coherently so the pin's fixture would
14804 // itself pass [`SupervisorSpec::validate`] once fed through
14805 // the sibling coherence pin below — the byte-equal projection
14806 // asserted here is a strictly weaker property (a `Copy` field
14807 // read) that does not depend on `validate` running, but
14808 // keeping the fixture validate-clean means a future extension
14809 // of the pin to exercise `validate` end-to-end does not have
14810 // to re-author the children shape.
14811 //
14812 // Route the `SimpleOneForOne ↔ non-SimpleOneForOne` fixture-
14813 // shape partition through the [`gen_platform::IsVariant`]
14814 // derive-generated
14815 // [`RestartStrategy::is_simple_one_for_one`] predicate rather
14816 // than the raw `matches!(estrategia, RestartStrategy::
14817 // SimpleOneForOne)` open-coded pattern-match — same closed-
14818 // set-typed-enum arm-discriminator dispatch discipline the
14819 // sibling [`crate::upgrade::UpgradeInstruction::is_restart`]
14820 // convergence (915a934) extended onto its two paired positive
14821 // / negated `matches!` sites and the peer
14822 // [`crate::aplicacao::PlacementStrategy`] `IsVariant`-derived
14823 // predicate convergence (766ec63) extended onto the M3 mesh-
14824 // slot per-`:placement` distribution-strategy discriminator
14825 // axis. See the sibling `round_trip_all_strategies` and the
14826 // peer `manifest::tests::
14827 // caixa_estrategia_and_supervisor_view_reads_through_lifted_estrategia_accessor`
14828 // fixture for the two peer sites the same lift closes on.
14829 let children = if estrategia.is_simple_one_for_one() {
14830 Vec::new()
14831 } else {
14832 vec![ChildSpec {
14833 caixa: "worker".into(),
14834 versao: "^0.1".into(),
14835 restart: RestartPolicy::Permanent,
14836 }]
14837 };
14838 let s = SupervisorSpec {
14839 estrategia,
14840 children,
14841 ..SupervisorSpec::default()
14842 };
14843 assert_eq!(
14844 s.estrategia(),
14845 estrategia,
14846 "SupervisorSpec::estrategia must return :supervisor :estrategia \
14847 verbatim (got {:?}, expected {estrategia:?})",
14848 s.estrategia(),
14849 );
14850 assert_eq!(
14851 s.estrategia(),
14852 s.estrategia,
14853 "SupervisorSpec::estrategia accessor and .estrategia field \
14854 access must byte-equal — the accessor is the substrate-\
14855 primitive typed dispatch every downstream sibling-restart-\
14856 strategy consumer must route through",
14857 );
14858 }
14859 }
14860
14861 #[test]
14862 fn validate_reads_through_lifted_estrategia_accessor() {
14863 // Two-consumer coherence pin: the [`SupervisorSpec::validate`]
14864 // `SimpleOneForOne ↔ non-SimpleOneForOne` `match` partition
14865 // dispatch (which reads through [`SupervisorSpec::estrategia`]
14866 // to fan across the strategy-arm shape-gate cascades) and the
14867 // non-`SimpleOneForOne`-arm [`SupervisorError::NoChildren`]
14868 // error carrier's `estrategia:` field (which reads through
14869 // [`SupervisorSpec::estrategia`] to name the strategy the empty
14870 // `:children` list was declared against) must both key off the
14871 // lifted accessor, so any future rebrand on the typed slot's
14872 // reader shape lands at exactly one place. Pins the two-site
14873 // coherence by exercising the `NoChildren` error surface end-to-
14874 // end across every non-`SimpleOneForOne` variant and asserting
14875 // the surfaced `estrategia:` field byte-equals the accessor's
14876 // return. Peer of the sibling M3
14877 // `validate_placement_reads_through_lifted_estrategia_accessor`
14878 // (921fe1b) three-consumer coherence pin on the per-`:placement`
14879 // distribution-strategy axis.
14880 for estrategia in [
14881 RestartStrategy::OneForOne,
14882 RestartStrategy::OneForAll,
14883 RestartStrategy::RestForOne,
14884 ] {
14885 let s = SupervisorSpec {
14886 estrategia,
14887 children: Vec::new(),
14888 ..SupervisorSpec::default()
14889 };
14890 let err = s.validate().unwrap_err();
14891 match err {
14892 SupervisorError::NoChildren { estrategia: e } => {
14893 assert_eq!(
14894 e,
14895 s.estrategia(),
14896 "NoChildren.estrategia must byte-equal \
14897 SupervisorSpec::estrategia() — the empty-`:children` \
14898 refusal reads through the lifted accessor",
14899 );
14900 assert_eq!(
14901 e, estrategia,
14902 "NoChildren.estrategia must carry the author-declared \
14903 :supervisor :estrategia variant verbatim (got {e:?}, \
14904 expected {estrategia:?})",
14905 );
14906 }
14907 other => panic!("expected NoChildren, got {other:?} for estrategia={estrategia:?}"),
14908 }
14909 }
14910 }
14911
14912 // ── per-`:supervisor` `:max-restarts` typed-accessor coherence pins ────
14913 //
14914 // The [`SupervisorSpec::max_restarts`] accessor lift extends the peer M3
14915 // [`crate::CircuitBreaker::max_failures`] (3a74062) `Copy`-return
14916 // required-`u32` scalar accessor discipline onto the M2 supervisor-slot
14917 // per-`:supervisor` restart-budget-count `Copy`-`u32` scalar axis.
14918 // The two pins below cover (1) the accessor's byte-equal projection
14919 // against the raw field access across every representative value in
14920 // the `u32` accept-set (`1` lower boundary, `SUPERVISOR_MAX_RESTARTS_MAX`
14921 // upper boundary, `0` past-the-guard zero sentinel, `u32::MAX`
14922 // past-the-guard cap sentinel), and (2) the [`SupervisorSpec::validate`]
14923 // zero-floor / cap composition — the validate gate and the accessor
14924 // must route through the same substrate-primitive typed dispatch, so
14925 // any future silent detour that had the accessor perform a
14926 // bounds-collapsing clamp would fail here at caixa-core build time.
14927 // Peer of the sibling M3
14928 // `circuit_breaker_max_failures_returns_max_failures_u32_byte_equal_across_permutations`
14929 // (3a74062) pin on the per-`CircuitBreaker :max-failures` axis.
14930
14931 #[test]
14932 fn supervisor_spec_max_restarts_returns_max_restarts_u32_byte_equal_across_permutations() {
14933 // The canonical per-`:supervisor` restart-budget-count scalar pin:
14934 // [`SupervisorSpec::max_restarts`] must return the `:supervisor
14935 // :max-restarts` typed `u32` verbatim, `Copy`-projected from the
14936 // typed slot's own `u32` storage, byte-equal to the raw field
14937 // access across every representative value in the accept-set —
14938 // `1` (the lower boundary of the `1..=SUPERVISOR_MAX_RESTARTS_MAX`
14939 // accept-set the surrounding [`SupervisorSpec::validate`] gate
14940 // carves out on the sibling `ZeroMaxRestarts` refusal),
14941 // `SUPERVISOR_MAX_RESTARTS_MAX` (the upper boundary the same gate
14942 // carves out on the sibling `MaxRestartsExceedsCap` refusal), `0`
14943 // (a past-the-guard sentinel that pins the accessor doesn't
14944 // perform a silent bounds-collapse into `1` on the zero arm —
14945 // validate rejects zero but the accessor must ship the raw slot
14946 // verbatim so a validate-time gate regression surfaces at the
14947 // emit boundary rather than being silently absorbed), `u32::MAX`
14948 // (a past-the-guard sentinel that pins the accessor doesn't
14949 // perform a silent bounds-collapse through
14950 // `SUPERVISOR_MAX_RESTARTS_MAX` at the return path).
14951 //
14952 // Peer of the sibling M3
14953 // `circuit_breaker_max_failures_returns_max_failures_u32_byte_equal_across_permutations`
14954 // (3a74062) pin on the M3 mesh-slot `Copy`-`u32` sub-struct
14955 // required-scalar axis — same "the substrate-primitive accessor
14956 // must byte-equal the raw field access verbatim across every
14957 // value in the `u32` accept-set" discipline extended onto the M2
14958 // supervisor-slot per-`:supervisor` restart-budget-count axis.
14959 for max_restarts in [1u32, SUPERVISOR_MAX_RESTARTS_MAX, 0, u32::MAX] {
14960 let s = SupervisorSpec {
14961 max_restarts,
14962 ..SupervisorSpec::default()
14963 };
14964 assert_eq!(
14965 s.max_restarts(),
14966 max_restarts,
14967 "SupervisorSpec::max_restarts must return :supervisor \
14968 :max-restarts verbatim (got {}, expected {max_restarts})",
14969 s.max_restarts(),
14970 );
14971 assert_eq!(
14972 s.max_restarts(),
14973 s.max_restarts,
14974 "SupervisorSpec::max_restarts accessor and .max_restarts \
14975 field access must byte-equal — the accessor is the \
14976 substrate-primitive typed dispatch every downstream \
14977 restart-budget-count consumer must route through",
14978 );
14979 }
14980 }
14981
14982 #[test]
14983 fn validate_max_restarts_zero_floor_and_cap_arms_route_through_accessor() {
14984 // Composition pin: [`SupervisorSpec::validate`]'s `:max-restarts`
14985 // zero-floor + upper-cap bracket must key off
14986 // [`SupervisorSpec::max_restarts`], not the raw `.max_restarts`
14987 // field access. Structurally: a `SupervisorSpec { max_restarts:
14988 // 0, .. }` must surface the `ZeroMaxRestarts` refusal exactly, a
14989 // `SupervisorSpec { max_restarts: SUPERVISOR_MAX_RESTARTS_MAX + 1,
14990 // .. }` must surface the `MaxRestartsExceedsCap` refusal exactly
14991 // (with the offending count carried verbatim from the accessor
14992 // return), and a `SupervisorSpec { max_restarts: 1, .. }` (the
14993 // lower boundary of the accept-set) plus a `SupervisorSpec {
14994 // max_restarts: SUPERVISOR_MAX_RESTARTS_MAX, .. }` (the upper
14995 // boundary) must pass validate. The four together jointly pin the
14996 // accessor + validate-gate composition: any future silent detour
14997 // that had the accessor return a fresh `1` on the zero arm (a
14998 // `.max_restarts().max(1)` collapse) would silently absorb the
14999 // `ZeroMaxRestarts` refusal at the accessor boundary and the
15000 // validate gate would accept a struct-literal `SupervisorSpec {
15001 // max_restarts: 0, .. }` — the composition pin catches that at
15002 // caixa-core build time.
15003 //
15004 // Peer of the sibling M3
15005 // `validate_politicas_max_failures_zero_floor_arm_routes_through_accessor`
15006 // (3a74062) pin on the sibling per-`CircuitBreaker :max-failures`
15007 // composition axis — same "the validate / shape-gate predicate
15008 // must route through the substrate-primitive typed dispatch"
15009 // discipline extended onto the peer M2 supervisor-slot
15010 // required-`u32` composition axis.
15011 let child = ChildSpec {
15012 caixa: "worker".into(),
15013 versao: "^0.1".into(),
15014 restart: RestartPolicy::Permanent,
15015 };
15016 // Zero-floor arm.
15017 let s = SupervisorSpec {
15018 max_restarts: 0,
15019 children: vec![child.clone()],
15020 ..SupervisorSpec::default()
15021 };
15022 assert_eq!(
15023 s.validate().unwrap_err(),
15024 SupervisorError::ZeroMaxRestarts,
15025 "validate must reject max_restarts == 0 with ZeroMaxRestarts \
15026 — the accessor and the validate gate must route through the \
15027 same substrate-primitive typed dispatch on the zero-floor arm",
15028 );
15029 // Cap arm — the surfaced `max_restarts:` field must byte-equal
15030 // the accessor's return so a future rebrand on the accessor
15031 // lands in the diagnostic without a coordinated rewrite.
15032 let over_cap = SUPERVISOR_MAX_RESTARTS_MAX + 1;
15033 let s = SupervisorSpec {
15034 max_restarts: over_cap,
15035 children: vec![child.clone()],
15036 ..SupervisorSpec::default()
15037 };
15038 match s.validate().unwrap_err() {
15039 SupervisorError::MaxRestartsExceedsCap { max_restarts } => {
15040 assert_eq!(
15041 max_restarts,
15042 s.max_restarts(),
15043 "MaxRestartsExceedsCap.max_restarts must byte-equal \
15044 SupervisorSpec::max_restarts() — the cap-arm refusal \
15045 reads through the lifted accessor",
15046 );
15047 assert_eq!(
15048 max_restarts, over_cap,
15049 "MaxRestartsExceedsCap.max_restarts must carry the \
15050 author-declared :supervisor :max-restarts value \
15051 verbatim (got {max_restarts}, expected {over_cap})",
15052 );
15053 }
15054 other => panic!("expected MaxRestartsExceedsCap, got {other:?}"),
15055 }
15056 // Lower + upper accept-set boundaries.
15057 for max_restarts in [1u32, SUPERVISOR_MAX_RESTARTS_MAX] {
15058 let s = SupervisorSpec {
15059 max_restarts,
15060 children: vec![child.clone()],
15061 ..SupervisorSpec::default()
15062 };
15063 assert!(
15064 s.validate().is_ok(),
15065 "validate must accept max_restarts == {max_restarts} \
15066 (an accept-set boundary of \
15067 1..=SUPERVISOR_MAX_RESTARTS_MAX)",
15068 );
15069 }
15070 }
15071
15072 // ── per-`:supervisor` `:restart-window` typed-accessor coherence pins ─
15073 //
15074 // The [`SupervisorSpec::restart_window`] accessor lift extends the peer
15075 // M2 [`crate::LimitsSpec::wall_clock`] (8cb717b) `Option<Duration>`
15076 // accessor discipline and the peer M3 [`crate::MeshPolicy::timeout`]
15077 // (7073d0f) `Option<Duration>` accessor discipline onto the M2
15078 // supervisor-slot per-`:supervisor` restart-intensity-denominator
15079 // `Option<Duration>` scalar axis — third `Copy`-return accessor on the
15080 // M2 supervisor-slot `SupervisorSpec` type, closing the last unlifted
15081 // per-`:supervisor` scalar-value axis. The three pins below cover
15082 // (1) the accessor's byte-equal projection against the raw field
15083 // access across every representative value in the `Option<Duration>`
15084 // accept-set (`None` never-reset sentinel, `Some(Duration::from_millis(1))`
15085 // lower boundary, `Some(SUPERVISOR_RESTART_WINDOW_MAX)` upper boundary,
15086 // `Some(Duration::ZERO)` past-the-guard zero sentinel, `Some(Duration::MAX)`
15087 // past-the-guard above-cap sentinel), (2) the [`SupervisorSpec::validate`]
15088 // `if let Some(w) = self.restart_window() { … }` bracket-arm
15089 // composition — the validate gate and the accessor must route through
15090 // the same substrate-primitive typed dispatch, so any future silent
15091 // detour that had the accessor perform a bounds-collapsing clamp
15092 // would fail here at caixa-core build time, and (3) the accessor's
15093 // by-copy idempotence pin — the returned `Option<Duration>` must
15094 // outlive `&self` and two successive calls must return byte-equal
15095 // values. Peer of the sibling M2
15096 // `limits_wall_clock_returns_option_duration_byte_equal_across_permutations`
15097 // (8cb717b) pin on the per-`:limits :wall-clock` axis and the sibling
15098 // M3 `mesh_policy_timeout_returns_timeout_option_byte_equal_across_permutations`
15099 // (7073d0f) pin on the per-`:politicas :timeout` axis.
15100
15101 #[test]
15102 fn supervisor_spec_restart_window_returns_option_duration_byte_equal_across_permutations() {
15103 // The canonical per-`:supervisor` restart-intensity-denominator
15104 // scalar pin: [`SupervisorSpec::restart_window`] must return the
15105 // `:supervisor :restart-window` typed [`Duration`] verbatim as an
15106 // `Option<Duration>`, `Copy`-projected from the typed slot's own
15107 // `Option<Duration>` storage, byte-equal to the raw field access
15108 // across every representative value in the accept-set — `None`
15109 // (the "never reset — every restart across the supervisor's
15110 // lifetime counts against the sibling `:max-restarts` budget"
15111 // sentinel the field's own docstring names and the peer
15112 // `validate_accepts_none_restart_window` pin locks in on the
15113 // [`SupervisorSpec::validate`] entry-side),
15114 // `Some(Duration::from_millis(1))` (the structural minimum a
15115 // validated `:restart-window` may carry, the integer-millisecond
15116 // floor [`SupervisorError::RestartWindowNotCanonical`] rejects
15117 // everything sub-ms; `Duration::ZERO` is separately rejected by
15118 // [`SupervisorError::RestartWindowZero`]),
15119 // `Some(SUPERVISOR_RESTART_WINDOW_MAX)` (the upper boundary the
15120 // surrounding [`SupervisorSpec::validate`] gate carves out on the
15121 // sibling [`SupervisorError::RestartWindowExceedsCap`] refusal),
15122 // `Some(Duration::ZERO)` (a past-the-guard sentinel that pins the
15123 // accessor doesn't perform a silent bounds-collapse into `None` on
15124 // the zero-Duration arm — validate rejects zero but the accessor
15125 // must ship the raw slot verbatim so a validate-time gate
15126 // regression surfaces at the emit boundary rather than being
15127 // silently absorbed), and `Some(Duration::MAX)` (a past-the-guard
15128 // sentinel that pins the accessor doesn't perform a silent
15129 // bounds-collapse through [`SUPERVISOR_RESTART_WINDOW_MAX`] at the
15130 // return path).
15131 //
15132 // Peer of the sibling M2
15133 // `limits_wall_clock_returns_option_duration_byte_equal_across_permutations`
15134 // (8cb717b) pin on the per-`:limits :wall-clock` axis and the
15135 // sibling M3
15136 // `mesh_policy_timeout_returns_timeout_option_byte_equal_across_permutations`
15137 // (7073d0f) pin on the per-`:politicas :timeout` axis — same "the
15138 // substrate-primitive accessor must byte-equal the raw field
15139 // access verbatim across every value in the `Option<Duration>`
15140 // accept-set" discipline extended onto the M2 supervisor-slot
15141 // per-`:supervisor` `Option<Duration>` axis. Pins against a future
15142 // silent detour that re-derived the restart-window from a peer
15143 // axis (an accidental `.max_restarts.into()` collapse that read
15144 // the restart-budget-count as a duration — the two axes serve
15145 // different halves of the `MaxIntensity / Period` restart-
15146 // intensity ratio, and confusing them silently inverts the
15147 // ratio's numerator and denominator), a `None → Some(Duration::ZERO)`
15148 // "zero means never reset" collapse (the canonical
15149 // `Option<Duration>` → `Duration` collapse footgun the
15150 // [`SupervisorError::RestartWindowZero`] validate arm guards on
15151 // the peer zero-floor axis; a zero period either trips on the
15152 // first failure or never trips depending on operator
15153 // interpretation, neither of which is the author's "never reset"
15154 // intent that `None` expresses structurally), or a per-arm
15155 // variant swap that landed on one consumer without the other.
15156 for restart_window in [
15157 None,
15158 Some(Duration::from_millis(1)),
15159 Some(SUPERVISOR_RESTART_WINDOW_MAX),
15160 Some(Duration::ZERO),
15161 Some(Duration::MAX),
15162 ] {
15163 let s = SupervisorSpec {
15164 restart_window,
15165 ..SupervisorSpec::default()
15166 };
15167 assert_eq!(
15168 s.restart_window(),
15169 restart_window,
15170 "SupervisorSpec::restart_window must return :supervisor \
15171 :restart-window verbatim (got {:?}, expected {restart_window:?})",
15172 s.restart_window(),
15173 );
15174 assert_eq!(
15175 s.restart_window(),
15176 s.restart_window,
15177 "SupervisorSpec::restart_window accessor and \
15178 .restart_window field access must byte-equal — the \
15179 accessor is the substrate-primitive typed dispatch every \
15180 downstream restart-intensity-denominator consumer must \
15181 route through",
15182 );
15183 }
15184 }
15185
15186 #[test]
15187 fn validate_restart_window_bracket_arm_routes_through_accessor() {
15188 // Composition pin: [`SupervisorSpec::validate`]'s
15189 // `:restart-window` `if let Some(w) = self.restart_window() { … }`
15190 // zero-floor + integer-millisecond canonical-form + upper-cap
15191 // bracket-arm must key off [`SupervisorSpec::restart_window`], not
15192 // the raw `.restart_window` field access. Structurally: a
15193 // `SupervisorSpec { restart_window: None, .. }` must pass the
15194 // arm gate structurally (the `if let Some(_)` shape returns
15195 // early on the `None` arm — the accessor and the validate gate
15196 // must agree on `None → skip the bracket cascade` so an authored
15197 // `:restart-window ()` structurally routes through the "never
15198 // reset" sentinel path), a `SupervisorSpec { restart_window:
15199 // Some(Duration::ZERO), .. }` must surface the `RestartWindowZero`
15200 // refusal exactly, a `SupervisorSpec { restart_window:
15201 // Some(Duration::from_micros(1500)), .. }` must surface the
15202 // `RestartWindowNotCanonical` refusal exactly (with the offending
15203 // duration carried verbatim from the accessor return), a
15204 // `SupervisorSpec { restart_window: Some(SUPERVISOR_RESTART_WINDOW_MAX
15205 // + Duration::from_millis(1)), .. }` must surface the
15206 // `RestartWindowExceedsCap` refusal exactly (with the offending
15207 // duration carried verbatim from the accessor return), and a
15208 // `SupervisorSpec { restart_window: Some(Duration::from_millis(1)),
15209 // .. }` (the lower boundary of the accept-set) plus a
15210 // `SupervisorSpec { restart_window: Some(SUPERVISOR_RESTART_WINDOW_MAX),
15211 // .. }` (the upper boundary) must pass validate. The six together
15212 // jointly pin the accessor + validate-gate composition: any future
15213 // silent detour that had the accessor return a fresh `None` on any
15214 // `Some` arm (a `.restart_window().filter(|w| !w.is_zero())`
15215 // collapse) would silently absorb the `RestartWindowZero` refusal
15216 // at the accessor boundary and the validate gate would accept a
15217 // struct-literal `SupervisorSpec { restart_window:
15218 // Some(Duration::ZERO), .. }` — the composition pin catches that
15219 // at caixa-core build time.
15220 //
15221 // Peer of the sibling M2 [`crate::LimitsSpec::wall_clock`]
15222 // (8cb717b) validate-arm-route pin on the per-`:limits :wall-clock`
15223 // axis and the peer M3 [`crate::MeshPolicy::timeout`] (7073d0f)
15224 // accessor-composition pin on the per-`:politicas :timeout` axis —
15225 // same "the validate / shape-gate predicate must route through
15226 // the substrate-primitive typed dispatch" discipline extended
15227 // onto the peer M2 supervisor-slot optional-`Duration` axis.
15228 let child = ChildSpec {
15229 caixa: "worker".into(),
15230 versao: "^0.1".into(),
15231 restart: RestartPolicy::Permanent,
15232 };
15233 // None arm — must not surface any :restart-window-shaped refusal;
15234 // the `if let Some(_)` bracket returns early on `None` structurally.
15235 let s = SupervisorSpec {
15236 restart_window: None,
15237 children: vec![child.clone()],
15238 ..SupervisorSpec::default()
15239 };
15240 assert!(
15241 s.validate().is_ok(),
15242 "validate must accept restart_window: None (the never-reset \
15243 sentinel) — the `if let Some(_)` bracket returns early on \
15244 the None arm and the accessor must agree",
15245 );
15246 // Zero-floor arm.
15247 let s = SupervisorSpec {
15248 restart_window: Some(Duration::ZERO),
15249 children: vec![child.clone()],
15250 ..SupervisorSpec::default()
15251 };
15252 assert_eq!(
15253 s.validate().unwrap_err(),
15254 SupervisorError::RestartWindowZero,
15255 "validate must reject restart_window == Some(Duration::ZERO) \
15256 with RestartWindowZero — the accessor and the validate gate \
15257 must route through the same substrate-primitive typed \
15258 dispatch on the zero-floor arm",
15259 );
15260 // Non-canonical (sub-ms) arm — the surfaced `window:` field must
15261 // byte-equal the accessor's return so a future rebrand on the
15262 // accessor lands in the diagnostic without a coordinated rewrite.
15263 let sub_ms = Duration::from_micros(1500);
15264 let s = SupervisorSpec {
15265 restart_window: Some(sub_ms),
15266 children: vec![child.clone()],
15267 ..SupervisorSpec::default()
15268 };
15269 match s.validate().unwrap_err() {
15270 SupervisorError::RestartWindowNotCanonical { window } => {
15271 assert_eq!(
15272 Some(window),
15273 s.restart_window(),
15274 "RestartWindowNotCanonical.window must byte-equal \
15275 SupervisorSpec::restart_window().unwrap() — the \
15276 non-canonical-arm refusal reads through the lifted \
15277 accessor",
15278 );
15279 assert_eq!(
15280 window, sub_ms,
15281 "RestartWindowNotCanonical.window must carry the \
15282 author-declared :supervisor :restart-window value \
15283 verbatim (got {window:?}, expected {sub_ms:?})",
15284 );
15285 }
15286 other => panic!("expected RestartWindowNotCanonical, got {other:?}"),
15287 }
15288 // Cap arm — the surfaced `window:` field must byte-equal the
15289 // accessor's return.
15290 let over_cap = SUPERVISOR_RESTART_WINDOW_MAX + Duration::from_millis(1);
15291 let s = SupervisorSpec {
15292 restart_window: Some(over_cap),
15293 children: vec![child.clone()],
15294 ..SupervisorSpec::default()
15295 };
15296 match s.validate().unwrap_err() {
15297 SupervisorError::RestartWindowExceedsCap { window } => {
15298 assert_eq!(
15299 Some(window),
15300 s.restart_window(),
15301 "RestartWindowExceedsCap.window must byte-equal \
15302 SupervisorSpec::restart_window().unwrap() — the \
15303 cap-arm refusal reads through the lifted accessor",
15304 );
15305 assert_eq!(
15306 window, over_cap,
15307 "RestartWindowExceedsCap.window must carry the \
15308 author-declared :supervisor :restart-window value \
15309 verbatim (got {window:?}, expected {over_cap:?})",
15310 );
15311 }
15312 other => panic!("expected RestartWindowExceedsCap, got {other:?}"),
15313 }
15314 // Lower + upper accept-set boundaries.
15315 for restart_window in [Duration::from_millis(1), SUPERVISOR_RESTART_WINDOW_MAX] {
15316 let s = SupervisorSpec {
15317 restart_window: Some(restart_window),
15318 children: vec![child.clone()],
15319 ..SupervisorSpec::default()
15320 };
15321 assert!(
15322 s.validate().is_ok(),
15323 "validate must accept restart_window == Some({restart_window:?}) \
15324 (an accept-set boundary of \
15325 1ms..=SUPERVISOR_RESTART_WINDOW_MAX)",
15326 );
15327 }
15328 }
15329
15330 #[test]
15331 fn supervisor_spec_restart_window_projects_option_duration_by_copy() {
15332 // The by-copy pin: [`SupervisorSpec::restart_window`] returns
15333 // `Option<Duration>` by copy — `Duration` is `Copy` (so
15334 // `Option<Duration>` is `Copy`) and the accessor must return by
15335 // value, not by reference. Peer of the sibling M2
15336 // [`crate::LimitsSpec::wall_clock`] (8cb717b) by-copy pin on the
15337 // per-`:limits :wall-clock` axis and the sibling M3
15338 // [`crate::MeshPolicy::timeout`] (7073d0f) by-copy pin on the
15339 // per-`:politicas :timeout` axis, extended onto the peer M2
15340 // supervisor-slot `Option<Duration>` copy-invariant shape — the
15341 // accessor's returned `Option<Duration>` must outlive `&self`
15342 // (multiple calls must return equal values from a dropped-`&self`
15343 // copy, since the returned Option carries no borrow), and calling
15344 // the accessor twice on the same SupervisorSpec must yield the
15345 // same `Option<Duration>` verbatim (idempotent, no side effects
15346 // on `&self`).
15347 //
15348 // Pins against a future silent detour that returned
15349 // `Option<&Duration>` (which would type-check but silently break
15350 // every downstream caller — the future wasm-operator's
15351 // per-supervisor restart-intensity counter consumes `Duration` by
15352 // value and `&Duration` would fold to a detached copy at the call
15353 // site), an accidental `Option::as_ref()` projection
15354 // (`self.restart_window.as_ref()` would also type-check but
15355 // return `Option<&Duration>`), or a one-arm-only accessor that
15356 // reads `Some(*w)` in the Some arm but reads a fresh
15357 // `Default::default()` (which would collapse to `Duration::ZERO`,
15358 // not `None`) in the None arm — a footgun the
15359 // [`SupervisorError::RestartWindowZero`] validate arm explicitly
15360 // closes since Erlang/OTP's `MaxIntensity / Period` invariant
15361 // requires `Period > 0` and `None` structurally expresses "never
15362 // reset" instead.
15363 for restart_window in [
15364 None,
15365 Some(Duration::from_millis(1)),
15366 Some(Duration::from_secs(60)),
15367 Some(SUPERVISOR_RESTART_WINDOW_MAX),
15368 ] {
15369 let s = SupervisorSpec {
15370 restart_window,
15371 ..SupervisorSpec::default()
15372 };
15373 let first = s.restart_window();
15374 let second = s.restart_window();
15375 assert_eq!(
15376 first, second,
15377 "SupervisorSpec::restart_window must be idempotent — two \
15378 successive calls on the same &self must return the \
15379 same Option<Duration>",
15380 );
15381 assert_eq!(
15382 first, restart_window,
15383 "SupervisorSpec::restart_window must return :supervisor \
15384 :restart-window verbatim by copy — got {first:?}, \
15385 expected {restart_window:?}",
15386 );
15387 }
15388 }
15389
15390 // ── per-`:supervisor` `:children` typed-accessor coherence pins ─────────
15391 //
15392 // The [`SupervisorSpec::children`] accessor lift is the seed of the
15393 // slice-return (`&[T]`) accessor discipline on the substrate — the four
15394 // peer `Vec`-carry axes ([`crate::Placement::clusters`],
15395 // [`crate::AplicacaoSpec::membros`], [`crate::AplicacaoSpec::contratos`],
15396 // [`crate::UpgradeFromEntry::instructions`]) still key off the raw field
15397 // access at the time of this seed, and inherit this pin family's
15398 // discipline as future compounding runs migrate their consumers. The
15399 // three pins below cover (1) the accessor's byte-equal projection
15400 // against the raw field access across the empty / singleton / cohort
15401 // fixtures the [`SupervisorSpec::validate`] partition-dispatch fans
15402 // between, (2) the [`SupervisorSpec::validate`] `SimpleOneForOne ↔
15403 // non-SimpleOneForOne` partition dispatch's paired `.is_empty()`
15404 // consumer routing through the accessor on both arms, and (3) the
15405 // per-child validate loop's traversal reading the same slice-view the
15406 // accessor projects. Peer of the sibling M2
15407 // [`validate_reads_through_lifted_estrategia_accessor`] (eafb619)
15408 // two-consumer coherence pin on the per-`:supervisor`
15409 // sibling-restart-strategy `Copy`-composite-enum scalar axis, extended
15410 // onto the per-`:supervisor` static-child-list `Vec`-carry axis.
15411
15412 #[test]
15413 fn supervisor_spec_children_returns_children_slice_byte_equal_across_permutations() {
15414 // The canonical per-`:supervisor` static-child-list scalar-shape
15415 // pin: [`SupervisorSpec::children`] must return the `:supervisor
15416 // :children` typed `Vec<ChildSpec>` verbatim as a `&[ChildSpec]`
15417 // slice-view over the same backing buffer the raw
15418 // `self.children.as_slice()` field access borrows from, byte-
15419 // equal across every representative fixture in the accept-set —
15420 // the empty slice (the `SimpleOneForOne`-arm sentinel),
15421 // the singleton slice (the minimal non-`SimpleOneForOne` shape),
15422 // and a two-child cohort (a peer non-`SimpleOneForOne` shape
15423 // with the peer three restart-policy variants in play).
15424 //
15425 // Pins against a future silent detour that returned
15426 // `&Vec<ChildSpec>` (which would type-check but leak the
15427 // storage-side `Vec`'s grow/push/reserve surface no consumer of
15428 // the typed view reaches for), a fresh-allocated
15429 // `Vec<ChildSpec>` copy (which would type-check via a coercion
15430 // but silently break every downstream caller that relied on the
15431 // slice sharing the backing buffer's identity), or an
15432 // out-of-order or length-drifted projection (which would silently
15433 // split the per-child validate loop's traversal input from the
15434 // paired partition-dispatch `.is_empty()` probe's input).
15435 //
15436 // Peer of the sibling
15437 // `supervisor_spec_estrategia_returns_estrategia_verbatim_across_permutations`
15438 // (eafb619) `Copy`-composite-enum byte-equal pin on the
15439 // per-`:supervisor` sibling-restart-strategy axis, extended onto
15440 // the per-`:supervisor` static-child-list `Vec`-carry axis.
15441 let fixtures: Vec<Vec<ChildSpec>> = vec![
15442 Vec::new(),
15443 vec![child("worker", "^0.1", RestartPolicy::Permanent)],
15444 vec![
15445 child("worker", "^0.1", RestartPolicy::Permanent),
15446 child("cache-server", "^0.1", RestartPolicy::Transient),
15447 ],
15448 vec![
15449 child("worker", "^0.1", RestartPolicy::Permanent),
15450 child("cache-server", "^0.1", RestartPolicy::Transient),
15451 child("scratch-job", "^0.1", RestartPolicy::Temporary),
15452 ],
15453 ];
15454 for children in fixtures {
15455 let s = SupervisorSpec {
15456 children: children.clone(),
15457 ..SupervisorSpec::default()
15458 };
15459 assert_eq!(
15460 s.children(),
15461 children.as_slice(),
15462 "SupervisorSpec::children must return :supervisor \
15463 :children verbatim (got {:?}, expected {:?})",
15464 s.children(),
15465 children.as_slice(),
15466 );
15467 assert_eq!(
15468 s.children(),
15469 s.children.as_slice(),
15470 "SupervisorSpec::children accessor and \
15471 .children.as_slice() field access must byte-equal — \
15472 the accessor is the substrate-primitive typed \
15473 dispatch every downstream static-child-list consumer \
15474 must route through",
15475 );
15476 assert_eq!(
15477 s.children().len(),
15478 s.children.len(),
15479 "SupervisorSpec::children().len() must byte-equal \
15480 self.children.len() — a length-drift would silently \
15481 split the paired partition-dispatch `.is_empty()` \
15482 probe input from the per-child validate loop's \
15483 traversal input",
15484 );
15485 }
15486 }
15487
15488 #[test]
15489 fn validate_reads_through_lifted_children_accessor() {
15490 // Three-consumer coherence pin: the [`SupervisorSpec::validate`]
15491 // `SimpleOneForOne`-arm `!self.children().is_empty()` refusal
15492 // probe (which must trip [`SupervisorError::SimpleOneForOneWithStaticChildren`]
15493 // when the accessor projects a non-empty slice under a
15494 // `SimpleOneForOne` estrategia), the peer non-`SimpleOneForOne`-arm
15495 // `self.children().is_empty()` refusal probe (which must trip
15496 // [`SupervisorError::NoChildren`] when the accessor projects the
15497 // empty slice under any peer estrategia), and the per-child
15498 // validate loop's `for child in self.children()` traversal
15499 // (which must reach every entry in the same order the accessor
15500 // projects) must all key off the lifted accessor, so any future
15501 // rebrand on the typed slot's reader shape lands at exactly one
15502 // place. Pins the three-site coherence by exercising each
15503 // production consumer end-to-end: (1) the
15504 // `SimpleOneForOneWithStaticChildren` refusal under a non-empty
15505 // slice + `SimpleOneForOne` estrategia, (2) the `NoChildren`
15506 // refusal under the empty slice + non-`SimpleOneForOne`
15507 // estrategia across every peer variant, and (3) the per-child
15508 // duplicate-detection surface fires on the second entry of a
15509 // two-child cohort that shares a `:caixa` name (which requires
15510 // the loop to reach both entries — a first-entry-only projection
15511 // would silently pass since the dedup HashSet has room for the
15512 // first insert).
15513 //
15514 // Peer of the sibling M2
15515 // [`validate_reads_through_lifted_estrategia_accessor`] (eafb619)
15516 // two-consumer coherence pin on the per-`:supervisor`
15517 // sibling-restart-strategy axis, extended onto the
15518 // per-`:supervisor` static-child-list `Vec`-carry axis.
15519
15520 // (1) `SimpleOneForOne`-arm probe: a non-empty slice under a
15521 // `SimpleOneForOne` estrategia must trip
15522 // `SimpleOneForOneWithStaticChildren`.
15523 let s = SupervisorSpec {
15524 estrategia: RestartStrategy::SimpleOneForOne,
15525 children: vec![child("worker", "^0.1", RestartPolicy::Permanent)],
15526 ..SupervisorSpec::default()
15527 };
15528 assert_eq!(
15529 s.validate().unwrap_err(),
15530 SupervisorError::SimpleOneForOneWithStaticChildren,
15531 "SimpleOneForOne + non-empty children must trip \
15532 SimpleOneForOneWithStaticChildren — the accessor projects \
15533 a non-empty slice, and the SimpleOneForOne-arm refusal \
15534 probe reads through the lifted accessor",
15535 );
15536 assert!(
15537 !s.children().is_empty(),
15538 "the SimpleOneForOne-arm refusal input must be a non-empty \
15539 slice per the accessor's projection",
15540 );
15541
15542 // (2) Peer non-`SimpleOneForOne`-arm probe: the empty slice
15543 // under any peer estrategia must trip `NoChildren`.
15544 for estrategia in [
15545 RestartStrategy::OneForOne,
15546 RestartStrategy::OneForAll,
15547 RestartStrategy::RestForOne,
15548 ] {
15549 let s = SupervisorSpec {
15550 estrategia,
15551 children: Vec::new(),
15552 ..SupervisorSpec::default()
15553 };
15554 match s.validate().unwrap_err() {
15555 SupervisorError::NoChildren { estrategia: e } => {
15556 assert_eq!(
15557 e, estrategia,
15558 "NoChildren.estrategia must carry the author-\
15559 declared :supervisor :estrategia variant \
15560 verbatim (got {e:?}, expected {estrategia:?})",
15561 );
15562 }
15563 other => panic!(
15564 "expected NoChildren, got {other:?} for \
15565 estrategia={estrategia:?}"
15566 ),
15567 }
15568 assert!(
15569 s.children().is_empty(),
15570 "the non-SimpleOneForOne-arm refusal input must be the \
15571 empty slice per the accessor's projection",
15572 );
15573 }
15574
15575 // (3) Per-child validate loop: a two-child cohort that shares a
15576 // `:caixa` name must trip `DuplicateChildCaixa` — the loop must
15577 // reach both entries through the accessor.
15578 let s = SupervisorSpec {
15579 estrategia: RestartStrategy::OneForOne,
15580 children: vec![
15581 child("worker", "^0.1", RestartPolicy::Permanent),
15582 child("worker", "^0.2", RestartPolicy::Transient),
15583 ],
15584 ..SupervisorSpec::default()
15585 };
15586 match s.validate().unwrap_err() {
15587 SupervisorError::DuplicateChildCaixa { caixa } => {
15588 assert_eq!(
15589 caixa, "worker",
15590 "DuplicateChildCaixa.caixa must carry the shared \
15591 child `:caixa` name verbatim",
15592 );
15593 }
15594 other => panic!("expected DuplicateChildCaixa, got {other:?}"),
15595 }
15596 assert_eq!(
15597 s.children().len(),
15598 2,
15599 "the per-child validate loop's traversal input must be a \
15600 two-element slice per the accessor's projection",
15601 );
15602 }
15603
15604 // Shared helper for the M2 per-`:children` per-slot-gate ≡
15605 // `validate` equivalence pins: builds an `OneForOne`-estrategia
15606 // one-cohort spec whose peer `:estrategia`↔`:children.is_empty()`
15607 // partition, `:max-restarts` zero-floor/cap, and `:restart-window`
15608 // bracket all pass cleanly so the sole failing surface is the
15609 // per-child cascade [`SupervisorSpec::validate_children`] owns, and
15610 // pins the two-altitude equivalence on the paired probe.
15611 fn assert_validate_children_matches_gate(children: Vec<ChildSpec>, expected: &SupervisorError) {
15612 let s = SupervisorSpec {
15613 estrategia: RestartStrategy::OneForOne,
15614 children,
15615 ..SupervisorSpec::default()
15616 };
15617 let via_gate = s.validate_children().unwrap_err();
15618 let via_validate = s.validate().unwrap_err();
15619 assert_eq!(&via_gate, expected, "validate_children direct dispatch",);
15620 assert_eq!(&via_validate, expected, "validate() end-to-end dispatch",);
15621 assert_eq!(
15622 via_gate, via_validate,
15623 "per-slot gate ≡ validate() must discriminate the same \
15624 refusal shape",
15625 );
15626 }
15627
15628 #[test]
15629 fn validate_children_matches_gate_on_per_axis_refusal_shapes() {
15630 // Fail-before-pass-after equivalence pin on the M2
15631 // per-`:children` per-slot gate ≡ [`SupervisorSpec::validate`]
15632 // convergence — sibling of the M3 mesh-slot
15633 // `validate_membros_*` / `validate_contratos_*` /
15634 // `validate_entrada_*` per-slot-gate ≡ `validate` pins on the
15635 // peer per-entry axes. Sweeps four of the five refusal shapes
15636 // the per-slot gate owns: (1) `EmptyChildName` on an empty-
15637 // `:caixa` child, (2) `ChildCaixaInvalid` on a structurally
15638 // invalid `:caixa` DNS-1123 label, (3) `EmptyChildVersion` on
15639 // an empty-`:versao` child, (4) `DuplicateChildCaixa` on a
15640 // duplicate-`:caixa` fan-out. Companion pin
15641 // `validate_children_matches_gate_on_versao_invalid_and_clean_pass`
15642 // covers `ChildVersaoInvalid` (whose parser-owned reason string
15643 // needs pattern-matching, not equality) and the clean-pass
15644 // canonical fixture; together the two pins guarantee the
15645 // per-slot gate and `validate` discriminate the same set on
15646 // every per-child-covered input.
15647 assert_validate_children_matches_gate(
15648 vec![child("", "^0.1", RestartPolicy::Permanent)],
15649 &SupervisorError::EmptyChildName,
15650 );
15651 assert_validate_children_matches_gate(
15652 vec![child("Worker", "^0.1", RestartPolicy::Permanent)],
15653 &SupervisorError::ChildCaixaInvalid {
15654 caixa: "Worker".into(),
15655 reason: "contains uppercase character 'W' (K8s DNS-1123 label names are lowercase-only; use \"worker\")".into(),
15656 },
15657 );
15658 assert_validate_children_matches_gate(
15659 vec![child("worker", "", RestartPolicy::Permanent)],
15660 &SupervisorError::EmptyChildVersion {
15661 caixa: "worker".into(),
15662 },
15663 );
15664 assert_validate_children_matches_gate(
15665 vec![
15666 child("worker", "^0.1", RestartPolicy::Permanent),
15667 child("worker", "^0.2", RestartPolicy::Transient),
15668 ],
15669 &SupervisorError::DuplicateChildCaixa {
15670 caixa: "worker".into(),
15671 },
15672 );
15673 }
15674
15675 #[test]
15676 fn validate_children_matches_gate_on_versao_invalid_and_clean_pass() {
15677 // Second half of the two-altitude equivalence pin — covers the
15678 // one refusal shape whose reason string is parser-owned
15679 // (`ChildVersaoInvalid`, whose reason comes from the shared
15680 // [`crate::version::parse_requirement`] impl and may drift) and
15681 // the clean-pass canonical fixture. Sibling pin
15682 // `validate_children_matches_gate_on_per_axis_refusal_shapes`
15683 // covers the four equality-comparable refusal shapes.
15684 let s_bad_versao = SupervisorSpec {
15685 estrategia: RestartStrategy::OneForOne,
15686 children: vec![child("worker", "not-a-req", RestartPolicy::Permanent)],
15687 ..SupervisorSpec::default()
15688 };
15689 let via_gate = s_bad_versao.validate_children().unwrap_err();
15690 let via_validate = s_bad_versao.validate().unwrap_err();
15691 match (&via_gate, &via_validate) {
15692 (
15693 SupervisorError::ChildVersaoInvalid {
15694 caixa: cg,
15695 versao: vg,
15696 ..
15697 },
15698 SupervisorError::ChildVersaoInvalid {
15699 caixa: cv,
15700 versao: vv,
15701 ..
15702 },
15703 ) => {
15704 assert_eq!(cg, "worker", "per-slot gate :caixa carrier");
15705 assert_eq!(vg, "not-a-req", "per-slot gate :versao carrier");
15706 assert_eq!(cv, "worker", "validate() :caixa carrier");
15707 assert_eq!(vv, "not-a-req", "validate() :versao carrier");
15708 }
15709 other => panic!("expected ChildVersaoInvalid on both altitudes, got {other:?}"),
15710 }
15711 assert_eq!(
15712 via_gate, via_validate,
15713 "per-slot gate ≡ validate() on ChildVersaoInvalid full envelope",
15714 );
15715
15716 let s_ok = SupervisorSpec {
15717 estrategia: RestartStrategy::OneForOne,
15718 children: vec![
15719 child("worker-a", "^0.1", RestartPolicy::Permanent),
15720 child("worker-b", "~0.2.3", RestartPolicy::Transient),
15721 child("collector", "*", RestartPolicy::Temporary),
15722 ],
15723 ..SupervisorSpec::default()
15724 };
15725 s_ok.validate_children()
15726 .expect("per-slot gate must accept the clean-pass fixture");
15727 s_ok.validate()
15728 .expect("validate() must accept the clean-pass fixture");
15729 }
15730
15731 #[test]
15732 fn validate_children_is_self_contained_on_children_slot() {
15733 // Self-containment pin: [`SupervisorSpec::validate_children`]
15734 // resolves the per-child cascade against `&self` alone, without
15735 // depending on the peer `:estrategia`/`:max-restarts`/
15736 // `:restart-window` gates having run first — same posture the M3
15737 // peer per-slot gates carry (`validate_membros`,
15738 // `validate_contratos`, `validate_entrada`, `validate_placement`,
15739 // routing through their own oracles rather than borrowing state
15740 // threaded down from `validate`). A future consumer that reaches
15741 // the per-slot gate directly on a spec whose peer slots would
15742 // fail `validate` still surfaces the per-child refusal, not the
15743 // peer refusal.
15744 //
15745 // Construct a spec whose `:max-restarts` is `0` (which would
15746 // trip [`SupervisorError::ZeroMaxRestarts`] at `validate` after
15747 // the partition-dispatch) and whose `:children` carries a
15748 // `DuplicateChildCaixa` shape: the per-slot gate called directly
15749 // must surface `DuplicateChildCaixa`, proving it does not depend
15750 // on the peer `:max-restarts` gate running first.
15751 let s = SupervisorSpec {
15752 estrategia: RestartStrategy::OneForOne,
15753 max_restarts: 0,
15754 restart_window: Some(Duration::from_secs(60)),
15755 children: vec![
15756 child("worker", "^0.1", RestartPolicy::Permanent),
15757 child("worker", "^0.2", RestartPolicy::Transient),
15758 ],
15759 };
15760 assert_eq!(
15761 s.validate_children().unwrap_err(),
15762 SupervisorError::DuplicateChildCaixa {
15763 caixa: "worker".into(),
15764 },
15765 "per-slot gate must resolve per-child refusal directly against \
15766 `&self` — a dependency on the peer `:max-restarts` gate \
15767 running first would surface ZeroMaxRestarts here instead",
15768 );
15769 // The peer gate is still the surface `validate` reaches — pin
15770 // the ordering to establish that `validate_children` truly runs
15771 // last in `validate`'s dispatch, so a direct call bypasses the
15772 // peer gates on any spec whose per-child cascade would fail.
15773 assert_eq!(
15774 s.validate().unwrap_err(),
15775 SupervisorError::ZeroMaxRestarts,
15776 "validate() must surface the peer `:max-restarts` gate before \
15777 reaching the per-child cascade — this pins the dispatch \
15778 ordering the per-slot gate's self-containment complements",
15779 );
15780 }
15781
15782 #[test]
15783 fn child_spec_restart_accessor_is_const_fn() {
15784 // The [`ChildSpec::restart`] per-`:children` restart-decision-
15785 // policy `Copy`-return scalar accessor is declared
15786 // `#[must_use] pub const fn` — matching the sibling M2
15787 // per-`:supervisor` [`SupervisorSpec::estrategia`] (pinned by
15788 // [`supervisor_spec_estrategia_accessor_is_const_fn`] below,
15789 // both converted in this commit), the sibling M2
15790 // per-`:supervisor` [`SupervisorSpec::max_restarts`] (b698ec0)
15791 // `Copy`-`u32` accessor already `pub const fn`, and the peer M3
15792 // mesh-slot per-`:entrada` [`crate::Entrada::port`] (bafa004) /
15793 // per-`:placement` [`crate::Placement::estrategia`] (bafa004)
15794 // `Copy`-return `pub const fn` scalar accessors on the sibling
15795 // M3 surface. Pin the `const`-eval posture here so a future
15796 // accidental downgrade to non-`const` (an added runtime helper
15797 // reachable only from a non-`const` context, an
15798 // `Option<RestartPolicy>`-shape migration on the per-child
15799 // restart-decision axis once heterogeneous per-cluster
15800 // restart-policy overlays land that would silently drop the
15801 // `const` qualifier, a manual hand-rolled shadow) trips at
15802 // caixa-core build time rather than surfacing as a downstream
15803 // `const`-context regression far from the declaration.
15804 //
15805 // Same shape as the sibling M3
15806 // [`crate::aplicacao::tests::placement_estrategia_accessor_is_const_fn`]
15807 // and [`crate::aplicacao::tests::entrada_port_accessor_is_const_fn`]
15808 // (bafa004) pins on the peer M3 mesh-slot `Copy`-return scalar
15809 // accessor axis — the load-bearing witness lives in the
15810 // module-scope `const fn` wrapper `restart_via_const_fn` below:
15811 // a body that calls [`ChildSpec::restart`] under a `const fn`
15812 // signature is well-formed only when the callee is itself
15813 // `const fn`, so any future accidental downgrade of
15814 // [`ChildSpec::restart`] to non-`const` fails at caixa-core
15815 // build time (const-eval E0015 `cannot call non-const method`),
15816 // strictly stronger than a runtime `assert!(CONST)` and
15817 // side-stepping the destructor-in-const restriction that
15818 // blocks direct `const _: RestartPolicy = FIXTURE.restart()`
15819 // items on `ChildSpec`'s `String` carriers.
15820 //
15821 // The runtime body sweeps every closed-set [`RestartPolicy`]
15822 // arm and asserts the wrapped and direct dispatches agree.
15823 const fn restart_via_const_fn(c: &ChildSpec) -> RestartPolicy {
15824 c.restart()
15825 }
15826 for restart in [
15827 RestartPolicy::Permanent,
15828 RestartPolicy::Transient,
15829 RestartPolicy::Temporary,
15830 ] {
15831 let c = ChildSpec {
15832 caixa: "worker".into(),
15833 versao: "^0.1".into(),
15834 restart,
15835 };
15836 assert_eq!(
15837 restart_via_const_fn(&c),
15838 c.restart(),
15839 "const-fn-wrapped and direct dispatch on \
15840 ChildSpec::restart must agree for {restart:?}",
15841 );
15842 assert_eq!(
15843 c.restart(),
15844 restart,
15845 "ChildSpec::restart must return the storage-side \
15846 RestartPolicy verbatim for {restart:?} (a violation \
15847 means the accessor stopped being a raw field-return \
15848 copy)",
15849 );
15850 }
15851 }
15852
15853 #[test]
15854 fn supervisor_spec_estrategia_accessor_is_const_fn() {
15855 // The [`SupervisorSpec::estrategia`] per-`:supervisor`
15856 // sibling-restart-strategy `Copy`-return scalar accessor is
15857 // declared `#[must_use] pub const fn` — matching the sibling M2
15858 // per-`:children` [`ChildSpec::restart`] (pinned by
15859 // [`child_spec_restart_accessor_is_const_fn`] above, both
15860 // converted in this commit), the sibling M2 per-`:supervisor`
15861 // [`SupervisorSpec::max_restarts`] (b698ec0) `Copy`-`u32`
15862 // accessor already `pub const fn`, and mirroring the peer M3
15863 // mesh-slot per-`:placement`
15864 // [`crate::Placement::estrategia`] (bafa004) `Copy`-return
15865 // `pub const fn` scalar accessor whose method-name discipline
15866 // the [`SupervisorSpec::estrategia`] method was authored to
15867 // match. Pin the `const`-eval posture here so a future
15868 // accidental downgrade to non-`const` (an added runtime helper
15869 // reachable only from a non-`const` context, an
15870 // `Option<RestartStrategy>`-shape migration once the substrate
15871 // grows per-cluster strategy overlays that would silently drop
15872 // the `const` qualifier, a manual hand-rolled shadow) trips at
15873 // caixa-core build time rather than surfacing as a downstream
15874 // `const`-context regression far from the declaration.
15875 //
15876 // Same shape as the sibling
15877 // [`child_spec_restart_accessor_is_const_fn`] pin above — the
15878 // load-bearing witness lives in the module-scope `const fn`
15879 // wrapper `estrategia_via_const_fn` below: a body that calls
15880 // [`SupervisorSpec::estrategia`] under a `const fn` signature
15881 // is well-formed only when the callee is itself `const fn`,
15882 // side-stepping the destructor-in-const restriction that would
15883 // otherwise block a direct
15884 // `const _: RestartStrategy = FIXTURE.estrategia()` item on
15885 // `SupervisorSpec`'s `Vec<ChildSpec>` / `Option<Duration>`
15886 // carriers.
15887 //
15888 // The runtime body sweeps every closed-set [`RestartStrategy`]
15889 // arm via [`RestartStrategy::ALL`] and asserts the wrapped and
15890 // direct dispatches agree.
15891 const fn estrategia_via_const_fn(s: &SupervisorSpec) -> RestartStrategy {
15892 s.estrategia()
15893 }
15894 for &estrategia in RestartStrategy::ALL {
15895 let s = SupervisorSpec {
15896 estrategia,
15897 max_restarts: 5,
15898 restart_window: Some(Duration::from_secs(60)),
15899 children: Vec::new(),
15900 };
15901 assert_eq!(
15902 estrategia_via_const_fn(&s),
15903 s.estrategia(),
15904 "const-fn-wrapped and direct dispatch on \
15905 SupervisorSpec::estrategia must agree for {estrategia:?}",
15906 );
15907 assert_eq!(
15908 s.estrategia(),
15909 estrategia,
15910 "SupervisorSpec::estrategia must return the storage-side \
15911 RestartStrategy verbatim for {estrategia:?} (a violation \
15912 means the accessor stopped being a raw field-return \
15913 copy)",
15914 );
15915 }
15916 }
15917
15918 // Per-variant equivalence pins for the [`supervisor_caixa_only_ctors!`]
15919 // macro definition (see the paired doc-block above the macro
15920 // definition) — every generated `<ctor>(caixa: &str) -> Self`
15921 // constructor folds the uniform `Self::<Variant> { caixa:
15922 // caixa.to_string() }` one-field struct-literal onto one substrate
15923 // primitive. The three per-variant equivalence pins below
15924 // (fail-before-pass-after by construction — a byte-mismatched macro
15925 // arm would trip its equivalence pin first) lock each generated
15926 // constructor to its struct-literal peer under `PartialEq`, so
15927 // every wire-up in [`SupervisorSpec::validate_children`] and
15928 // [`validate_no_self_supervision`] on that variant produces a
15929 // byte-equal `SupervisorError` to the pre-lift open-coded
15930 // struct-literal. The cross-axis pin that follows (non-default
15931 // caixa name) routes the sole constructor input axis through
15932 // `.to_string()`, so the fold does not silently collapse onto a
15933 // fixed name.
15934 //
15935 // Peer of the sibling `<slot>_ctor_matches_tuple_literal_wrap` /
15936 // `<slot>_violation_ctor_matches_struct_literal_wrap` /
15937 // `<slot>_slots_on_non_<owner>_ctor_matches_struct_literal_wrap` /
15938 // `missing_entry_ctor_matches_struct_literal_wrap` /
15939 // `entrada_host_invalid_ctor_matches_struct_literal_wrap` /
15940 // `contrato_wrong_target_ctor_matches_struct_literal_wrap` /
15941 // `contrato_missing_target_ctor_matches_struct_literal_wrap` /
15942 // `<variant>_ctor_matches_struct_literal_wrap` equivalence pins
15943 // on the six sibling ctor families the recent trajectory closed
15944 // on the peer `LayoutError` / `AplicacaoError` envelopes.
15945
15946 #[test]
15947 fn empty_child_version_ctor_matches_struct_literal_wrap() {
15948 assert_eq!(
15949 SupervisorError::empty_child_version("worker"),
15950 SupervisorError::EmptyChildVersion {
15951 caixa: "worker".to_string(),
15952 },
15953 "generated empty_child_version ctor must produce byte-equal \
15954 SupervisorError to the open-coded struct-literal wrap on the \
15955 same &str fixture",
15956 );
15957 }
15958
15959 #[test]
15960 fn duplicate_child_caixa_ctor_matches_struct_literal_wrap() {
15961 assert_eq!(
15962 SupervisorError::duplicate_child_caixa("worker"),
15963 SupervisorError::DuplicateChildCaixa {
15964 caixa: "worker".to_string(),
15965 },
15966 "generated duplicate_child_caixa ctor must produce byte-equal \
15967 SupervisorError to the open-coded struct-literal wrap on the \
15968 same &str fixture",
15969 );
15970 }
15971
15972 #[test]
15973 fn child_supervises_self_ctor_matches_struct_literal_wrap() {
15974 assert_eq!(
15975 SupervisorError::child_supervises_self("orquestra"),
15976 SupervisorError::ChildSupervisesSelf {
15977 caixa: "orquestra".to_string(),
15978 },
15979 "generated child_supervises_self ctor must produce byte-equal \
15980 SupervisorError to the open-coded struct-literal wrap on the \
15981 same &str fixture",
15982 );
15983 }
15984
15985 // Per-variant equivalence pins for the two lifted
15986 // [`SupervisorError::child_caixa_invalid`] /
15987 // [`SupervisorError::child_versao_invalid`] inherent constructors
15988 // (fail-before-pass-after by construction — a byte-mismatched ctor body
15989 // would trip its equivalence pin first). Each pins the ctor output to
15990 // its pre-lift struct-literal peer under `PartialEq`, so every wire-up
15991 // in [`SupervisorSpec::validate_children`] on the two variants
15992 // produces a byte-equal `SupervisorError` to the pre-lift open-coded
15993 // struct-literal on the same scalar fixtures. Peers of the sibling
15994 // `membro_caixa_invalid_ctor_matches_struct_literal_wrap` /
15995 // `entrada_para_invalid_ctor_matches_struct_literal_wrap` / … pins on
15996 // the peer `AplicacaoError` envelope's
15997 // [`crate::aplicacao::aplicacao_field_reason_ctors!`] fold.
15998
15999 #[test]
16000 fn child_caixa_invalid_ctor_matches_struct_literal_wrap() {
16001 let caixa = "Worker";
16002 let reason = "sample reason text";
16003 assert_eq!(
16004 SupervisorError::child_caixa_invalid(caixa, reason),
16005 SupervisorError::ChildCaixaInvalid {
16006 caixa: caixa.to_string(),
16007 reason: reason.to_string(),
16008 },
16009 "lifted child_caixa_invalid ctor must produce byte-equal \
16010 SupervisorError to the open-coded struct-literal wrap on the \
16011 same (&str, reason) fixture",
16012 );
16013 }
16014
16015 #[test]
16016 fn child_versao_invalid_ctor_matches_struct_literal_wrap() {
16017 let caixa = "worker";
16018 let versao = "not-a-req";
16019 let reason = "sample reason text";
16020 assert_eq!(
16021 SupervisorError::child_versao_invalid(caixa, versao, reason),
16022 SupervisorError::ChildVersaoInvalid {
16023 caixa: caixa.to_string(),
16024 versao: versao.to_string(),
16025 reason: reason.to_string(),
16026 },
16027 "lifted child_versao_invalid ctor must produce byte-equal \
16028 SupervisorError to the open-coded struct-literal wrap on the \
16029 same (&str, &str, reason) fixture",
16030 );
16031 }
16032
16033 #[test]
16034 fn supervisor_child_reason_ctors_route_reason_through_into_uniformly() {
16035 // Cross-axis pin: sweep the two lifted `{ …, reason }` ctors
16036 // against a `&str`-literal vs. `format!(…)` reason input to pin
16037 // both constructors accept the `impl Into<String>` bound
16038 // uniformly, so neither wire-up site drifts under a per-arm
16039 // wrapper transformation on the caller-side `reason` axis. Peer
16040 // of the sibling
16041 // `aplicacao_field_reason_ctors_route_reason_through_into_uniformly`
16042 // sweep on the peer `AplicacaoError` envelope.
16043 let via_literal = "literal reason text";
16044 let via_format = format!("{} reason text", "literal");
16045 assert_eq!(
16046 SupervisorError::child_caixa_invalid("Worker", via_literal),
16047 SupervisorError::child_caixa_invalid("Worker", via_format.clone()),
16048 );
16049 assert_eq!(
16050 SupervisorError::child_versao_invalid("worker", "not-a-req", via_literal),
16051 SupervisorError::child_versao_invalid("worker", "not-a-req", via_format),
16052 );
16053 }
16054
16055 #[test]
16056 fn supervisor_caixa_only_ctors_route_caixa_through_to_string() {
16057 // Cross-axis pin: sweep the sole constructor input axis (`caixa:
16058 // &str`) through a non-default fixture name against every
16059 // generated arm in the [`supervisor_caixa_only_ctors!`] macro,
16060 // so any wrapper-side lowercase / trim / truncate / re-order on
16061 // the `caixa.to_string()` sole-field construction surfaces
16062 // here rather than at a downstream diagnostic-shape mismatch.
16063 // Peer of the sibling `nome_only_ctor_routes_caixa_through_
16064 // nome_accessor` / `entrada_host_invalid_ctor_routes_host_
16065 // through_to_string` / `contrato_target_ctors_route_edge_
16066 // triple_through_verbatim` / `contrato_empty_pair_ctors_
16067 // route_edge_pair_through_verbatim` cross-axis routing pins on
16068 // the peer `LayoutError` / `AplicacaoError` envelopes; extended
16069 // here onto the `SupervisorError` `{ caixa: String }` envelope
16070 // so every substrate-primitive ctor family in caixa-core
16071 // guarantees the sole-field construction routes the caller's
16072 // `&str` through `.to_string()` verbatim.
16073 let name = "cache-v2";
16074 assert_eq!(
16075 SupervisorError::empty_child_version(name),
16076 SupervisorError::EmptyChildVersion {
16077 caixa: name.to_string(),
16078 },
16079 );
16080 assert_eq!(
16081 SupervisorError::duplicate_child_caixa(name),
16082 SupervisorError::DuplicateChildCaixa {
16083 caixa: name.to_string(),
16084 },
16085 );
16086 assert_eq!(
16087 SupervisorError::child_supervises_self(name),
16088 SupervisorError::ChildSupervisesSelf {
16089 caixa: name.to_string(),
16090 },
16091 );
16092 }
16093
16094 // ── supervisor_scalar_ctors! per-variant + cross-axis pins ──────────────
16095 //
16096 // Per-variant byte-equality pins guaranteeing every generated ctor arm in
16097 // the [`supervisor_scalar_ctors!`] macro produces a `SupervisorError`
16098 // structurally identical to the pre-lift `Self::<variant> { <field>: <val> }`
16099 // one-line struct-literal on the same `Copy`-`RestartStrategy | u32 |
16100 // Duration` fixture, plus one cross-axis sweep that routes each per-variant
16101 // `<field>: <ty>` scalar through the sole `$field:ident: $ty:ty` axis the
16102 // macro exposes so any wrapper-side truncation / re-order / silent `.into()`
16103 // / silent constant-substitution on any one variant surfaces here rather
16104 // than at a downstream per-`:supervisor` diagnostic-shape drift. Peer of the
16105 // sibling per-variant pins on `aplicacao_policy_scalar_ctors!` (7ef425e,
16106 // the 8-variant `AplicacaoError` `{ <field>: Duration | u32 }` fold on the
16107 // per-`:politicas` per-axis cap / canonical-form arms), plus the sibling
16108 // `supervisor_caixa_only_ctors!` (db09650), `SupervisorError::
16109 // {child_caixa_invalid,child_versao_invalid}` (d2ef2ec), and the peer
16110 // `DepError` / `AplicacaoError` / `LayoutError` / `LimitsError` /
16111 // `BehaviorError` / `UpgradeError` per-envelope ctor-macro pins.
16112 #[test]
16113 fn no_children_ctor_matches_struct_literal_wrap() {
16114 let estrategia = RestartStrategy::OneForAll;
16115 assert_eq!(
16116 SupervisorError::no_children(estrategia),
16117 SupervisorError::NoChildren { estrategia },
16118 "generated no_children ctor must produce byte-equal \
16119 `SupervisorError::NoChildren` to the pre-lift struct-literal wrap \
16120 on the same `Copy`-`RestartStrategy` fixture",
16121 );
16122 }
16123
16124 #[test]
16125 fn max_restarts_exceeds_cap_ctor_matches_struct_literal_wrap() {
16126 let max_restarts = SUPERVISOR_MAX_RESTARTS_MAX + 1;
16127 assert_eq!(
16128 SupervisorError::max_restarts_exceeds_cap(max_restarts),
16129 SupervisorError::MaxRestartsExceedsCap { max_restarts },
16130 "generated max_restarts_exceeds_cap ctor must produce byte-equal \
16131 `SupervisorError::MaxRestartsExceedsCap` to the pre-lift \
16132 struct-literal wrap on the same `Copy`-`u32` fixture",
16133 );
16134 }
16135
16136 #[test]
16137 fn restart_window_not_canonical_ctor_matches_struct_literal_wrap() {
16138 let window = Duration::from_micros(1_500);
16139 assert_eq!(
16140 SupervisorError::restart_window_not_canonical(window),
16141 SupervisorError::RestartWindowNotCanonical { window },
16142 "generated restart_window_not_canonical ctor must produce \
16143 byte-equal `SupervisorError::RestartWindowNotCanonical` to the \
16144 pre-lift struct-literal wrap on the same `Copy`-`Duration` fixture",
16145 );
16146 }
16147
16148 #[test]
16149 fn restart_window_exceeds_cap_ctor_matches_struct_literal_wrap() {
16150 let window = SUPERVISOR_RESTART_WINDOW_MAX + Duration::from_millis(1);
16151 assert_eq!(
16152 SupervisorError::restart_window_exceeds_cap(window),
16153 SupervisorError::RestartWindowExceedsCap { window },
16154 "generated restart_window_exceeds_cap ctor must produce \
16155 byte-equal `SupervisorError::RestartWindowExceedsCap` to the \
16156 pre-lift struct-literal wrap on the same `Copy`-`Duration` fixture",
16157 );
16158 }
16159
16160 #[test]
16161 fn supervisor_scalar_ctors_route_field_through_copy_uniformly() {
16162 // Cross-axis routing pin: sweep each generated `<field>: <ty>`
16163 // constructor input axis through a non-default `Copy` fixture against
16164 // every arm in the [`supervisor_scalar_ctors!`] macro, so any wrapper-
16165 // side silent `.into()` / silent constant-substitution / silent field
16166 // re-name away from the canonical `estrategia | max_restarts | window`
16167 // axes on any one variant, or a `RestartStrategy | u32 | Duration`
16168 // axis silently rerouted through some other `Copy` coercion, surfaces
16169 // here rather than at a downstream per-`:supervisor` diagnostic-shape
16170 // drift. Peer of the sibling
16171 // `aplicacao_policy_scalar_ctors_route_field_through_copy_uniformly`
16172 // (7ef425e) cross-axis routing pin on the peer `AplicacaoError`
16173 // envelope's per-`:politicas` per-axis ctor family, extended here onto
16174 // the last M2 per-`:supervisor` `Copy`-scalar `SupervisorError`
16175 // variant family folded onto a substrate primitive.
16176 //
16177 // Fixtures picked out of each variant's accept-set boundary rather
16178 // than the default value so a silent constant-substitution to a per-
16179 // variant sentinel surfaces here on the structural-equality assertion.
16180 // The `RestartStrategy` fixture picks `RestForOne` (a non-default arm
16181 // that isn't the `OneForOne` [`SUPERVISOR_ESTRATEGIA_DEFAULT`] and
16182 // isn't the `SimpleOneForOne` arm the sibling
16183 // `SimpleOneForOneWithStaticChildren` unit variant intercepts). The
16184 // `max_restarts` fixture picks an above-cap magnitude the cap arm
16185 // rejects; the two `Duration` fixtures pick the sub-millisecond and
16186 // above-cap ends of the `:restart-window` canonical-form + cap
16187 // bracket respectively.
16188 let estrategia = RestartStrategy::RestForOne;
16189 let above_cap_restarts = SUPERVISOR_MAX_RESTARTS_MAX + 137;
16190 let sub_ms = Duration::from_micros(1_500);
16191 let above_hour = SUPERVISOR_RESTART_WINDOW_MAX + Duration::from_secs(1);
16192 assert_eq!(
16193 SupervisorError::no_children(estrategia),
16194 SupervisorError::NoChildren { estrategia },
16195 );
16196 assert_eq!(
16197 SupervisorError::max_restarts_exceeds_cap(above_cap_restarts),
16198 SupervisorError::MaxRestartsExceedsCap {
16199 max_restarts: above_cap_restarts,
16200 },
16201 );
16202 assert_eq!(
16203 SupervisorError::restart_window_not_canonical(sub_ms),
16204 SupervisorError::RestartWindowNotCanonical { window: sub_ms },
16205 );
16206 assert_eq!(
16207 SupervisorError::restart_window_exceeds_cap(above_hour),
16208 SupervisorError::RestartWindowExceedsCap { window: above_hour },
16209 );
16210 }
16211
16212 #[test]
16213 fn restart_strategy_try_from_bytes_routes_through_from_wire_accessor() {
16214 // Fail-before-pass-after byte-parity pin on the newly lifted
16215 // `impl TryFrom<&[u8]> for RestartStrategy` — asserts the trait-
16216 // idiomatic byte-view reverse-projection standard-library impl
16217 // and the substrate-primitive [`RestartStrategy::from_wire`]
16218 // `Option<Self>` accessor resolve to the same four-arm
16219 // `PascalCase` wire accept-set across every arm the exhaustive
16220 // [`RestartStrategy::ALL`] slice enumerates. Extends the
16221 // substrate-wide trait-idiomatic byte-view reverse-projection
16222 // axis onto the first M2-OTP-shape supervisor-slot closed-set
16223 // fieldless typed enum peer — mirror of the paired
16224 // [`TryFrom<&str> for RestartStrategy`] str-view reverse-
16225 // projection axis on the same enum, and the byte-view companion
16226 // of the pre-existing byte-owned reverse-projection family
16227 // ([`AsRef<[u8]>`], [`From<RestartStrategy> for Vec<u8>`],
16228 // [`From<&RestartStrategy> for Vec<u8>`]) on this same enum.
16229 // Peer of the sibling
16230 // [`crate::kind::tests::caixa_kind_try_from_bytes_routes_through_from_wire_accessor`]
16231 // (18d1940),
16232 // [`crate::dialeto::tests::caixa_dialeto_try_from_bytes_routes_through_from_wire_accessor`]
16233 // (d102cb8), and
16234 // [`crate::dep::tests::dep_list_try_from_bytes_routes_through_from_wire_accessor`]
16235 // (b8f25d5) — tracks the "route through `from_wire` via
16236 // `std::str::from_utf8`" discipline the first-mover established.
16237 //
16238 // Rust's standard library carries no blanket
16239 // `impl<T: for<'a> TryFrom<&'a str>> TryFrom<&[u8]> for T`, so
16240 // a two-hop composition through [`std::str::from_utf8`] + the
16241 // paired [`TryFrom<&str>`] axis is reachable through the pre-
16242 // existing str-view reverse-projection axis alone. But that
16243 // two-hop shape has no compile-time link back to the byte-view
16244 // reverse-projection axis, forces every downstream
16245 // `<T: for<'a> TryFrom<&'a [u8]>>`-bound consumer to open-code
16246 // the composition at every call site, and admits a silent split
16247 // whenever a future call site takes a sibling byte-projection
16248 // axis whose parse arm-set carries no compile-time byte-view
16249 // surface. This impl closes the byte-view reverse-projection
16250 // axis at the substrate-primitive [`RestartStrategy::from_wire`]
16251 // accessor so every future `<T: for<'a> TryFrom<&'a [u8]>>`-
16252 // bound consumer reaches the same four-arm `PascalCase` wire
16253 // accept-set through one trait dispatch.
16254 for &variant in RestartStrategy::ALL {
16255 let wire_bytes: &[u8] = variant.as_str().as_bytes();
16256 assert_eq!(
16257 <RestartStrategy as TryFrom<&[u8]>>::try_from(wire_bytes),
16258 Ok(variant),
16259 "TryFrom<&[u8]> impl on RestartStrategy must round-trip \
16260 RestartStrategy::{variant:?}.as_str().as_bytes() back to \
16261 Ok(RestartStrategy::{variant:?}) — divergence from \
16262 RestartStrategy::from_wire signals a silent detour off \
16263 the substrate-primitive accessor"
16264 );
16265 assert_eq!(
16266 <RestartStrategy as TryFrom<&[u8]>>::try_from(wire_bytes).ok(),
16267 RestartStrategy::from_wire(variant.as_str()),
16268 "TryFrom<&[u8]> ok()-projection on \
16269 RestartStrategy::{variant:?}.as_str().as_bytes() must \
16270 byte-equal RestartStrategy::from_wire on the paired \
16271 &str input"
16272 );
16273 // Cross-axis witness: the byte-view reverse-projection axis
16274 // must agree with the paired str-view reverse-projection
16275 // axis ([`TryFrom<&str>`]) on every accepted arm — the two
16276 // reverse paths share one `PascalCase` accept-set through
16277 // the substrate-primitive `from_wire` accessor.
16278 let via_str: Result<RestartStrategy, ()> =
16279 <RestartStrategy as TryFrom<&str>>::try_from(variant.as_str());
16280 let via_bytes: Result<RestartStrategy, ()> =
16281 <RestartStrategy as TryFrom<&[u8]>>::try_from(wire_bytes);
16282 assert_eq!(
16283 via_bytes, via_str,
16284 "TryFrom<&[u8]> and TryFrom<&str> reverse-projection \
16285 axes on RestartStrategy must agree on \
16286 RestartStrategy::{variant:?} — divergence signals the \
16287 byte-view and str-view reverse paths have drifted off \
16288 the same substrate-primitive from_wire accessor"
16289 );
16290 // Forward/reverse byte-view cross-axis witness: feed the
16291 // paired [`AsRef<[u8]>`] byte-tail back through the new
16292 // impl and assert it round-trips to the originating arm.
16293 let via_asref: &[u8] = <RestartStrategy as AsRef<[u8]>>::as_ref(&variant);
16294 assert_eq!(
16295 <RestartStrategy as TryFrom<&[u8]>>::try_from(via_asref),
16296 Ok(variant),
16297 "TryFrom<&[u8]> ∘ AsRef<[u8]> must round-trip \
16298 RestartStrategy::{variant:?} — divergence signals the \
16299 forward and reverse byte-view axes have drifted off \
16300 the same substrate-primitive as_str/from_wire pair"
16301 );
16302 }
16303 }
16304
16305 #[test]
16306 fn restart_strategy_try_from_bytes_rejects_unknown_and_non_utf8_bytes() {
16307 // Rejection witness on the `impl TryFrom<&[u8]> for
16308 // RestartStrategy` — sweeps two rejection paths the byte-view
16309 // reverse-projection axis collapses onto the single unit-error
16310 // `Err(())` return: the invalid-UTF-8 rejection path
16311 // ([`std::str::from_utf8`] returns `Err` before
16312 // [`RestartStrategy::from_wire`] runs) and the valid-UTF-8-but-
16313 // unknown-wire rejection path ([`RestartStrategy::from_wire`]
16314 // returns `None` on a byte-string outside the four-arm
16315 // `PascalCase` accept-set). Both must reject, so a future
16316 // accidental widening of the trait impl's accept-set (a case-
16317 // fold path, a silent acceptance of the kebab-case dispatcher-
16318 // catalog byte-strings on this axis — which would collide the
16319 // two-axis wire/catalog split the sibling
16320 // [`RestartStrategy::from_wire`] doc block makes load-bearing —
16321 // a `#[serde(rename_all = "…")]` attribute drift that widens
16322 // the parse arm-set silently, a stray fallback that maps
16323 // invalid UTF-8 onto a default arm rather than the trait-
16324 // idiomatic `Err(())`) trips at caixa-core test time. Peer of
16325 // the sibling
16326 // [`crate::kind::tests::caixa_kind_try_from_bytes_rejects_unknown_and_non_utf8_bytes`]
16327 // (18d1940),
16328 // [`crate::dialeto::tests::caixa_dialeto_try_from_bytes_rejects_unknown_and_non_utf8_bytes`]
16329 // (d102cb8), and
16330 // [`crate::dep::tests::dep_list_try_from_bytes_rejects_unknown_and_non_utf8_bytes`]
16331 // (b8f25d5) rejection witnesses.
16332 //
16333 // Non-UTF-8 candidates:
16334 // - a lone 0xFF byte (never valid as a UTF-8 leading byte)
16335 // - a lone 0x80 continuation byte with no leading byte
16336 // - a truncated multi-byte sequence (0xC3 without its continuation)
16337 // - a UTF-16 BOM-style byte pair the UTF-8 validator rejects
16338 // - a UTF-16 surrogate half rejected by UTF-8
16339 let non_utf8_rejected: &[&[u8]] = &[
16340 &[0xFF],
16341 &[0x80],
16342 &[0xC3],
16343 &[0xFF, 0xFE],
16344 &[0xED, 0xA0, 0x80],
16345 ];
16346 for &input in non_utf8_rejected {
16347 assert_eq!(
16348 <RestartStrategy as TryFrom<&[u8]>>::try_from(input),
16349 Err(()),
16350 "TryFrom<&[u8]> impl on RestartStrategy must reject the \
16351 non-UTF-8 byte-sequence {input:?} with Err(()) — \
16352 silent acceptance signals the UTF-8 validation path \
16353 collapsed onto a default arm rather than the trait-\
16354 idiomatic unit-error"
16355 );
16356 }
16357 // Valid-UTF-8-but-unknown-wire candidates mirror the corpus
16358 // the sibling `restart_strategy_try_from_str_rejects_unknown_byte_strings`
16359 // (5b828ed) str-view rejection witness already pins on the
16360 // paired [`TryFrom<&str>`] axis: the empty byte-string,
16361 // whitespace-only padding, the kebab-case dispatcher-catalog
16362 // byte-strings on the sibling axis the pre-existing
16363 // [`std::str::FromStr`] impl the [`gen_platform::FromStrKind`]
16364 // derive installs parses onto (a caller who confuses the two
16365 // axes trips here rather than at a downstream K8s-CR round-
16366 // trip miss), lowercase / uppercase / mixed-case folds of each
16367 // `PascalCase` arm, whitespace-padded / trailing-newline /
16368 // quote-wrapped forms, and plausible-but-wrong English rebrand
16369 // candidates.
16370 let unknown_wire_rejected: &[&[u8]] = &[
16371 b"",
16372 b" ",
16373 b"\n",
16374 b"\t",
16375 b"one-for-one",
16376 b"one-for-all",
16377 b"rest-for-one",
16378 b"simple-one-for-one",
16379 b"oneforone",
16380 b"one_for_one",
16381 b"OneForOnes",
16382 b"ONEFORONE",
16383 b"oneforall",
16384 b"restforone",
16385 b"simpleoneforone",
16386 b"OneForOne ",
16387 b" OneForOne",
16388 b" OneForAll ",
16389 b"OneForOne\n",
16390 b"RestForOne\t",
16391 b"OneForEach",
16392 b"AllForOne",
16393 b"one for one",
16394 b"\"OneForOne\"",
16395 b"?",
16396 ];
16397 for &input in unknown_wire_rejected {
16398 assert_eq!(
16399 <RestartStrategy as TryFrom<&[u8]>>::try_from(input),
16400 Err(()),
16401 "TryFrom<&[u8]> impl on RestartStrategy must reject the \
16402 valid-UTF-8-but-unknown-wire byte-string {input:?} \
16403 with Err(()) — silent acceptance signals an accept-\
16404 set widening off the paired RestartStrategy::from_wire \
16405 resolver"
16406 );
16407 // Cross-axis witness: on a byte-string that is valid UTF-8,
16408 // the byte-view reverse-projection axis must agree with the
16409 // paired str-view reverse-projection axis
16410 // ([`TryFrom<&str>`]) — both route through the same
16411 // [`RestartStrategy::from_wire`] resolver, so the two
16412 // rejection paths align by construction.
16413 if let Ok(s) = std::str::from_utf8(input) {
16414 assert_eq!(
16415 <RestartStrategy as TryFrom<&[u8]>>::try_from(input),
16416 <RestartStrategy as TryFrom<&str>>::try_from(s),
16417 "TryFrom<&[u8]> and TryFrom<&str> reverse-\
16418 projection axes on RestartStrategy must agree on \
16419 the valid-UTF-8 input {input:?} — divergence \
16420 signals the two reverse paths have drifted off \
16421 the same substrate-primitive from_wire accessor"
16422 );
16423 }
16424 }
16425 }
16426
16427 #[test]
16428 fn restart_strategy_try_from_vec_bytes_routes_through_borrowed_byte_view_axis() {
16429 // Fail-before-pass-after byte-parity pin on the newly lifted
16430 // `impl TryFrom<Vec<u8>> for RestartStrategy` — asserts the trait-
16431 // idiomatic owned-byte-vec reverse-projection standard-library
16432 // impl and the sibling borrowed-input [`TryFrom<&[u8]>`] axis
16433 // resolve to the same four-arm `PascalCase` wire accept-set
16434 // across every arm the exhaustive [`RestartStrategy::ALL`] slice
16435 // enumerates. Extends the substrate-wide trait-idiomatic byte-
16436 // owned reverse-projection axis onto the first M2-OTP-shape
16437 // supervisor-slot closed-set fieldless typed enum peer — owned-
16438 // input mirror of the paired [`TryFrom<&[u8]>`] byte-view
16439 // reverse-projection axis (c699a83), and byte-owned reverse
16440 // companion of the pre-existing byte-owned *forward*-projection
16441 // pair ([`From<RestartStrategy> for Vec<u8>`],
16442 // [`From<&RestartStrategy> for Vec<u8>`]) on this same enum.
16443 // Peer of the sibling first-mover
16444 // [`crate::kind::tests::caixa_kind_try_from_vec_bytes_routes_through_borrowed_byte_view_axis`]
16445 // (99c2849) on the [`crate::CaixaKind`] closed-set typed-enum
16446 // peer, the sibling second-mover
16447 // [`crate::dialeto::tests::caixa_dialeto_try_from_vec_bytes_routes_through_borrowed_byte_view_axis`]
16448 // (83a1526) on the [`crate::CaixaDialeto`] peer, and the sibling
16449 // third-mover
16450 // [`crate::dep::tests::dep_list_try_from_vec_bytes_routes_through_borrowed_byte_view_axis`]
16451 // (42091cb) on the [`crate::dep::DepList`] peer — tracks the
16452 // "delegate through `TryFrom<&[u8]>` on the `Vec<u8>::as_slice`
16453 // borrow" discipline the first-mover established.
16454 //
16455 // Rust's standard library carries no blanket
16456 // `impl<T: for<'a> TryFrom<&'a [u8]>> TryFrom<Vec<u8>> for T`,
16457 // so an owned-byte-vec caller otherwise picks between an open-
16458 // coded `<T as TryFrom<&[u8]>>::try_from(bytes.as_slice())` at
16459 // every call site whose type bounds have no compile-time link
16460 // back to the byte-owned reverse-projection axis, or a
16461 // `String::from_utf8(bytes)` two-hop shape whose error surface
16462 // leaks the standard-library `FromUtf8Error` type. This impl
16463 // closes the byte-owned reverse-projection axis at the
16464 // substrate-primitive [`RestartStrategy::from_wire`] accessor so
16465 // every future `<T: TryFrom<Vec<u8>>>`-bound owned-byte-vec
16466 // consumer reaches the same four-arm `PascalCase` wire accept-
16467 // set through one trait dispatch.
16468 for &variant in RestartStrategy::ALL {
16469 let wire_bytes: Vec<u8> = variant.as_str().as_bytes().to_vec();
16470 assert_eq!(
16471 <RestartStrategy as TryFrom<Vec<u8>>>::try_from(wire_bytes.clone()),
16472 Ok(variant),
16473 "TryFrom<Vec<u8>> impl on RestartStrategy must round-trip \
16474 RestartStrategy::{variant:?}.as_str().as_bytes().to_vec() \
16475 back to Ok(RestartStrategy::{variant:?}) — divergence \
16476 from the sibling TryFrom<&[u8]> axis signals a silent \
16477 detour off the substrate-primitive from_wire accessor"
16478 );
16479 // Cross-axis witness: the owned-byte-vec reverse-projection
16480 // axis must agree with the borrowed byte-slice reverse-
16481 // projection axis on every accepted arm — the two axes share
16482 // one `PascalCase` wire vocabulary through the substrate-
16483 // primitive `from_wire` accessor, and the owned-input axis
16484 // delegates to the borrowed peer by design.
16485 let via_owned: Result<RestartStrategy, ()> =
16486 <RestartStrategy as TryFrom<Vec<u8>>>::try_from(wire_bytes.clone());
16487 let via_borrowed: Result<RestartStrategy, ()> =
16488 <RestartStrategy as TryFrom<&[u8]>>::try_from(wire_bytes.as_slice());
16489 assert_eq!(
16490 via_owned, via_borrowed,
16491 "TryFrom<Vec<u8>> and TryFrom<&[u8]> reverse-projection \
16492 axes on RestartStrategy must agree on \
16493 RestartStrategy::{variant:?} — divergence signals the \
16494 owned-input and borrowed-input byte-view reverse paths \
16495 have drifted off the same substrate-primitive \
16496 from_wire accessor"
16497 );
16498 // Cross-axis witness against the paired str-view reverse
16499 // axis ([`TryFrom<&str>`]) — the three reverse paths (str-
16500 // view, byte-view borrowed, byte-view owned) share one
16501 // substrate primitive.
16502 let via_str: Result<RestartStrategy, ()> =
16503 <RestartStrategy as TryFrom<&str>>::try_from(variant.as_str());
16504 assert_eq!(
16505 via_owned, via_str,
16506 "TryFrom<Vec<u8>> and TryFrom<&str> reverse-projection \
16507 axes on RestartStrategy must agree on \
16508 RestartStrategy::{variant:?} — divergence signals the \
16509 byte-owned and str-view reverse paths have drifted off \
16510 the same substrate-primitive from_wire accessor"
16511 );
16512 // Four-corner witness: because [`RestartStrategy`] carries
16513 // no wire-vs-diagnostic split (as_str and from_wire share
16514 // one `PascalCase` byte-vocabulary — unlike the sibling
16515 // [`crate::CaixaKind`] whose peer test deliberately declines
16516 // this witness), the byte-owned reverse-projection axis on
16517 // this enum *does* round-trip against the paired byte-owned
16518 // forward-projection pair. Pin every corner of the {owned-
16519 // input, borrowed-input} × {From<Self> → Vec<u8>,
16520 // From<&Self> → Vec<u8>} square onto the same Ok(variant)
16521 // return so a future accident that drops one corner off the
16522 // substrate-primitive accessor trips here.
16523 let owned_forward: Vec<u8> = <Vec<u8> as From<RestartStrategy>>::from(variant);
16524 let borrowed_forward: Vec<u8> = <Vec<u8> as From<&RestartStrategy>>::from(&variant);
16525 assert_eq!(
16526 owned_forward, wire_bytes,
16527 "From<RestartStrategy> for Vec<u8> forward projection on \
16528 RestartStrategy::{variant:?} must byte-equal \
16529 variant.as_str().as_bytes().to_vec() — divergence \
16530 signals the paired forward pair drifted off the \
16531 substrate-primitive as_str accessor"
16532 );
16533 assert_eq!(
16534 borrowed_forward, wire_bytes,
16535 "From<&RestartStrategy> for Vec<u8> forward projection \
16536 on &RestartStrategy::{variant:?} must byte-equal \
16537 variant.as_str().as_bytes().to_vec() — divergence \
16538 signals the paired forward pair drifted off the \
16539 substrate-primitive as_str accessor"
16540 );
16541 assert_eq!(
16542 <RestartStrategy as TryFrom<Vec<u8>>>::try_from(owned_forward.clone()),
16543 Ok(variant),
16544 "Four-corner round-trip on RestartStrategy::{variant:?} \
16545 through From<RestartStrategy> for Vec<u8> then \
16546 TryFrom<Vec<u8>> for RestartStrategy must return \
16547 Ok(variant) — divergence signals the byte-owned \
16548 forward pair and the byte-owned reverse axis have \
16549 drifted apart"
16550 );
16551 assert_eq!(
16552 <RestartStrategy as TryFrom<Vec<u8>>>::try_from(borrowed_forward),
16553 Ok(variant),
16554 "Four-corner round-trip on RestartStrategy::{variant:?} \
16555 through From<&RestartStrategy> for Vec<u8> then \
16556 TryFrom<Vec<u8>> for RestartStrategy must return \
16557 Ok(variant) — divergence signals the borrowed-input \
16558 forward corner and the owned-input reverse corner have \
16559 drifted apart"
16560 );
16561 }
16562 }
16563
16564 #[test]
16565 fn restart_strategy_try_from_vec_bytes_rejects_unknown_and_non_utf8_bytes() {
16566 // Rejection witness on the `impl TryFrom<Vec<u8>> for
16567 // RestartStrategy` — sweeps the same two rejection paths the
16568 // sibling borrowed `TryFrom<&[u8]>` axis collapses onto the
16569 // single unit-error return: the invalid-UTF-8 rejection path
16570 // (`std::str::from_utf8` on the underlying byte-slice returns
16571 // `Err` before [`RestartStrategy::from_wire`] runs) and the
16572 // valid-UTF-8-but-unknown-wire rejection path
16573 // ([`RestartStrategy::from_wire`] returns `None` on a byte-
16574 // string outside the four-arm `PascalCase` accept-set). Both
16575 // must reject so a future accidental widening of the trait
16576 // impl's accept-set (a case-fold path, a silent acceptance of
16577 // the kebab-case dispatcher-catalog byte-strings on this axis —
16578 // which would collide the two-axis wire/catalog split the
16579 // sibling [`RestartStrategy::from_wire`] doc block makes load-
16580 // bearing — a `#[serde(rename_all = "…")]` attribute drift that
16581 // widens the parse arm-set silently, a stray
16582 // `String::from_utf8_lossy` detour that widens the input
16583 // surface with the U+FFFD replacement character, an
16584 // `Option::unwrap_or_default`-shape fallback that maps invalid
16585 // UTF-8 onto a default arm rather than the trait-idiomatic
16586 // `Err(())`) trips at caixa-core test time. Peer of the sibling
16587 // first-mover
16588 // [`crate::kind::tests::caixa_kind_try_from_vec_bytes_rejects_unknown_and_non_utf8_bytes`]
16589 // (99c2849) on the [`crate::CaixaKind`] peer, the sibling
16590 // second-mover
16591 // [`crate::dialeto::tests::caixa_dialeto_try_from_vec_bytes_rejects_unknown_and_non_utf8_bytes`]
16592 // (83a1526) on the [`crate::CaixaDialeto`] peer, and the
16593 // sibling third-mover
16594 // [`crate::dep::tests::dep_list_try_from_vec_bytes_rejects_unknown_and_non_utf8_bytes`]
16595 // (42091cb) on the [`crate::dep::DepList`] peer rejection
16596 // witnesses.
16597 let non_utf8_rejected: &[&[u8]] = &[
16598 &[0xFF],
16599 &[0x80],
16600 &[0xC3],
16601 &[0xFF, 0xFE],
16602 &[0xED, 0xA0, 0x80], // UTF-16 surrogate half — rejected by UTF-8
16603 ];
16604 for &input in non_utf8_rejected {
16605 let owned: Vec<u8> = input.to_vec();
16606 assert_eq!(
16607 <RestartStrategy as TryFrom<Vec<u8>>>::try_from(owned),
16608 Err(()),
16609 "TryFrom<Vec<u8>> impl on RestartStrategy must reject \
16610 the non-UTF-8 byte-sequence {input:?} with Err(()) — \
16611 silent acceptance signals the UTF-8 validation path \
16612 collapsed onto a default arm rather than the trait-\
16613 idiomatic unit-error"
16614 );
16615 // Cross-axis witness: the owned-input axis must agree with
16616 // the borrowed-input axis on every rejected input.
16617 assert_eq!(
16618 <RestartStrategy as TryFrom<Vec<u8>>>::try_from(input.to_vec()),
16619 <RestartStrategy as TryFrom<&[u8]>>::try_from(input),
16620 "TryFrom<Vec<u8>> and TryFrom<&[u8]> reverse-projection \
16621 axes on RestartStrategy must agree on the non-UTF-8 \
16622 input {input:?} — divergence signals the owned-input \
16623 and borrowed-input byte-view reverse paths have drifted \
16624 off the same substrate-primitive from_wire accessor"
16625 );
16626 }
16627 // Valid-UTF-8-but-unknown-wire candidates mirror the corpus the
16628 // sibling borrowed-input rejection witness
16629 // [`restart_strategy_try_from_bytes_rejects_unknown_and_non_utf8_bytes`]
16630 // (c699a83) already pins on the paired byte-view axis: the
16631 // empty byte-string, whitespace-only padding, the kebab-case
16632 // dispatcher-catalog byte-strings on the sibling axis the pre-
16633 // existing [`std::str::FromStr`] impl the
16634 // [`gen_platform::FromStrKind`] derive installs parses onto (a
16635 // caller who confuses the two axes trips here rather than at a
16636 // downstream K8s-CR round-trip miss), lowercase / uppercase /
16637 // mixed-case folds of each `PascalCase` arm, whitespace-padded
16638 // / trailing-newline / quote-wrapped forms, and plausible-but-
16639 // wrong English rebrand candidates.
16640 let unknown_wire_rejected: &[&[u8]] = &[
16641 b"",
16642 b" ",
16643 b"\n",
16644 b"\t",
16645 b"one-for-one",
16646 b"one-for-all",
16647 b"rest-for-one",
16648 b"simple-one-for-one",
16649 b"oneforone",
16650 b"one_for_one",
16651 b"OneForOnes",
16652 b"ONEFORONE",
16653 b"oneforall",
16654 b"restforone",
16655 b"simpleoneforone",
16656 b"OneForOne ",
16657 b" OneForOne",
16658 b" OneForAll ",
16659 b"OneForOne\n",
16660 b"RestForOne\t",
16661 b"OneForEach",
16662 b"AllForOne",
16663 b"one for one",
16664 b"\"OneForOne\"",
16665 b"?",
16666 ];
16667 for &input in unknown_wire_rejected {
16668 let owned: Vec<u8> = input.to_vec();
16669 assert_eq!(
16670 <RestartStrategy as TryFrom<Vec<u8>>>::try_from(owned),
16671 Err(()),
16672 "TryFrom<Vec<u8>> impl on RestartStrategy must reject \
16673 the valid-UTF-8-but-unknown-wire byte-string {input:?} \
16674 with Err(()) — silent acceptance signals an accept-\
16675 set widening off the paired RestartStrategy::from_wire \
16676 resolver"
16677 );
16678 // Cross-axis witness against the borrowed byte-view axis:
16679 // the two paths must agree by construction, since the owned
16680 // axis delegates to the borrowed peer.
16681 assert_eq!(
16682 <RestartStrategy as TryFrom<Vec<u8>>>::try_from(input.to_vec()),
16683 <RestartStrategy as TryFrom<&[u8]>>::try_from(input),
16684 "TryFrom<Vec<u8>> and TryFrom<&[u8]> reverse-projection \
16685 axes on RestartStrategy must agree on the valid-UTF-8-\
16686 but-unknown-wire input {input:?} — divergence signals \
16687 the owned-input and borrowed-input byte-view reverse \
16688 paths have drifted off the same substrate-primitive \
16689 from_wire accessor"
16690 );
16691 }
16692 }
16693
16694 #[test]
16695 fn restart_policy_try_from_bytes_routes_through_from_wire_accessor() {
16696 // Fail-before-pass-after byte-parity pin on the newly lifted
16697 // `impl TryFrom<&[u8]> for RestartPolicy` — asserts the trait-
16698 // idiomatic byte-view reverse-projection standard-library impl
16699 // and the substrate-primitive [`RestartPolicy::from_wire`]
16700 // `Option<Self>` accessor resolve to the same three-arm
16701 // `PascalCase` wire accept-set across every arm the exhaustive
16702 // [`RestartPolicy::ALL`] slice enumerates. Closes the substrate-
16703 // wide trait-idiomatic byte-view reverse-projection axis on the
16704 // M2-OTP-shape `:supervisor :estrategia` + `:children :restart`
16705 // slot pair the sibling [`RestartStrategy`] first-mover
16706 // (c699a83) opened one commit prior — mirror of the paired
16707 // [`TryFrom<&str> for RestartPolicy`] str-view reverse-
16708 // projection axis on the same enum, and the byte-view companion
16709 // of the pre-existing byte-owned reverse-projection family
16710 // ([`AsRef<[u8]>`], [`From<RestartPolicy> for Vec<u8>`],
16711 // [`From<&RestartPolicy> for Vec<u8>`]) on this same enum. Peer
16712 // of the sibling
16713 // [`restart_strategy_try_from_bytes_routes_through_from_wire_accessor`]
16714 // (c699a83),
16715 // [`crate::kind::tests::caixa_kind_try_from_bytes_routes_through_from_wire_accessor`]
16716 // (18d1940),
16717 // [`crate::dialeto::tests::caixa_dialeto_try_from_bytes_routes_through_from_wire_accessor`]
16718 // (d102cb8), and
16719 // [`crate::dep::tests::dep_list_try_from_bytes_routes_through_from_wire_accessor`]
16720 // (b8f25d5) — tracks the "route through `from_wire` via
16721 // `std::str::from_utf8`" discipline the first-mover established.
16722 //
16723 // Rust's standard library carries no blanket
16724 // `impl<T: for<'a> TryFrom<&'a str>> TryFrom<&[u8]> for T`, so a
16725 // two-hop composition through [`std::str::from_utf8`] + the
16726 // paired [`TryFrom<&str>`] axis is reachable through the pre-
16727 // existing str-view reverse-projection axis alone. But that
16728 // two-hop shape has no compile-time link back to the byte-view
16729 // reverse-projection axis, forces every downstream
16730 // `<T: for<'a> TryFrom<&'a [u8]>>`-bound consumer to open-code
16731 // the composition at every call site, and admits a silent split
16732 // whenever a future call site takes a sibling byte-projection
16733 // axis whose parse arm-set carries no compile-time byte-view
16734 // surface. This impl closes the byte-view reverse-projection
16735 // axis at the substrate-primitive [`RestartPolicy::from_wire`]
16736 // accessor so every future `<T: for<'a> TryFrom<&'a [u8]>>`-
16737 // bound consumer reaches the same three-arm `PascalCase` wire
16738 // accept-set through one trait dispatch.
16739 for &variant in RestartPolicy::ALL {
16740 let wire_bytes: &[u8] = variant.as_str().as_bytes();
16741 assert_eq!(
16742 <RestartPolicy as TryFrom<&[u8]>>::try_from(wire_bytes),
16743 Ok(variant),
16744 "TryFrom<&[u8]> impl on RestartPolicy must round-trip \
16745 RestartPolicy::{variant:?}.as_str().as_bytes() back to \
16746 Ok(RestartPolicy::{variant:?}) — divergence from \
16747 RestartPolicy::from_wire signals a silent detour off \
16748 the substrate-primitive accessor"
16749 );
16750 assert_eq!(
16751 <RestartPolicy as TryFrom<&[u8]>>::try_from(wire_bytes).ok(),
16752 RestartPolicy::from_wire(variant.as_str()),
16753 "TryFrom<&[u8]> ok()-projection on \
16754 RestartPolicy::{variant:?}.as_str().as_bytes() must \
16755 byte-equal RestartPolicy::from_wire on the paired \
16756 &str input"
16757 );
16758 // Cross-axis witness: the byte-view reverse-projection axis
16759 // must agree with the paired str-view reverse-projection
16760 // axis ([`TryFrom<&str>`]) on every accepted arm — the two
16761 // reverse paths share one `PascalCase` accept-set through
16762 // the substrate-primitive `from_wire` accessor.
16763 let via_str: Result<RestartPolicy, ()> =
16764 <RestartPolicy as TryFrom<&str>>::try_from(variant.as_str());
16765 let via_bytes: Result<RestartPolicy, ()> =
16766 <RestartPolicy as TryFrom<&[u8]>>::try_from(wire_bytes);
16767 assert_eq!(
16768 via_bytes, via_str,
16769 "TryFrom<&[u8]> and TryFrom<&str> reverse-projection \
16770 axes on RestartPolicy must agree on \
16771 RestartPolicy::{variant:?} — divergence signals the \
16772 byte-view and str-view reverse paths have drifted off \
16773 the same substrate-primitive from_wire accessor"
16774 );
16775 // Forward/reverse byte-view cross-axis witness: feed the
16776 // paired [`AsRef<[u8]>`] byte-tail back through the new
16777 // impl and assert it round-trips to the originating arm.
16778 let via_asref: &[u8] = <RestartPolicy as AsRef<[u8]>>::as_ref(&variant);
16779 assert_eq!(
16780 <RestartPolicy as TryFrom<&[u8]>>::try_from(via_asref),
16781 Ok(variant),
16782 "TryFrom<&[u8]> ∘ AsRef<[u8]> must round-trip \
16783 RestartPolicy::{variant:?} — divergence signals the \
16784 forward and reverse byte-view axes have drifted off \
16785 the same substrate-primitive as_str/from_wire pair"
16786 );
16787 }
16788 }
16789
16790 #[test]
16791 fn restart_policy_try_from_bytes_rejects_unknown_and_non_utf8_bytes() {
16792 // Rejection witness on the `impl TryFrom<&[u8]> for RestartPolicy`
16793 // — sweeps two rejection paths the byte-view reverse-projection
16794 // axis collapses onto the single unit-error `Err(())` return: the
16795 // invalid-UTF-8 rejection path ([`std::str::from_utf8`] returns
16796 // `Err` before [`RestartPolicy::from_wire`] runs) and the
16797 // valid-UTF-8-but-unknown-wire rejection path
16798 // ([`RestartPolicy::from_wire`] returns `None` on a byte-string
16799 // outside the three-arm `PascalCase` accept-set). Both must
16800 // reject, so a future accidental widening of the trait impl's
16801 // accept-set (a case-fold path, a silent acceptance of the
16802 // kebab-case dispatcher-catalog byte-strings on this axis — which
16803 // would collide the two-axis wire/catalog split the sibling
16804 // [`RestartPolicy::from_wire`] doc block makes load-bearing — a
16805 // `#[serde(rename_all = "…")]` attribute drift that widens the
16806 // parse arm-set silently, a stray fallback that maps invalid
16807 // UTF-8 onto a default arm rather than the trait-idiomatic
16808 // `Err(())`) trips at caixa-core test time. Peer of the sibling
16809 // [`restart_strategy_try_from_bytes_rejects_unknown_and_non_utf8_bytes`]
16810 // (c699a83),
16811 // [`crate::kind::tests::caixa_kind_try_from_bytes_rejects_unknown_and_non_utf8_bytes`]
16812 // (18d1940),
16813 // [`crate::dialeto::tests::caixa_dialeto_try_from_bytes_rejects_unknown_and_non_utf8_bytes`]
16814 // (d102cb8), and
16815 // [`crate::dep::tests::dep_list_try_from_bytes_rejects_unknown_and_non_utf8_bytes`]
16816 // (b8f25d5) rejection witnesses.
16817 //
16818 // Non-UTF-8 candidates:
16819 // - a lone 0xFF byte (never valid as a UTF-8 leading byte)
16820 // - a lone 0x80 continuation byte with no leading byte
16821 // - a truncated multi-byte sequence (0xC3 without its continuation)
16822 // - a UTF-16 BOM-style byte pair the UTF-8 validator rejects
16823 // - a UTF-16 surrogate half rejected by UTF-8
16824 let non_utf8_rejected: &[&[u8]] = &[
16825 &[0xFF],
16826 &[0x80],
16827 &[0xC3],
16828 &[0xFF, 0xFE],
16829 &[0xED, 0xA0, 0x80],
16830 ];
16831 for &input in non_utf8_rejected {
16832 assert_eq!(
16833 <RestartPolicy as TryFrom<&[u8]>>::try_from(input),
16834 Err(()),
16835 "TryFrom<&[u8]> impl on RestartPolicy must reject the \
16836 non-UTF-8 byte-sequence {input:?} with Err(()) — \
16837 silent acceptance signals the UTF-8 validation path \
16838 collapsed onto a default arm rather than the trait-\
16839 idiomatic unit-error"
16840 );
16841 }
16842 // Valid-UTF-8-but-unknown-wire candidates mirror the corpus the
16843 // sibling `restart_policy_try_from_str_rejects_unknown_byte_strings`
16844 // str-view rejection witness already pins on the paired
16845 // [`TryFrom<&str>`] axis: the empty byte-string, whitespace-only
16846 // padding, the kebab-case dispatcher-catalog byte-strings on the
16847 // sibling axis the pre-existing [`std::str::FromStr`] impl the
16848 // [`gen_platform::FromStrKind`] derive installs parses onto (a
16849 // caller who confuses the two axes trips here rather than at a
16850 // downstream K8s-CR round-trip miss), lowercase / uppercase /
16851 // mixed-case folds of each `PascalCase` arm, whitespace-padded /
16852 // trailing-newline / quote-wrapped forms, and plausible-but-wrong
16853 // English rebrand candidates (`Ephemeral`, `Always`, `Never`,
16854 // `OnAbnormalExit`, `intrinsic`).
16855 let unknown_wire_rejected: &[&[u8]] = &[
16856 b"",
16857 b" ",
16858 b"\n",
16859 b"\t",
16860 b"permanent",
16861 b"temporary",
16862 b"transient",
16863 b"PERMANENT",
16864 b"TEMPORARY",
16865 b"TRANSIENT",
16866 b"Permanents",
16867 b"Permanent ",
16868 b" Permanent",
16869 b" Temporary ",
16870 b"Permanent\n",
16871 b"Transient\t",
16872 b"\"Permanent\"",
16873 b"Ephemeral",
16874 b"Always",
16875 b"Never",
16876 b"OnAbnormalExit",
16877 b"intrinsic",
16878 b"?",
16879 ];
16880 for &input in unknown_wire_rejected {
16881 assert_eq!(
16882 <RestartPolicy as TryFrom<&[u8]>>::try_from(input),
16883 Err(()),
16884 "TryFrom<&[u8]> impl on RestartPolicy must reject the \
16885 valid-UTF-8-but-unknown-wire byte-string {input:?} \
16886 with Err(()) — silent acceptance signals an accept-\
16887 set widening off the paired RestartPolicy::from_wire \
16888 resolver"
16889 );
16890 // Cross-axis witness: on a byte-string that is valid UTF-8,
16891 // the byte-view reverse-projection axis must agree with the
16892 // paired str-view reverse-projection axis
16893 // ([`TryFrom<&str>`]) — both route through the same
16894 // [`RestartPolicy::from_wire`] resolver, so the two
16895 // rejection paths align by construction.
16896 if let Ok(s) = std::str::from_utf8(input) {
16897 assert_eq!(
16898 <RestartPolicy as TryFrom<&[u8]>>::try_from(input),
16899 <RestartPolicy as TryFrom<&str>>::try_from(s),
16900 "TryFrom<&[u8]> and TryFrom<&str> reverse-\
16901 projection axes on RestartPolicy must agree on \
16902 the valid-UTF-8 input {input:?} — divergence \
16903 signals the two reverse paths have drifted off \
16904 the same substrate-primitive from_wire accessor"
16905 );
16906 }
16907 }
16908 }
16909
16910 #[test]
16911 fn supervisor_scalar_ctors_are_const_zero_runtime_work() {
16912 // Const-eval pin: the [`supervisor_scalar_ctors!`] macro spells every
16913 // generated ctor `const fn` so a caller can pin a `SupervisorError`
16914 // at compile time — the same zero-runtime-work property the pre-lift
16915 // `|<slot>| SupervisorError::<Variant> { <slot> }` closure carried on
16916 // its `Copy`-pass-through construction path (no `.to_string()` /
16917 // `.into()` allocation, no branching). If any future edit silently
16918 // drops the `const` qualifier from the macro body the per-arm `const`
16919 // bindings below fail to compile, which surfaces the regression at
16920 // the substrate-primitive definition rather than at some downstream
16921 // consumer that had come to rely on the `const`-constructibility.
16922 // Peer of the sibling
16923 // `aplicacao_policy_scalar_ctors_are_const_zero_runtime_work`
16924 // (7ef425e) const-eval pin on the peer `AplicacaoError` envelope's
16925 // per-`:politicas` per-axis ctor family.
16926 const NO_CHILDREN: SupervisorError =
16927 SupervisorError::no_children(RestartStrategy::OneForAll);
16928 const MAX_RESTARTS_CAP: SupervisorError = SupervisorError::max_restarts_exceeds_cap(1_337);
16929 const WINDOW_NC: SupervisorError =
16930 SupervisorError::restart_window_not_canonical(Duration::from_micros(1));
16931 const WINDOW_CAP: SupervisorError =
16932 SupervisorError::restart_window_exceeds_cap(Duration::from_secs(3_601));
16933 assert!(matches!(NO_CHILDREN, SupervisorError::NoChildren { .. }));
16934 assert!(matches!(
16935 MAX_RESTARTS_CAP,
16936 SupervisorError::MaxRestartsExceedsCap { .. }
16937 ));
16938 assert!(matches!(
16939 WINDOW_NC,
16940 SupervisorError::RestartWindowNotCanonical { .. }
16941 ));
16942 assert!(matches!(
16943 WINDOW_CAP,
16944 SupervisorError::RestartWindowExceedsCap { .. }
16945 ));
16946 }
16947
16948 #[test]
16949 fn restart_policy_try_from_vec_bytes_routes_through_borrowed_byte_view_axis() {
16950 // Fail-before-pass-after byte-parity pin on the newly lifted
16951 // `impl TryFrom<Vec<u8>> for RestartPolicy` — asserts the trait-
16952 // idiomatic owned-byte-vec reverse-projection standard-library
16953 // impl and the sibling borrowed-input [`TryFrom<&[u8]>`] axis
16954 // resolve to the same three-arm `PascalCase` wire accept-set
16955 // across every arm the exhaustive [`RestartPolicy::ALL`] slice
16956 // enumerates. Closes the substrate-wide trait-idiomatic byte-
16957 // owned reverse-projection axis on the M2-OTP-shape
16958 // `:supervisor :estrategia` + `:children :restart` slot pair the
16959 // sibling [`RestartStrategy`] first-mover
16960 // [`restart_strategy_try_from_vec_bytes_routes_through_borrowed_byte_view_axis`]
16961 // (34951fe) opened one commit-window prior — owned-input mirror
16962 // of the paired [`TryFrom<&[u8]>`] byte-view reverse-projection
16963 // axis on this same enum (d9ef5f0), and byte-owned reverse
16964 // companion of the pre-existing byte-owned *forward*-projection
16965 // pair ([`From<RestartPolicy> for Vec<u8>`],
16966 // [`From<&RestartPolicy> for Vec<u8>`]) on this same enum. Peer
16967 // of the sibling first-mover
16968 // [`crate::kind::tests::caixa_kind_try_from_vec_bytes_routes_through_borrowed_byte_view_axis`]
16969 // (99c2849) on the [`crate::CaixaKind`] closed-set typed-enum
16970 // peer, the sibling second-mover
16971 // [`crate::dialeto::tests::caixa_dialeto_try_from_vec_bytes_routes_through_borrowed_byte_view_axis`]
16972 // (83a1526) on the [`crate::CaixaDialeto`] peer, the sibling
16973 // third-mover
16974 // [`crate::dep::tests::dep_list_try_from_vec_bytes_routes_through_borrowed_byte_view_axis`]
16975 // (42091cb) on the [`crate::dep::DepList`] peer, and the sibling
16976 // fourth-mover
16977 // [`restart_strategy_try_from_vec_bytes_routes_through_borrowed_byte_view_axis`]
16978 // (34951fe) on the [`RestartStrategy`] peer — tracks the
16979 // "delegate through `TryFrom<&[u8]>` on the `Vec<u8>::as_slice`
16980 // borrow" discipline the first-mover established.
16981 //
16982 // Rust's standard library carries no blanket
16983 // `impl<T: for<'a> TryFrom<&'a [u8]>> TryFrom<Vec<u8>> for T`,
16984 // so an owned-byte-vec caller otherwise picks between an open-
16985 // coded `<T as TryFrom<&[u8]>>::try_from(bytes.as_slice())` at
16986 // every call site whose type bounds have no compile-time link
16987 // back to the byte-owned reverse-projection axis, or a
16988 // `String::from_utf8(bytes)` two-hop shape whose error surface
16989 // leaks the standard-library `FromUtf8Error` type. This impl
16990 // closes the byte-owned reverse-projection axis at the
16991 // substrate-primitive [`RestartPolicy::from_wire`] accessor so
16992 // every future `<T: TryFrom<Vec<u8>>>`-bound owned-byte-vec
16993 // consumer reaches the same three-arm `PascalCase` wire accept-
16994 // set through one trait dispatch.
16995 for &variant in RestartPolicy::ALL {
16996 let wire_bytes: Vec<u8> = variant.as_str().as_bytes().to_vec();
16997 assert_eq!(
16998 <RestartPolicy as TryFrom<Vec<u8>>>::try_from(wire_bytes.clone()),
16999 Ok(variant),
17000 "TryFrom<Vec<u8>> impl on RestartPolicy must round-trip \
17001 RestartPolicy::{variant:?}.as_str().as_bytes().to_vec() \
17002 back to Ok(RestartPolicy::{variant:?}) — divergence \
17003 from the sibling TryFrom<&[u8]> axis signals a silent \
17004 detour off the substrate-primitive from_wire accessor"
17005 );
17006 // Cross-axis witness: the owned-byte-vec reverse-projection
17007 // axis must agree with the borrowed byte-slice reverse-
17008 // projection axis on every accepted arm — the two axes share
17009 // one `PascalCase` wire vocabulary through the substrate-
17010 // primitive `from_wire` accessor, and the owned-input axis
17011 // delegates to the borrowed peer by design.
17012 let via_owned: Result<RestartPolicy, ()> =
17013 <RestartPolicy as TryFrom<Vec<u8>>>::try_from(wire_bytes.clone());
17014 let via_borrowed: Result<RestartPolicy, ()> =
17015 <RestartPolicy as TryFrom<&[u8]>>::try_from(wire_bytes.as_slice());
17016 assert_eq!(
17017 via_owned, via_borrowed,
17018 "TryFrom<Vec<u8>> and TryFrom<&[u8]> reverse-projection \
17019 axes on RestartPolicy must agree on \
17020 RestartPolicy::{variant:?} — divergence signals the \
17021 owned-input and borrowed-input byte-view reverse paths \
17022 have drifted off the same substrate-primitive \
17023 from_wire accessor"
17024 );
17025 // Cross-axis witness against the paired str-view reverse
17026 // axis ([`TryFrom<&str>`]) — the three reverse paths (str-
17027 // view, byte-view borrowed, byte-view owned) share one
17028 // substrate primitive.
17029 let via_str: Result<RestartPolicy, ()> =
17030 <RestartPolicy as TryFrom<&str>>::try_from(variant.as_str());
17031 assert_eq!(
17032 via_owned, via_str,
17033 "TryFrom<Vec<u8>> and TryFrom<&str> reverse-projection \
17034 axes on RestartPolicy must agree on \
17035 RestartPolicy::{variant:?} — divergence signals the \
17036 byte-owned and str-view reverse paths have drifted off \
17037 the same substrate-primitive from_wire accessor"
17038 );
17039 // Four-corner witness: because [`RestartPolicy`] carries
17040 // no wire-vs-diagnostic split (as_str and from_wire share
17041 // one `PascalCase` byte-vocabulary — like the sibling
17042 // [`RestartStrategy`] and unlike the sibling
17043 // [`crate::CaixaKind`] whose peer test deliberately declines
17044 // this witness), the byte-owned reverse-projection axis on
17045 // this enum *does* round-trip against the paired byte-owned
17046 // forward-projection pair. Pin every corner of the {owned-
17047 // input, borrowed-input} × {From<Self> → Vec<u8>,
17048 // From<&Self> → Vec<u8>} square onto the same Ok(variant)
17049 // return so a future accident that drops one corner off the
17050 // substrate-primitive accessor trips here.
17051 let owned_forward: Vec<u8> = <Vec<u8> as From<RestartPolicy>>::from(variant);
17052 let borrowed_forward: Vec<u8> = <Vec<u8> as From<&RestartPolicy>>::from(&variant);
17053 assert_eq!(
17054 owned_forward, wire_bytes,
17055 "From<RestartPolicy> for Vec<u8> forward projection on \
17056 RestartPolicy::{variant:?} must byte-equal \
17057 variant.as_str().as_bytes().to_vec() — divergence \
17058 signals the paired forward pair drifted off the \
17059 substrate-primitive as_str accessor"
17060 );
17061 assert_eq!(
17062 borrowed_forward, wire_bytes,
17063 "From<&RestartPolicy> for Vec<u8> forward projection \
17064 on &RestartPolicy::{variant:?} must byte-equal \
17065 variant.as_str().as_bytes().to_vec() — divergence \
17066 signals the paired forward pair drifted off the \
17067 substrate-primitive as_str accessor"
17068 );
17069 assert_eq!(
17070 <RestartPolicy as TryFrom<Vec<u8>>>::try_from(owned_forward.clone()),
17071 Ok(variant),
17072 "Four-corner round-trip on RestartPolicy::{variant:?} \
17073 through From<RestartPolicy> for Vec<u8> then \
17074 TryFrom<Vec<u8>> for RestartPolicy must return \
17075 Ok(variant) — divergence signals the byte-owned \
17076 forward pair and the byte-owned reverse axis have \
17077 drifted apart"
17078 );
17079 assert_eq!(
17080 <RestartPolicy as TryFrom<Vec<u8>>>::try_from(borrowed_forward),
17081 Ok(variant),
17082 "Four-corner round-trip on RestartPolicy::{variant:?} \
17083 through From<&RestartPolicy> for Vec<u8> then \
17084 TryFrom<Vec<u8>> for RestartPolicy must return \
17085 Ok(variant) — divergence signals the borrowed-input \
17086 forward corner and the owned-input reverse corner have \
17087 drifted apart"
17088 );
17089 }
17090 }
17091
17092 #[test]
17093 fn restart_policy_try_from_vec_bytes_rejects_unknown_and_non_utf8_bytes() {
17094 // Rejection witness on the `impl TryFrom<Vec<u8>> for
17095 // RestartPolicy` — sweeps the same two rejection paths the
17096 // sibling borrowed `TryFrom<&[u8]>` axis collapses onto the
17097 // single unit-error return: the invalid-UTF-8 rejection path
17098 // (`std::str::from_utf8` on the underlying byte-slice returns
17099 // `Err` before [`RestartPolicy::from_wire`] runs) and the
17100 // valid-UTF-8-but-unknown-wire rejection path
17101 // ([`RestartPolicy::from_wire`] returns `None` on a byte-
17102 // string outside the three-arm `PascalCase` accept-set). Both
17103 // must reject so a future accidental widening of the trait
17104 // impl's accept-set (a case-fold path, a silent acceptance of
17105 // the kebab-case dispatcher-catalog byte-strings on this axis —
17106 // which would collide the two-axis wire/catalog split the
17107 // sibling [`RestartPolicy::from_wire`] doc block makes load-
17108 // bearing — a `#[serde(rename_all = "…")]` attribute drift that
17109 // widens the parse arm-set silently, a stray
17110 // `String::from_utf8_lossy` detour that widens the input
17111 // surface with the U+FFFD replacement character, an
17112 // `Option::unwrap_or_default`-shape fallback that maps invalid
17113 // UTF-8 onto a default arm rather than the trait-idiomatic
17114 // `Err(())`) trips at caixa-core test time. Peer of the sibling
17115 // first-mover
17116 // [`crate::kind::tests::caixa_kind_try_from_vec_bytes_rejects_unknown_and_non_utf8_bytes`]
17117 // (99c2849) on the [`crate::CaixaKind`] peer, the sibling
17118 // second-mover
17119 // [`crate::dialeto::tests::caixa_dialeto_try_from_vec_bytes_rejects_unknown_and_non_utf8_bytes`]
17120 // (83a1526) on the [`crate::CaixaDialeto`] peer, the sibling
17121 // third-mover
17122 // [`crate::dep::tests::dep_list_try_from_vec_bytes_rejects_unknown_and_non_utf8_bytes`]
17123 // (42091cb) on the [`crate::dep::DepList`] peer, and the
17124 // sibling fourth-mover
17125 // [`restart_strategy_try_from_vec_bytes_rejects_unknown_and_non_utf8_bytes`]
17126 // (34951fe) on the [`RestartStrategy`] peer rejection
17127 // witnesses.
17128 let non_utf8_rejected: &[&[u8]] = &[
17129 &[0xFF],
17130 &[0x80],
17131 &[0xC3],
17132 &[0xFF, 0xFE],
17133 &[0xED, 0xA0, 0x80], // UTF-16 surrogate half — rejected by UTF-8
17134 ];
17135 for &input in non_utf8_rejected {
17136 let owned: Vec<u8> = input.to_vec();
17137 assert_eq!(
17138 <RestartPolicy as TryFrom<Vec<u8>>>::try_from(owned),
17139 Err(()),
17140 "TryFrom<Vec<u8>> impl on RestartPolicy must reject \
17141 the non-UTF-8 byte-sequence {input:?} with Err(()) — \
17142 silent acceptance signals the UTF-8 validation path \
17143 collapsed onto a default arm rather than the trait-\
17144 idiomatic unit-error"
17145 );
17146 // Cross-axis witness: the owned-input axis must agree with
17147 // the borrowed-input axis on every rejected input.
17148 assert_eq!(
17149 <RestartPolicy as TryFrom<Vec<u8>>>::try_from(input.to_vec()),
17150 <RestartPolicy as TryFrom<&[u8]>>::try_from(input),
17151 "TryFrom<Vec<u8>> and TryFrom<&[u8]> reverse-projection \
17152 axes on RestartPolicy must agree on the non-UTF-8 \
17153 input {input:?} — divergence signals the owned-input \
17154 and borrowed-input byte-view reverse paths have drifted \
17155 off the same substrate-primitive from_wire accessor"
17156 );
17157 }
17158 // Valid-UTF-8-but-unknown-wire candidates mirror the corpus the
17159 // sibling borrowed-input rejection witness
17160 // [`restart_policy_try_from_bytes_rejects_unknown_and_non_utf8_bytes`]
17161 // (d9ef5f0) already pins on the paired byte-view axis: the
17162 // empty byte-string, whitespace-only padding, the kebab-case
17163 // dispatcher-catalog byte-strings on the sibling axis the pre-
17164 // existing [`std::str::FromStr`] impl the
17165 // [`gen_platform::FromStrKind`] derive installs parses onto (a
17166 // caller who confuses the two axes trips here rather than at a
17167 // downstream K8s-CR round-trip miss), lowercase / uppercase /
17168 // mixed-case folds of each `PascalCase` arm, whitespace-padded /
17169 // trailing-newline / quote-wrapped forms, and plausible-but-
17170 // wrong English rebrand candidates (`Ephemeral`, `Always`,
17171 // `Never`, `OnAbnormalExit`, `intrinsic`).
17172 let unknown_wire_rejected: &[&[u8]] = &[
17173 b"",
17174 b" ",
17175 b"\n",
17176 b"\t",
17177 b"permanent",
17178 b"temporary",
17179 b"transient",
17180 b"PERMANENT",
17181 b"TEMPORARY",
17182 b"TRANSIENT",
17183 b"Permanents",
17184 b"Permanent ",
17185 b" Permanent",
17186 b" Temporary ",
17187 b"Permanent\n",
17188 b"Transient\t",
17189 b"\"Permanent\"",
17190 b"Ephemeral",
17191 b"Always",
17192 b"Never",
17193 b"OnAbnormalExit",
17194 b"intrinsic",
17195 b"?",
17196 ];
17197 for &input in unknown_wire_rejected {
17198 let owned: Vec<u8> = input.to_vec();
17199 assert_eq!(
17200 <RestartPolicy as TryFrom<Vec<u8>>>::try_from(owned),
17201 Err(()),
17202 "TryFrom<Vec<u8>> impl on RestartPolicy must reject \
17203 the valid-UTF-8-but-unknown-wire byte-string {input:?} \
17204 with Err(()) — silent acceptance signals an accept-\
17205 set widening off the paired RestartPolicy::from_wire \
17206 resolver"
17207 );
17208 // Cross-axis witness against the borrowed byte-view axis:
17209 // the two paths must agree by construction, since the owned
17210 // axis delegates to the borrowed peer.
17211 assert_eq!(
17212 <RestartPolicy as TryFrom<Vec<u8>>>::try_from(input.to_vec()),
17213 <RestartPolicy as TryFrom<&[u8]>>::try_from(input),
17214 "TryFrom<Vec<u8>> and TryFrom<&[u8]> reverse-projection \
17215 axes on RestartPolicy must agree on the valid-UTF-8-\
17216 but-unknown-wire input {input:?} — divergence signals \
17217 the owned-input and borrowed-input byte-view reverse \
17218 paths have drifted off the same substrate-primitive \
17219 from_wire accessor"
17220 );
17221 }
17222 }
17223
17224 #[test]
17225 fn restart_strategy_try_from_owned_string_routes_through_borrowed_str_view_axis() {
17226 // Fail-before-pass-after byte-parity pin on the newly lifted
17227 // `impl TryFrom<String> for RestartStrategy` — asserts the
17228 // trait-idiomatic string-owned reverse-projection standard-
17229 // library impl and the sibling borrowed-input [`TryFrom<&str>`]
17230 // axis resolve to the same four-arm `PascalCase` wire accept-set
17231 // across every arm the exhaustive [`RestartStrategy::ALL`] slice
17232 // enumerates. Extends the substrate-wide trait-idiomatic string-
17233 // owned reverse-projection axis onto the first M2-OTP-shape
17234 // supervisor-slot closed-set fieldless typed-enum peer — owned-
17235 // input mirror of the paired [`TryFrom<&str>`] str-view reverse-
17236 // projection axis, and string-owned reverse companion of the
17237 // pre-existing string-owned *forward*-projection pair
17238 // ([`From<RestartStrategy> for String`],
17239 // [`From<&RestartStrategy> for String`]) on this same enum. Peer
17240 // of the sibling opener
17241 // [`crate::aplicacao::tests::rate_limit_try_from_owned_string_routes_through_borrowed_str_view_axis`]
17242 // (a2e6f02) on the compound [`crate::aplicacao::RateLimit`]
17243 // primitive, the sibling first-mover
17244 // [`crate::aplicacao::tests::wit_shape_try_from_owned_string_routes_through_borrowed_str_view_axis`]
17245 // (e6aac29) on the [`crate::aplicacao::WitShape`] closed-set peer,
17246 // the sibling second-mover
17247 // [`crate::aplicacao::tests::rate_limit_unit_try_from_owned_string_routes_through_borrowed_str_view_axis`]
17248 // (94a9c5e) on the [`crate::aplicacao::RateLimitUnit`] peer, and
17249 // the sibling third-mover
17250 // [`crate::aplicacao::tests::placement_strategy_try_from_owned_string_routes_through_borrowed_str_view_axis`]
17251 // (d81a70a) on the [`crate::aplicacao::PlacementStrategy`] peer —
17252 // tracks the "delegate through `TryFrom<&str>` on the
17253 // `String::as_str` borrow" discipline the compound-primitive
17254 // opener and closed-set-peer first-mover established.
17255 //
17256 // Rust's standard library carries no blanket
17257 // `impl<T: for<'a> TryFrom<&'a str>> TryFrom<String> for T`, so
17258 // an owned-`String` caller otherwise picks between an open-coded
17259 // `<T as TryFrom<&str>>::try_from(s.as_str())` at every call
17260 // site (whose type bounds have no compile-time link back to the
17261 // string-owned reverse-projection axis) or a `let s: &str = &s;
17262 // T::try_from(s)` two-step whose borrow arithmetic leaks a per-
17263 // call-site lifetime dance. This impl closes the string-owned
17264 // reverse-projection axis at the substrate-primitive
17265 // [`RestartStrategy::from_wire`] accessor so every future
17266 // `<T: TryFrom<String>>`-bound owned-string consumer reaches the
17267 // same four-arm `PascalCase` accept-set through one trait
17268 // dispatch.
17269 for &variant in RestartStrategy::ALL {
17270 let wire_string: String = variant.as_str().to_string();
17271 assert_eq!(
17272 <RestartStrategy as TryFrom<String>>::try_from(wire_string.clone()),
17273 Ok(variant),
17274 "TryFrom<String> impl on RestartStrategy must round-trip \
17275 RestartStrategy::{variant:?}.as_str().to_string() back \
17276 to Ok(RestartStrategy::{variant:?}) — divergence from \
17277 the sibling TryFrom<&str> axis signals a silent detour \
17278 off the substrate-primitive from_wire accessor"
17279 );
17280 // Cross-axis witness: the string-owned reverse-projection
17281 // axis must agree with the borrowed `&str` reverse-projection
17282 // axis on every accepted arm — the two axes share one
17283 // `PascalCase` wire vocabulary through the substrate-primitive
17284 // `from_wire` accessor, and the owned-input axis delegates to
17285 // the borrowed peer by design.
17286 let via_owned: Result<RestartStrategy, ()> =
17287 <RestartStrategy as TryFrom<String>>::try_from(wire_string.clone());
17288 let via_borrowed: Result<RestartStrategy, ()> =
17289 <RestartStrategy as TryFrom<&str>>::try_from(wire_string.as_str());
17290 assert_eq!(
17291 via_owned, via_borrowed,
17292 "TryFrom<String> and TryFrom<&str> reverse-projection \
17293 axes on RestartStrategy must agree on \
17294 RestartStrategy::{variant:?} — divergence signals the \
17295 owned-`String` and borrowed-`&str` reverse paths have \
17296 drifted off the same substrate-primitive from_wire \
17297 accessor"
17298 );
17299 // Cross-axis witness against the paired byte-view and byte-
17300 // owned reverse axes — the four reverse paths (str-view
17301 // borrowed, string-owned, byte-view borrowed, byte-owned)
17302 // share one substrate primitive.
17303 let via_bytes_borrowed: Result<RestartStrategy, ()> =
17304 <RestartStrategy as TryFrom<&[u8]>>::try_from(wire_string.as_bytes());
17305 let via_bytes_owned: Result<RestartStrategy, ()> =
17306 <RestartStrategy as TryFrom<Vec<u8>>>::try_from(wire_string.as_bytes().to_vec());
17307 assert_eq!(
17308 via_owned, via_bytes_borrowed,
17309 "TryFrom<String> and TryFrom<&[u8]> reverse-projection \
17310 axes on RestartStrategy must agree on \
17311 RestartStrategy::{variant:?} — divergence signals the \
17312 string-owned and byte-view reverse paths have drifted \
17313 off the same substrate-primitive from_wire accessor"
17314 );
17315 assert_eq!(
17316 via_owned, via_bytes_owned,
17317 "TryFrom<String> and TryFrom<Vec<u8>> reverse-projection \
17318 axes on RestartStrategy must agree on \
17319 RestartStrategy::{variant:?} — divergence signals the \
17320 string-owned and byte-owned reverse paths have drifted \
17321 off the same substrate-primitive from_wire accessor"
17322 );
17323 // Closed-cycle witness against the paired string-owned
17324 // forward-projection pair: `Self → String → TryFrom<String>
17325 // → Self` round-trips to the originating arm on every
17326 // canonical `PascalCase` scalar. Both the owned-input
17327 // `From<RestartStrategy> for String` and the borrowed-input
17328 // `From<&RestartStrategy> for String` corners must feed back
17329 // through the new impl to `Ok(variant)`.
17330 let owned_forward: String = <String as From<RestartStrategy>>::from(variant);
17331 let borrowed_forward: String = <String as From<&RestartStrategy>>::from(&variant);
17332 assert_eq!(
17333 owned_forward, wire_string,
17334 "From<RestartStrategy> for String forward projection on \
17335 RestartStrategy::{variant:?} must byte-equal \
17336 variant.as_str().to_string() — divergence signals the \
17337 paired forward pair drifted off the substrate-primitive \
17338 as_str accessor"
17339 );
17340 assert_eq!(
17341 borrowed_forward, wire_string,
17342 "From<&RestartStrategy> for String forward projection on \
17343 &RestartStrategy::{variant:?} must byte-equal \
17344 variant.as_str().to_string() — divergence signals the \
17345 paired forward pair drifted off the substrate-primitive \
17346 as_str accessor"
17347 );
17348 assert_eq!(
17349 <RestartStrategy as TryFrom<String>>::try_from(owned_forward.clone()),
17350 Ok(variant),
17351 "Closed-cycle round-trip on RestartStrategy::{variant:?} \
17352 through From<RestartStrategy> for String then \
17353 TryFrom<String> for RestartStrategy must return \
17354 Ok(variant) — divergence signals the string-owned \
17355 forward pair and the string-owned reverse axis have \
17356 drifted apart"
17357 );
17358 assert_eq!(
17359 <RestartStrategy as TryFrom<String>>::try_from(borrowed_forward),
17360 Ok(variant),
17361 "Closed-cycle round-trip on RestartStrategy::{variant:?} \
17362 through From<&RestartStrategy> for String then \
17363 TryFrom<String> for RestartStrategy must return \
17364 Ok(variant) — divergence signals the borrowed-input \
17365 forward corner and the owned-input string reverse \
17366 corner have drifted apart"
17367 );
17368 }
17369 }
17370
17371 #[test]
17372 fn restart_strategy_try_from_owned_string_rejects_unknown_wire_strings() {
17373 // Rejection witness on the `impl TryFrom<String> for
17374 // RestartStrategy` — sweeps the corpus of valid-UTF-8-but-
17375 // unknown-wire byte-strings the sibling borrowed [`TryFrom<&str>`]
17376 // axis already rejects and asserts every one lands on `Err(())`,
17377 // so a future accidental widening of the trait impl's accept-set
17378 // (a case-fold path, a silent inclusion of the kebab-case
17379 // dispatcher-catalog byte-strings on the sibling axis that would
17380 // collide the two-axis wire/catalog split the sibling
17381 // [`RestartStrategy::from_wire`] doc block makes load-bearing, a
17382 // stray fallback that maps whitespace-padded canonical scalars
17383 // onto their unpadded arm rather than the trait-idiomatic
17384 // `Err(())`) trips at caixa-core test time. Peer of the sibling
17385 // borrowed-input rejection witness
17386 // [`restart_strategy_try_from_str_rejects_unknown_byte_strings`]
17387 // on the same enum, and the sibling byte-view / byte-owned
17388 // rejection witnesses
17389 // [`restart_strategy_try_from_bytes_rejects_unknown_and_non_utf8_bytes`]
17390 // (c699a83) /
17391 // [`restart_strategy_try_from_vec_bytes_rejects_unknown_and_non_utf8_bytes`]
17392 // (34951fe) on the same enum.
17393 let unknown_wire_rejected: &[&str] = &[
17394 "",
17395 " ",
17396 "\n",
17397 "\t",
17398 "one-for-one",
17399 "one-for-all",
17400 "rest-for-one",
17401 "simple-one-for-one",
17402 "oneforone",
17403 "one_for_one",
17404 "OneForOnes",
17405 "ONEFORONE",
17406 "oneforall",
17407 "restforone",
17408 "simpleoneforone",
17409 "OneForOne ",
17410 " OneForOne",
17411 " OneForAll ",
17412 "OneForOne\n",
17413 "RestForOne\t",
17414 "OneForEach",
17415 "AllForOne",
17416 "one for one",
17417 "\"OneForOne\"",
17418 "?",
17419 ];
17420 for &input in unknown_wire_rejected {
17421 let owned: String = input.to_string();
17422 assert_eq!(
17423 <RestartStrategy as TryFrom<String>>::try_from(owned),
17424 Err(()),
17425 "TryFrom<String> impl on RestartStrategy must reject the \
17426 valid-UTF-8-but-unknown-wire byte-string {input:?} with \
17427 Err(()) — silent acceptance signals an accept-set \
17428 widening off the paired RestartStrategy::from_wire \
17429 resolver"
17430 );
17431 // Cross-axis witness against the borrowed str-view axis:
17432 // the two paths must agree by construction, since the owned
17433 // axis delegates to the borrowed peer.
17434 assert_eq!(
17435 <RestartStrategy as TryFrom<String>>::try_from(input.to_string()),
17436 <RestartStrategy as TryFrom<&str>>::try_from(input),
17437 "TryFrom<String> and TryFrom<&str> reverse-projection \
17438 axes on RestartStrategy must agree on the valid-UTF-8-\
17439 but-unknown-wire input {input:?} — divergence signals \
17440 the owned-`String` and borrowed-`&str` reverse paths \
17441 have drifted off the same substrate-primitive from_wire \
17442 accessor"
17443 );
17444 }
17445 }
17446
17447 #[test]
17448 fn restart_policy_try_from_owned_string_routes_through_borrowed_str_view_axis() {
17449 // Fail-before-pass-after byte-parity pin on the newly lifted
17450 // `impl TryFrom<String> for RestartPolicy` — asserts the trait-
17451 // idiomatic string-owned reverse-projection standard-library impl
17452 // and the sibling borrowed-input [`TryFrom<&str>`] axis resolve
17453 // to the same three-arm `PascalCase` wire accept-set across every
17454 // arm the exhaustive [`RestartPolicy::ALL`] slice enumerates.
17455 // Extends the substrate-wide trait-idiomatic string-owned reverse-
17456 // projection axis onto the second (and final) M2-OTP-shape
17457 // supervisor-slot closed-set fieldless typed-enum peer — owned-
17458 // input mirror of the paired [`TryFrom<&str>`] str-view reverse-
17459 // projection axis, and string-owned reverse companion of the
17460 // pre-existing string-owned *forward*-projection pair
17461 // ([`From<RestartPolicy> for String`],
17462 // [`From<&RestartPolicy> for String`]) on this same enum. Peer
17463 // of the sibling first-mover
17464 // [`crate::aplicacao::tests::rate_limit_try_from_owned_string_routes_through_borrowed_str_view_axis`]
17465 // (a2e6f02) on the compound [`crate::aplicacao::RateLimit`]
17466 // primitive, and the sibling
17467 // [`restart_strategy_try_from_owned_string_routes_through_borrowed_str_view_axis`]
17468 // (78fe8c8) on the sibling first M2-OTP-shape supervisor-slot
17469 // [`RestartStrategy`] peer — tracks the "delegate through
17470 // `TryFrom<&str>` on the `String::as_str` borrow" discipline the
17471 // compound-primitive opener and closed-set-peer first-mover
17472 // established. This closes the string-owned reverse-projection
17473 // axis on the M2-OTP-shape `:supervisor :estrategia` +
17474 // `:children :restart` slot pair.
17475 for &variant in RestartPolicy::ALL {
17476 let wire_string: String = variant.as_str().to_string();
17477 assert_eq!(
17478 <RestartPolicy as TryFrom<String>>::try_from(wire_string.clone()),
17479 Ok(variant),
17480 "TryFrom<String> impl on RestartPolicy must round-trip \
17481 RestartPolicy::{variant:?}.as_str().to_string() back \
17482 to Ok(RestartPolicy::{variant:?}) — divergence from \
17483 the sibling TryFrom<&str> axis signals a silent detour \
17484 off the substrate-primitive from_wire accessor"
17485 );
17486 // Cross-axis witness: the string-owned reverse-projection
17487 // axis must agree with the borrowed `&str` reverse-projection
17488 // axis on every accepted arm — the two axes share one
17489 // `PascalCase` wire vocabulary through the substrate-
17490 // primitive `from_wire` accessor, and the owned-input axis
17491 // delegates to the borrowed peer by design.
17492 let via_owned: Result<RestartPolicy, ()> =
17493 <RestartPolicy as TryFrom<String>>::try_from(wire_string.clone());
17494 let via_borrowed: Result<RestartPolicy, ()> =
17495 <RestartPolicy as TryFrom<&str>>::try_from(wire_string.as_str());
17496 assert_eq!(
17497 via_owned, via_borrowed,
17498 "TryFrom<String> and TryFrom<&str> reverse-projection \
17499 axes on RestartPolicy must agree on \
17500 RestartPolicy::{variant:?} — divergence signals the \
17501 owned-`String` and borrowed-`&str` reverse paths have \
17502 drifted off the same substrate-primitive from_wire \
17503 accessor"
17504 );
17505 // Cross-axis witness against the paired byte-view and byte-
17506 // owned reverse axes — the four reverse paths (str-view
17507 // borrowed, string-owned, byte-view borrowed, byte-owned)
17508 // share one substrate primitive.
17509 let via_bytes_borrowed: Result<RestartPolicy, ()> =
17510 <RestartPolicy as TryFrom<&[u8]>>::try_from(wire_string.as_bytes());
17511 let via_bytes_owned: Result<RestartPolicy, ()> =
17512 <RestartPolicy as TryFrom<Vec<u8>>>::try_from(wire_string.as_bytes().to_vec());
17513 assert_eq!(
17514 via_owned, via_bytes_borrowed,
17515 "TryFrom<String> and TryFrom<&[u8]> reverse-projection \
17516 axes on RestartPolicy must agree on \
17517 RestartPolicy::{variant:?} — divergence signals the \
17518 string-owned and byte-view reverse paths have drifted \
17519 off the same substrate-primitive from_wire accessor"
17520 );
17521 assert_eq!(
17522 via_owned, via_bytes_owned,
17523 "TryFrom<String> and TryFrom<Vec<u8>> reverse-projection \
17524 axes on RestartPolicy must agree on \
17525 RestartPolicy::{variant:?} — divergence signals the \
17526 string-owned and byte-owned reverse paths have drifted \
17527 off the same substrate-primitive from_wire accessor"
17528 );
17529 // Closed-cycle witness against the paired string-owned
17530 // forward-projection pair: `Self → String → TryFrom<String>
17531 // → Self` round-trips to the originating arm on every
17532 // canonical `PascalCase` scalar. Both the owned-input
17533 // `From<RestartPolicy> for String` and the borrowed-input
17534 // `From<&RestartPolicy> for String` corners must feed back
17535 // through the new impl to `Ok(variant)`.
17536 let owned_forward: String = <String as From<RestartPolicy>>::from(variant);
17537 let borrowed_forward: String = <String as From<&RestartPolicy>>::from(&variant);
17538 assert_eq!(
17539 owned_forward, wire_string,
17540 "From<RestartPolicy> for String forward projection on \
17541 RestartPolicy::{variant:?} must byte-equal \
17542 variant.as_str().to_string() — divergence signals the \
17543 paired forward pair drifted off the substrate-primitive \
17544 as_str accessor"
17545 );
17546 assert_eq!(
17547 borrowed_forward, wire_string,
17548 "From<&RestartPolicy> for String forward projection on \
17549 &RestartPolicy::{variant:?} must byte-equal \
17550 variant.as_str().to_string() — divergence signals the \
17551 paired forward pair drifted off the substrate-primitive \
17552 as_str accessor"
17553 );
17554 assert_eq!(
17555 <RestartPolicy as TryFrom<String>>::try_from(owned_forward.clone()),
17556 Ok(variant),
17557 "Closed-cycle round-trip on RestartPolicy::{variant:?} \
17558 through From<RestartPolicy> for String then \
17559 TryFrom<String> for RestartPolicy must return \
17560 Ok(variant) — divergence signals the string-owned \
17561 forward pair and the string-owned reverse axis have \
17562 drifted apart"
17563 );
17564 assert_eq!(
17565 <RestartPolicy as TryFrom<String>>::try_from(borrowed_forward),
17566 Ok(variant),
17567 "Closed-cycle round-trip on RestartPolicy::{variant:?} \
17568 through From<&RestartPolicy> for String then \
17569 TryFrom<String> for RestartPolicy must return \
17570 Ok(variant) — divergence signals the borrowed-input \
17571 forward corner and the owned-input string reverse \
17572 corner have drifted apart"
17573 );
17574 }
17575 }
17576
17577 #[test]
17578 fn restart_policy_try_from_owned_string_rejects_unknown_wire_strings() {
17579 // Rejection witness on the `impl TryFrom<String> for
17580 // RestartPolicy` — sweeps the corpus of valid-UTF-8-but-
17581 // unknown-wire byte-strings the sibling borrowed [`TryFrom<&str>`]
17582 // axis already rejects and asserts every one lands on `Err(())`,
17583 // so a future accidental widening of the trait impl's accept-set
17584 // (a case-fold path, a silent inclusion of the kebab-case
17585 // dispatcher-catalog byte-strings on the sibling axis that would
17586 // collide the two-axis wire/catalog split the sibling
17587 // [`RestartPolicy::from_wire`] doc block makes load-bearing, a
17588 // stray fallback that maps whitespace-padded canonical scalars
17589 // onto their unpadded arm rather than the trait-idiomatic
17590 // `Err(())`) trips at caixa-core test time. Peer of the sibling
17591 // borrowed-input rejection witness
17592 // [`restart_policy_try_from_str_rejects_unknown_byte_strings`]
17593 // on the same enum, and the sibling byte-view / byte-owned
17594 // rejection witnesses
17595 // [`restart_policy_try_from_bytes_rejects_unknown_and_non_utf8_bytes`]
17596 // (d9ef5f0) /
17597 // [`restart_policy_try_from_vec_bytes_rejects_unknown_and_non_utf8_bytes`]
17598 // (7592085) on the same enum.
17599 let unknown_wire_rejected: &[&str] = &[
17600 "",
17601 " ",
17602 "\n",
17603 "\t",
17604 "permanent",
17605 "temporary",
17606 "transient",
17607 "PERMANENT",
17608 "TEMPORARY",
17609 "TRANSIENT",
17610 "Permanents",
17611 "Permanent ",
17612 " Permanent",
17613 " Temporary ",
17614 "Permanent\n",
17615 "Transient\t",
17616 "\"Permanent\"",
17617 "Ephemeral",
17618 "Always",
17619 "Never",
17620 "OnAbnormalExit",
17621 "intrinsic",
17622 "?",
17623 ];
17624 for &input in unknown_wire_rejected {
17625 let owned: String = input.to_string();
17626 assert_eq!(
17627 <RestartPolicy as TryFrom<String>>::try_from(owned),
17628 Err(()),
17629 "TryFrom<String> impl on RestartPolicy must reject the \
17630 valid-UTF-8-but-unknown-wire byte-string {input:?} with \
17631 Err(()) — silent acceptance signals an accept-set \
17632 widening off the paired RestartPolicy::from_wire \
17633 resolver"
17634 );
17635 // Cross-axis witness against the borrowed str-view axis:
17636 // the two paths must agree by construction, since the owned
17637 // axis delegates to the borrowed peer.
17638 assert_eq!(
17639 <RestartPolicy as TryFrom<String>>::try_from(input.to_string()),
17640 <RestartPolicy as TryFrom<&str>>::try_from(input),
17641 "TryFrom<String> and TryFrom<&str> reverse-projection \
17642 axes on RestartPolicy must agree on the valid-UTF-8-\
17643 but-unknown-wire input {input:?} — divergence signals \
17644 the owned-`String` and borrowed-`&str` reverse paths \
17645 have drifted off the same substrate-primitive from_wire \
17646 accessor"
17647 );
17648 }
17649 }
17650}