Skip to main content

caixa_core/
dialeto.rs

1//! `defcaixa` is spoken by two unrelated declarations. This module makes that
2//! a **typed fact** instead of an anonymous parse failure.
3//!
4//! # The finding
5//!
6//! Measured 2026-07-31 over the pleme-io org checkout (270 `caixa.lisp` /
7//! `*.caixa.lisp` files found with `rg --no-ignore`; a bare `rg` from the org
8//! root returns 0, which is how this stayed invisible), the corpus splits into
9//! two schemas that share zero required slots:
10//!
11//! * [`CaixaDialeto::Pacote`] — this crate's [`crate::Caixa`]. `:nome
12//!   :versao :kind :deps :bibliotecas :exe :servicos` + the supervisor/mesh
13//!   slots. It declares a **tatara-lisp package**: the thing `feira` resolves,
14//!   builds, links and publishes.
15//! * [`CaixaDialeto::Molde`] — `:name :kind :ecosystem :package {…} :workflows
16//!   […] :ci-config {…} :files […]`. It declares a **repo's generated
17//!   surface**: which foreign ecosystem (rust / go / python / …), that
18//!   ecosystem's own package metadata, the CI shims to emit, and byte-captured
19//!   file bodies. Read by `pleme-doc-gen`, never by `feira`.
20//!
21//! `:package`, `:ecosystem`, `:supports` and `:profile` have no counterpart in
22//! [`crate::Caixa`] at all — the theory doc's own D4 note records the same
23//! thing: those manifests "are authored against a schema that does not exist in
24//! Rust". They are not two spellings of one declaration. They are two domains
25//! that collided on one word, because *caixa* names a box and both are boxes.
26//!
27//! # Why this is not a bug report about broken files
28//!
29//! The Molde-dialect files are not malformed. They are correct inputs to their
30//! own consumer, and nothing in the shipped `feira` reads them, so nothing is
31//! failing today. The hazard is **latent and certain**: any new declarative
32//! surface written against "a `.caixa.lisp` is a [`crate::Caixa`]" meets a
33//! corpus where that is false for the large majority of files, and gets a flat
34//! unknown-keyword rejection that reads as "this manifest is broken" rather
35//! than "this manifest is not yours".
36//!
37//! # What this module does about it
38//!
39//! [`classify`] is total: every `(defcaixa …)` form lands in exactly one
40//! [`CaixaDialeto`], including [`CaixaDialeto::Desconhecido`] for one that
41//! matches neither. [`crate::Caixa::from_lisp`] runs it first, so a foreign
42//! dialect is [`crate::ManifestError::DialetoEstrangeiro`] — an error that
43//! names the dialect it found and the consumer that speaks it — rather than an
44//! unknown-kwarg error indistinguishable from a typo.
45//!
46//! Tier-honest: this is **parse-time rejection with a named cause**, not
47//! unrepresentability. A caller that ignores the `Err` still gets nothing
48//! useful; what it can no longer do is mistake "wrong dialect" for "bad file".
49
50use tatara_lisp::{Atom, Sexp};
51
52/// Which `(defcaixa …)` declaration a source speaks.
53///
54/// The [`gen_platform::IsVariant`] derive emits per-arm arm-discriminator
55/// predicates (`is_pacote` / `is_molde` / `is_molde_posicional` /
56/// `is_desconhecido`) as substrate-side typed dispatches on the closed
57/// four-arm dialect-classification discriminator. Peer of the sibling
58/// closed-set fieldless typed enums' [`crate::CaixaKind`] /
59/// [`crate::supervisor::RestartStrategy`] /
60/// [`crate::supervisor::RestartPolicy`] /
61/// [`crate::aplicacao::PlacementStrategy`] /
62/// [`crate::aplicacao::RateLimitUnit`] /
63/// [`crate::dep::DepList`] `IsVariant` derives on the sibling
64/// closed-set typed-enum discriminator axes.
65///
66/// The pre-lift `is_molde_family` predicate hand-rolled its own
67/// `matches!(self, Self::Molde | Self::MoldePosicional)` two-arm literal
68/// with no compile-time link back to the closed set — post-lift it routes
69/// through `self.is_molde() || self.is_molde_posicional()` so a future
70/// arm rename (e.g. `Molde → MoldeKW` under an M4 vocabulary shift) trips
71/// exhaustively at every derive-generated predicate site rather than
72/// leaving the hand-rolled `matches!` silently drifting.
73#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, gen_platform::IsVariant)]
74pub enum CaixaDialeto {
75    /// This crate's [`crate::Caixa`] — a tatara-lisp package manifest.
76    /// Keyword-argument form headed by `:nome`.
77    Pacote,
78    /// `pleme-doc-gen`'s repo-surface declaration, keyword-argument form
79    /// headed by `:name` (plus `:ecosystem` / `:package`).
80    Molde,
81    /// The same declaration as [`Self::Molde`], written with the package name
82    /// as a bare positional symbol — `(defcaixa todoku-go :kind :Biblioteca
83    /// :ecosystem :go …)`. `pleme-doc-gen`'s parser reads the first token
84    /// after the head as the name, so this is one arity of one declaration,
85    /// not a third schema.
86    MoldePosicional,
87    /// A `(defcaixa …)` form matching neither. Kept as a variant rather than
88    /// an error so [`classify`] is total and a census can COUNT the residue —
89    /// a classifier that threw here would report "0 unknown" by construction.
90    Desconhecido,
91}
92
93impl CaixaDialeto {
94    /// Exhaustive iteration surface for every consumer that walks the
95    /// closed four-arm [`CaixaDialeto`] discriminator set — the
96    /// [`feira dialeto`](../../caixa_feira/cmd/dialeto/index.html)
97    /// census counter's per-arm accept-set, a future
98    /// `feira dialeto --list-dialects` CLI listing of the accepted
99    /// classifications, a future M4 `mesh.pleme.io/v1alpha1/Manifesto`
100    /// CR materializer's admission-webhook rejection body naming the
101    /// accepted-dialect set, any future census-report shape probe that
102    /// sweeps every arm to compute per-arm coverage. A future arm
103    /// addition (a fifth dialect the [`crate::dialeto`] module doc's
104    /// "third dialect" hazard actualises — the module explicitly frames
105    /// its purpose as "what stops a third dialect appearing", and this
106    /// slice is the substrate-side answer: the arm-set is one edit and
107    /// every consumer picks up the new entry by construction) extends
108    /// this slice as one edit and every downstream consumer picks up
109    /// the new entry through the shared iteration; the compiler-checked
110    /// exhaustiveness on the sibling method `match` arms
111    /// ([`Self::palavra_canonica`] / [`Self::consumidor`] /
112    /// [`Self::descricao`] / [`std::fmt::Display`]) is the build-time
113    /// guarantee that no arm forgets to grow.
114    ///
115    /// Peer of the sibling closed-set typed enums'
116    /// [`crate::CaixaKind::ALL`] (6b1f4fb) /
117    /// [`crate::aplicacao::PlacementStrategy::ALL`] (18c7342) /
118    /// [`crate::aplicacao::RateLimitUnit::ALL`] (6bce03d) /
119    /// [`crate::dep::DepList::ALL`] (45ee563) /
120    /// [`crate::supervisor::RestartStrategy::ALL`] (4eec29c) /
121    /// [`crate::supervisor::RestartPolicy::ALL`] (dd32ccf)
122    /// exhaustive-iteration surfaces — the seventh closed-set typed
123    /// enum on the caixa surface to converge onto the same
124    /// one-canonical-arm-list-per-enum discipline, and the first
125    /// dialect-classification axis (as distinct from an OTP-shape M2
126    /// slot or an M3 mesh slot) to reach it. Order matches variant
127    /// declaration order verbatim (`Pacote` → `Molde` →
128    /// `MoldePosicional` → `Desconhecido`) so the slice is the
129    /// canonical ordering every listing / rendering consumer defers to.
130    pub const ALL: &'static [Self] = &[
131        Self::Pacote,
132        Self::Molde,
133        Self::MoldePosicional,
134        Self::Desconhecido,
135    ];
136
137    /// Substrate-canonical `PascalCase` variant-name byte-string every consumer
138    /// that formats the dialect as census-facing text lands on. Returns the
139    /// per-arm `PascalCase` name of the variant (`"Pacote"` / `"Molde"` /
140    /// `"MoldePosicional"` / `"Desconhecido"`) — the one canonical
141    /// byte-string the paired [`std::fmt::Display`] impl routes through so
142    /// every downstream consumer (the `feira dialeto` census counter output
143    /// line, a future `feira dialeto --list-dialects` CLI enumeration, a
144    /// future M4 `mesh.pleme.io/v1alpha1/Manifesto` CR materializer's
145    /// admission-webhook rejection body naming the accepted-dialect set)
146    /// reaches for the same substrate primitive rather than the pre-lift
147    /// hand-rolled four-arm literal-string match every [`std::fmt::Display`]
148    /// call previously routed through in place.
149    ///
150    /// Peer of the sibling closed-set typed enums'
151    /// [`crate::CaixaKind::as_str`] / [`crate::supervisor::RestartStrategy::as_str`]
152    /// / [`crate::supervisor::RestartPolicy::as_str`] /
153    /// [`crate::aplicacao::PlacementStrategy::as_str`] /
154    /// [`crate::dep::DepList::as_str`] projections on the sibling closed-set
155    /// typed-enum discriminator axes — the seventh (and last unlifted)
156    /// closed-set fieldless typed enum on the caixa surface to converge
157    /// onto the same one-canonical-byte-string-per-arm-through-`as_str`
158    /// discipline the six siblings already carry. Unlike [`crate::CaixaKind`]
159    /// (which carries two axes: `as_str` returning lowercase Portuguese
160    /// diagnostic form vs `wire_name` returning `PascalCase` tatara-lisp
161    /// author-surface bytes), [`CaixaDialeto`] is an internal
162    /// classification with no wire surface — the `PascalCase` variant name
163    /// is the census-facing form every consumer reads, so `as_str`
164    /// suffices without a paired `wire_name` axis.
165    #[must_use]
166    pub const fn as_str(self) -> &'static str {
167        match self {
168            Self::Pacote => "Pacote",
169            Self::Molde => "Molde",
170            Self::MoldePosicional => "MoldePosicional",
171            Self::Desconhecido => "Desconhecido",
172        }
173    }
174
175    /// Substrate-canonical reverse projection on the [`CaixaDialeto`]
176    /// closed-set dialect-classification axis — parses the `PascalCase`
177    /// variant-name byte-string back to the typed variant, or `None` when
178    /// `s` is outside the closed-set arm-string set [`Self::as_str`]
179    /// emits. Walks the same four `"Pacote"` / `"Molde"` /
180    /// `"MoldePosicional"` / `"Desconhecido"` byte-strings the sibling
181    /// [`Self::as_str`] emitter returns, so the parse and emit halves of
182    /// the round-trip migrate through one caixa-core edit on any future
183    /// arm addition (the module doc's "third dialect" hazard actualising
184    /// as a fifth arm) — the compiler-checked exhaustiveness on
185    /// [`Self::as_str`]'s `match self` arms and the round-trip pin
186    /// [`tests::caixa_dialeto_round_trips_through_as_str_and_from_wire`]
187    /// together lock the two halves mutually.
188    ///
189    /// Prior to this lift the substrate carried only the forward
190    /// `Self → &str` projection on the dialect-classification axis (the
191    /// [`Self::as_str`] emitter, the [`std::fmt::Display`] impl routed
192    /// through it, the [`AsRef<str>`] impl routed through it) — every
193    /// future consumer that wanted to promote the census-facing text back
194    /// to the typed enum (a future `feira dialeto --filter
195    /// <Pacote|Molde|MoldePosicional|Desconhecido>` CLI arg-parse that
196    /// binds the wire form into the typed enum before dispatching to the
197    /// per-arm counter, a future M4 `mesh.pleme.io/v1alpha1/Manifesto`
198    /// CR materializer's admission-time re-parse of the per-dialect
199    /// audit body, a future audit-report re-loader that binds a prior
200    /// [`Self::as_str`] output back to the typed enum for cross-run
201    /// comparison) would have had to re-inline a four-arm `match s`
202    /// cascade that expressed no compile-time link back to the typed
203    /// [`CaixaDialeto`] enum.
204    ///
205    /// Same closed-set-reverse-projection discipline the sibling
206    /// [`crate::CaixaKind::from_wire`] (2aa6d23) /
207    /// [`crate::supervisor::RestartStrategy::from_wire`] (4eec29c) /
208    /// [`crate::supervisor::RestartPolicy::from_wire`] (dd32ccf) /
209    /// [`crate::aplicacao::PlacementStrategy::from_wire`] (18c7342) /
210    /// [`crate::dep::DepList::from_wire`] (45ee563) typed enums carry on
211    /// the peer wire-side `str → Self` axes — extends the family onto
212    /// the seventh closed-set fieldless typed enum on the caixa surface
213    /// (the dialect-classification axis), matching the same
214    /// two-way `str ↔ Self` round-trip every sibling closed-set enum
215    /// already carries. Method-named `from_wire` (not `from_str`) to
216    /// match the peer shapes verbatim and side-step the derived
217    /// [`std::str::FromStr`] impls the sibling
218    /// [`gen_platform::FromStrKind`]-carrying axes install on their
219    /// kebab-case dispatcher-catalog identity. Returns `Option<Self>`
220    /// (rather than `Result<Self, _>`) to match the peer shapes: the
221    /// caller picks the diagnostic form appropriate for its use site.
222    #[must_use]
223    pub fn from_wire(s: &str) -> Option<Self> {
224        match s {
225            "Pacote" => Some(Self::Pacote),
226            "Molde" => Some(Self::Molde),
227            "MoldePosicional" => Some(Self::MoldePosicional),
228            "Desconhecido" => Some(Self::Desconhecido),
229            _ => None,
230        }
231    }
232
233    /// The keyword an author should write for this dialect, once the
234    /// migration named in [`Self::consumidor`] completes.
235    #[must_use]
236    pub const fn palavra_canonica(self) -> &'static str {
237        match self {
238            Self::Pacote => "defcaixa",
239            Self::Molde | Self::MoldePosicional => "defmolde",
240            Self::Desconhecido => "?",
241        }
242    }
243
244    /// Who reads this dialect.
245    #[must_use]
246    pub const fn consumidor(self) -> &'static str {
247        match self {
248            Self::Pacote => "caixa-core / feira",
249            Self::Molde | Self::MoldePosicional => "pleme-doc-gen",
250            Self::Desconhecido => "nobody known",
251        }
252    }
253
254    /// A one-line description for a census row or an error message.
255    #[must_use]
256    pub const fn descricao(self) -> &'static str {
257        match self {
258            Self::Pacote => "tatara-lisp package manifest (:nome :versao :kind :deps …)",
259            Self::Molde => "repo-surface declaration (:name :ecosystem :package {…} …)",
260            Self::MoldePosicional => {
261                "repo-surface declaration, positional name (defcaixa <nome> :kind …)"
262            }
263            Self::Desconhecido => "unrecognised — matches no known defcaixa schema",
264        }
265    }
266
267    /// True when this arm belongs to the `defmolde` declaration family —
268    /// the two-arity closure of [`Self::Molde`] and [`Self::MoldePosicional`]
269    /// under the shared `defmolde` head keyword the sibling
270    /// [`Self::palavra_canonica`] projection already collapses onto
271    /// `"defmolde"` for both arms (and the sibling [`Self::consumidor`]
272    /// projection collapses onto `"pleme-doc-gen"` for the same two arms).
273    /// False on [`Self::Pacote`] (the sibling `defcaixa` tatara-lisp
274    /// package manifest, [`Self::palavra_canonica`] `→ "defcaixa"`) and
275    /// on [`Self::Desconhecido`] (the residue that names no known
276    /// declaration, [`Self::palavra_canonica`] `→ "?"`).
277    ///
278    /// The [`Self::Molde`] / [`Self::MoldePosicional`] split is one
279    /// declaration written two ways ([`Self::MoldePosicional`]'s
280    /// variant-declaration docstring at [`Self::MoldePosicional`] frames
281    /// it exactly: "the same declaration as [`Self::Molde`], written with
282    /// the package name as a bare positional symbol … this is one arity
283    /// of one declaration, not a third schema"). Every downstream gate
284    /// that keys off "does this dialect belong to the `defmolde` family"
285    /// (as distinct from the four-arm-per-arm census-counter axis the
286    /// sibling `feira dialeto` verb already fans on separately at
287    /// `caixa-feira/src/cmd/dialeto.rs:110-127`) previously hand-rolled
288    /// the two-arm collapse inline as `matches!(d, CaixaDialeto::Molde |
289    /// CaixaDialeto::MoldePosicional)` — a compile-time-anonymous
290    /// two-arm literal set with no link back to the [`CaixaDialeto`]
291    /// variant declaration nor to the sibling
292    /// [`Self::palavra_canonica`] / [`Self::consumidor`] projections
293    /// that already carry the same two-arm collapse under the shared
294    /// `defmolde` / `pleme-doc-gen` axis. The `feira dialeto` verb's
295    /// [`caixa-feira/src/cmd/dialeto.rs`] carried the same
296    /// `matches!` twice — once in the `--strict-palavra` gate that
297    /// refuses a repo-surface declaration still written as
298    /// `(defcaixa …)`, once in the wrong-declaration-under-`caixa.lisp`
299    /// gate that refuses a repo-surface declaration under the filename
300    /// `feira` loads as a package manifest — with no compile-time link
301    /// between the two hand-rolled arm sets. A future arm addition (the
302    /// module doc's "third dialect" hazard actualises as a fifth arm
303    /// [`CaixaDialeto`] that belongs to the `defmolde` declaration
304    /// family — a third arity variant, an alias-declaration family
305    /// pleme-doc-gen sharpens as its schema evolves) would silently
306    /// split the two hand-rolled `matches!` arm-sets from each other
307    /// and from the paired [`Self::palavra_canonica`] projection: one
308    /// call site picks up the new arm, one does not, and the disagreement
309    /// surfaces far from the arm-addition commit as a `feira dialeto`
310    /// consumer reporting a repo-surface declaration under one gate but
311    /// not the other. Routing every "belongs to the `defmolde` family"
312    /// predicate through this one substrate primitive closes the axis:
313    /// a future arm addition lands one match arm here (a compile-time
314    /// exhaustiveness error otherwise), not a coordinated per-`matches!`
315    /// rewrite across every caller.
316    ///
317    /// Peer of the sibling [`crate::CaixaKind::requires_lib`] (0421c22)
318    /// per-arm-set predicate on the [`crate::CaixaKind`] closed-set
319    /// discriminator's "kind requires a `lib/` surface" axis — extends
320    /// the same "one canonical typed predicate per per-arm-set gate,
321    /// one dispatch on the substrate primitive" discipline onto the
322    /// [`CaixaDialeto`] closed-set discriminator's "belongs to the
323    /// `defmolde` declaration family" axis. The dialect-classification
324    /// axis's second per-arm-set predicate (first being the implicit
325    /// palavra_canonica-through-consumidor-through-descricao arm-set
326    /// collapse already carried on the sibling projections) — the first
327    /// explicitly-typed per-arm-set predicate on the axis, matching the
328    /// discipline the sibling M2 [`crate::CaixaKind`] closed-set
329    /// discriminator already carries with `requires_lib`.
330    ///
331    /// Three consumers now route through this one typed dispatch: the
332    /// [`caixa-feira`](../../caixa_feira/cmd/dialeto/index.html) verb's
333    /// `--strict-palavra` gate (refusing a repo-surface declaration
334    /// still written as `(defcaixa …)`), the same verb's wrong-
335    /// declaration-under-`caixa.lisp` gate (refusing a repo-surface
336    /// declaration under the filename `feira` loads as a package
337    /// manifest), and [`crate::Caixa::from_lisp`]'s foreign-dialect
338    /// gate (raising [`crate::ManifestError::DialetoEstrangeiro`] before
339    /// the derive's `parse_kwargs_strict` walk on any `defmolde`-family
340    /// classification — the pre-lift hand-rolled three-arm
341    /// `match { Pacote => {}, Desconhecido => {}, foreign => Err(…) }`
342    /// literal whose `foreign =>` wildcard silently absorbed anything
343    /// non-Pacote-non-Desconhecido, now the third external consumer of
344    /// the `defmolde`-family partition).
345    #[must_use]
346    pub const fn is_molde_family(self) -> bool {
347        // Routed through the derive-generated per-arm predicates
348        // [`Self::is_molde`] + [`Self::is_molde_posicional`] so the
349        // two-arm collapse links compile-time back to the closed-set
350        // typed dispatch every peer arm-set predicate on the caixa
351        // surface (e.g. [`crate::CaixaKind::requires_lib`] on the
352        // sibling `:kind` axis) now carries. Byte-equivalent to the
353        // pre-lift `matches!(self, Self::Molde | Self::MoldePosicional)`
354        // form (the derived `is_*` predicates each expand to the same
355        // `matches!(self, Self::X)` shape by construction), but a
356        // future arm rename or IsVariant `#[is_variant(name = "…")]`
357        // override lands at exactly one dispatch on the substrate
358        // primitive rather than a hand-rolled two-arm literal.
359        self.is_molde() || self.is_molde_posicional()
360    }
361}
362
363/// [`std::fmt::Display`] routed through [`CaixaDialeto::as_str`], so the
364/// pretty-printed byte-string every consumer that formats the dialect as
365/// user-facing / census text lands on (the `feira dialeto` per-manifest
366/// `--list` row, the `feira dialeto` census summary line's per-arm
367/// counters, a future M4 admission-webhook's rejection body naming the
368/// accepted-dialect set) reaches for the same `PascalCase` per-arm
369/// byte-string the [`CaixaDialeto::as_str`] helper returns.
370///
371/// Prior to this lift the [`std::fmt::Display`] impl hand-rolled its own
372/// four-arm literal-string match — the one hand-rolled per-arm dispatch
373/// on the closed [`CaixaDialeto`] discriminator that had NO substrate
374/// primitive accessor to defer to (the sibling [`CaixaDialeto::palavra_canonica`] /
375/// [`CaixaDialeto::consumidor`] / [`CaixaDialeto::descricao`] projections
376/// carry distinct byte-shapes per axis, so none of them could serve as
377/// the Display source). A future variant addition (a fifth dialect the
378/// module doc's "third dialect" hazard actualises) would land one arm at
379/// the enum and per-arm returns at the paired accessors, but a hand-rolled
380/// [`std::fmt::Display`] match would silently drop the new arm to compile-
381/// fail-at-the-match-arm-site rather than through the shared substrate
382/// primitive. Routing [`std::fmt::Display`] through [`CaixaDialeto::as_str`]
383/// closes the last unlifted per-arm `PascalCase`-name projection on the
384/// caixa surface — the seventh (and last unlifted) closed-set fieldless
385/// typed enum on the caixa surface to converge onto the same
386/// `Display`-through-`as_str` discipline the six siblings
387/// ([`crate::CaixaKind`] / [`crate::supervisor::RestartStrategy`] /
388/// [`crate::supervisor::RestartPolicy`] /
389/// [`crate::aplicacao::PlacementStrategy`] / [`crate::aplicacao::RateLimitUnit`]
390/// / [`crate::dep::DepList`]) already carry.
391impl std::fmt::Display for CaixaDialeto {
392    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
393        f.write_str(self.as_str())
394    }
395}
396
397/// Substrate-canonical [`AsRef<str>`] projection on the [`CaixaDialeto`]
398/// closed-set fieldless typed dialect-classification enum — routes through
399/// the same [`CaixaDialeto::as_str`] `pub const fn` scalar accessor the
400/// paired [`std::fmt::Display`] impl already delegates through, so any
401/// future consumer that binds a [`CaixaDialeto`] through the standard-
402/// library `impl AsRef<str>` bound (a [`std::process::Command::arg`]
403/// shell-out that composes the canonical `PascalCase` variant-name into a
404/// `feira dialeto --strict-palavra <Pacote|Molde|MoldePosicional|Desconhecido>`
405/// diagnostic overlay, a `tracing::field::Value::Str`-arm structured-log
406/// recorder on the [`crate::Caixa::from_lisp`] foreign-dialect
407/// [`crate::ManifestError::DialetoEstrangeiro`] refusal path, a
408/// [`std::collections::HashMap`] lookup keyed on the canonical name
409/// through `map.get::<str>(dialeto.as_ref())` on a future M4 admission-
410/// webhook's per-dialect rejection-body composition table) reaches the
411/// paired `"Pacote"` / `"Molde"` / `"MoldePosicional"` / `"Desconhecido"`
412/// byte-string through one substrate-primitive dispatch rather than an
413/// open-coded `.as_str()` re-inlining at every wire-up.
414///
415/// Same "route the trait impl through the substrate-primitive accessor"
416/// discipline the sibling [`crate::CaixaVersion`] [`AsRef<str>`] impl
417/// (16d5c7e), the paired M2 [`crate::supervisor::RestartStrategy`]
418/// [`AsRef<str>`] impl (63eb1a4), the paired M2
419/// [`crate::supervisor::RestartPolicy`] [`AsRef<str>`] impl (419ea81),
420/// the M3 [`crate::aplicacao::PlacementStrategy`] [`AsRef<str>`] impl
421/// (d86edd2), the M3 [`crate::aplicacao::RateLimitUnit`] [`AsRef<str>`]
422/// impl (d8136db), and the top-level [`crate::CaixaKind`] [`AsRef<str>`]
423/// impl (cd2091f) carry — extends the substrate primitive's
424/// [`AsRef<str>`] projection axis onto the seventh closed-set typed enum
425/// on the caixa surface: the dialect-classification axis previously
426/// carried [`fmt::Display`]-through-`as_str` but not yet the paired
427/// [`AsRef<str>`] impl, so a downstream consumer that bound the enum
428/// through the standard-library `AsRef<str>` trait had to reach the
429/// canonical byte-string through an open-coded `.as_str()` call rather
430/// than the trait-idiomatic `.as_ref()` the peer closed-set typed enums
431/// already admit.
432///
433/// Pinned load-bearing by
434/// [`tests::caixa_dialeto_as_ref_str_routes_through_as_str_accessor`]
435/// (byte-parity pin against [`CaixaDialeto::as_str`] across the four-arm
436/// closed set) and
437/// [`tests::caixa_dialeto_as_ref_str_routes_through_display_via_shared_accessor`]
438/// (three-path convergence: `AsRef<str>` + `Display` + `as_str` all
439/// resolve to the same byte-string per arm) — any future silent detour
440/// that routes the impl through a divergent projection (a per-arm inline
441/// `match self { CaixaDialeto::Pacote => "Pacote", … }` re-inlining that
442/// opens a compile-time link to the un-lifted arm-literal, a swap onto
443/// the second-axis [`CaixaDialeto::palavra_canonica`] /
444/// [`CaixaDialeto::consumidor`] / [`CaixaDialeto::descricao`] accessors
445/// that carry distinct byte-shapes per axis) trips at caixa-core test
446/// time under `assert_eq!` rather than at a downstream
447/// `impl AsRef<str>`-bound consumer's silent split.
448impl AsRef<str> for CaixaDialeto {
449    fn as_ref(&self) -> &str {
450        self.as_str()
451    }
452}
453
454/// Trait-idiomatic reverse projection on the [`CaixaDialeto`] closed-set
455/// dialect-classification typed enum — routes byte-for-byte through the
456/// paired substrate-primitive [`CaixaDialeto::from_wire`] `Option<Self>`
457/// accessor so every future consumer that binds a `PascalCase` variant-
458/// name byte-string through the standard-library `.try_into()` /
459/// [`TryFrom`] axis (a future `feira dialeto --filter
460/// <Pacote|Molde|MoldePosicional|Desconhecido>` CLI arg-parse that
461/// composes into `let d: CaixaDialeto = s.try_into()?`, a future audit-
462/// report re-loader binding a prior [`CaixaDialeto::as_str`] output
463/// through `CaixaDialeto::try_from(&s)?`, a generic
464/// `<T: TryFrom<&str>>`-bound loader over any of the substrate's closed-
465/// set typed enums) reaches the same four-arm accept-set the sibling
466/// [`CaixaDialeto::from_wire`] parses through and the sibling
467/// [`CaixaDialeto::as_str`] emits, rather than an open-coded per-arm
468/// `match s { "Pacote" => …, … }` cascade whose arm-set has no
469/// compile-time link back to the substrate primitive.
470///
471/// Complements the pre-existing forward-projection triple
472/// ([`std::fmt::Display`], [`AsRef<str>`], [`CaixaDialeto::as_str`]) with
473/// the paired trait-idiomatic reverse-projection axis: Rust-side
474/// newtype/typed-enum convention pairs [`AsRef<str>`] with either
475/// [`std::str::FromStr`] or [`TryFrom<&str>`] on the same primitive so a
476/// caller who can project *out to* a `&str` can also project *in from*
477/// one. The [`TryFrom<&str>`] axis is deliberately chosen over
478/// [`std::str::FromStr`] to sidestep the `clippy::should_implement_trait`
479/// lint that the sibling method-named `from_wire` would trigger under a
480/// `FromStr` impl (the same design tradeoff the peer
481/// [`crate::CaixaKind`] `TryFrom<&str>` impl (3c83606) and the peer
482/// [`crate::provedor::ferrite::FerriteRuntime::from_wire`] block note)
483/// — this impl closes the trait-idiomatic reverse axis without disturbing
484/// the method-named `from_wire` shape every sibling closed-set typed
485/// enum on the substrate already carries.
486///
487/// `type Error = ()` matches the sibling [`CaixaDialeto::from_wire`]'s
488/// `Option<Self>` return-shape's deliberate deferral of error typing:
489/// the caller picks the diagnostic form appropriate for its use site
490/// (a future `feira dialeto --filter` arg-parse composes its own per-verb
491/// "unknown dialect: <arg> — accepted: {…}" message enumerating
492/// [`CaixaDialeto::ALL`], a future admission-webhook rejection body
493/// wraps the `Err(())` outcome with the accepted-set enumeration for
494/// operator diagnostics, a `Result::map_err` at the call site lifts the
495/// unit-error to a per-verb error type). Same shape the peer
496/// [`crate::CaixaKind`] `TryFrom<&str>` impl (3c83606) and the peer
497/// [`FerriteRuntime::from_wire`] doc block motivate on the sibling
498/// closed-set typed enums' reverse projections.
499///
500/// The paired [`TryFrom<&str>`] impl reaches the same four-arm accept-
501/// set the [`CaixaDialeto::from_wire`] resolver dispatches through, so
502/// any future arm addition (the module doc's "third dialect" hazard
503/// actualises as a fifth arm belonging to the `defmolde` family or a
504/// wholly new declaration) grows the trait-idiomatic axis by
505/// construction — one caixa-core edit on [`CaixaDialeto::from_wire`]
506/// extends both the method-named reverse projection every existing
507/// consumer keys off and the trait-idiomatic reverse projection this
508/// impl exposes, without a coordinated rewrite across every future
509/// `TryFrom<&str>`-bound consumer's arm-set.
510///
511/// Pinned load-bearing by
512/// [`tests::caixa_dialeto_try_from_str_routes_through_from_wire_accessor`]
513/// (byte-parity pin against [`CaixaDialeto::from_wire`] across the four-
514/// arm accept-set) and
515/// [`tests::caixa_dialeto_try_from_str_rejects_unknown_byte_strings`]
516/// (rejection witness against silent accept-set widening).
517impl TryFrom<&str> for CaixaDialeto {
518    type Error = ();
519
520    fn try_from(s: &str) -> Result<Self, Self::Error> {
521        Self::from_wire(s).ok_or(())
522    }
523}
524
525/// Trait-idiomatic forward projection on the [`CaixaDialeto`] closed-set
526/// dialect-classification typed enum — routes byte-for-byte through the
527/// sibling substrate-primitive [`CaixaDialeto::as_str`] `pub const fn`
528/// accessor so every future consumer that needs `&'static str` lifetime
529/// bytes on the dialect-classification axis (a
530/// `tracing::field::valuable::Value::Str` recording where the `Str` arm's
531/// typing demands `&'static str`, a
532/// `Cow::Borrowed::<'static, str>(dialeto.into())` composer on the future
533/// M4 admission-webhook rejection body where the `Cow<'static, str>`
534/// typing rules out the sibling [`AsRef<str>`] borrowed return, a generic
535/// `<T: Into<&'static str>>`-bound serializer or error formatter that
536/// requires the `'static` bound) reaches the same four `"Pacote"` /
537/// `"Molde"` / `"MoldePosicional"` / `"Desconhecido"` byte-strings the
538/// sibling [`CaixaDialeto::as_str`] emitter returns, rather than an
539/// open-coded per-arm literal cascade whose arm-set has no compile-time
540/// link back to the substrate primitive.
541///
542/// Return type is `&'static str` by construction — every
543/// [`CaixaDialeto::as_str`] arm resolves to a compile-time `pub const fn`
544/// return of a `&'static str` literal, so the trait's return-type promise
545/// is upheld structurally without a `String::leak()` cast or a per-arm
546/// inline literal.
547///
548/// Complements the pre-existing reverse-projection axis pair
549/// ([`TryFrom<&str>`] above + method-named [`CaixaDialeto::from_wire`])
550/// with the trait-idiomatic forward-projection axis: Rust-side
551/// newtype/typed-enum convention pairs [`TryFrom<&str>`] with the mirror-
552/// image [`From<Self> for &'static str`] on the same primitive so a
553/// caller who can project *in from* a `&str` can also project *out to*
554/// one under a `'static`-lifetime bound. The
555/// [`AsRef<str>`] impl already carries the same emit-set on the borrowed
556/// return path; this impl closes the trait-idiomatic axis pair with the
557/// stricter `&'static str` lifetime the sibling `AsRef<str>` cannot
558/// promise (its return borrows from `&self`, not from the
559/// [`CaixaDialeto::as_str`] `pub const fn`'s static-string result).
560///
561/// Same "route the trait impl through the substrate-primitive accessor"
562/// discipline the sibling [`crate::supervisor::RestartStrategy`]
563/// `From<Self> for &'static str` impl (523157d — first-mover on this
564/// forward-projection family), [`crate::supervisor::RestartPolicy`]
565/// `From<Self> for &'static str` impl (9fb37d0 — second peer, closing
566/// the M2 OTP-shape sibling pair), and [`crate::CaixaKind`]
567/// `From<Self> for &'static str` impl (edb827b — third peer, opening
568/// the campaign onto the top-level caixa surface) carry — extends the
569/// substrate primitive's trait-idiomatic forward-projection axis onto
570/// the fourth closed-set fieldless typed enum on the caixa surface: the
571/// dialect-classification axis, previously carrying the paired
572/// [`std::fmt::Display`] / [`AsRef<str>`] / [`CaixaDialeto::as_str`] /
573/// [`TryFrom<&str>`] / [`CaixaDialeto::from_wire`] forward+reverse
574/// projections but not yet the trait-idiomatic forward projection with
575/// the `&'static str` lifetime bound.
576///
577/// Unlike the peer [`crate::CaixaKind`] impl (which carries a two-axis
578/// split between the lowercase Portuguese `as_str` diagnostic axis and
579/// the `PascalCase` `wire_name` author-surface axis, so the trait's
580/// round-trip witness must cross through the wire axis rather than
581/// composing the two trait impls directly), [`CaixaDialeto`] is an
582/// internal classification whose [`CaixaDialeto::as_str`] output and
583/// [`CaixaDialeto::from_wire`] input share the same `PascalCase`
584/// vocabulary by construction — the trait-idiomatic axis pair
585/// ([`From<Self> for &'static str`] + [`TryFrom<&str> for Self`])
586/// therefore round-trips directly, without an intermediate wire-vocab
587/// hop.
588///
589/// The paired [`CaixaDialeto::as_str`] accessor's four-arm emit-set is
590/// the single source of truth — every future arm addition (the module
591/// doc's "third dialect" hazard actualises as a fifth arm belonging to
592/// the `defmolde` family or a wholly new declaration) grows the trait-
593/// idiomatic forward axis by construction: one caixa-core edit on
594/// [`CaixaDialeto::as_str`] extends every one of the sibling forward-
595/// projection paths ([`std::fmt::Display`], [`AsRef<str>`],
596/// [`CaixaDialeto::as_str`] itself, and this
597/// [`From<Self> for &'static str`]) without a coordinated rewrite across
598/// every future `Into<&'static str>`-bound consumer's arm-set. This lift
599/// closes the fourth peer on the trait-idiomatic forward-projection
600/// campaign the recently-landed peer commits opened; the remaining ten
601/// closed-set typed enums on the caixa substrate surface
602/// (`PlacementStrategy`, `WitShape`, `RateLimitUnit`,
603/// `PathShapeViolation`, `InvariantKind`, `ArchVerdict`, `Severity`,
604/// `FixSafety`, `Semantic`, `FerriteRuntime`) are the future targets
605/// of this campaign.
606///
607/// Pinned load-bearing by
608/// [`tests::caixa_dialeto_from_into_static_str_routes_through_as_str_accessor`]
609/// (byte-parity pin against [`CaixaDialeto::as_str`] across the four-arm
610/// emit-set, plus a `const`-context materialization witness for the
611/// `&'static str` lifetime promise, plus a paired `.into()` shape
612/// assertion covering the blanket-derived `Into<&'static str>` shape)
613/// and
614/// [`tests::caixa_dialeto_from_into_static_str_and_as_str_partition_the_emit_set`]
615/// (partition pin asserting `<&'static str as From<CaixaDialeto>>::from`
616/// and [`CaixaDialeto::as_str`] agree on every arm, plus a two-way
617/// direct round-trip witness through the paired trait-idiomatic
618/// [`TryFrom<&str>`] axis that closes the two-way `Self ↔ &'static str`
619/// round-trip on the trait-idiomatic axis pair without the wire-vocab
620/// intermediate the peer [`crate::CaixaKind`] axis pair requires).
621impl From<CaixaDialeto> for &'static str {
622    fn from(dialeto: CaixaDialeto) -> &'static str {
623        dialeto.as_str()
624    }
625}
626
627/// A source that is not a `(defcaixa …)` / `(defmolde …)` form at all.
628#[derive(Debug, Clone, PartialEq, Eq, thiserror::Error)]
629pub enum DialetoError {
630    #[error("source has no top-level form")]
631    Vazio,
632    #[error("top-level form is not a list — a manifest is `(defcaixa …)`")]
633    NaoEhLista,
634    #[error(
635        "top-level form is headed by `{encontrado}`, not `defcaixa` or `defmolde` \
636         (a manifest's first form must be the declaration itself)"
637    )]
638    CabecaErrada { encontrado: String },
639    #[error("manifest does not parse as tatara-lisp: {0}")]
640    Leitura(String),
641}
642
643impl DialetoError {
644    /// Construct a [`DialetoError::CabecaErrada`] naming the offending
645    /// head symbol found at the top-level form.
646    ///
647    /// Substrate primitive every [`classify_form`] wrong-head fallthrough
648    /// wire-up site now routes through, folding the pre-lift uniform
649    /// three-line `Self::CabecaErrada { encontrado: <head>.to_string() }`
650    /// one-field struct-literal onto one substrate primitive matching the
651    /// peer `LimitsError::unknown_byte_unit(unit: &str)` /
652    /// `LimitsError::unknown_duration_unit(unit: &str)`
653    /// (`limits_codec_unit_only_ctors!` — 29fac09) single-slot
654    /// discipline on the sibling one-field `{ <field>: String }` envelope
655    /// axis, and matching the peer `ManifestError::code_path_empty` /
656    /// `BehaviorError::empty_path` / `UpgradeError::duplicate_from` /
657    /// `AplicacaoError::placement_cluster_duplicate` (94dabc8 / 0e33b37 /
658    /// 7e52aec / 92b1c92) single-slot inherent-ctor discipline every
659    /// sibling `{ <field>: <T> }` error-envelope variant on caixa-core's
660    /// error surface now carries.
661    ///
662    /// The one open-coded wire-up site — `classify_form`'s wrong-head
663    /// fallthrough arm on the `head: &str` binding read from the
664    /// top-level form via [`tatara_lisp::Sexp::as_symbol`] — opened the
665    /// identical three-line
666    /// `Self::CabecaErrada { encontrado: <head>.to_string() }` block
667    /// against the codec-scoped `<head>: &str` binding. Now routes
668    /// through `DialetoError::cabeca_errada(head)`, byte-equal to the
669    /// pre-lift struct-literal on the same `&str` fixture, so any future
670    /// widening of the diagnostic shape (e.g. carrying the source-file
671    /// path alongside the head symbol, carrying the head symbol's
672    /// position offset for an authoring-surface caret pointer) lands at
673    /// exactly one dispatch on the substrate primitive rather than re-
674    /// inlining the struct-literal at every wrong-head fallthrough
675    /// consumer.
676    #[must_use]
677    pub fn cabeca_errada(encontrado: &str) -> Self {
678        Self::CabecaErrada {
679            encontrado: encontrado.to_string(),
680        }
681    }
682
683    /// Construct a [`DialetoError::Leitura`] carrying the offending
684    /// tatara-lisp reader-error message `reason` verbatim in the
685    /// variant's tuple-newtype payload.
686    ///
687    /// Substrate primitive every [`classify`] tatara-lisp-reader
688    /// map-err wire-up site now routes through, folding the pre-lift
689    /// uniform `Self::Leitura(<into-String-expr>)` tuple-newtype
690    /// construction onto one substrate primitive matching the peer
691    /// `LimitsError::empty_byte_size` / `LimitsError::empty_duration`
692    /// (7a4b003 / 319216c) `(String)` single-slot tuple-newtype
693    /// discipline on the sibling
694    /// [`crate::limits::LimitsError`] envelope's empty-shape axis of
695    /// the paired codec-magnitude family. Peer to the sibling
696    /// [`DialetoError::cabeca_errada`] ctor on the same envelope's
697    /// wrong-head axis but on the tatara-lisp-reader axis rather than
698    /// the classifier-fallthrough axis. Closes the last un-lifted
699    /// variant on [`DialetoError`] — every one of the sole wire-up
700    /// sites (the [`classify`] tatara-lisp-reader `.map_err(|e|
701    /// Self::Leitura(e.to_string()))` arm) opened the identical
702    /// `DialetoError::Leitura(<into-String-expr>)` block against the
703    /// codec-scoped `String` (`e.to_string()`) binding, so the fold
704    /// routes the site through one dispatch on a uniform
705    /// `impl Into<String>` param, byte-equal to the pre-lift
706    /// tuple-newtype construction on the same argument.
707    ///
708    /// The `impl Into<String>` bound covers both wire-up shapes on
709    /// [`classify`] — a `String` binding (`e.to_string()` on the
710    /// [`tatara_lisp::Error`]-carrying `e` binding) and a `&str`
711    /// binding (a future admission-webhook consumer probing a
712    /// caller-scoped `&'static str` fixture, a future
713    /// `feira lint --tatara-reader-round-trip` verb sweeping every
714    /// `tatara_lisp::read` return through the same shape gate) —
715    /// without forcing the caller to spell the conversion at the
716    /// wire-up site. Same shape the peer
717    /// [`crate::limits::LimitsError::empty_byte_size`] /
718    /// [`crate::limits::LimitsError::empty_duration`] /
719    /// [`crate::limits::LimitsError::bad_millicores`] /
720    /// [`crate::limits::LimitsError::bad_byte_magnitude`] /
721    /// [`crate::limits::LimitsError::bad_duration_magnitude`] folds
722    /// carry on the peer bad-magnitude and empty-shape axes of the
723    /// same paired `(String)` tuple-newtype codec-magnitude family.
724    /// `#[must_use]` fires a compile warning at any wire-up that
725    /// mistakenly discards the constructed error.
726    ///
727    /// Every future consumer that wants to construct this variant
728    /// outside [`classify`] (a deferred `feira lint --tatara-reader-
729    /// round-trip` per-caixa admission verb probing each authored
730    /// manifest against the tatara-lisp-reader shape gate, an M4
731    /// typed `mesh.pleme.io/v1alpha1/Servico` CR materializer's
732    /// per-manifest admission validator re-checking one edited
733    /// `caixa.lisp` against the reader floor, a per-`caixa.lisp`
734    /// value-shape pre-emitter probing each declared manifest ahead
735    /// of the operator's admit-cycle) now reaches the variant
736    /// through one call rather than re-inlining the tuple-newtype
737    /// block in lockstep with the pre-existing wire-up.
738    #[must_use]
739    pub fn leitura(reason: impl Into<String>) -> Self {
740        Self::Leitura(reason.into())
741    }
742}
743
744/// Classify a manifest source without committing to either schema.
745///
746/// Deliberately reads only the head symbol and the set of top-level keywords —
747/// enough to route, never enough to half-parse. A classifier that started
748/// validating would grow into a third parser, which is the shape of the problem
749/// it exists to name.
750///
751/// # Errors
752/// [`DialetoError`] when the source is not a manifest declaration at all.
753pub fn classify(src: &str) -> Result<CaixaDialeto, DialetoError> {
754    let forms = tatara_lisp::read(src).map_err(|e| DialetoError::leitura(e.to_string()))?;
755    let first = forms.first().ok_or(DialetoError::Vazio)?;
756    classify_form(first)
757}
758
759/// [`classify`] over an already-read form.
760///
761/// # Errors
762/// [`DialetoError`] when the form is not a manifest declaration.
763pub fn classify_form(form: &Sexp) -> Result<CaixaDialeto, DialetoError> {
764    let list = form.as_list().ok_or(DialetoError::NaoEhLista)?;
765    let head = list
766        .first()
767        .and_then(Sexp::as_symbol)
768        .ok_or(DialetoError::NaoEhLista)?;
769
770    match head {
771        // `defmolde` is unambiguous by construction — it exists precisely so a
772        // consumer never has to infer which declaration it holds. Both arities
773        // are the same declaration; the positional one keeps its own variant
774        // only so a census can report the split.
775        "defmolde" => {
776            return Ok(if starts_with_positional_name(&list[1..]) {
777                CaixaDialeto::MoldePosicional
778            } else {
779                CaixaDialeto::Molde
780            });
781        }
782        "defcaixa" => {}
783        other => {
784            return Err(DialetoError::cabeca_errada(other));
785        }
786    }
787
788    let args = &list[1..];
789
790    // `(defcaixa <symbol> :kind … :ecosystem …)`. Only the Molde dialect has a
791    // positional arity; `Caixa` is keyword-only, so a leading bare symbol
792    // settles it without looking further.
793    if starts_with_positional_name(args) {
794        return Ok(CaixaDialeto::MoldePosicional);
795    }
796
797    let keys = top_level_keywords(args);
798    let has = |k: &str| keys.iter().any(|s| s == k);
799
800    // Order matters, and it is not arbitrary: `:nome` and `:name` are the two
801    // required head slots and no file in the measured corpus carries both.
802    // Checking them FIRST means the decision rests on the one slot each schema
803    // makes mandatory, rather than on optional evidence like `:ecosystem`.
804    if has("nome") {
805        return Ok(CaixaDialeto::Pacote);
806    }
807    if has("name") || has("ecosystem") || has("package") {
808        return Ok(CaixaDialeto::Molde);
809    }
810    Ok(CaixaDialeto::Desconhecido)
811}
812
813/// True when the first argument is a bare symbol rather than a keyword — the
814/// positional-name arity.
815fn starts_with_positional_name(args: &[Sexp]) -> bool {
816    matches!(args.first(), Some(Sexp::Atom(Atom::Symbol(_))))
817}
818
819/// The top-level keyword names (without the leading `:`) of a kwarg list.
820///
821/// Steps in pairs so a keyword appearing as a VALUE — `:kind :Biblioteca`, or a
822/// nested `(:nome "dep" :versao "^0.1")` inside `:deps` — is never counted as a
823/// top-level slot. A naive scan for `:nome` anywhere in the source classifies
824/// every Molde manifest with a `:deps` list as a Pacote.
825fn top_level_keywords(args: &[Sexp]) -> Vec<String> {
826    let mut out = Vec::new();
827    let mut i = 0;
828    while i < args.len() {
829        if let Sexp::Atom(Atom::Keyword(k)) = &args[i] {
830            out.push(k.clone());
831            i += 2;
832        } else {
833            i += 1;
834        }
835    }
836    out
837}
838
839#[cfg(test)]
840mod tests {
841    use super::*;
842
843    const PACOTE: &str = r#"
844      (defcaixa
845        :nome   "checkout"
846        :versao "0.1.0"
847        :kind   Servico
848        :deps   ((:nome "caixa-teia" :versao "^0.1")))
849    "#;
850
851    const MOLDE: &str = r#"
852      (defcaixa
853        :name "base64"
854        :kind :Biblioteca
855        :ecosystem :rust-single-crate
856        :package {:name "base64" :version "0.22.1"}
857        :workflows [:auto-release])
858    "#;
859
860    const MOLDE_POSICIONAL: &str = r#"
861      (defcaixa todoku-go
862        :kind :Biblioteca
863        :ecosystem :go
864        :package {:name "todoku-go" :version "0.3.0"})
865    "#;
866
867    #[test]
868    fn the_package_dialect_is_recognised() {
869        assert_eq!(classify(PACOTE), Ok(CaixaDialeto::Pacote));
870    }
871
872    #[test]
873    fn the_repo_surface_dialect_is_recognised() {
874        assert_eq!(classify(MOLDE), Ok(CaixaDialeto::Molde));
875    }
876
877    #[test]
878    fn the_positional_arity_is_recognised() {
879        assert_eq!(
880            classify(MOLDE_POSICIONAL),
881            Ok(CaixaDialeto::MoldePosicional)
882        );
883    }
884
885    #[test]
886    fn defmolde_classifies_without_inference() {
887        // The whole point of the new keyword: no schema sniffing required.
888        let src = r#"(defmolde :name "x" :kind :Biblioteca :ecosystem :go)"#;
889        assert_eq!(classify(src), Ok(CaixaDialeto::Molde));
890        let pos = r"(defmolde todoku-go :kind :Biblioteca :ecosystem :go)";
891        assert_eq!(classify(pos), Ok(CaixaDialeto::MoldePosicional));
892    }
893
894    #[test]
895    fn a_nested_nome_does_not_make_a_repo_surface_look_like_a_package() {
896        // The exact failure a substring scan produces: `:deps ((:nome …))`
897        // contains `:nome`, but not as a top-level slot.
898        let src = r#"
899          (defcaixa
900            :name "x"
901            :ecosystem :rust-single-crate
902            :deps ((:nome "inner" :versao "^0.1")))
903        "#;
904        assert_eq!(classify(src), Ok(CaixaDialeto::Molde));
905    }
906
907    #[test]
908    fn a_keyword_in_value_position_is_not_a_slot() {
909        // `:kind :Biblioteca` — the value is itself a keyword. Stepping one at
910        // a time would read `:Biblioteca` as a top-level slot.
911        let src = r#"(defcaixa :kind :Biblioteca :name "x")"#;
912        assert_eq!(classify(src), Ok(CaixaDialeto::Molde));
913    }
914
915    #[test]
916    fn an_unrecognised_defcaixa_is_reported_not_guessed() {
917        let src = r#"(defcaixa :licenca "MIT")"#;
918        assert_eq!(classify(src), Ok(CaixaDialeto::Desconhecido));
919    }
920
921    #[test]
922    fn a_form_that_is_not_a_manifest_is_an_error_not_a_dialect() {
923        assert_eq!(
924            classify("(defflake :nome \"x\")"),
925            Err(DialetoError::cabeca_errada("defflake"))
926        );
927        assert_eq!(classify(""), Err(DialetoError::Vazio));
928    }
929
930    #[test]
931    fn every_dialect_names_its_consumer_and_its_canonical_keyword() {
932        // Guards the routing table itself: a new variant added without an arm
933        // here is a compile error in the match, and a variant that claims
934        // `defcaixa` while being read by pleme-doc-gen would re-open the
935        // collision this module closes. Sweeps [`CaixaDialeto::ALL`] rather
936        // than the pre-lift open-coded four-arm literal list — a future arm
937        // addition extends the slice as one edit and this pin picks it up
938        // by construction.
939        for &d in CaixaDialeto::ALL {
940            assert!(!d.descricao().is_empty(), "{d}");
941            assert!(!d.consumidor().is_empty(), "{d}");
942        }
943        assert_eq!(CaixaDialeto::Pacote.palavra_canonica(), "defcaixa");
944        assert_eq!(CaixaDialeto::Molde.palavra_canonica(), "defmolde");
945        assert_ne!(
946            CaixaDialeto::Pacote.palavra_canonica(),
947            CaixaDialeto::Molde.palavra_canonica(),
948            "the two dialects must not share a canonical keyword — that IS the defect"
949        );
950    }
951
952    #[test]
953    fn caixa_dialeto_all_enumerates_every_variant_exactly_once() {
954        // Three-legged exhaustiveness pin, peer of the sibling
955        // `caixa_kind_all_enumerates_every_variant_exactly_once`
956        // (caixa-core/src/kind.rs) /
957        // `restart_strategy_all_enumerates_every_variant_exactly_once`
958        // (caixa-core/src/supervisor.rs) shape.
959        //
960        // 1. arm-count invariant: `ALL.len()` matches the declared arm
961        //    count (four — a fifth arm added without extending `ALL`
962        //    fails this pin at caixa-core test time);
963        // 2. pairwise-distinctness invariant: every variant appears at
964        //    most once in the slice (a duplicate arm would silently
965        //    double-count in the census consumer, so the pin rejects
966        //    duplicates outright);
967        // 3. coverage invariant: every literal `CaixaDialeto::X` is in
968        //    the slice (the compiler-checked exhaustiveness on the peer
969        //    per-arm `match self` in the accessors keeps the enum arm
970        //    set and the `ALL` slice mutually aligned).
971        assert_eq!(
972            CaixaDialeto::ALL.len(),
973            4,
974            "ALL must list every arm exactly once; a fifth arm added \
975             without extending ALL fails this pin — extend ALL alongside \
976             the new variant"
977        );
978
979        let mut seen: Vec<CaixaDialeto> = Vec::new();
980        for &d in CaixaDialeto::ALL {
981            assert!(
982                !seen.contains(&d),
983                "ALL contains a duplicate arm: {d}. Every variant appears \
984                 exactly once — a duplicate would double-count in every \
985                 iteration consumer"
986            );
987            seen.push(d);
988        }
989
990        // Coverage: exhaustively assert every literal variant is somewhere
991        // in the slice. Written as an exhaustive `match` so a future arm
992        // addition fails to compile here (missing match arm) until the
993        // corresponding `assert` is added — the compiler enforces the pin's
994        // completeness rather than a hand-maintained variant list.
995        for variant in [
996            CaixaDialeto::Pacote,
997            CaixaDialeto::Molde,
998            CaixaDialeto::MoldePosicional,
999            CaixaDialeto::Desconhecido,
1000        ] {
1001            let coverage_probe = match variant {
1002                CaixaDialeto::Pacote
1003                | CaixaDialeto::Molde
1004                | CaixaDialeto::MoldePosicional
1005                | CaixaDialeto::Desconhecido => variant,
1006            };
1007            assert!(
1008                CaixaDialeto::ALL.contains(&coverage_probe),
1009                "ALL is missing variant {coverage_probe} — extend the slice"
1010            );
1011        }
1012    }
1013
1014    #[test]
1015    fn caixa_dialeto_all_is_const_and_matches_iteration_count() {
1016        // Pins the const-ness of the slice at const-fold time. A future
1017        // change that promoted `ALL` to a non-const initializer (a lazy-
1018        // static, a runtime-computed Vec) would fail to compile here —
1019        // the pin locks in the compile-time-known iteration surface
1020        // every consumer builds against. Peer of the sibling
1021        // `caixa_kind_all_is_const_and_matches_iteration_count` (kind.rs)
1022        // / `restart_strategy_all_is_const_and_matches_iteration_count`
1023        // (supervisor.rs) shape.
1024        const ALL: &[CaixaDialeto] = CaixaDialeto::ALL;
1025        assert_eq!(ALL.len(), CaixaDialeto::ALL.len());
1026        // Sweep the iterator without collapsing to `.len()` so a future
1027        // change to `ALL`'s carrier that decouples `.len()` from the
1028        // iteration count (a lazy-computed shape, an alias `impl Iterator`
1029        // return, a wrapper newtype) still passes here iff the two agree
1030        // arm-for-arm; the `#[allow]` opts this local pin out of the
1031        // clippy `iter_count` collapse that would defeat the intent.
1032        #[allow(clippy::iter_count)]
1033        let iterated = ALL.iter().count();
1034        assert_eq!(iterated, CaixaDialeto::ALL.len());
1035    }
1036
1037    #[test]
1038    fn caixa_dialeto_all_covers_every_variant_by_display_probe() {
1039        // Fanning `Display` over the slice sweeps the paired accessors
1040        // ([`CaixaDialeto::palavra_canonica`] / [`CaixaDialeto::consumidor`]
1041        // / [`CaixaDialeto::descricao`]) at every arm — every returned
1042        // byte-string is non-empty (the accessors' contract). A future
1043        // arm added without extending its per-arm `match self` return
1044        // would compile-fail at the accessor call inside the loop;
1045        // together with the `ALL.len() == 4` pin above, this locks the
1046        // accessor arm-set and the `ALL` slice mutually.
1047        for &d in CaixaDialeto::ALL {
1048            let display_form = d.to_string();
1049            assert!(
1050                !display_form.is_empty(),
1051                "Display must render a non-empty byte-string for every \
1052                 arm; empty: {d:?}"
1053            );
1054            // Consumidor / descricao / palavra-canonica must each surface
1055            // a non-empty scalar; every downstream diagnostic consumer
1056            // reaches through these accessors.
1057            assert!(!d.palavra_canonica().is_empty(), "{d}");
1058            assert!(!d.consumidor().is_empty(), "{d}");
1059            assert!(!d.descricao().is_empty(), "{d}");
1060        }
1061    }
1062
1063    #[test]
1064    fn caixa_dialeto_as_str_returns_pascal_case_variant_name() {
1065        // Fail-before-pass-after per-arm shape pin: the four
1066        // [`CaixaDialeto::as_str`] arms must return the canonical
1067        // `PascalCase` byte-string that names the variant. Pre-lift this
1068        // byte-string existed only inside the hand-rolled Display impl's
1069        // four-arm literal-string match — every consumer that wanted the
1070        // `PascalCase` name reached through `format!("{d}")`'s allocation
1071        // path. Pinning the four arms explicitly here refuses a future
1072        // regression that ever reroutes an arm to a distinct spelling
1073        // (`"pacote"` lowercase, `"MoldePositional"` English rebrand,
1074        // `"Unknown"` for `Desconhecido`) — the census output and the
1075        // typed accessor would silently disagree until a downstream
1076        // consumer surfaced the drift at census time. Peer of the sibling
1077        // [`crate::supervisor::tests::restart_strategy_variants_serialize_to_lifted_scalar_values`]
1078        // / `placement_strategy_variants_serialize_to_lifted_scalar_values`
1079        // / `caixa_kind_as_str_returns_lifted_peer_const` shape on the
1080        // sibling closed-set typed-enum discriminator axes — the seventh
1081        // (and last unlifted) closed-set typed enum on the caixa surface
1082        // to converge onto the same per-arm-shape-pin discipline.
1083        for (variant, expected) in [
1084            (CaixaDialeto::Pacote, "Pacote"),
1085            (CaixaDialeto::Molde, "Molde"),
1086            (CaixaDialeto::MoldePosicional, "MoldePosicional"),
1087            (CaixaDialeto::Desconhecido, "Desconhecido"),
1088        ] {
1089            assert_eq!(
1090                variant.as_str(),
1091                expected,
1092                "CaixaDialeto::{variant:?}.as_str() must return the \
1093                 canonical `PascalCase` variant-name byte-string; drift here \
1094                 splits the census-facing text from the substrate \
1095                 primitive every downstream consumer will read"
1096            );
1097        }
1098    }
1099
1100    #[test]
1101    fn caixa_dialeto_display_routes_through_as_str_helper() {
1102        // Fail-before-pass-after convergence pin: for every arm in
1103        // [`CaixaDialeto::ALL`], the [`std::fmt::Display`] rendered form
1104        // must byte-equal [`CaixaDialeto::as_str`]'s return value. Pre-
1105        // lift these two paths were structurally independent — the
1106        // Display impl hand-rolled its own four-arm literal-string
1107        // match with no compile-time link back to any substrate accessor
1108        // — so a future variant rename could land at `Display` without
1109        // touching a paired accessor (or vice versa), silently splitting
1110        // the two paths on the renamed arm. Pinning the byte-equality
1111        // here makes any such split a caixa-core build-time failure at
1112        // this test rather than surfacing far from the rename commit as
1113        // a downstream census consumer emitting one spelling while the
1114        // typed accessor returned another. Peer of the sibling
1115        // [`crate::kind::tests::caixa_kind_display_routes_through_as_str_helper`]
1116        // (which pins the same convergence on the [`crate::CaixaKind`]
1117        // closed-set axis) — extends the discipline onto the seventh
1118        // (and last unlifted) closed-set fieldless typed enum on the
1119        // caixa surface.
1120        for &variant in CaixaDialeto::ALL {
1121            assert_eq!(
1122                variant.to_string(),
1123                variant.as_str(),
1124                "CaixaDialeto::{variant:?} Display must route through \
1125                 CaixaDialeto::as_str (single source of truth: the \
1126                 lifted per-arm `PascalCase` variant-name byte-string)"
1127            );
1128        }
1129    }
1130
1131    #[test]
1132    fn caixa_dialeto_as_ref_str_routes_through_as_str_accessor() {
1133        // Fail-before-pass-after byte-parity pin on the lifted
1134        // `impl AsRef<str> for CaixaDialeto` — asserts the standard-
1135        // library trait impl and the substrate-primitive
1136        // [`CaixaDialeto::as_str`] `pub const fn` accessor resolve to
1137        // the same `&str` per instance across the four-arm closed set,
1138        // so any future silent detour that routes the impl through a
1139        // divergent projection (a per-arm inline
1140        // `match self { CaixaDialeto::Pacote => "Pacote", … }` re-inlining
1141        // that opens a compile-time link to the un-lifted arm-literal,
1142        // a swap onto the second-axis
1143        // [`CaixaDialeto::palavra_canonica`] /
1144        // [`CaixaDialeto::consumidor`] / [`CaixaDialeto::descricao`]
1145        // accessors that carry distinct byte-shapes per axis) trips at
1146        // caixa-core test time under `PartialEq` rather than at a
1147        // downstream `impl AsRef<str>`-bound consumer's silent split.
1148        // Sweeps every one of the four arms [`CaixaDialeto::ALL`]
1149        // carries so no arm's projection is covered only by the sibling
1150        // `Display` path. Peer of the sibling
1151        // `rate_limit_unit_as_ref_str_routes_through_as_suffix_accessor`
1152        // (d8136db) on the M3 `:politicas :rate-limit` closed-set typed
1153        // enum, and the peer
1154        // [`crate::kind::tests::caixa_kind_as_ref_str_routes_through_as_str_accessor`]
1155        // (cd2091f) pin on the top-level closed-set typed
1156        // discriminator — the pins together close the substrate
1157        // primitive's `AsRef<str>` projection axis onto the seventh
1158        // closed-set fieldless typed enum on the caixa surface.
1159        for &variant in CaixaDialeto::ALL {
1160            assert_eq!(
1161                <CaixaDialeto as AsRef<str>>::as_ref(&variant),
1162                variant.as_str(),
1163                "AsRef<str> impl on CaixaDialeto::{variant:?} must \
1164                 byte-equal CaixaDialeto::as_str on the same instance \
1165                 — divergence signals a silent detour off the \
1166                 substrate-primitive accessor"
1167            );
1168        }
1169    }
1170
1171    #[test]
1172    fn caixa_dialeto_as_ref_str_routes_through_display_via_shared_accessor() {
1173        // Fail-before-pass-after byte-parity pin on the three-path
1174        // convergence discipline the [`CaixaDialeto`] closed-set
1175        // dialect-classification enum now carries on the `&str`-
1176        // projection axis: `<CaixaDialeto as AsRef<str>>::as_ref(&v)`
1177        // (the newly lifted impl), `format!("{v}")` (the pre-existing
1178        // [`fmt::Display`] impl), and `v.as_str()` (the substrate-
1179        // primitive `pub const fn` accessor both trait impls delegate
1180        // through) must resolve to the same byte-string on every
1181        // instance across the four-arm closed set. Refuses any future
1182        // divergence between the two trait impls (a stray
1183        // [`fmt::Display::fmt`] rewrite that hand-rolls the arms
1184        // rather than delegating through the shared accessor; a
1185        // hypothetical `AsRef<str>` rewrite that inlines a per-arm
1186        // literal cascade) that would silently split the two
1187        // projection paths of the same closed-set typed enum. Mirrors
1188        // the sibling three-path-convergence discipline the peer
1189        // [`crate::aplicacao::RateLimitUnit`] typed enum carries
1190        // (`rate_limit_unit_as_ref_str_routes_through_display_via_shared_accessor`,
1191        // d8136db), the peer [`crate::CaixaKind`] triple
1192        // (`caixa_kind_as_ref_str_routes_through_display_via_shared_accessor`,
1193        // cd2091f), and the [`crate::CaixaVersion`] typed newtype
1194        // triple (`caixa_version_as_ref_str_routes_through_display_via_shared_accessor`,
1195        // 16d5c7e).
1196        for &variant in CaixaDialeto::ALL {
1197            let via_as_ref: &str = <CaixaDialeto as AsRef<str>>::as_ref(&variant);
1198            let via_display: String = format!("{variant}");
1199            let via_accessor: &str = variant.as_str();
1200            assert_eq!(via_as_ref, via_accessor);
1201            assert_eq!(via_display, via_accessor);
1202            assert_eq!(via_as_ref, via_display.as_str());
1203        }
1204    }
1205
1206    #[test]
1207    fn caixa_dialeto_is_molde_family_returns_true_on_molde_and_positional_arms() {
1208        // Fail-before-pass-after per-arm shape pin on the two `defmolde`
1209        // declaration-family arms: [`CaixaDialeto::is_molde_family`] must
1210        // return `true` for [`CaixaDialeto::Molde`] and
1211        // [`CaixaDialeto::MoldePosicional`] — the two-arity closure of
1212        // one declaration ([`CaixaDialeto::MoldePosicional`]'s docstring:
1213        // "same declaration as [`Self::Molde`], written with the package
1214        // name as a bare positional symbol … one arity of one
1215        // declaration, not a third schema"). A future accidental flip that
1216        // reversed a per-arm arm's return without touching the paired
1217        // false-arm pin would silently open the substrate primitive to
1218        // false-positive on either arm — the `feira dialeto` verb's
1219        // `--strict-palavra` gate would then silently accept
1220        // repo-surface declarations under `(defcaixa …)` on one arm and
1221        // reject them on the other. Pinning the two true arms explicitly
1222        // here refuses that split at caixa-core build time.
1223        assert!(
1224            CaixaDialeto::Molde.is_molde_family(),
1225            "CaixaDialeto::Molde.is_molde_family() must return true — \
1226             Molde is the primary `defmolde` arm"
1227        );
1228        assert!(
1229            CaixaDialeto::MoldePosicional.is_molde_family(),
1230            "CaixaDialeto::MoldePosicional.is_molde_family() must return \
1231             true — MoldePosicional is the positional-arity form of the \
1232             same `defmolde` declaration Molde carries"
1233        );
1234    }
1235
1236    #[test]
1237    fn caixa_dialeto_is_molde_family_returns_false_on_pacote_and_desconhecido_arms() {
1238        // Fail-before-pass-after per-arm shape pin on the two non-`defmolde`
1239        // arms: [`CaixaDialeto::is_molde_family`] must return `false` for
1240        // [`CaixaDialeto::Pacote`] (the sibling `defcaixa` tatara-lisp
1241        // package manifest, `palavra_canonica → "defcaixa"`) and for
1242        // [`CaixaDialeto::Desconhecido`] (the residue that names no
1243        // known declaration, `palavra_canonica → "?"`). Pinning the two
1244        // false arms explicitly here refuses a future accidental flip
1245        // that let the predicate widen to include either arm — the
1246        // `feira dialeto` verb's `--strict-palavra` gate would then
1247        // spuriously refuse every `(defcaixa …)` package manifest as if
1248        // it were a repo-surface declaration.
1249        assert!(
1250            !CaixaDialeto::Pacote.is_molde_family(),
1251            "CaixaDialeto::Pacote.is_molde_family() must return false — \
1252             Pacote is the `defcaixa` tatara-lisp package manifest, not \
1253             the `defmolde` repo-surface declaration"
1254        );
1255        assert!(
1256            !CaixaDialeto::Desconhecido.is_molde_family(),
1257            "CaixaDialeto::Desconhecido.is_molde_family() must return \
1258             false — the residue arm names no known declaration; it is \
1259             not silently promoted into the `defmolde` family"
1260        );
1261    }
1262
1263    #[test]
1264    fn caixa_dialeto_is_molde_family_agrees_with_palavra_canonica_defmolde_projection() {
1265        // Load-bearing pin: for every arm in [`CaixaDialeto::ALL`], the
1266        // typed [`CaixaDialeto::is_molde_family`] predicate must agree
1267        // byte-for-byte with the paired [`CaixaDialeto::palavra_canonica`]
1268        // projection's `== "defmolde"` classifier — i.e. the two paths
1269        // partition the four-arm discriminator set into the same
1270        // `{Molde, MoldePosicional}` and `{Pacote, Desconhecido}` halves.
1271        // Pre-lift the sibling [`CaixaDialeto::palavra_canonica`] projection
1272        // (which returns `"defmolde"` for `Molde | MoldePosicional`,
1273        // `"defcaixa"` for `Pacote`, `"?"` for `Desconhecido`) was the
1274        // only substrate-side surface carrying the two-arm collapse; the
1275        // hand-rolled `matches!(d, CaixaDialeto::Molde |
1276        // CaixaDialeto::MoldePosicional)` sites in the `feira dialeto`
1277        // verb expressed no compile-time link back to it. A future arm
1278        // addition — the module doc's "third dialect" hazard actualises
1279        // as a fifth arm belonging to the `defmolde` family — would land
1280        // one match arm at [`Self::palavra_canonica`]'s `defmolde` return
1281        // (extending the sibling projection) but silently split the
1282        // hand-rolled two-arm `matches!` predicate sites if the new arm's
1283        // `is_molde_family` return were forgotten. Pinning byte-equality
1284        // between the two paths here makes any such split a caixa-core
1285        // build-time failure at this test rather than surfacing far from
1286        // the arm-addition commit as a downstream `--strict-palavra` /
1287        // `caixa.lisp`-holds-wrong-declaration gate silently ignoring the
1288        // new arm.
1289        for &d in CaixaDialeto::ALL {
1290            let via_palavra_canonica = d.palavra_canonica() == "defmolde";
1291            let via_is_molde_family = d.is_molde_family();
1292            assert_eq!(
1293                via_is_molde_family, via_palavra_canonica,
1294                "CaixaDialeto::{d:?}.is_molde_family() ({via_is_molde_family}) \
1295                 must agree with CaixaDialeto::{d:?}.palavra_canonica() == \
1296                 \"defmolde\" ({via_palavra_canonica}) — a split between the \
1297                 typed predicate and the sibling keyword projection would let \
1298                 a future arm addition land at one path and drift at the other, \
1299                 which is exactly the drift this pin refuses"
1300            );
1301        }
1302    }
1303
1304    #[test]
1305    fn caixa_dialeto_is_molde_family_is_const_fn() {
1306        // Const-context pin: [`CaixaDialeto::is_molde_family`] must remain
1307        // `const fn` (its match is a fieldless-arm literal-pattern
1308        // discriminator, so no non-const operation exists on the resolution
1309        // path). Downstream consumers reaching for the predicate from a
1310        // `const` context (a future substrate-wide const-fold-driven audit
1311        // table that materializes per-arm gate-membership at build time,
1312        // a per-arm CR-admission-webhook gate registration in a `const`
1313        // context) rely on the const-ness. A future accidental downgrade
1314        // to non-`const` (an added runtime helper reachable only from a
1315        // non-`const` context) trips at caixa-core build time rather than
1316        // surfacing as a downstream `const`-context regression far from
1317        // the predicate declaration. Peer of the sibling
1318        // [`caixa_dialeto_as_str_is_const_fn`] pin on the paired
1319        // [`CaixaDialeto::as_str`] byte-string axis.
1320        const ARMS: [(CaixaDialeto, bool); 4] = [
1321            (CaixaDialeto::Pacote, CaixaDialeto::Pacote.is_molde_family()),
1322            (CaixaDialeto::Molde, CaixaDialeto::Molde.is_molde_family()),
1323            (
1324                CaixaDialeto::MoldePosicional,
1325                CaixaDialeto::MoldePosicional.is_molde_family(),
1326            ),
1327            (
1328                CaixaDialeto::Desconhecido,
1329                CaixaDialeto::Desconhecido.is_molde_family(),
1330            ),
1331        ];
1332        // Materialize the const-fold-evaluated table into a runtime slice
1333        // assertion — carries the same `bool = const fn call` shape a raw
1334        // `assert!(const_bool)` would, without tripping the
1335        // `assertions_on_constants` clippy lint that a per-arm
1336        // `assert!(CONST)` on a `const bool` triggers when the arm-count
1337        // is enumerated flat rather than compared as a whole-table shape.
1338        assert_eq!(
1339            ARMS,
1340            [
1341                (CaixaDialeto::Pacote, false),
1342                (CaixaDialeto::Molde, true),
1343                (CaixaDialeto::MoldePosicional, true),
1344                (CaixaDialeto::Desconhecido, false),
1345            ],
1346            "CaixaDialeto::is_molde_family() must evaluate in const context \
1347             for every arm and land on the {{false, true, true, false}} \
1348             partition — a future accidental downgrade to non-`const` \
1349             would trip the const-context array-initializer here"
1350        );
1351    }
1352
1353    #[test]
1354    fn caixa_dialeto_as_str_is_const_fn() {
1355        // Const-context pin: [`CaixaDialeto::as_str`] must remain
1356        // `const fn` (its match arms return `pub const` byte-strings, so
1357        // no non-const operation exists on the resolution path).
1358        // Downstream consumers reaching for the accessor from a `const`
1359        // context (a future substrate-wide const-fold-driven audit table
1360        // that materializes every dialect's census label at build time,
1361        // a per-arm CR-admission-webhook message registration in a
1362        // `const` gate) rely on the const-ness. A future accidental
1363        // downgrade to non-`const` (an added runtime helper reachable
1364        // only from a non-`const` context, a manual hand-rolled `impl`
1365        // that shadows this method) trips at caixa-core build time
1366        // rather than surfacing as a downstream `const`-context
1367        // regression far from the accessor declaration. Peer of the
1368        // sibling [`crate::kind::tests::caixa_kind_wire_name_is_const_fn`]
1369        // pin on the paired [`crate::CaixaKind`] byte-string axis.
1370        const PACOTE: &str = CaixaDialeto::Pacote.as_str();
1371        const MOLDE: &str = CaixaDialeto::Molde.as_str();
1372        const MOLDE_POSICIONAL: &str = CaixaDialeto::MoldePosicional.as_str();
1373        const DESCONHECIDO: &str = CaixaDialeto::Desconhecido.as_str();
1374        assert_eq!(PACOTE, "Pacote");
1375        assert_eq!(MOLDE, "Molde");
1376        assert_eq!(MOLDE_POSICIONAL, "MoldePosicional");
1377        assert_eq!(DESCONHECIDO, "Desconhecido");
1378    }
1379
1380    #[test]
1381    fn caixa_dialeto_is_variant_predicates_partition_the_arm_set() {
1382        // Fail-before-pass-after pin on the [`gen_platform::IsVariant`]
1383        // derive: for each of the four variants at [`CaixaDialeto::ALL`]`[idx]`
1384        // the observed four-slot predicate row must equal a one-hot row
1385        // with the `true` at exactly `idx`. Pre-derive the closed four-arm
1386        // dialect-classification partition lived only inside the paired
1387        // per-arm projections' four-arm match resolvers ([`Self::as_str`] /
1388        // [`Self::palavra_canonica`] / [`Self::consumidor`] /
1389        // [`Self::descricao`]) plus the two-arm [`Self::is_molde_family`]
1390        // hand-rolled `matches!` (now routed through the derived
1391        // predicates); a future rebrand (an accidental
1392        // `#[is_variant(name = "…")]` drift, a manual hand-rolled `impl`
1393        // that shadows the derive-generated method, an arm rename that
1394        // reroutes one arm through the wrong predicate lane) trips this
1395        // pin at caixa-core build time rather than surfacing far from the
1396        // derive declaration as a downstream [`Self::is_molde_family`]
1397        // consumer accepting the wrong arm-set. The expected row is
1398        // generated live from the [`Self::ALL`] declaration order rather
1399        // than transcribed by hand so a copy-paste flip reroutes at the
1400        // identity-diagonal assertion.
1401        //
1402        // Peer of the sibling
1403        // [`crate::kind::tests::caixa_kind_is_variant_predicates_partition_the_arm_set`]
1404        // / [`crate::supervisor::tests::restart_strategy_is_variant_predicates_partition_the_arm_set`]
1405        // / [`crate::aplicacao::tests::placement_strategy_is_variant_predicates_partition_the_arm_set`]
1406        // / [`crate::upgrade::tests::upgrade_instruction_is_variant_predicates_partition_the_arm_set`]
1407        // pins on the sibling closed-set typed-enum discriminator axes.
1408        for (idx, &variant) in CaixaDialeto::ALL.iter().enumerate() {
1409            let observed = [
1410                variant.is_pacote(),
1411                variant.is_molde(),
1412                variant.is_molde_posicional(),
1413                variant.is_desconhecido(),
1414            ];
1415            let mut expected = [false; 4];
1416            expected[idx] = true;
1417            assert_eq!(
1418                observed, expected,
1419                "CaixaDialeto::{variant:?} at ALL[{idx}] is_* predicates \
1420                 must fire only on their own arm lane (identity diagonal); \
1421                 got {observed:?}",
1422            );
1423        }
1424    }
1425
1426    #[test]
1427    fn caixa_dialeto_is_variant_predicates_are_const_fn() {
1428        // The [`gen_platform::IsVariant`] derive emits `const fn`
1429        // predicates on the peer [`crate::CaixaKind`] +
1430        // [`crate::upgrade::UpgradeInstruction`] +
1431        // [`crate::supervisor::RestartStrategy`] +
1432        // [`crate::supervisor::RestartPolicy`] +
1433        // [`crate::aplicacao::PlacementStrategy`] +
1434        // [`crate::aplicacao::RateLimitUnit`] +
1435        // [`crate::dep::DepList`] closed-set typed enums — pin the same
1436        // posture on [`CaixaDialeto`] so a future accidental downgrade
1437        // to non-`const` (an added runtime helper reachable only from a
1438        // non-`const` context, a manual hand-rolled `impl` that shadows
1439        // the derive-generated method) trips at caixa-core build time
1440        // rather than surfacing as a downstream `const`-context
1441        // regression far from the derive declaration.
1442        // Use `const { assert!(…) }` (peer of the sibling
1443        // [`crate::render::PathShapeViolation`] +
1444        // [`crate::aplicacao::RateLimitUnit`] +
1445        // [`caixa_theme::style::Semantic`] const-fn pins) so the
1446        // const-context evaluation trips at const-fold time without
1447        // opening a per-`const bool` `assertions_on_constants` clippy
1448        // debt row this crate does not carry today for `dialeto.rs`.
1449        const { assert!(CaixaDialeto::Pacote.is_pacote()) };
1450        const { assert!(CaixaDialeto::Molde.is_molde()) };
1451        const { assert!(CaixaDialeto::MoldePosicional.is_molde_posicional()) };
1452        const { assert!(CaixaDialeto::Desconhecido.is_desconhecido()) };
1453    }
1454
1455    #[test]
1456    fn caixa_dialeto_from_wire_accepts_every_as_str_output() {
1457        // Fail-before-pass-after per-arm accept pin on the newly lifted
1458        // [`CaixaDialeto::from_wire`] reverse projection: every arm in
1459        // [`CaixaDialeto::ALL`] must parse back through `from_wire` when
1460        // fed its own [`CaixaDialeto::as_str`] output, landing on
1461        // `Some(same_variant)` — a regression that hand-rolled either
1462        // side's per-arm match without threading through the shared
1463        // four-string closed set would silently disagree on any future
1464        // arm rename and this pin flags it at caixa-core build time.
1465        // Peer of the sibling
1466        // [`crate::kind::tests::caixa_kind_wire_round_trips_through_from_wire`]
1467        // (2aa6d23) /
1468        // `placement_strategy_from_wire_accepts_every_lifted_constant`
1469        // (18c7342) /
1470        // `dep_list_round_trips_through_as_str_and_from_wire` (45ee563)
1471        // shape on the sibling closed-set typed-enum reverse-projection
1472        // axes.
1473        for &variant in CaixaDialeto::ALL {
1474            let wire = variant.as_str();
1475            let parsed = CaixaDialeto::from_wire(wire).unwrap_or_else(|| {
1476                panic!(
1477                    "CaixaDialeto::from_wire({wire:?}) must accept every \
1478                     CaixaDialeto::as_str output — got None for the \
1479                     wire byte-string of {variant:?}"
1480                )
1481            });
1482            assert_eq!(
1483                parsed, variant,
1484                "CaixaDialeto::from_wire(CaixaDialeto::{variant:?}.as_str()) \
1485                 must return CaixaDialeto::{variant:?} — the (as_str, \
1486                 from_wire) pair must form a total round-trip on the \
1487                 closed four-arm CaixaDialeto arm-set"
1488            );
1489        }
1490    }
1491
1492    #[test]
1493    fn caixa_dialeto_from_wire_rejects_unknown_byte_strings() {
1494        // Rejection pin on the parser's accept-set: any string outside
1495        // the four-arm [`CaixaDialeto::as_str`] output set must return
1496        // `None`. A future accidental widening of the accept-set (a
1497        // case-insensitive match that accepts `"pacote"` on the wire
1498        // axis, a hand-rolled Levenshtein-forgiving arm-lookup that
1499        // admits `"Pacotee"` typos, a silent acceptance of the sibling
1500        // [`Self::palavra_canonica`] `"defcaixa"` / `"defmolde"`
1501        // byte-shapes on this axis) would silently drift the parser's
1502        // accept-set from the emitter's — a downstream audit-report
1503        // re-loader that bound a prior audit's [`Self::as_str`] output
1504        // back to the typed enum through this parser would then bind a
1505        // malformed byte-string to a plausibly-wrong typed arm the
1506        // caller does not route through any fallback, silently
1507        // misclassifying the reloaded row. Also rejects the sibling
1508        // [`Self::palavra_canonica`] (`"defcaixa"` / `"defmolde"`) and
1509        // the sibling [`Self::consumidor`] (`"caixa-core / feira"`,
1510        // `"pleme-doc-gen"`, `"nobody known"`) byte-shapes, which are
1511        // the substrate's *distinct-axis* projections on the same enum
1512        // — the two-axis split the sibling
1513        // [`Self::palavra_canonica`] / [`Self::consumidor`] /
1514        // [`Self::descricao`] docstrings explicitly frame forbids
1515        // accepting one axis's byte-shapes as parseable on the other
1516        // axis. Peer of the sibling
1517        // [`crate::kind::tests::caixa_kind_from_wire_rejects_unknown_byte_strings`]
1518        // (2aa6d23) /
1519        // `placement_strategy_from_wire_rejects_unknown_byte_strings`
1520        // (18c7342) /
1521        // `dep_list_from_wire_returns_none_on_unknown_wire_scalar`
1522        // (45ee563) rejection pins on the sibling closed-set typed-enum
1523        // reverse-projection axes.
1524        for bad in [
1525            "",
1526            " ",
1527            "pacote",
1528            "PACOTE",
1529            "molde",
1530            "MoldePositional",
1531            "desconhecido",
1532            "Unknown",
1533            "defcaixa",
1534            "defmolde",
1535            "?",
1536            "caixa-core / feira",
1537            "pleme-doc-gen",
1538            "nobody known",
1539            "Pacote ",
1540            " Pacote",
1541        ] {
1542            assert!(
1543                CaixaDialeto::from_wire(bad).is_none(),
1544                "CaixaDialeto::from_wire({bad:?}) must return None — the \
1545                 parser's accept-set is exactly the four CaixaDialeto::as_str \
1546                 outputs; a widening would silently split the parser's \
1547                 accept-set from the emitter's arm-set"
1548            );
1549        }
1550    }
1551
1552    #[test]
1553    fn cabeca_errada_ctor_matches_struct_literal_wrap() {
1554        // Fail-before-pass-after byte-identity pin: the lifted
1555        // [`DialetoError::cabeca_errada`] ctor MUST land on the exact
1556        // same struct-literal shape the pre-lift open-coded wire-up
1557        // block wrote by hand — `DialetoError::CabecaErrada {
1558        // encontrado: <head>.to_string() }`. A future accidental
1559        // divergence (`.into()` swap, per-arm constant substitution, an
1560        // added default field, an `.to_ascii_lowercase()` normalization
1561        // silently injected into the ctor body, a rebrand of the
1562        // `encontrado` field carrying a distinct byte-shape) trips this
1563        // pin at caixa-core build time rather than surfacing far from
1564        // the ctor declaration as a downstream `classify_form`
1565        // wrong-head consumer emitting one diagnostic shape while a
1566        // hand-written test peer opens another. Peer of the sibling
1567        // `unknown_byte_unit_ctor_matches_struct_literal_wrap`
1568        // (limits.rs; 29fac09) / `duplicate_from_ctor_matches_struct_
1569        // literal_wrap` (upgrade.rs; 7e52aec) shape on the sibling
1570        // single-slot `{ <field>: String }` envelope constructors.
1571        assert_eq!(
1572            DialetoError::cabeca_errada("defflake"),
1573            DialetoError::CabecaErrada {
1574                encontrado: "defflake".to_string(),
1575            },
1576            "DialetoError::cabeca_errada must byte-equal the pre-lift \
1577             open-coded struct-literal — a drift here means the ctor \
1578             stopped being a substrate primitive for the wrong-head \
1579             fallthrough site"
1580        );
1581    }
1582
1583    #[test]
1584    fn cabeca_errada_routes_encontrado_verbatim_across_boundary_inputs() {
1585        // Fail-before-pass-after boundary-sweep pin: the lifted
1586        // [`DialetoError::cabeca_errada`] ctor MUST route its
1587        // `encontrado: &str` argument verbatim into the
1588        // [`DialetoError::CabecaErrada`] `encontrado: String` field
1589        // for every boundary-covering `&str` input — empty string, a
1590        // canonical `defcaixa`-adjacent head, a non-ASCII head, a
1591        // whitespace-carrying head, a Unicode-full-width head. Any
1592        // wrapper-side truncation, silent `.trim()`, accidental
1593        // `.to_ascii_lowercase()` normalization, or `.into()` divergence
1594        // on the ctor body surfaces here as a byte-mismatch against the
1595        // input rather than at a downstream
1596        // [`DialetoError::to_string()`] diagnostic-shape drift at a
1597        // wrong-head fallthrough consumer far from the ctor declaration.
1598        // Peer of the sibling `limits_codec_unit_only_ctors_route_unit_
1599        // verbatim_across_every_variant` (limits.rs; 29fac09) shape on
1600        // the sibling single-slot `{ <field>: String }` envelope
1601        // boundary-sweep discipline.
1602        for encontrado in [
1603            "",
1604            "defflake",
1605            "def-molde",
1606            "defcaixa ",
1607            " defcaixa",
1608            "μdefcaixa",
1609            "\u{00A0}defcaixa",
1610            "\u{3000}defcaixa",
1611            "def\u{2028}caixa",
1612        ] {
1613            let via_ctor = DialetoError::cabeca_errada(encontrado);
1614            let via_literal = DialetoError::CabecaErrada {
1615                encontrado: encontrado.to_string(),
1616            };
1617            assert_eq!(
1618                via_ctor, via_literal,
1619                "DialetoError::cabeca_errada({encontrado:?}) must byte- \
1620                 equal the open-coded struct-literal on the same input — \
1621                 a drift here would let the ctor silently normalize / \
1622                 truncate the head symbol before it reached the \
1623                 CabecaErrada envelope"
1624            );
1625            let DialetoError::CabecaErrada { encontrado: routed } = via_ctor else {
1626                panic!(
1627                    "DialetoError::cabeca_errada must construct the \
1628                     CabecaErrada arm — got a different variant on \
1629                     input {encontrado:?}"
1630                );
1631            };
1632            assert_eq!(
1633                routed, encontrado,
1634                "DialetoError::cabeca_errada must route the input \
1635                 {encontrado:?} verbatim into the encontrado field — \
1636                 any wrapper-side truncation / normalization surfaces \
1637                 here rather than at a downstream diagnostic shape drift"
1638            );
1639        }
1640    }
1641
1642    #[test]
1643    fn classify_form_wrong_head_routes_through_cabeca_errada_ctor() {
1644        // Fail-before-pass-after routing pin: [`classify`]'s wrong-head
1645        // fallthrough site MUST construct its `Err(DialetoError::…)`
1646        // through the substrate-primitive [`DialetoError::cabeca_errada`]
1647        // ctor rather than through an open-coded struct-literal. Pre-
1648        // lift the wire-up hand-rolled a three-line
1649        // `Self::CabecaErrada { encontrado: other.to_string() }` block
1650        // with no compile-time link back to the substrate primitive; a
1651        // future accidental rebrand of the ctor body (an added
1652        // `.trim()` on `encontrado`, a per-arm constant prefix like
1653        // `"unknown-head:"`, a widening of the field into a
1654        // `(String, usize)` tuple carrying a caret offset) would then
1655        // silently split the two paths — the ctor consumers pick up
1656        // the new shape, the open-coded wire-up does not. Pinning
1657        // byte-equality between the observed `Err` and the ctor-
1658        // constructed `Err` refuses that split at caixa-core build
1659        // time rather than surfacing far from the wire-up commit as a
1660        // downstream diagnostic-consumer split.
1661        for head in ["defflake", "deffoobar", "defcaixaz", "let", "defmoldez"] {
1662            let src = format!("({head} :nome \"x\")");
1663            let observed = classify(&src);
1664            let via_ctor = Err(DialetoError::cabeca_errada(head));
1665            assert_eq!(
1666                observed, via_ctor,
1667                "classify({src:?}) must return the same Err shape as \
1668                 DialetoError::cabeca_errada({head:?}) — a drift here \
1669                 means the wire-up de-lifted its wrong-head fallthrough \
1670                 arm off the substrate primitive"
1671            );
1672        }
1673    }
1674
1675    #[test]
1676    fn leitura_ctor_matches_tuple_literal_wrap_on_str_binding() {
1677        // Fail-before-pass-after byte-identity pin: the lifted
1678        // [`DialetoError::leitura`] ctor MUST land on the exact same
1679        // tuple-newtype wrap the pre-lift open-coded wire-up block wrote by
1680        // hand — `DialetoError::Leitura(<into-String-expr>)`. A future
1681        // accidental divergence (an added `.trim()` on the reader reason,
1682        // a per-arm constant prefix like `"tatara-lisp:"`, a widening of
1683        // the tuple carrying a caret offset, a rebrand of the payload
1684        // carrying a distinct byte-shape) trips this pin at caixa-core
1685        // build time rather than surfacing far from the ctor declaration
1686        // as a downstream [`classify`] tatara-lisp-reader consumer
1687        // emitting one diagnostic shape while a hand-written test peer
1688        // opens another. Peer of the sibling
1689        // `cabeca_errada_ctor_matches_struct_literal_wrap` pin above on
1690        // the same [`DialetoError`] envelope's wrong-head axis, and of
1691        // the peer `LimitsError::empty_byte_size` /
1692        // `LimitsError::empty_duration` (7a4b003 / 319216c) shape on the
1693        // sibling `(String)` single-slot tuple-newtype envelope
1694        // constructors.
1695        let reason: &str = "unclosed paren at 1:12";
1696        assert_eq!(
1697            DialetoError::leitura(reason),
1698            DialetoError::Leitura(reason.to_string()),
1699            "DialetoError::leitura must byte-equal the pre-lift open-coded \
1700             tuple-newtype wrap — a drift here means the ctor stopped \
1701             being a substrate primitive for the tatara-lisp-reader \
1702             fallthrough site"
1703        );
1704    }
1705
1706    #[test]
1707    fn leitura_ctor_matches_tuple_literal_wrap_on_string_binding() {
1708        // Fail-before-pass-after byte-identity pin on the `String` wire-up
1709        // shape: the lifted [`DialetoError::leitura`] ctor MUST land on
1710        // the same tuple-newtype wrap when the caller passes an owned
1711        // `String` (the actual [`classify`] wire-up shape — `e.to_string()`
1712        // on a [`tatara_lisp::Error`]-carrying binding). Pins that the
1713        // `impl Into<String>` param covers the owned-`String` path with no
1714        // silent double-allocation or intermediate `&str` reslicing. Peer
1715        // of the sibling `_on_str_binding` pin above — together they close
1716        // the `impl Into<String>` bound's two authored wire-up shapes on
1717        // the ctor's substrate primitive.
1718        let reason: String = String::from("read: unexpected EOF at 3:1");
1719        let via_ctor = DialetoError::leitura(reason.clone());
1720        let via_literal = DialetoError::Leitura(reason.clone());
1721        assert_eq!(
1722            via_ctor, via_literal,
1723            "DialetoError::leitura must byte-equal the pre-lift open-coded \
1724             tuple-newtype wrap on the same owned-String fixture — a drift \
1725             here would let the ctor silently reshape the reader reason \
1726             before it reached the Leitura envelope"
1727        );
1728        let DialetoError::Leitura(routed) = via_ctor else {
1729            panic!(
1730                "DialetoError::leitura must construct the Leitura arm — \
1731                 got a different variant on input {reason:?}"
1732            );
1733        };
1734        assert_eq!(
1735            routed, reason,
1736            "DialetoError::leitura must route the input {reason:?} \
1737             verbatim into the tuple-newtype payload — any wrapper-side \
1738             truncation / normalization surfaces here rather than at a \
1739             downstream diagnostic shape drift"
1740        );
1741    }
1742
1743    #[test]
1744    fn leitura_routes_reason_verbatim_across_boundary_inputs() {
1745        // Fail-before-pass-after boundary-sweep pin: the lifted
1746        // [`DialetoError::leitura`] ctor MUST route its
1747        // `reason: impl Into<String>` argument verbatim into the
1748        // [`DialetoError::Leitura`] tuple-newtype `String` payload for
1749        // every boundary-covering input — empty string, a canonical
1750        // tatara-lisp reader error, a non-ASCII reason, a
1751        // whitespace-carrying reason, a Unicode-full-width reason. Any
1752        // wrapper-side truncation, silent `.trim()`, accidental
1753        // `.to_ascii_lowercase()` normalization, or `.into()` divergence
1754        // on the ctor body surfaces here as a byte-mismatch against the
1755        // input rather than at a downstream [`DialetoError::to_string()`]
1756        // diagnostic-shape drift at a tatara-lisp-reader fallthrough
1757        // consumer far from the ctor declaration. Peer of the sibling
1758        // `cabeca_errada_routes_encontrado_verbatim_across_boundary_inputs`
1759        // pin above on the same [`DialetoError`] envelope's wrong-head
1760        // axis.
1761        for reason in [
1762            "",
1763            "unclosed paren at 1:12",
1764            "unexpected token ')'",
1765            "read: eof",
1766            " leading whitespace",
1767            "trailing whitespace ",
1768            "μnicode reason",
1769            "\u{00A0}NBSP-prefixed reason",
1770            "\u{3000}ideographic-space reason",
1771            "reason\u{2028}with-line-separator",
1772        ] {
1773            let via_ctor = DialetoError::leitura(reason);
1774            let via_literal = DialetoError::Leitura(reason.to_string());
1775            assert_eq!(
1776                via_ctor, via_literal,
1777                "DialetoError::leitura({reason:?}) must byte-equal the \
1778                 open-coded tuple-newtype wrap on the same input — a \
1779                 drift here would let the ctor silently normalize / \
1780                 truncate the reader reason before it reached the \
1781                 Leitura envelope"
1782            );
1783            let DialetoError::Leitura(routed) = via_ctor else {
1784                panic!(
1785                    "DialetoError::leitura must construct the Leitura \
1786                     arm — got a different variant on input {reason:?}"
1787                );
1788            };
1789            assert_eq!(
1790                routed, reason,
1791                "DialetoError::leitura must route the input {reason:?} \
1792                 verbatim into the tuple-newtype payload — any \
1793                 wrapper-side truncation / normalization surfaces here \
1794                 rather than at a downstream diagnostic shape drift"
1795            );
1796        }
1797    }
1798
1799    #[test]
1800    fn classify_reader_error_routes_through_leitura_ctor() {
1801        // Fail-before-pass-after routing pin: [`classify`]'s
1802        // tatara-lisp-reader map-err site MUST construct its
1803        // `Err(DialetoError::…)` through the substrate-primitive
1804        // [`DialetoError::leitura`] ctor rather than through an
1805        // open-coded tuple-newtype wrap. Pre-lift the wire-up hand-rolled
1806        // a `Self::Leitura(e.to_string())` block with no compile-time
1807        // link back to the substrate primitive; a future accidental
1808        // rebrand of the ctor body (an added `.trim()` on the reader
1809        // reason, a per-arm constant prefix like `"tatara-lisp:"`, a
1810        // widening of the payload into a `(String, usize)` tuple
1811        // carrying a caret offset) would then silently split the two
1812        // paths — the ctor consumers pick up the new shape, the
1813        // open-coded wire-up does not. Pinning byte-equality between
1814        // the observed `Err` and the ctor-constructed `Err` refuses
1815        // that split at caixa-core build time rather than surfacing far
1816        // from the wire-up commit as a downstream diagnostic-consumer
1817        // split. Peer of the sibling
1818        // `classify_form_wrong_head_routes_through_cabeca_errada_ctor`
1819        // pin above on the same [`DialetoError`] envelope's wrong-head
1820        // fallthrough axis.
1821        //
1822        // The malformed sources below each name a distinct
1823        // tatara-lisp-reader failure shape (unclosed paren, stray close
1824        // paren, unterminated string), so together they sweep the
1825        // reader's rejection surface rather than pinning against one
1826        // specific error message the reader upstream is free to reword.
1827        for src in [
1828            "(defcaixa :nome \"x\"",
1829            "defcaixa :nome \"x\")",
1830            "(defcaixa :nome \"unterminated",
1831        ] {
1832            let observed = classify(src);
1833            let Err(DialetoError::Leitura(reason)) = observed.clone() else {
1834                panic!(
1835                    "classify({src:?}) must return the Leitura arm — got \
1836                     {observed:?}"
1837                );
1838            };
1839            let via_ctor: Result<CaixaDialeto, DialetoError> =
1840                Err(DialetoError::leitura(reason.clone()));
1841            assert_eq!(
1842                observed, via_ctor,
1843                "classify({src:?}) must return the same Err shape as \
1844                 DialetoError::leitura({reason:?}) — a drift here means \
1845                 the wire-up de-lifted its tatara-lisp-reader fallthrough \
1846                 arm off the substrate primitive"
1847            );
1848        }
1849    }
1850
1851    #[test]
1852    fn caixa_dialeto_try_from_str_routes_through_from_wire_accessor() {
1853        // Fail-before-pass-after byte-parity pin on the lifted
1854        // `impl TryFrom<&str> for CaixaDialeto`: for every arm in
1855        // [`CaixaDialeto::ALL`], the `.try_into()` / `TryFrom::try_from`
1856        // path must resolve to the same variant the sibling
1857        // [`CaixaDialeto::from_wire`] resolver returns on the same
1858        // [`CaixaDialeto::as_str`] wire byte-string input. Pins the
1859        // three-path convergence discipline the [`CaixaDialeto`] closed-
1860        // set typed enum now carries on the `str → Self` reverse-
1861        // projection axis: `<CaixaDialeto as TryFrom<&str>>::try_from(s)`
1862        // (the newly lifted trait-idiomatic reverse projection),
1863        // `CaixaDialeto::from_wire(s)` (the substrate-primitive method-
1864        // named `Option<Self>` accessor the trait impl delegates through),
1865        // and the round-trip identity `variant.as_str() → variant`
1866        // (the four-arm closed accept-set shared between the emitter and
1867        // both reverse-projection consumers) must resolve to the same
1868        // typed [`CaixaDialeto`] discriminator on every arm.
1869        //
1870        // A future silent detour that routes the impl through a
1871        // divergent projection (a per-arm inline
1872        // `match s { "Pacote" => …, … }` re-inlining that opens a
1873        // compile-time link to the un-lifted arm-literal, a swap onto
1874        // the second-axis [`CaixaDialeto::palavra_canonica`] /
1875        // [`CaixaDialeto::consumidor`] / [`CaixaDialeto::descricao`]
1876        // accessors that carry distinct byte-shapes per axis, an accept-
1877        // set widening that silently accepts one axis's byte-shapes as
1878        // parseable on the other axis) trips at caixa-core test time
1879        // under `assert_eq!` rather than at a downstream
1880        // `TryFrom<&str>`-bound consumer's silent split. Peer of the
1881        // sibling
1882        // [`crate::kind::tests::caixa_kind_try_from_str_routes_through_from_wire_accessor`]
1883        // (3c83606) on the top-level [`crate::CaixaKind`] closed-set
1884        // discriminator's reverse-projection axis — extends the trait-
1885        // idiomatic reverse-projection axis onto the seventh closed-set
1886        // fieldless typed enum on the caixa surface (the second one to
1887        // carry the paired `TryFrom<&str>` impl).
1888        for &variant in CaixaDialeto::ALL {
1889            let wire = variant.as_str();
1890            let via_try_from: CaixaDialeto = <CaixaDialeto as TryFrom<&str>>::try_from(wire)
1891                .unwrap_or_else(|()| {
1892                    panic!(
1893                        "CaixaDialeto::try_from({wire:?}) must accept every \
1894                         CaixaDialeto::as_str output — got Err(()) for the \
1895                         wire byte-string of {variant:?}"
1896                    )
1897                });
1898            let via_from_wire: CaixaDialeto = CaixaDialeto::from_wire(wire).unwrap_or_else(|| {
1899                panic!(
1900                    "CaixaDialeto::from_wire({wire:?}) must accept every \
1901                     CaixaDialeto::as_str output — got None for the wire \
1902                     byte-string of {variant:?}"
1903                )
1904            });
1905            assert_eq!(
1906                via_try_from, variant,
1907                "CaixaDialeto::try_from(CaixaDialeto::{variant:?}.as_str()) \
1908                 must return CaixaDialeto::{variant:?} — the trait-idiomatic \
1909                 reverse projection must land on the same arm the method-named \
1910                 from_wire resolver does",
1911            );
1912            assert_eq!(
1913                via_try_from, via_from_wire,
1914                "CaixaDialeto::try_from({wire:?}) ({via_try_from:?}) must \
1915                 byte-equal CaixaDialeto::from_wire({wire:?}) ({via_from_wire:?}) \
1916                 on the same input — divergence signals a silent detour off the \
1917                 shared substrate-primitive resolver",
1918            );
1919            assert_eq!(
1920                <CaixaDialeto as TryFrom<&str>>::try_from(wire).ok(),
1921                CaixaDialeto::from_wire(wire),
1922                "the Result::ok() projection of TryFrom<&str> must byte-equal \
1923                 the sibling from_wire Option<Self> output on {wire:?} — the \
1924                 two accessors must share the same accept-set and typed \
1925                 outcome per arm",
1926            );
1927        }
1928    }
1929
1930    #[test]
1931    fn caixa_dialeto_try_from_str_rejects_unknown_byte_strings() {
1932        // Rejection witness on the trait-idiomatic reverse-projection
1933        // axis: any string outside the four-arm [`CaixaDialeto::as_str`]
1934        // output set must resolve to `Err(())` through the lifted
1935        // [`impl TryFrom<&str> for CaixaDialeto`]. A future accidental
1936        // widening of the accept-set (a case-insensitive match that
1937        // accepts `"pacote"` on the wire axis, a hand-rolled Levenshtein-
1938        // forgiving arm-lookup that admits `"Pacotee"` typos, a silent
1939        // acceptance of the sibling [`CaixaDialeto::palavra_canonica`]
1940        // `"defcaixa"` / `"defmolde"` byte-shapes on this axis, a swap
1941        // onto the [`CaixaDialeto::consumidor`] `"pleme-doc-gen"` /
1942        // `"caixa-core / feira"` / `"nobody known"` byte-shapes) would
1943        // silently drift the trait-idiomatic parser's accept-set from
1944        // the sibling [`CaixaDialeto::from_wire`] resolver's — a
1945        // downstream `TryFrom<&str>`-bound consumer binding a malformed
1946        // byte-string through this impl would then bind a plausibly-
1947        // wrong typed arm the caller does not route through any fallback,
1948        // silently misclassifying the reloaded row.
1949        //
1950        // Sweeps the same rejection set the sibling
1951        // [`caixa_dialeto_from_wire_rejects_unknown_byte_strings`] pin
1952        // walks (the shared `from_wire` resolver both accessors delegate
1953        // through) so the trait-idiomatic axis and the method-named axis
1954        // stay locked to the same accept-set by construction. Peer of the
1955        // sibling
1956        // [`crate::kind::tests::caixa_kind_try_from_str_rejects_unknown_byte_strings`]
1957        // (3c83606) on the top-level [`crate::CaixaKind`] closed-set
1958        // discriminator's trait-idiomatic reverse-projection axis.
1959        for bad in [
1960            "",
1961            " ",
1962            "pacote",
1963            "PACOTE",
1964            "molde",
1965            "MoldePositional",
1966            "desconhecido",
1967            "Unknown",
1968            "defcaixa",
1969            "defmolde",
1970            "?",
1971            "caixa-core / feira",
1972            "pleme-doc-gen",
1973            "nobody known",
1974            "Pacote ",
1975            " Pacote",
1976        ] {
1977            assert_eq!(
1978                <CaixaDialeto as TryFrom<&str>>::try_from(bad),
1979                Err(()),
1980                "CaixaDialeto::try_from({bad:?}) must return Err(()) — the \
1981                 trait-idiomatic parser's accept-set is exactly the four \
1982                 CaixaDialeto::as_str outputs; a widening would silently \
1983                 split the trait-idiomatic reverse-projection axis from the \
1984                 sibling from_wire resolver's arm-set"
1985            );
1986        }
1987    }
1988
1989    #[test]
1990    fn caixa_dialeto_from_into_static_str_routes_through_as_str_accessor() {
1991        // Fail-before-pass-after byte-parity pin on the newly lifted
1992        // `impl From<CaixaDialeto> for &'static str` — asserts the
1993        // standard-library trait impl and the substrate-primitive
1994        // [`CaixaDialeto::as_str`] `pub const fn` accessor resolve to
1995        // the same four-arm emit-set across every arm the exhaustive
1996        // [`CaixaDialeto::ALL`] slice enumerates. Any future silent
1997        // detour that routes the trait impl through a divergent
1998        // projection (a per-arm inline `match dialeto { Pacote =>
1999        // "Pacote", … }` re-inlining that opens a compile-time link to
2000        // the un-lifted arm-literal, an accidental swap onto the second-
2001        // axis [`CaixaDialeto::palavra_canonica`] /
2002        // [`CaixaDialeto::consumidor`] / [`CaixaDialeto::descricao`]
2003        // accessors that carry distinct byte-shapes per axis) trips at
2004        // caixa-core test time under `assert_eq!` rather than at a
2005        // downstream `impl Into<&'static str>`-bound consumer's silent
2006        // split. Sweeps every one of the four arms [`CaixaDialeto::ALL`]
2007        // carries so no arm's projection is covered only by the sibling
2008        // method-named `as_str` / [`std::fmt::Display`] / [`AsRef<str>`]
2009        // paths. Materializes the `<&'static str as
2010        // From<CaixaDialeto>>::from` output in a `const`-shape binding
2011        // to make the `'static` lifetime promise a build-time invariant
2012        // — a future accidental downgrade of any of the four arms'
2013        // returned literals to a non-`&'static str` (a `String::leak()`-
2014        // produced return, a `Box::leak`-cast, an intermediate lifetime-
2015        // erasing helper) trips at caixa-core build time rather than at
2016        // a downstream `'static`-bound consumer. Peer of the sibling
2017        // [`crate::supervisor::tests::restart_strategy_from_into_static_str_routes_through_as_str_accessor`]
2018        // (523157d) /
2019        // [`crate::supervisor::tests::restart_policy_from_into_static_str_routes_through_as_str_accessor`]
2020        // (9fb37d0) /
2021        // [`crate::kind::tests::caixa_kind_from_into_static_str_routes_through_as_str_accessor`]
2022        // (edb827b) pins on the sibling closed-set typed-enum forward-
2023        // projection axes — extends the trait-idiomatic forward-
2024        // projection axis onto the fourth closed-set fieldless typed
2025        // enum on the caixa surface (the dialect-classification axis,
2026        // second-of-two closed-set typed enums in caixa-core outside
2027        // the OTP-shape M2 slot).
2028        const PACOTE: &str = CaixaDialeto::Pacote.as_str();
2029        const MOLDE: &str = CaixaDialeto::Molde.as_str();
2030        const MOLDE_POSICIONAL: &str = CaixaDialeto::MoldePosicional.as_str();
2031        const DESCONHECIDO: &str = CaixaDialeto::Desconhecido.as_str();
2032        for &variant in CaixaDialeto::ALL {
2033            let via_trait: &'static str = <&'static str as From<CaixaDialeto>>::from(variant);
2034            let via_method: &'static str = variant.as_str();
2035            assert_eq!(
2036                via_trait, via_method,
2037                "From<CaixaDialeto> for &'static str impl must round-trip \
2038                 CaixaDialeto::{variant:?} to the same `PascalCase` byte-string \
2039                 CaixaDialeto::as_str returns — divergence signals a silent \
2040                 detour off the substrate-primitive accessor"
2041            );
2042            let via_into: &'static str = variant.into();
2043            assert_eq!(
2044                via_into, via_method,
2045                "Into<&'static str>::into on CaixaDialeto::{variant:?} must \
2046                 byte-equal CaixaDialeto::as_str on the same input — the \
2047                 blanket-derived Into shape must resolve to the same as_str \
2048                 dispatch as the explicit From impl"
2049            );
2050        }
2051        assert_eq!(
2052            [PACOTE, MOLDE, MOLDE_POSICIONAL, DESCONHECIDO],
2053            ["Pacote", "Molde", "MoldePosicional", "Desconhecido"],
2054            "const-context CaixaDialeto::as_str must resolve to the four \
2055             `PascalCase` variant-name byte-strings — a future accidental \
2056             downgrade of any arm to a non-const or non-static byte-string \
2057             breaks the `&'static str`-lifetime promise the paired \
2058             From<CaixaDialeto> for &'static str impl carries by \
2059             construction"
2060        );
2061    }
2062
2063    #[test]
2064    fn caixa_dialeto_from_into_static_str_and_as_str_partition_the_emit_set() {
2065        // Cross-axis partition pin: the paired trait-idiomatic
2066        // `From<CaixaDialeto> for &'static str` forward projection and
2067        // the method-named [`CaixaDialeto::as_str`] forward projection
2068        // must resolve identically on *every* arm, not just the ones
2069        // named in the primary byte-parity pin above. Sweeps every
2070        // [`CaixaDialeto::ALL`] arm and asserts the trait's `From::from`
2071        // output byte-equals the method-named accessor's return-value on
2072        // each, locking the two forward-projection paths together by
2073        // construction so any future detour (a stray `From` special-case
2074        // that lands on a divergent per-arm literal outside the paired
2075        // `as_str` dispatch, a hypothetical rebrand touching one axis
2076        // without the other) trips at caixa-core test time. Peer of the
2077        // sibling forward-projection partition pins
2078        // [`crate::supervisor::tests::restart_strategy_from_into_static_str_and_as_str_partition_the_emit_set`]
2079        // (523157d) /
2080        // [`crate::supervisor::tests::restart_policy_from_into_static_str_and_as_str_partition_the_emit_set`]
2081        // (9fb37d0) /
2082        // [`crate::kind::tests::caixa_kind_from_into_static_str_and_as_str_partition_the_emit_set`]
2083        // (edb827b) — extends the round-trip discipline onto the fourth
2084        // closed-set typed enum on the caixa surface, closing the two-way
2085        // `Self ↔ &'static str` round-trip on the trait-idiomatic pair
2086        // (`From<Self> for &'static str` + `TryFrom<&str> for Self`) as
2087        // well as the pre-existing method-named pair (`as_str` +
2088        // `from_wire`).
2089        for &variant in CaixaDialeto::ALL {
2090            let via_trait: &'static str = <&'static str as From<CaixaDialeto>>::from(variant);
2091            let via_method: &'static str = variant.as_str();
2092            assert_eq!(
2093                via_trait, via_method,
2094                "From<CaixaDialeto> for &'static str and \
2095                 CaixaDialeto::as_str must resolve identically on \
2096                 CaixaDialeto::{variant:?} — divergence signals the \
2097                 two forward-projection paths have drifted onto different \
2098                 emit-sets"
2099            );
2100        }
2101        // Round-trip witness: every arm's forward `From` output re-parses
2102        // through the paired trait-idiomatic reverse `TryFrom<&str>` back
2103        // to the original variant. Closes the two-way `CaixaDialeto ↔
2104        // &'static str` round-trip on the trait-idiomatic axis pair
2105        // directly (no wire-vocab intermediate the peer [`CaixaKind`]
2106        // axis pair requires — the emit-side [`CaixaDialeto::as_str`]
2107        // and the parse-side [`CaixaDialeto::from_wire`] share the same
2108        // `PascalCase` byte-string vocabulary by construction), mirroring
2109        // the pre-existing method-named `as_str` + `from_wire` round-trip
2110        // on the substrate-primitive axis pair.
2111        for &variant in CaixaDialeto::ALL {
2112            let emitted: &'static str = variant.into();
2113            let re_parsed: Result<CaixaDialeto, ()> =
2114                <CaixaDialeto as TryFrom<&str>>::try_from(emitted);
2115            assert_eq!(
2116                re_parsed,
2117                Ok(variant),
2118                "trait-idiomatic axis pair must round-trip \
2119                 CaixaDialeto::{variant:?} through `.into::<&'static \
2120                 str>()` and back through `TryFrom<&str>` — a break signals \
2121                 the forward-emit and reverse-parse axes have drifted onto \
2122                 different vocabularies"
2123            );
2124        }
2125    }
2126
2127    #[test]
2128    fn caixa_dialeto_is_molde_family_routes_through_is_variant_derived_predicates() {
2129        // Byte-parity pin on the post-lift [`CaixaDialeto::is_molde_family`]
2130        // convergence: for every arm in [`CaixaDialeto::ALL`], the typed
2131        // predicate must byte-equal the direct
2132        // `self.is_molde() || self.is_molde_posicional()` composition of
2133        // the two derived per-arm predicates. Pre-lift the predicate
2134        // hand-rolled `matches!(self, Self::Molde | Self::MoldePosicional)`
2135        // with no compile-time link back to the closed-set typed dispatch;
2136        // post-lift it routes through the derived predicates so a future
2137        // arm rename or `#[is_variant(name = "…")]` override lands at
2138        // exactly one dispatch on the substrate primitive. Pinning the
2139        // byte-equality here refuses a future accidental split between
2140        // the composed predicate and the paired derived predicates
2141        // (a hand-rolled shadow `impl` that overrides one path but not
2142        // the other, an accidental rebrand of `is_molde_family`'s body
2143        // back to the pre-lift `matches!` form) at caixa-core build time.
2144        for &d in CaixaDialeto::ALL {
2145            let via_derived = d.is_molde() || d.is_molde_posicional();
2146            let via_is_molde_family = d.is_molde_family();
2147            assert_eq!(
2148                via_is_molde_family, via_derived,
2149                "CaixaDialeto::{d:?}.is_molde_family() ({via_is_molde_family}) \
2150                 must byte-equal the composed derived predicates \
2151                 is_molde() || is_molde_posicional() ({via_derived}) — a \
2152                 split between the composed predicate and its derived \
2153                 building blocks would let a future arm rename land at one \
2154                 path and drift at the other, which is exactly the drift \
2155                 the IsVariant lift refuses"
2156            );
2157        }
2158    }
2159}