Skip to main content

icydb_diagnostic_code/
fact.rs

1//! Module: fact
2//!
3//! Responsibility: production-safe numeric diagnostic-fact identities.
4//! Does not own: Candid records, rich labels, prose, or subsystem projections.
5//! Boundary: freezes the numeric vocabulary shared by public errors and host tooling.
6
7use std::fmt;
8
9use crate::ErrorCode;
10
11/// Maximum number of numeric facts carried by one public error.
12pub const MAX_PUBLIC_DIAGNOSTIC_FACTS: usize = 80;
13
14macro_rules! define_fact_tag_registry {
15    ($($name:ident = $raw:literal;)+) => {
16        /// Stable semantic identity for one numeric public diagnostic fact.
17        #[derive(Clone, Copy, Eq, Hash, PartialEq)]
18        pub enum DiagnosticFactTag {
19            $(
20                #[doc = concat!("Public fact tag ", stringify!($raw), ".")]
21                $name,
22            )+
23        }
24
25        impl DiagnosticFactTag {
26            /// Return the fixed public wire value.
27            #[must_use]
28            pub const fn raw(self) -> u8 {
29                match self {
30                    $(Self::$name => $raw,)+
31                }
32            }
33
34            /// Recover a known tag from its public wire value.
35            #[must_use]
36            pub const fn known(raw: u8) -> Option<Self> {
37                match raw {
38                    $($raw => Some(Self::$name),)+
39                    _ => None,
40                }
41            }
42        }
43
44        #[cfg(test)]
45        const ORDERED_FACT_TAGS: &[DiagnosticFactTag] = &[
46            $(DiagnosticFactTag::$name,)+
47        ];
48    };
49}
50
51// This table is a public numeric registry. Append only within a released
52// major-version contract; do not reuse or reinterpret an assigned value.
53define_fact_tag_registry! {
54    AcceptedSchemaFingerprintMethod = 1;
55    AcceptedSchemaFingerprintHigh = 2;
56    AcceptedSchemaFingerprintLow = 3;
57    ExpectedFingerprintPrefix = 4;
58    ActualFingerprintPrefix = 5;
59    EntityTag = 6;
60    ExpectedEntityTag = 7;
61    ActualEntityTag = 8;
62    ConstraintId = 9;
63    FieldId = 10;
64    IndexId = 11;
65    RelationId = 12;
66    MutationOperation = 13;
67    RowOperation = 14;
68    BatchPosition = 15;
69    FirstBatchPosition = 16;
70    DuplicateBatchPosition = 17;
71    ClauseIndex = 18;
72    TermIndex = 19;
73    FirstTermIndex = 20;
74    DuplicateTermIndex = 21;
75    ProjectionIndex = 22;
76    GroupIndex = 23;
77    AggregateIndex = 24;
78    ArgumentIndex = 25;
79    BranchIndex = 26;
80    ComponentIndex = 27;
81    ParameterIndex = 28;
82    SourceSpanStart = 29;
83    SourceSpanEnd = 30;
84    Expected = 31;
85    Actual = 32;
86    Minimum = 33;
87    Maximum = 34;
88    Limit = 35;
89    ExpectedCount = 36;
90    ActualCount = 37;
91    ExpectedRevision = 38;
92    ActualRevision = 39;
93    CurrentRevision = 40;
94    RequestedRevision = 41;
95    ExpectedVersion = 42;
96    ActualVersion = 43;
97    CurrentVersion = 44;
98    RequestedVersion = 45;
99    ExpectedOffset = 46;
100    ActualOffset = 47;
101    ExpectedArity = 48;
102    ActualArity = 49;
103    ExpectedLength = 50;
104    ActualLength = 51;
105    ExpectedSlotCount = 52;
106    ActualSlotCount = 53;
107    RowLayout = 54;
108    HistoryFloor = 55;
109    CurrentLayout = 56;
110    PhysicalSlot = 57;
111    PhysicalGeneration = 58;
112    ExpectedMemoryId = 59;
113    ActualMemoryId = 60;
114    ConstraintKind = 61;
115    ConstraintContext = 62;
116    FieldKind = 63;
117    ValueKind = 64;
118    TypeFamily = 65;
119    FunctionKind = 66;
120    OperatorKind = 67;
121    AggregateKind = 68;
122    KeyNamespaceKind = 69;
123    ComponentKind = 70;
124    MismatchKind = 71;
125    DecodeReason = 72;
126    BudgetResource = 73;
127    MigrationPhase = 74;
128    DatabaseControlRecordKind = 75;
129    StateKind = 76;
130    PayloadComponent = 77;
131    ExpectedSignaturePrefix = 78;
132    ActualSignaturePrefix = 79;
133    FindingPosition = 80;
134    RootField = 81;
135    RecordMember = 82;
136    TupleElement = 83;
137    Newtype = 84;
138    EnumVariant = 85;
139    ListElement = 86;
140    SetElement = 87;
141    MapEntryKey = 88;
142    MapEntryValue = 89;
143    ExecutionBudgetScope = 90;
144    ExecutionLane = 91;
145    QueryShapeFingerprintPrefix = 92;
146}
147
148/// Compact reason carried by [`DiagnosticFactTag::DecodeReason`].
149///
150/// Values are global within that fact tag. They identify only bounded decode
151/// or validation categories and never retain rejected payload bytes.
152#[derive(Clone, Copy, Eq, Hash, PartialEq)]
153pub enum DiagnosticDecodeReason {
154    CursorEmpty,
155    CursorTooLong,
156    CursorOddLength,
157    CursorInvalidHex,
158    CursorGroupedDirectionMismatch,
159    CursorTokenEncode,
160    CursorTokenDecode,
161    RecoveryMarkerMagic,
162    RecoveryMarkerChecksum,
163    RecoveryMarkerState,
164}
165
166/// Compact operation carried by [`DiagnosticFactTag::MutationOperation`].
167#[derive(Clone, Copy, Eq, Hash, PartialEq)]
168pub enum DiagnosticMutationOperation {
169    Insert,
170    Replace,
171    Update,
172    Delete,
173}
174
175macro_rules! define_numeric_fact_value_registry {
176    (
177        $(#[$enum_meta:meta])*
178        pub enum $name:ident {
179            $($variant:ident = $raw:literal;)+
180        }
181    ) => {
182        $(#[$enum_meta])*
183        #[derive(Clone, Copy, Eq, Hash, PartialEq)]
184        pub enum $name {
185            $(
186                #[doc = concat!("Compact diagnostic value ", stringify!($raw), ".")]
187                $variant,
188            )+
189        }
190
191        impl $name {
192            /// Return the fixed numeric fact value.
193            #[must_use]
194            pub const fn raw(self) -> u64 {
195                match self {
196                    $(Self::$variant => $raw,)+
197                }
198            }
199
200            /// Recover a known compact value from its public numeric identity.
201            #[must_use]
202            pub const fn known(raw: u64) -> Option<Self> {
203                match raw {
204                    $($raw => Some(Self::$variant),)+
205                    _ => None,
206                }
207            }
208        }
209
210        impl fmt::Debug for $name {
211            fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
212                write!(f, "{}", self.raw())
213            }
214        }
215    };
216}
217
218define_numeric_fact_value_registry! {
219    /// Compact hard-budget resource carried by [`DiagnosticFactTag::BudgetResource`].
220    pub enum DiagnosticExecutionBudgetResource {
221        QueryExecutions = 1;
222        PlanningSteps = 2;
223        PlanCompilations = 3;
224        KeyIndexEntriesVisited = 4;
225        RowsVisited = 5;
226        StoredBytesRead = 6;
227        PredicateExpressionSteps = 7;
228        NestedValueSteps = 8;
229        DecodedBytes = 9;
230        MaterializedBytes = 10;
231        SortEntries = 11;
232        SortComparisons = 12;
233        SortTemporaryBytes = 13;
234        GroupDistinctEntries = 14;
235        GroupDistinctStateBytes = 15;
236        CursorSteps = 16;
237        TemporaryBytes = 17;
238        DiagnosticSteps = 18;
239        ResultRows = 19;
240        ResultBytes = 20;
241        InstructionUnits = 21;
242    }
243}
244
245impl DiagnosticExecutionBudgetResource {
246    /// Every maintained hard-budget resource in stable numeric order.
247    pub const ALL: [Self; 21] = [
248        Self::QueryExecutions,
249        Self::PlanningSteps,
250        Self::PlanCompilations,
251        Self::KeyIndexEntriesVisited,
252        Self::RowsVisited,
253        Self::StoredBytesRead,
254        Self::PredicateExpressionSteps,
255        Self::NestedValueSteps,
256        Self::DecodedBytes,
257        Self::MaterializedBytes,
258        Self::SortEntries,
259        Self::SortComparisons,
260        Self::SortTemporaryBytes,
261        Self::GroupDistinctEntries,
262        Self::GroupDistinctStateBytes,
263        Self::CursorSteps,
264        Self::TemporaryBytes,
265        Self::DiagnosticSteps,
266        Self::ResultRows,
267        Self::ResultBytes,
268        Self::InstructionUnits,
269    ];
270}
271
272define_numeric_fact_value_registry! {
273    /// Compact counter owner carried by [`DiagnosticFactTag::ExecutionBudgetScope`].
274    pub enum DiagnosticExecutionBudgetScope {
275        Execution = 1;
276        Request = 2;
277    }
278}
279
280define_numeric_fact_value_registry! {
281    /// Compact execution lane carried by [`DiagnosticFactTag::ExecutionLane`].
282    pub enum DiagnosticExecutionLane {
283        PublicRead = 1;
284        TrustedRead = 2;
285        Diagnostic = 3;
286        Mutation = 4;
287        Recovery = 5;
288    }
289}
290
291define_numeric_fact_value_registry! {
292    /// Compact accepted constraint family carried by [`DiagnosticFactTag::ConstraintKind`].
293    pub enum DiagnosticConstraintKind {
294        Check = 1;
295        NotNull = 2;
296        Relation = 3;
297        TargetedRule = 4;
298        Unique = 5;
299    }
300}
301
302define_numeric_fact_value_registry! {
303    /// Compact enforcement boundary carried by [`DiagnosticFactTag::ConstraintContext`].
304    pub enum DiagnosticConstraintContext {
305        Integrity = 1;
306        MigrationValidation = 2;
307        WriteAdmission = 3;
308    }
309}
310
311define_numeric_fact_value_registry! {
312    /// Compact storage component carried by [`DiagnosticFactTag::ComponentKind`].
313    pub enum DiagnosticComponentKind {
314        CommitDataKey = 1;
315        IndexKey = 2;
316        IndexKeyComponent = 3;
317        RelationTargetPrimaryKey = 4;
318    }
319}
320
321define_numeric_fact_value_registry! {
322    /// Compact semantic family carried by [`DiagnosticFactTag::TypeFamily`].
323    pub enum DiagnosticTypeFamily {
324        Blob = 1;
325        Bool = 2;
326        Collection = 3;
327        Null = 4;
328        Numeric = 5;
329        Opaque = 6;
330        Structured = 7;
331        Text = 8;
332        Unknown = 9;
333    }
334}
335
336define_numeric_fact_value_registry! {
337    /// Compact function identity carried by [`DiagnosticFactTag::FunctionKind`].
338    pub enum DiagnosticFunctionKind {
339        Abs = 1;
340        Cbrt = 2;
341        Ceiling = 3;
342        Coalesce = 4;
343        CollectionContains = 5;
344        Contains = 6;
345        EndsWith = 7;
346        Exp = 8;
347        Floor = 9;
348        IsEmpty = 10;
349        IsMissing = 11;
350        IsNotEmpty = 12;
351        IsNotNull = 13;
352        IsNull = 14;
353        Left = 15;
354        Length = 16;
355        Ln = 17;
356        Log = 18;
357        Log2 = 19;
358        Log10 = 20;
359        Lower = 21;
360        Ltrim = 22;
361        Mod = 23;
362        NullIf = 24;
363        OctetLength = 25;
364        Position = 26;
365        Power = 27;
366        Replace = 28;
367        Right = 29;
368        Round = 30;
369        Rtrim = 31;
370        Sign = 32;
371        Sqrt = 33;
372        StartsWith = 34;
373        Substring = 35;
374        Trim = 36;
375        Trunc = 37;
376        Upper = 38;
377        InList = 39;
378    }
379}
380
381define_numeric_fact_value_registry! {
382    /// Compact operator identity carried by [`DiagnosticFactTag::OperatorKind`].
383    pub enum DiagnosticOperatorKind {
384        Not = 1;
385        Add = 2;
386        And = 3;
387        Div = 4;
388        Eq = 5;
389        Gt = 6;
390        Gte = 7;
391        Lt = 8;
392        Lte = 9;
393        Mul = 10;
394        Ne = 11;
395        Or = 12;
396        Sub = 13;
397        In = 14;
398        NotIn = 15;
399        Contains = 16;
400        StartsWith = 17;
401        EndsWith = 18;
402    }
403}
404
405define_numeric_fact_value_registry! {
406    /// Compact aggregate identity carried by [`DiagnosticFactTag::AggregateKind`].
407    pub enum DiagnosticAggregateKind {
408        Count = 1;
409        Sum = 2;
410        Avg = 3;
411        Exists = 4;
412        Min = 5;
413        Max = 6;
414        First = 7;
415        Last = 8;
416    }
417}
418
419impl DiagnosticDecodeReason {
420    /// Return the fixed numeric fact value.
421    #[must_use]
422    pub const fn raw(self) -> u64 {
423        match self {
424            Self::CursorEmpty => 1,
425            Self::CursorTooLong => 2,
426            Self::CursorOddLength => 3,
427            Self::CursorInvalidHex => 4,
428            Self::CursorGroupedDirectionMismatch => 5,
429            Self::CursorTokenEncode => 6,
430            Self::CursorTokenDecode => 7,
431            Self::RecoveryMarkerMagic => 8,
432            Self::RecoveryMarkerChecksum => 9,
433            Self::RecoveryMarkerState => 10,
434        }
435    }
436
437    /// Recover a known compact decode reason.
438    #[must_use]
439    pub const fn known(raw: u64) -> Option<Self> {
440        match raw {
441            1 => Some(Self::CursorEmpty),
442            2 => Some(Self::CursorTooLong),
443            3 => Some(Self::CursorOddLength),
444            4 => Some(Self::CursorInvalidHex),
445            5 => Some(Self::CursorGroupedDirectionMismatch),
446            6 => Some(Self::CursorTokenEncode),
447            7 => Some(Self::CursorTokenDecode),
448            8 => Some(Self::RecoveryMarkerMagic),
449            9 => Some(Self::RecoveryMarkerChecksum),
450            10 => Some(Self::RecoveryMarkerState),
451            _ => None,
452        }
453    }
454}
455
456impl DiagnosticMutationOperation {
457    /// Return the fixed numeric fact value.
458    #[must_use]
459    pub const fn raw(self) -> u64 {
460        match self {
461            Self::Insert => 1,
462            Self::Replace => 2,
463            Self::Update => 3,
464            Self::Delete => 4,
465        }
466    }
467
468    /// Recover a known compact mutation operation.
469    #[must_use]
470    pub const fn known(raw: u64) -> Option<Self> {
471        match raw {
472            1 => Some(Self::Insert),
473            2 => Some(Self::Replace),
474            3 => Some(Self::Update),
475            4 => Some(Self::Delete),
476            _ => None,
477        }
478    }
479}
480
481impl fmt::Debug for DiagnosticFactTag {
482    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
483        write!(f, "{}", self.raw())
484    }
485}
486
487impl fmt::Debug for DiagnosticDecodeReason {
488    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
489        write!(f, "{}", self.raw())
490    }
491}
492
493impl fmt::Debug for DiagnosticMutationOperation {
494    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
495        write!(f, "{}", self.raw())
496    }
497}
498
499/// Pack two accepted `u32` identities into one fact value without narrowing.
500#[must_use]
501pub const fn pack_u32_pair(high: u32, low: u32) -> u64 {
502    (high as u64) << 32 | low as u64
503}
504
505/// Recover the two accepted identities from one packed fact value.
506#[must_use]
507pub const fn unpack_u32_pair(value: u64) -> (u32, u32) {
508    let bytes = value.to_be_bytes();
509    (
510        u32::from_be_bytes([bytes[0], bytes[1], bytes[2], bytes[3]]),
511        u32::from_be_bytes([bytes[4], bytes[5], bytes[6], bytes[7]]),
512    )
513}
514
515/// Why one numeric fact sequence does not satisfy its owning E-code schema.
516///
517/// This taxonomy intentionally carries no prose. Host tooling owns rendering.
518#[derive(Clone, Copy, Debug, Eq, PartialEq)]
519pub enum DiagnosticFactSchemaMismatch {
520    /// The sequence exceeds the global public fact ceiling.
521    GlobalMaximumExceeded,
522    /// The sequence exceeds the tighter ceiling for its E-code.
523    CodeMaximumExceeded,
524    /// Required, allowed, repeated, or ordered tags do not match the E-code.
525    InvalidSequence,
526    /// One known compact tag carries a value outside its frozen numeric registry.
527    InvalidValue,
528}
529
530/// Validate facts already expressed with known production tag identities.
531///
532/// The validator allocates nothing. It is the runtime-side entry point used
533/// immediately before facts cross the public facade.
534pub fn validate_known_diagnostic_fact_schema(
535    code: ErrorCode,
536    facts: &[(DiagnosticFactTag, u64)],
537) -> Result<(), DiagnosticFactSchemaMismatch> {
538    validate_diagnostic_fact_schema(code, facts.len(), |index| {
539        let (tag, value) = facts[index];
540        (tag.raw(), value)
541    })
542}
543
544/// Validate raw host/tooling facts against their owning E-code schema.
545///
546/// Unknown tags remain renderable by callers, but make a known E-code context
547/// invalid instead of being heuristically reinterpreted.
548pub fn validate_raw_diagnostic_fact_schema(
549    code: ErrorCode,
550    facts: &[(u8, u64)],
551) -> Result<(), DiagnosticFactSchemaMismatch> {
552    validate_diagnostic_fact_schema(code, facts.len(), |index| facts[index])
553}
554
555#[expect(
556    clippy::too_many_lines,
557    reason = "the frozen E-code schema registry keeps every numeric owner visible in one exhaustive dispatch"
558)]
559fn validate_diagnostic_fact_schema(
560    code: ErrorCode,
561    fact_count: usize,
562    fact_at: impl Fn(usize) -> (u8, u64),
563) -> Result<(), DiagnosticFactSchemaMismatch> {
564    if fact_count > MAX_PUBLIC_DIAGNOSTIC_FACTS {
565        return Err(DiagnosticFactSchemaMismatch::GlobalMaximumExceeded);
566    }
567
568    let maximum = diagnostic_fact_maximum(code);
569    if fact_count > maximum {
570        return Err(DiagnosticFactSchemaMismatch::CodeMaximumExceeded);
571    }
572
573    let valid_sequence = match code.raw() {
574        3 => query_plan_schema(fact_count, &fact_at),
575        6 => cursor_schema(fact_count, &fact_at),
576        16 => store_corruption_schema(fact_count, &fact_at),
577        18 => runtime_corruption_schema(fact_count, &fact_at),
578        19 => incompatible_format_schema(fact_count, &fact_at),
579        20 => runtime_invariant_schema(fact_count, &fact_at),
580        21 => runtime_conflict_schema(fact_count, &fact_at),
581        23 => runtime_unsupported_schema(fact_count, &fact_at),
582        24 => runtime_internal_schema(fact_count, &fact_at),
583        138 => tags_match(
584            fact_count,
585            &fact_at,
586            &[
587                DiagnosticFactTag::ExpectedArity,
588                DiagnosticFactTag::ActualArity,
589            ],
590        ),
591        141 | 142 | 169 | 170 => {
592            tags_match(fact_count, &fact_at, &[DiagnosticFactTag::ProjectionIndex])
593        }
594        175 => tags_match(fact_count, &fact_at, &[DiagnosticFactTag::ParameterIndex]),
595        177 | 237 => {
596            tags_match(fact_count, &fact_at, &[DiagnosticFactTag::Limit])
597                || tags_match(
598                    fact_count,
599                    &fact_at,
600                    &[DiagnosticFactTag::ActualLength, DiagnosticFactTag::Limit],
601                )
602        }
603        178 | 180 | 202 | 203 | 205 | 236 | 269 => tags_match(
604            fact_count,
605            &fact_at,
606            &[DiagnosticFactTag::ActualCount, DiagnosticFactTag::Limit],
607        ),
608        196 | 234 => tags_match(
609            fact_count,
610            &fact_at,
611            &[
612                DiagnosticFactTag::EntityTag,
613                DiagnosticFactTag::FieldId,
614                DiagnosticFactTag::MutationOperation,
615                DiagnosticFactTag::BatchPosition,
616            ],
617        ),
618        197 => tags_match(
619            fact_count,
620            &fact_at,
621            &[
622                DiagnosticFactTag::RowLayout,
623                DiagnosticFactTag::HistoryFloor,
624                DiagnosticFactTag::CurrentLayout,
625            ],
626        ),
627        198 => tags_match(
628            fact_count,
629            &fact_at,
630            &[
631                DiagnosticFactTag::RowLayout,
632                DiagnosticFactTag::ExpectedSlotCount,
633                DiagnosticFactTag::ActualSlotCount,
634            ],
635        ),
636        201 => tags_match(
637            fact_count,
638            &fact_at,
639            &[DiagnosticFactTag::ActualCount, DiagnosticFactTag::Minimum],
640        ),
641        223 => constraint_schema(fact_count, &fact_at, true),
642        225 => constraint_schema(fact_count, &fact_at, false),
643        233 => tags_match(
644            fact_count,
645            &fact_at,
646            &[
647                DiagnosticFactTag::EntityTag,
648                DiagnosticFactTag::MutationOperation,
649                DiagnosticFactTag::BatchPosition,
650            ],
651        ),
652        235 => {
653            tags_match(fact_count, &fact_at, &[DiagnosticFactTag::ActualCount]) && fact_at(0).1 == 0
654        }
655        238 | 270 | 271 | 272 => tags_match(
656            fact_count,
657            &fact_at,
658            &[DiagnosticFactTag::ActualLength, DiagnosticFactTag::Limit],
659        ),
660        273 => tags_match(
661            fact_count,
662            &fact_at,
663            &[
664                DiagnosticFactTag::BudgetResource,
665                DiagnosticFactTag::Limit,
666                DiagnosticFactTag::Actual,
667                DiagnosticFactTag::ExecutionBudgetScope,
668                DiagnosticFactTag::ExecutionLane,
669                DiagnosticFactTag::QueryShapeFingerprintPrefix,
670            ],
671        ),
672        274 => tags_match(
673            fact_count,
674            &fact_at,
675            &[
676                DiagnosticFactTag::BudgetResource,
677                DiagnosticFactTag::Limit,
678                DiagnosticFactTag::Actual,
679            ],
680        ),
681        239 => tags_match(
682            fact_count,
683            &fact_at,
684            &[
685                DiagnosticFactTag::BatchPosition,
686                DiagnosticFactTag::ExpectedEntityTag,
687                DiagnosticFactTag::ActualEntityTag,
688            ],
689        ),
690        240 => tags_match(
691            fact_count,
692            &fact_at,
693            &[
694                DiagnosticFactTag::EntityTag,
695                DiagnosticFactTag::FirstBatchPosition,
696                DiagnosticFactTag::DuplicateBatchPosition,
697            ],
698        ),
699        _ => fact_count == 0,
700    };
701    if !valid_sequence {
702        return Err(DiagnosticFactSchemaMismatch::InvalidSequence);
703    }
704
705    for index in 0..fact_count {
706        let (raw_tag, value) = fact_at(index);
707        let Some(tag) = DiagnosticFactTag::known(raw_tag) else {
708            return Err(DiagnosticFactSchemaMismatch::InvalidSequence);
709        };
710        if !diagnostic_fact_value_is_valid(tag, value) {
711            return Err(DiagnosticFactSchemaMismatch::InvalidValue);
712        }
713    }
714    Ok(())
715}
716
717const fn diagnostic_fact_maximum(code: ErrorCode) -> usize {
718    match code.raw() {
719        6 | 16 | 18 | 24 | 197 | 198 | 233 | 239 | 240 | 274 => 3,
720        141 | 142 | 169 | 170 | 175 | 235 => 1,
721        19 | 21 | 138 | 177 | 178 | 180 | 201 | 202 | 203 | 205 | 236 | 237 | 238 | 269 | 270
722        | 271 | 272 => 2,
723        3 | 20 => 5,
724        23 | 273 => 6,
725        196 | 234 => 4,
726        223 => 73,
727        225 => 9,
728        _ => 0,
729    }
730}
731
732#[expect(
733    clippy::too_many_lines,
734    reason = "the query-plan E-code deliberately owns several exact finite fact sequences"
735)]
736fn query_plan_schema(fact_count: usize, fact_at: &impl Fn(usize) -> (u8, u64)) -> bool {
737    fact_count == 0
738        || tags_match(fact_count, fact_at, &[DiagnosticFactTag::TermIndex])
739        || tags_match(fact_count, fact_at, &[DiagnosticFactTag::ComponentIndex])
740        || tags_match(fact_count, fact_at, &[DiagnosticFactTag::GroupIndex])
741        || tags_match(fact_count, fact_at, &[DiagnosticFactTag::ClauseIndex])
742        || tags_match(fact_count, fact_at, &[DiagnosticFactTag::AggregateIndex])
743        || tags_match(fact_count, fact_at, &[DiagnosticFactTag::AggregateKind])
744        || tags_match(fact_count, fact_at, &[DiagnosticFactTag::ProjectionIndex])
745        || tags_match(
746            fact_count,
747            fact_at,
748            &[
749                DiagnosticFactTag::FirstTermIndex,
750                DiagnosticFactTag::DuplicateTermIndex,
751            ],
752        )
753        || tags_match(
754            fact_count,
755            fact_at,
756            &[
757                DiagnosticFactTag::ClauseIndex,
758                DiagnosticFactTag::OperatorKind,
759            ],
760        )
761        || tags_match(
762            fact_count,
763            fact_at,
764            &[
765                DiagnosticFactTag::AggregateIndex,
766                DiagnosticFactTag::AggregateKind,
767            ],
768        )
769        || tags_match(
770            fact_count,
771            fact_at,
772            &[
773                DiagnosticFactTag::AggregateKind,
774                DiagnosticFactTag::TypeFamily,
775            ],
776        )
777        || tags_match(
778            fact_count,
779            fact_at,
780            &[
781                DiagnosticFactTag::OperatorKind,
782                DiagnosticFactTag::TypeFamily,
783            ],
784        )
785        || tags_match(
786            fact_count,
787            fact_at,
788            &[
789                DiagnosticFactTag::BranchIndex,
790                DiagnosticFactTag::TypeFamily,
791            ],
792        )
793        || tags_match(
794            fact_count,
795            fact_at,
796            &[DiagnosticFactTag::TypeFamily, DiagnosticFactTag::TypeFamily],
797        )
798        || tags_match(
799            fact_count,
800            fact_at,
801            &[
802                DiagnosticFactTag::ClauseIndex,
803                DiagnosticFactTag::AggregateIndex,
804                DiagnosticFactTag::ActualCount,
805            ],
806        )
807        || tags_match(
808            fact_count,
809            fact_at,
810            &[
811                DiagnosticFactTag::FunctionKind,
812                DiagnosticFactTag::ExpectedArity,
813                DiagnosticFactTag::ActualArity,
814            ],
815        )
816        || tags_match(
817            fact_count,
818            fact_at,
819            &[
820                DiagnosticFactTag::FunctionKind,
821                DiagnosticFactTag::ArgumentIndex,
822                DiagnosticFactTag::TypeFamily,
823            ],
824        )
825        || tags_match(
826            fact_count,
827            fact_at,
828            &[
829                DiagnosticFactTag::OperatorKind,
830                DiagnosticFactTag::TypeFamily,
831                DiagnosticFactTag::TypeFamily,
832            ],
833        )
834        || tags_match(
835            fact_count,
836            fact_at,
837            &[
838                DiagnosticFactTag::BranchIndex,
839                DiagnosticFactTag::TypeFamily,
840                DiagnosticFactTag::TypeFamily,
841            ],
842        )
843        || tags_match(
844            fact_count,
845            fact_at,
846            &[
847                DiagnosticFactTag::TypeFamily,
848                DiagnosticFactTag::BranchIndex,
849                DiagnosticFactTag::TypeFamily,
850            ],
851        )
852        || tags_match(
853            fact_count,
854            fact_at,
855            &[
856                DiagnosticFactTag::BranchIndex,
857                DiagnosticFactTag::TypeFamily,
858                DiagnosticFactTag::BranchIndex,
859                DiagnosticFactTag::TypeFamily,
860            ],
861        )
862        || tags_match(
863            fact_count,
864            fact_at,
865            &[
866                DiagnosticFactTag::FunctionKind,
867                DiagnosticFactTag::ArgumentIndex,
868                DiagnosticFactTag::TypeFamily,
869                DiagnosticFactTag::ArgumentIndex,
870                DiagnosticFactTag::TypeFamily,
871            ],
872        )
873}
874
875fn cursor_schema(fact_count: usize, fact_at: &impl Fn(usize) -> (u8, u64)) -> bool {
876    if fact_count == 0 {
877        return true;
878    }
879    if tags_match(fact_count, fact_at, &[DiagnosticFactTag::DecodeReason]) {
880        return matches!(fact_at(0).1, 1 | 3 | 5 | 6 | 7);
881    }
882    if tags_match(
883        fact_count,
884        fact_at,
885        &[
886            DiagnosticFactTag::ActualLength,
887            DiagnosticFactTag::Maximum,
888            DiagnosticFactTag::DecodeReason,
889        ],
890    ) {
891        return fact_at(2).1 == DiagnosticDecodeReason::CursorTooLong.raw();
892    }
893    if tags_match(
894        fact_count,
895        fact_at,
896        &[
897            DiagnosticFactTag::ComponentIndex,
898            DiagnosticFactTag::DecodeReason,
899        ],
900    ) {
901        return matches!(fact_at(1).1, 4 | 6 | 7);
902    }
903    tags_match(
904        fact_count,
905        fact_at,
906        &[
907            DiagnosticFactTag::ExpectedSignaturePrefix,
908            DiagnosticFactTag::ActualSignaturePrefix,
909        ],
910    ) || tags_match(
911        fact_count,
912        fact_at,
913        &[
914            DiagnosticFactTag::ExpectedOffset,
915            DiagnosticFactTag::ActualOffset,
916        ],
917    )
918}
919
920fn store_corruption_schema(fact_count: usize, fact_at: &impl Fn(usize) -> (u8, u64)) -> bool {
921    fact_count == 0
922        || (tags_match(
923            fact_count,
924            fact_at,
925            &[
926                DiagnosticFactTag::ComponentKind,
927                DiagnosticFactTag::ActualLength,
928                DiagnosticFactTag::Limit,
929            ],
930        ) && fact_at(0).1 == DiagnosticComponentKind::CommitDataKey.raw())
931        || tags_match(
932            fact_count,
933            fact_at,
934            &[
935                DiagnosticFactTag::ExpectedEntityTag,
936                DiagnosticFactTag::ActualEntityTag,
937            ],
938        )
939}
940
941fn runtime_corruption_schema(fact_count: usize, fact_at: &impl Fn(usize) -> (u8, u64)) -> bool {
942    store_corruption_schema(fact_count, fact_at)
943        || (tags_match(fact_count, fact_at, &[DiagnosticFactTag::DecodeReason])
944            && matches!(fact_at(0).1, 8..=10))
945}
946
947fn incompatible_format_schema(fact_count: usize, fact_at: &impl Fn(usize) -> (u8, u64)) -> bool {
948    fact_count == 0
949        || tags_match(fact_count, fact_at, &[DiagnosticFactTag::ExpectedVersion])
950        || tags_match(
951            fact_count,
952            fact_at,
953            &[
954                DiagnosticFactTag::ExpectedVersion,
955                DiagnosticFactTag::ActualVersion,
956            ],
957        )
958}
959
960fn runtime_invariant_schema(fact_count: usize, fact_at: &impl Fn(usize) -> (u8, u64)) -> bool {
961    fact_count == 0
962        || (tags_match(
963            fact_count,
964            fact_at,
965            &[
966                DiagnosticFactTag::EntityTag,
967                DiagnosticFactTag::PhysicalGeneration,
968                DiagnosticFactTag::ComponentKind,
969                DiagnosticFactTag::ActualArity,
970                DiagnosticFactTag::Maximum,
971            ],
972        ) && fact_at(2).1 == DiagnosticComponentKind::IndexKey.raw())
973}
974
975fn runtime_conflict_schema(fact_count: usize, fact_at: &impl Fn(usize) -> (u8, u64)) -> bool {
976    fact_count == 0
977        || tags_match(fact_count, fact_at, &[DiagnosticFactTag::ExpectedRevision])
978        || tags_match(
979            fact_count,
980            fact_at,
981            &[
982                DiagnosticFactTag::ExpectedRevision,
983                DiagnosticFactTag::CurrentRevision,
984            ],
985        )
986}
987
988fn runtime_unsupported_schema(fact_count: usize, fact_at: &impl Fn(usize) -> (u8, u64)) -> bool {
989    fact_count == 0
990        || (tags_match(
991            fact_count,
992            fact_at,
993            &[
994                DiagnosticFactTag::EntityTag,
995                DiagnosticFactTag::PhysicalGeneration,
996                DiagnosticFactTag::ComponentIndex,
997                DiagnosticFactTag::ComponentKind,
998                DiagnosticFactTag::ActualLength,
999                DiagnosticFactTag::Limit,
1000            ],
1001        ) && fact_at(3).1 == DiagnosticComponentKind::IndexKeyComponent.raw())
1002}
1003
1004fn runtime_internal_schema(fact_count: usize, fact_at: &impl Fn(usize) -> (u8, u64)) -> bool {
1005    fact_count == 0
1006        || tags_match(
1007            fact_count,
1008            fact_at,
1009            &[
1010                DiagnosticFactTag::ExpectedMemoryId,
1011                DiagnosticFactTag::ActualMemoryId,
1012            ],
1013        )
1014        || (tags_match(
1015            fact_count,
1016            fact_at,
1017            &[
1018                DiagnosticFactTag::ComponentKind,
1019                DiagnosticFactTag::ExpectedArity,
1020                DiagnosticFactTag::ActualArity,
1021            ],
1022        ) && fact_at(0).1 == DiagnosticComponentKind::RelationTargetPrimaryKey.raw())
1023}
1024
1025fn constraint_schema(
1026    fact_count: usize,
1027    fact_at: &impl Fn(usize) -> (u8, u64),
1028    allow_targeted_path: bool,
1029) -> bool {
1030    const COMMON: &[DiagnosticFactTag] = &[
1031        DiagnosticFactTag::AcceptedSchemaFingerprintMethod,
1032        DiagnosticFactTag::AcceptedSchemaFingerprintHigh,
1033        DiagnosticFactTag::AcceptedSchemaFingerprintLow,
1034        DiagnosticFactTag::EntityTag,
1035        DiagnosticFactTag::ConstraintId,
1036        DiagnosticFactTag::ConstraintKind,
1037        DiagnosticFactTag::ConstraintContext,
1038    ];
1039    if fact_count < COMMON.len()
1040        || !tags_prefix_matches(fact_count, fact_at, COMMON)
1041        || fact_at(6).1 != DiagnosticConstraintContext::WriteAdmission.raw()
1042    {
1043        return false;
1044    }
1045
1046    let constraint_kind = fact_at(5).1;
1047    if DiagnosticConstraintKind::known(constraint_kind).is_none() {
1048        return false;
1049    }
1050    let mut index = COMMON.len();
1051    if index < fact_count && fact_at(index).0 == DiagnosticFactTag::MutationOperation.raw() {
1052        index += 1;
1053        if index < fact_count && fact_at(index).0 == DiagnosticFactTag::BatchPosition.raw() {
1054            index += 1;
1055        }
1056    }
1057
1058    let path_len = fact_count - index;
1059    if path_len == 0 {
1060        return !allow_targeted_path
1061            || constraint_kind != DiagnosticConstraintKind::TargetedRule.raw();
1062    }
1063    allow_targeted_path
1064        && constraint_kind == DiagnosticConstraintKind::TargetedRule.raw()
1065        && path_len <= 64
1066        && (index..fact_count).all(|position| {
1067            DiagnosticFactTag::known(fact_at(position).0).is_some_and(is_value_path_tag)
1068        })
1069}
1070
1071fn tags_match(
1072    fact_count: usize,
1073    fact_at: &impl Fn(usize) -> (u8, u64),
1074    expected: &[DiagnosticFactTag],
1075) -> bool {
1076    fact_count == expected.len() && tags_prefix_matches(fact_count, fact_at, expected)
1077}
1078
1079fn tags_prefix_matches(
1080    fact_count: usize,
1081    fact_at: &impl Fn(usize) -> (u8, u64),
1082    expected: &[DiagnosticFactTag],
1083) -> bool {
1084    fact_count >= expected.len()
1085        && expected
1086            .iter()
1087            .enumerate()
1088            .all(|(index, tag)| fact_at(index).0 == tag.raw())
1089}
1090
1091const fn is_value_path_tag(tag: DiagnosticFactTag) -> bool {
1092    matches!(
1093        tag,
1094        DiagnosticFactTag::RootField
1095            | DiagnosticFactTag::RecordMember
1096            | DiagnosticFactTag::TupleElement
1097            | DiagnosticFactTag::Newtype
1098            | DiagnosticFactTag::EnumVariant
1099            | DiagnosticFactTag::ListElement
1100            | DiagnosticFactTag::SetElement
1101            | DiagnosticFactTag::MapEntryKey
1102            | DiagnosticFactTag::MapEntryValue
1103    )
1104}
1105
1106const fn diagnostic_fact_value_is_valid(tag: DiagnosticFactTag, value: u64) -> bool {
1107    match tag {
1108        DiagnosticFactTag::AcceptedSchemaFingerprintMethod
1109        | DiagnosticFactTag::ExpectedMemoryId
1110        | DiagnosticFactTag::ActualMemoryId => value <= u8::MAX as u64,
1111        DiagnosticFactTag::ConstraintId
1112        | DiagnosticFactTag::FieldId
1113        | DiagnosticFactTag::IndexId
1114        | DiagnosticFactTag::RelationId
1115        | DiagnosticFactTag::BatchPosition
1116        | DiagnosticFactTag::FirstBatchPosition
1117        | DiagnosticFactTag::DuplicateBatchPosition
1118        | DiagnosticFactTag::RowLayout
1119        | DiagnosticFactTag::HistoryFloor
1120        | DiagnosticFactTag::CurrentLayout
1121        | DiagnosticFactTag::RootField
1122        | DiagnosticFactTag::Newtype
1123        | DiagnosticFactTag::ListElement
1124        | DiagnosticFactTag::SetElement
1125        | DiagnosticFactTag::MapEntryKey
1126        | DiagnosticFactTag::MapEntryValue => value <= u32::MAX as u64,
1127        DiagnosticFactTag::ConstraintKind => DiagnosticConstraintKind::known(value).is_some(),
1128        DiagnosticFactTag::ConstraintContext => DiagnosticConstraintContext::known(value).is_some(),
1129        DiagnosticFactTag::TypeFamily => DiagnosticTypeFamily::known(value).is_some(),
1130        DiagnosticFactTag::FunctionKind => DiagnosticFunctionKind::known(value).is_some(),
1131        DiagnosticFactTag::OperatorKind => DiagnosticOperatorKind::known(value).is_some(),
1132        DiagnosticFactTag::AggregateKind => DiagnosticAggregateKind::known(value).is_some(),
1133        DiagnosticFactTag::ComponentKind => DiagnosticComponentKind::known(value).is_some(),
1134        DiagnosticFactTag::DecodeReason => DiagnosticDecodeReason::known(value).is_some(),
1135        DiagnosticFactTag::BudgetResource => {
1136            DiagnosticExecutionBudgetResource::known(value).is_some()
1137        }
1138        DiagnosticFactTag::ExecutionBudgetScope => {
1139            DiagnosticExecutionBudgetScope::known(value).is_some()
1140        }
1141        DiagnosticFactTag::ExecutionLane => DiagnosticExecutionLane::known(value).is_some(),
1142        DiagnosticFactTag::MutationOperation => DiagnosticMutationOperation::known(value).is_some(),
1143        _ => true,
1144    }
1145}
1146
1147#[cfg(test)]
1148mod tests {
1149    use super::{
1150        DiagnosticAggregateKind, DiagnosticComponentKind, DiagnosticConstraintContext,
1151        DiagnosticConstraintKind, DiagnosticDecodeReason, DiagnosticExecutionBudgetResource,
1152        DiagnosticExecutionBudgetScope, DiagnosticExecutionLane, DiagnosticFactSchemaMismatch,
1153        DiagnosticFactTag, DiagnosticFunctionKind, DiagnosticMutationOperation,
1154        DiagnosticOperatorKind, DiagnosticTypeFamily, ORDERED_FACT_TAGS, pack_u32_pair,
1155        unpack_u32_pair, validate_known_diagnostic_fact_schema,
1156        validate_raw_diagnostic_fact_schema,
1157    };
1158    use crate::ErrorCode;
1159
1160    #[test]
1161    fn fact_tag_registry_is_fixed_unique_and_contiguous() {
1162        for (index, tag) in ORDERED_FACT_TAGS.iter().copied().enumerate() {
1163            let expected = u8::try_from(index + 1).expect("fact-tag index fits u8");
1164            assert_eq!(tag.raw(), expected);
1165            assert_eq!(DiagnosticFactTag::known(expected), Some(tag));
1166        }
1167
1168        assert_eq!(DiagnosticFactTag::known(0), None);
1169        assert_eq!(DiagnosticFactTag::known(93), None);
1170        assert_eq!(DiagnosticFactTag::known(u8::MAX), None);
1171    }
1172
1173    #[test]
1174    fn execution_budget_fact_value_registries_are_fixed() {
1175        for (index, resource) in DiagnosticExecutionBudgetResource::ALL
1176            .iter()
1177            .copied()
1178            .enumerate()
1179        {
1180            let expected = u64::try_from(index + 1).expect("resource index fits u64");
1181            assert_eq!(resource.raw(), expected);
1182            assert_eq!(
1183                DiagnosticExecutionBudgetResource::known(expected),
1184                Some(resource)
1185            );
1186        }
1187        assert_eq!(DiagnosticExecutionBudgetResource::known(0), None);
1188        assert_eq!(DiagnosticExecutionBudgetResource::known(22), None);
1189
1190        assert_eq!(DiagnosticExecutionBudgetScope::Execution.raw(), 1);
1191        assert_eq!(DiagnosticExecutionBudgetScope::Request.raw(), 2);
1192        assert_eq!(DiagnosticExecutionBudgetScope::known(3), None);
1193
1194        assert_eq!(DiagnosticExecutionLane::PublicRead.raw(), 1);
1195        assert_eq!(DiagnosticExecutionLane::TrustedRead.raw(), 2);
1196        assert_eq!(DiagnosticExecutionLane::Diagnostic.raw(), 3);
1197        assert_eq!(DiagnosticExecutionLane::Mutation.raw(), 4);
1198        assert_eq!(DiagnosticExecutionLane::Recovery.raw(), 5);
1199        assert_eq!(DiagnosticExecutionLane::known(6), None);
1200    }
1201
1202    #[test]
1203    fn accepted_identity_pair_packing_is_exact() {
1204        for pair in [
1205            (0, 0),
1206            (1, 2),
1207            (u32::MAX, 0),
1208            (0, u32::MAX),
1209            (u32::MAX, u32::MAX),
1210        ] {
1211            assert_eq!(unpack_u32_pair(pack_u32_pair(pair.0, pair.1)), pair);
1212        }
1213    }
1214
1215    #[test]
1216    fn constraint_fact_value_registries_are_fixed() {
1217        assert_eq!(DiagnosticConstraintKind::Check.raw(), 1);
1218        assert_eq!(DiagnosticConstraintKind::NotNull.raw(), 2);
1219        assert_eq!(DiagnosticConstraintKind::Relation.raw(), 3);
1220        assert_eq!(DiagnosticConstraintKind::TargetedRule.raw(), 4);
1221        assert_eq!(DiagnosticConstraintKind::Unique.raw(), 5);
1222        assert_eq!(DiagnosticConstraintKind::known(0), None);
1223        assert_eq!(DiagnosticConstraintKind::known(6), None);
1224
1225        assert_eq!(DiagnosticConstraintContext::Integrity.raw(), 1);
1226        assert_eq!(DiagnosticConstraintContext::MigrationValidation.raw(), 2);
1227        assert_eq!(DiagnosticConstraintContext::WriteAdmission.raw(), 3);
1228        assert_eq!(DiagnosticConstraintContext::known(0), None);
1229        assert_eq!(DiagnosticConstraintContext::known(4), None);
1230    }
1231
1232    #[test]
1233    fn component_kind_registry_is_fixed_and_numeric() {
1234        let kinds = [
1235            DiagnosticComponentKind::CommitDataKey,
1236            DiagnosticComponentKind::IndexKey,
1237            DiagnosticComponentKind::IndexKeyComponent,
1238            DiagnosticComponentKind::RelationTargetPrimaryKey,
1239        ];
1240
1241        for (index, kind) in kinds.iter().copied().enumerate() {
1242            let expected = (index + 1) as u64;
1243            assert_eq!(kind.raw(), expected);
1244            assert_eq!(DiagnosticComponentKind::known(expected), Some(kind));
1245            assert_eq!(format!("{kind:?}"), expected.to_string());
1246        }
1247        assert_eq!(DiagnosticComponentKind::known(0), None);
1248        assert_eq!(DiagnosticComponentKind::known(5), None);
1249    }
1250
1251    #[test]
1252    fn decode_reason_registry_is_fixed_and_numeric() {
1253        let reasons = [
1254            DiagnosticDecodeReason::CursorEmpty,
1255            DiagnosticDecodeReason::CursorTooLong,
1256            DiagnosticDecodeReason::CursorOddLength,
1257            DiagnosticDecodeReason::CursorInvalidHex,
1258            DiagnosticDecodeReason::CursorGroupedDirectionMismatch,
1259            DiagnosticDecodeReason::CursorTokenEncode,
1260            DiagnosticDecodeReason::CursorTokenDecode,
1261            DiagnosticDecodeReason::RecoveryMarkerMagic,
1262            DiagnosticDecodeReason::RecoveryMarkerChecksum,
1263            DiagnosticDecodeReason::RecoveryMarkerState,
1264        ];
1265
1266        for (index, reason) in reasons.iter().copied().enumerate() {
1267            let expected = (index + 1) as u64;
1268            assert_eq!(reason.raw(), expected);
1269            assert_eq!(DiagnosticDecodeReason::known(expected), Some(reason));
1270            assert_eq!(format!("{reason:?}"), expected.to_string());
1271        }
1272
1273        assert_eq!(DiagnosticDecodeReason::known(0), None);
1274        assert_eq!(DiagnosticDecodeReason::known(11), None);
1275    }
1276
1277    #[test]
1278    fn mutation_operation_registry_is_fixed_and_numeric() {
1279        let operations = [
1280            DiagnosticMutationOperation::Insert,
1281            DiagnosticMutationOperation::Replace,
1282            DiagnosticMutationOperation::Update,
1283            DiagnosticMutationOperation::Delete,
1284        ];
1285
1286        for (index, operation) in operations.iter().copied().enumerate() {
1287            let expected = (index + 1) as u64;
1288            assert_eq!(operation.raw(), expected);
1289            assert_eq!(
1290                DiagnosticMutationOperation::known(expected),
1291                Some(operation)
1292            );
1293            assert_eq!(format!("{operation:?}"), expected.to_string());
1294        }
1295
1296        assert_eq!(DiagnosticMutationOperation::known(0), None);
1297        assert_eq!(DiagnosticMutationOperation::known(5), None);
1298    }
1299
1300    #[test]
1301    fn query_kind_registries_are_fixed_contiguous_and_numeric() {
1302        for raw in 1..=9 {
1303            let value = DiagnosticTypeFamily::known(raw).expect("type family should be known");
1304            assert_eq!(value.raw(), raw);
1305            assert_eq!(format!("{value:?}"), raw.to_string());
1306        }
1307        assert_eq!(DiagnosticTypeFamily::known(0), None);
1308        assert_eq!(DiagnosticTypeFamily::known(10), None);
1309
1310        for raw in 1..=39 {
1311            let value = DiagnosticFunctionKind::known(raw).expect("function kind should be known");
1312            assert_eq!(value.raw(), raw);
1313            assert_eq!(format!("{value:?}"), raw.to_string());
1314        }
1315        assert_eq!(DiagnosticFunctionKind::known(0), None);
1316        assert_eq!(DiagnosticFunctionKind::known(40), None);
1317
1318        for raw in 1..=18 {
1319            let value = DiagnosticOperatorKind::known(raw).expect("operator kind should be known");
1320            assert_eq!(value.raw(), raw);
1321            assert_eq!(format!("{value:?}"), raw.to_string());
1322        }
1323        assert_eq!(DiagnosticOperatorKind::known(0), None);
1324        assert_eq!(DiagnosticOperatorKind::known(19), None);
1325
1326        for raw in 1..=8 {
1327            let value =
1328                DiagnosticAggregateKind::known(raw).expect("aggregate kind should be known");
1329            assert_eq!(value.raw(), raw);
1330            assert_eq!(format!("{value:?}"), raw.to_string());
1331        }
1332        assert_eq!(DiagnosticAggregateKind::known(0), None);
1333        assert_eq!(DiagnosticAggregateKind::known(9), None);
1334    }
1335
1336    #[test]
1337    fn per_code_schema_rejects_missing_disallowed_and_noncanonical_tags() {
1338        let valid = [
1339            (DiagnosticFactTag::ActualCount, 5),
1340            (DiagnosticFactTag::Limit, 4),
1341        ];
1342        assert_eq!(
1343            validate_known_diagnostic_fact_schema(
1344                ErrorCode::RUNTIME_BOUNDARY_MUTATION_BATCH_TOO_MANY_ITEMS,
1345                &valid,
1346            ),
1347            Ok(())
1348        );
1349        assert_eq!(
1350            validate_known_diagnostic_fact_schema(
1351                ErrorCode::RUNTIME_BOUNDARY_MUTATION_BATCH_TOO_MANY_ITEMS,
1352                &valid[..1],
1353            ),
1354            Err(DiagnosticFactSchemaMismatch::InvalidSequence)
1355        );
1356        assert_eq!(
1357            validate_known_diagnostic_fact_schema(
1358                ErrorCode::RUNTIME_BOUNDARY_MUTATION_BATCH_TOO_MANY_ITEMS,
1359                &[valid[1], valid[0]],
1360            ),
1361            Err(DiagnosticFactSchemaMismatch::InvalidSequence)
1362        );
1363        assert_eq!(
1364            validate_known_diagnostic_fact_schema(ErrorCode::QUERY_VALIDATE, &valid),
1365            Err(DiagnosticFactSchemaMismatch::CodeMaximumExceeded)
1366        );
1367    }
1368
1369    #[test]
1370    fn execution_budget_schema_requires_complete_typed_attribution() {
1371        let valid = [
1372            (
1373                DiagnosticFactTag::BudgetResource,
1374                DiagnosticExecutionBudgetResource::StoredBytesRead.raw(),
1375            ),
1376            (DiagnosticFactTag::Limit, 4_096),
1377            (DiagnosticFactTag::Actual, 4_097),
1378            (
1379                DiagnosticFactTag::ExecutionBudgetScope,
1380                DiagnosticExecutionBudgetScope::Request.raw(),
1381            ),
1382            (
1383                DiagnosticFactTag::ExecutionLane,
1384                DiagnosticExecutionLane::TrustedRead.raw(),
1385            ),
1386            (DiagnosticFactTag::QueryShapeFingerprintPrefix, 17),
1387        ];
1388        assert_eq!(
1389            validate_known_diagnostic_fact_schema(
1390                ErrorCode::RUNTIME_BOUNDARY_EXECUTION_BUDGET_EXCEEDED,
1391                &valid,
1392            ),
1393            Ok(())
1394        );
1395        assert_eq!(
1396            validate_known_diagnostic_fact_schema(
1397                ErrorCode::RUNTIME_BOUNDARY_EXECUTION_BUDGET_EXCEEDED,
1398                &valid[..5],
1399            ),
1400            Err(DiagnosticFactSchemaMismatch::InvalidSequence)
1401        );
1402
1403        let mut invalid_resource = valid;
1404        invalid_resource[0].1 = 0;
1405        assert_eq!(
1406            validate_known_diagnostic_fact_schema(
1407                ErrorCode::RUNTIME_BOUNDARY_EXECUTION_BUDGET_EXCEEDED,
1408                &invalid_resource,
1409            ),
1410            Err(DiagnosticFactSchemaMismatch::InvalidValue)
1411        );
1412    }
1413
1414    #[test]
1415    fn raw_schema_keeps_unknown_context_numeric_but_marks_it_invalid() {
1416        assert_eq!(
1417            validate_raw_diagnostic_fact_schema(
1418                ErrorCode::QUERY_INVALID_CONTINUATION_CURSOR,
1419                &[(u8::MAX, 17)],
1420            ),
1421            Err(DiagnosticFactSchemaMismatch::InvalidSequence)
1422        );
1423        assert_eq!(
1424            validate_raw_diagnostic_fact_schema(
1425                ErrorCode::QUERY_INVALID_CONTINUATION_CURSOR,
1426                &[(DiagnosticFactTag::DecodeReason.raw(), u64::MAX)],
1427            ),
1428            Err(DiagnosticFactSchemaMismatch::InvalidSequence)
1429        );
1430    }
1431
1432    #[test]
1433    fn constraint_schema_enforces_authority_operation_and_bounded_path_suffix() {
1434        let mut targeted = vec![
1435            (DiagnosticFactTag::AcceptedSchemaFingerprintMethod, 1),
1436            (DiagnosticFactTag::AcceptedSchemaFingerprintHigh, 2),
1437            (DiagnosticFactTag::AcceptedSchemaFingerprintLow, 3),
1438            (DiagnosticFactTag::EntityTag, 17),
1439            (DiagnosticFactTag::ConstraintId, 4),
1440            (
1441                DiagnosticFactTag::ConstraintKind,
1442                DiagnosticConstraintKind::TargetedRule.raw(),
1443            ),
1444            (
1445                DiagnosticFactTag::ConstraintContext,
1446                DiagnosticConstraintContext::WriteAdmission.raw(),
1447            ),
1448            (
1449                DiagnosticFactTag::MutationOperation,
1450                DiagnosticMutationOperation::Insert.raw(),
1451            ),
1452            (DiagnosticFactTag::BatchPosition, 0),
1453        ];
1454        targeted.extend((0..64).map(|index| (DiagnosticFactTag::ListElement, index)));
1455        assert_eq!(targeted.len(), 73);
1456        assert_eq!(
1457            validate_known_diagnostic_fact_schema(
1458                ErrorCode::RUNTIME_BOUNDARY_CONSTRAINT_VIOLATION,
1459                targeted.as_slice(),
1460            ),
1461            Ok(())
1462        );
1463
1464        let mut overlong = targeted.clone();
1465        overlong.push((DiagnosticFactTag::ListElement, 64));
1466        assert_eq!(
1467            validate_known_diagnostic_fact_schema(
1468                ErrorCode::RUNTIME_BOUNDARY_CONSTRAINT_VIOLATION,
1469                overlong.as_slice(),
1470            ),
1471            Err(DiagnosticFactSchemaMismatch::CodeMaximumExceeded)
1472        );
1473
1474        let mut non_targeted_path = targeted;
1475        non_targeted_path[5].1 = DiagnosticConstraintKind::Unique.raw();
1476        assert_eq!(
1477            validate_known_diagnostic_fact_schema(
1478                ErrorCode::RUNTIME_BOUNDARY_CONSTRAINT_VIOLATION,
1479                non_targeted_path.as_slice(),
1480            ),
1481            Err(DiagnosticFactSchemaMismatch::InvalidSequence)
1482        );
1483    }
1484
1485    #[test]
1486    fn schema_enforces_global_ceiling_before_per_code_ceiling() {
1487        let facts = vec![(DiagnosticFactTag::ActualCount.raw(), 0); 81];
1488        assert_eq!(
1489            validate_raw_diagnostic_fact_schema(ErrorCode::QUERY_PLAN, facts.as_slice()),
1490            Err(DiagnosticFactSchemaMismatch::GlobalMaximumExceeded)
1491        );
1492    }
1493}