1use omena_abstract_value::{AbstractCssValueV0, FactPrecision};
10use omena_cascade::{
11 CascadeDeclaration, CascadeLevel, CascadeOriginV0, CascadeOutcome, CascadeProof,
12 ElementSignature, GuardedCascadeWinnerAuthorityV0, GuardedCascadeWinnerPlaneAnswerV0,
13 GuardedCascadeWinnerRootV0, SupportsTargetCapabilityV0,
14};
15use omena_cascade_proof::{
16 CanonicalSmtInputV0, DischargeLedgerLookupStatusV0, DischargeLedgerLookupV0,
17 DischargeLedgerVerdictV0,
18};
19use omena_evidence_graph::{
20 EvidenceDemandEdgeV0, EvidenceGraphBuildErrorV0, EvidenceGraphV0, EvidenceNodeKeyV0,
21 EvidenceNodeSeedV0, GuaranteeFamilyV0, GuaranteeKindV0, build_evidence_graph_from_edges_v0,
22};
23use omena_incremental::{IncrementalComputationPlanV0, IncrementalSnapshotV0};
24use omena_parser::ModuleInstanceKeyV0;
25use omena_transform_cst::{
26 StableNodeKeyV0, TransformBuildProfileV0, TransformDagEdgeV0, TransformPassContractV0,
27 TransformPassDescriptorV0, TransformPassKind, TransformStrictPolicyDescriptorV0,
28 strict_policy_descriptor_for_profile,
29};
30use serde::{Deserialize, Serialize};
31use serde_json::Value;
32
33const TRANSFORM_PASS_OUTCOME_EVIDENCE_QUERY_V0: &str =
34 "omena-transform-passes.transform-pass-execution-outcome";
35const TRANSFORM_PROVENANCE_NODE_EVIDENCE_QUERY_V0: &str =
36 "omena-transform-passes.provenance-derivation-node";
37const TRANSFORM_EVIDENCE_EDGE_KIND_V0: &str = "transform-evidence";
38
39#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize)]
40#[serde(rename_all = "camelCase")]
41pub enum TransformPassExecutionStatus {
42 RegistryAndPlannerReady,
43}
44
45#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize)]
46#[serde(rename_all = "camelCase")]
47pub enum TransformPassDispatchKindV0 {
48 TextLocalSliceRewrite,
49 StructuralIrTransaction,
50 ModuleEvaluationHandler,
51 EmissionBoundary,
52}
53
54#[derive(Debug, Clone, PartialEq, Eq, Serialize)]
55#[serde(rename_all = "camelCase")]
56pub struct TransformPassRegistryEntryV0 {
57 pub contract: TransformPassContractV0,
58 pub descriptor: TransformPassDescriptorV0,
59 pub module_family: &'static str,
60 pub query_family: &'static str,
61 pub dispatch_kind: TransformPassDispatchKindV0,
62 pub execution_status: TransformPassExecutionStatus,
63}
64
65#[derive(Debug, Clone, PartialEq, Eq, Serialize)]
66#[serde(rename_all = "camelCase")]
67pub struct TransformPassRegistryV0 {
68 pub schema_version: &'static str,
69 pub product: &'static str,
70 pub entries: Vec<TransformPassRegistryEntryV0>,
71}
72
73#[derive(Debug, Clone, PartialEq, Eq, Serialize)]
74#[serde(rename_all = "camelCase")]
75pub struct TransformPassesBoundarySummaryV0 {
76 pub schema_version: &'static str,
77 pub product: &'static str,
78 pub registry_entries: Vec<TransformPassRegistryEntryV0>,
79 pub dag_edges: Vec<TransformDagEdgeV0>,
80 pub pass_count: usize,
81 pub full_catalog_registered: bool,
82 pub semantic_aware_pass_count: usize,
83 pub cascade_aware_pass_count: usize,
84 pub structural_pass_count: usize,
85 pub text_local_pass_count: usize,
86 pub module_evaluation_pass_count: usize,
87 pub planner_enforces_dag_edges: bool,
88 pub planner_uses_pass_descriptors: bool,
89 pub ordinal_has_execution_semantics: bool,
90 pub execution_runtime_ready: bool,
91 pub incremental_execution_runtime_ready: bool,
92 pub module_evaluation_native_output_marker: &'static str,
93 pub module_evaluation_requires_native_product_output: bool,
94 pub module_evaluation_requires_oracle_readiness: bool,
95 pub module_evaluation_legacy_output_is_oracle_only: bool,
96 pub module_evaluation_preserves_source_without_native_output: bool,
97 pub implemented_mutation_pass_ids: Vec<&'static str>,
98 pub next_surfaces: Vec<&'static str>,
99}
100
101#[derive(Debug, Clone, PartialEq, Eq, Serialize)]
102#[serde(rename_all = "camelCase")]
103pub struct TransformPassPlanV0 {
104 pub schema_version: &'static str,
105 pub product: &'static str,
106 pub build_profile: TransformBuildProfileV0,
107 pub requested_pass_ids: Vec<&'static str>,
108 pub ordered_pass_ids: Vec<&'static str>,
109 pub satisfied_dag_edge_count: usize,
110 pub violated_dag_edge_count: usize,
111 pub all_requested_registered: bool,
112 pub conflicting_unordered_pass_pairs: Vec<TransformPlanPassConflictV0>,
113}
114
115#[derive(Debug, Clone, PartialEq, Eq, Serialize)]
116#[serde(rename_all = "camelCase")]
117pub struct TransformPlanPassConflictV0 {
118 pub pass_a: &'static str,
119 pub pass_b: &'static str,
120}
121
122#[derive(Debug, Clone, PartialEq, Eq, Serialize)]
123#[serde(rename_all = "camelCase")]
124pub struct TransformStructuralIrShadowFieldReportV0 {
125 pub field: &'static str,
126 pub string_path_values: Vec<String>,
127 pub ir_path_values: Vec<String>,
128 pub typed_path_values: Vec<String>,
129 pub matches: bool,
130}
131
132#[derive(Debug, Clone, PartialEq, Eq, Serialize)]
133#[serde(rename_all = "camelCase")]
134pub struct TransformStructuralIrShadowFixtureReportV0 {
135 pub schema_version: &'static str,
136 pub product: &'static str,
137 pub fixture: String,
138 pub pass_id: &'static str,
139 pub dialect: &'static str,
140 pub string_path_mutation_count: Option<usize>,
141 pub ir_path_mutation_count: Option<usize>,
142 pub typed_path_mutation_count: Option<usize>,
143 pub ir_path_transaction_commit_count: Option<u64>,
144 pub typed_payload_projections_consumed: usize,
145 pub typed_payload_memo_hits: usize,
146 pub fields: Vec<TransformStructuralIrShadowFieldReportV0>,
147 pub all_fields_match: bool,
148 pub all_typed_path_fields_match: bool,
149}
150
151#[derive(Debug, Clone, PartialEq, Eq, Serialize)]
152#[serde(rename_all = "camelCase")]
153pub struct TransformStructuralIrShadowEquivalenceReportV0 {
154 pub schema_version: &'static str,
155 pub product: &'static str,
156 pub fixture_count: usize,
157 pub compared_pass_ids: Vec<&'static str>,
158 pub compared_fields: Vec<&'static str>,
159 pub reports: Vec<TransformStructuralIrShadowFixtureReportV0>,
160 pub all_fields_match: bool,
161 pub all_typed_path_fields_match: bool,
162 pub typed_payload_projections_consumed: usize,
163 pub typed_payload_memo_hits: usize,
164}
165
166#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize)]
167#[serde(rename_all = "camelCase")]
168pub enum TransformPassRuntimeStatus {
169 Applied,
170 NoChange,
171 PlannedOnly,
172}
173
174#[derive(Debug, Clone, PartialEq, Eq, Serialize)]
175#[serde(rename_all = "camelCase")]
176pub struct TransformPassExecutionOutcomeV0 {
177 pub pass_id: &'static str,
178 pub status: TransformPassRuntimeStatus,
179 pub input_byte_len: usize,
180 pub output_byte_len: usize,
181 pub mutation_count: usize,
182 pub provenance_preserved: bool,
183 pub detail: &'static str,
184}
185
186impl TransformPassExecutionOutcomeV0 {
187 pub fn evidence_node_key(&self) -> EvidenceNodeKeyV0 {
188 EvidenceNodeKeyV0::new(TRANSFORM_PASS_OUTCOME_EVIDENCE_QUERY_V0, self.pass_id)
189 }
190
191 pub fn evidence_node_seed(&self) -> EvidenceNodeSeedV0 {
192 EvidenceNodeSeedV0::new(
193 self.evidence_node_key(),
194 vec![
195 ["pass:", self.pass_id].concat(),
196 ["detail:", self.detail].concat(),
197 ["mutationCount:", self.mutation_count.to_string().as_str()].concat(),
198 [
199 "provenancePreserved:",
200 self.provenance_preserved.to_string().as_str(),
201 ]
202 .concat(),
203 ],
204 GuaranteeKindV0::for_label_less_family(),
205 )
206 }
207
208 pub fn evidence_demand_edge(&self) -> EvidenceDemandEdgeV0 {
209 EvidenceDemandEdgeV0::new(
210 TRANSFORM_PASS_OUTCOME_EVIDENCE_QUERY_V0,
211 self.evidence_node_key(),
212 TRANSFORM_EVIDENCE_EDGE_KIND_V0,
213 )
214 }
215}
216
217#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize)]
218#[serde(rename_all = "camelCase")]
219pub enum TransformEvaluationProfileV0 {
220 Scss,
221 Less,
222}
223
224#[derive(Debug, Clone, PartialEq, Eq, Serialize)]
225#[serde(tag = "kind", rename_all = "camelCase")]
226pub enum TransformPreconditionV0 {
227 EvaluatorOutput {
228 profile: TransformEvaluationProfileV0,
229 },
230 ResolvedImportReplacements,
231 CssModulesComposesResolution,
232 DesignTokenRoutes,
233 SelectorIdentity,
234 ClosedStyleWorldBundle,
235 ClosedWorldBundle,
236}
237
238#[derive(Debug, Clone, PartialEq, Eq, Serialize)]
239#[serde(tag = "kind", rename_all = "camelCase")]
240pub enum TransformNoChangeReasonV0 {
241 NoMutation,
242 EmissionBoundary,
243 ProfileNotApplicable {
244 profile: TransformEvaluationProfileV0,
245 },
246 NoMatchingSelectorRewrite,
247 DialectNotApplicable,
248}
249
250#[derive(Debug, Clone, PartialEq, Eq, Serialize)]
251#[serde(
252 tag = "kind",
253 rename_all = "camelCase",
254 rename_all_fields = "camelCase"
255)]
256pub enum TransformBlockedReasonV0 {
257 MissingPrecondition {
258 precondition: TransformPreconditionV0,
259 },
260 PrecisionBelowFloor {
261 required: FactPrecision,
262 observed: FactPrecision,
263 },
264 DischargeMissing {
265 lookup_status: Option<DischargeLedgerLookupStatusV0>,
266 verdict: Option<DischargeLedgerVerdictV0>,
267 },
268 StrictVerification {
269 reasons: Vec<TransformStrictPolicyReasonV0>,
270 },
271 PassImplementation,
272 ClosedWorldAdmission {
273 reasons: Vec<TransformStrictPolicyReasonV0>,
274 },
275}
276
277#[derive(Debug, Clone, PartialEq, Eq, Serialize)]
278#[serde(tag = "kind", rename_all = "camelCase")]
279pub enum TransformRejectionReasonV0 {
280 IrTransaction {
281 pass: TransformPassKind,
282 },
283 SemanticPreservation,
284 StrictVerification {
285 reasons: Vec<TransformStrictPolicyReasonV0>,
286 },
287}
288
289#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize)]
290#[serde(
291 tag = "kind",
292 rename_all = "camelCase",
293 rename_all_fields = "camelCase"
294)]
295pub enum TransformStructuralDecisionClassV0 {
296 FactConsuming { required_precision: FactPrecision },
297 StaticExact,
298 ObligationDischarge,
299 NonRemovalRewrite,
300}
301
302#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize)]
303#[serde(rename_all = "camelCase")]
304pub struct TransformStructuralDecisionPolicyV0 {
305 pub pass: TransformPassKind,
306 pub class: TransformStructuralDecisionClassV0,
307 pub reason: &'static str,
308}
309
310impl TransformStructuralDecisionPolicyV0 {
311 pub const fn new(
312 pass: TransformPassKind,
313 class: TransformStructuralDecisionClassV0,
314 reason: &'static str,
315 ) -> Self {
316 Self {
317 pass,
318 class,
319 reason,
320 }
321 }
322
323 pub const fn required_precision(self) -> Option<FactPrecision> {
324 match self.class {
325 TransformStructuralDecisionClassV0::FactConsuming { required_precision } => {
326 Some(required_precision)
327 }
328 TransformStructuralDecisionClassV0::StaticExact
329 | TransformStructuralDecisionClassV0::ObligationDischarge
330 | TransformStructuralDecisionClassV0::NonRemovalRewrite => None,
331 }
332 }
333}
334
335pub const TRANSFORM_STRUCTURAL_DECISION_POLICIES_V0: &[TransformStructuralDecisionPolicyV0] = &[
336 TransformStructuralDecisionPolicyV0::new(
337 TransformPassKind::ImportInline,
338 TransformStructuralDecisionClassV0::NonRemovalRewrite,
339 "materializes explicitly resolved imports without reachability pruning",
340 ),
341 TransformStructuralDecisionPolicyV0::new(
342 TransformPassKind::ResolveCssModulesComposes,
343 TransformStructuralDecisionClassV0::NonRemovalRewrite,
344 "materializes explicit CSS Modules composition resolution",
345 ),
346 TransformStructuralDecisionPolicyV0::new(
347 TransformPassKind::DesignTokenRouting,
348 TransformStructuralDecisionClassV0::NonRemovalRewrite,
349 "rewrites values through explicit design-token routes",
350 ),
351 TransformStructuralDecisionPolicyV0::new(
352 TransformPassKind::HashCssModuleClassNames,
353 TransformStructuralDecisionClassV0::NonRemovalRewrite,
354 "rewrites selectors through an explicit identity map",
355 ),
356 TransformStructuralDecisionPolicyV0::new(
357 TransformPassKind::RuleDeduplication,
358 TransformStructuralDecisionClassV0::StaticExact,
359 "removes only statically equivalent duplicate rules",
360 ),
361 TransformStructuralDecisionPolicyV0::new(
362 TransformPassKind::RuleMerging,
363 TransformStructuralDecisionClassV0::NonRemovalRewrite,
364 "combines adjacent declarations without reachability pruning",
365 ),
366 TransformStructuralDecisionPolicyV0::new(
367 TransformPassKind::SelectorMerging,
368 TransformStructuralDecisionClassV0::NonRemovalRewrite,
369 "combines equivalent selector blocks without reachability pruning",
370 ),
371 TransformStructuralDecisionPolicyV0::new(
372 TransformPassKind::NestingUnwrap,
373 TransformStructuralDecisionClassV0::NonRemovalRewrite,
374 "expands nested selectors without reachability pruning",
375 ),
376 TransformStructuralDecisionPolicyV0::new(
377 TransformPassKind::ScopeFlatten,
378 TransformStructuralDecisionClassV0::ObligationDischarge,
379 "requires accepted scope-flatten obligations",
380 ),
381 TransformStructuralDecisionPolicyV0::new(
382 TransformPassKind::LayerFlatten,
383 TransformStructuralDecisionClassV0::ObligationDischarge,
384 "requires accepted layer-flatten obligations",
385 ),
386 TransformStructuralDecisionPolicyV0::new(
387 TransformPassKind::SupportsStaticEval,
388 TransformStructuralDecisionClassV0::StaticExact,
389 "removes only statically decided supports branches",
390 ),
391 TransformStructuralDecisionPolicyV0::new(
392 TransformPassKind::MediaStaticEval,
393 TransformStructuralDecisionClassV0::StaticExact,
394 "removes only statically unsatisfiable media branches",
395 ),
396 TransformStructuralDecisionPolicyV0::new(
397 TransformPassKind::ContainerStaticEval,
398 TransformStructuralDecisionClassV0::StaticExact,
399 "removes only statically unsatisfiable container branches",
400 ),
401 TransformStructuralDecisionPolicyV0::new(
402 TransformPassKind::NativeCssStaticEval,
403 TransformStructuralDecisionClassV0::StaticExact,
404 "folds only statically evaluable native CSS expressions",
405 ),
406 TransformStructuralDecisionPolicyV0::new(
407 TransformPassKind::DeadMediaBranchRemoval,
408 TransformStructuralDecisionClassV0::StaticExact,
409 "removes only media branches selected by explicit static policy",
410 ),
411 TransformStructuralDecisionPolicyV0::new(
412 TransformPassKind::DeadSupportsBranchRemoval,
413 TransformStructuralDecisionClassV0::StaticExact,
414 "removes only statically decided supports branches",
415 ),
416 TransformStructuralDecisionPolicyV0::new(
417 TransformPassKind::TreeShakeClass,
418 TransformStructuralDecisionClassV0::FactConsuming {
419 required_precision: FactPrecision::Conservative,
420 },
421 "removes class rules only from a closed-world reachability over-approximation",
422 ),
423 TransformStructuralDecisionPolicyV0::new(
424 TransformPassKind::TreeShakeKeyframes,
425 TransformStructuralDecisionClassV0::FactConsuming {
426 required_precision: FactPrecision::Conservative,
427 },
428 "removes keyframes only from a closed-world reachability over-approximation",
429 ),
430 TransformStructuralDecisionPolicyV0::new(
431 TransformPassKind::TreeShakeValue,
432 TransformStructuralDecisionClassV0::FactConsuming {
433 required_precision: FactPrecision::Conservative,
434 },
435 "removes CSS Modules values only from a closed-world reachability over-approximation",
436 ),
437 TransformStructuralDecisionPolicyV0::new(
438 TransformPassKind::TreeShakeCustomProperty,
439 TransformStructuralDecisionClassV0::FactConsuming {
440 required_precision: FactPrecision::Conservative,
441 },
442 "removes custom properties only from a closed-world reachability over-approximation",
443 ),
444 TransformStructuralDecisionPolicyV0::new(
445 TransformPassKind::EmptyRuleRemoval,
446 TransformStructuralDecisionClassV0::StaticExact,
447 "removes only structurally empty rules",
448 ),
449];
450
451pub fn transform_structural_decision_policy(
452 pass: TransformPassKind,
453) -> Option<&'static TransformStructuralDecisionPolicyV0> {
454 TRANSFORM_STRUCTURAL_DECISION_POLICIES_V0
455 .iter()
456 .find(|policy| policy.pass == pass)
457}
458
459#[derive(Debug, Clone, PartialEq, Eq, Deserialize, Serialize)]
460#[serde(tag = "kind", rename_all = "camelCase")]
461pub enum RollbackScopeV0 {
462 RejectPreservedInput,
463 InversePatch,
464 CommittedIrrecoverable,
465}
466
467#[derive(Debug, Clone, PartialEq, Eq, Deserialize, Serialize)]
468#[serde(rename_all = "camelCase")]
469pub struct RollbackReceiptV0 {
470 pub pass_id: String,
471 pub attempted_mutation_count: Option<usize>,
472 pub input_content_signature: String,
473 #[serde(skip_serializing_if = "Option::is_none")]
474 pub output_preserved_content_signature: Option<String>,
475 pub restorable: RollbackScopeV0,
476}
477
478#[derive(Debug, Clone, PartialEq, Eq, Serialize)]
479#[serde(rename_all = "camelCase")]
480pub struct TransformDischargeEvidenceV0 {
481 pub evidence_node_key: EvidenceNodeKeyV0,
482 pub guarantee_family: GuaranteeFamilyV0,
483 pub ledger_cell_key: String,
484 pub boundedness_kind: String,
485}
486
487#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Serialize)]
492#[serde(rename_all = "camelCase")]
493pub enum TransformWinnerEqualityAxisV0 {
494 CascadeLevel,
495 LayerRank,
496 ScopeProximity,
497 Specificity,
498 SourceOrder,
499}
500
501#[derive(Debug, Clone, PartialEq, Eq, Serialize)]
503#[serde(
504 tag = "kind",
505 rename_all = "camelCase",
506 rename_all_fields = "camelCase"
507)]
508pub enum TransformWinnerEqualityAbsenceReasonV0 {
509 DriverUnavailable {
510 level: Option<CascadeLevel>,
511 },
512 AffectedPairUnavailable,
513 SpecificityInexact,
514 WinnerNotDefinite,
515 WinnerChanged,
516 GuardedWinnerFunctionsDiffer {
517 input_root: GuardedCascadeWinnerRootV0,
518 output_root: GuardedCascadeWinnerRootV0,
519 },
520 GuardedWinnerPlaneDisagreement {
521 side: &'static str,
522 canonical_mtbdd: GuardedCascadeWinnerPlaneAnswerV0,
523 scenario_sweep: GuardedCascadeWinnerPlaneAnswerV0,
524 },
525}
526
527#[derive(Debug, Clone, PartialEq, Eq, Serialize)]
529#[serde(rename_all = "camelCase")]
530pub struct TransformWinnerEqualityAbsenceV0 {
531 pub axis: TransformWinnerEqualityAxisV0,
532 pub reason: TransformWinnerEqualityAbsenceReasonV0,
533}
534
535#[derive(Debug, Clone, PartialEq, Eq, Serialize)]
537#[serde(rename_all = "camelCase")]
538pub struct TransformWinnerEqualityAffectedPairV0 {
539 pub element_signature: ElementSignature,
540 pub property: String,
541}
542
543#[derive(Debug, Clone, PartialEq, Eq, Serialize)]
548#[serde(rename_all = "camelCase")]
549pub struct TransformWinnerEqualityWitnessV0 {
550 pub winner: CascadeDeclaration,
551 pub proof: CascadeProof,
552}
553
554impl TransformWinnerEqualityWitnessV0 {
555 pub fn from_cascade_outcome(outcome: &CascadeOutcome) -> Option<Self> {
556 match outcome {
557 CascadeOutcome::Definite { winner, proof, .. } => Some(Self {
558 winner: winner.clone(),
559 proof: proof.as_ref().clone(),
560 }),
561 CascadeOutcome::RankedSet(_) | CascadeOutcome::Inherit | CascadeOutcome::Top => None,
562 }
563 }
564}
565
566#[derive(Debug, Clone, PartialEq, Eq, Serialize)]
568#[serde(
569 tag = "kind",
570 rename_all = "camelCase",
571 rename_all_fields = "camelCase"
572)]
573pub enum TransformWinnerEqualityObservationV0 {
574 ObservedEqual {
575 axes: Vec<TransformWinnerEqualityAxisV0>,
576 input: TransformWinnerEqualityWitnessV0,
577 output: TransformWinnerEqualityWitnessV0,
578 },
579 ObservedDifferent {
580 axes: Vec<TransformWinnerEqualityAxisV0>,
581 input: TransformWinnerEqualityWitnessV0,
582 output: TransformWinnerEqualityWitnessV0,
583 },
584 Absent {
585 reasons: Vec<TransformWinnerEqualityAbsenceV0>,
586 },
587 ObservedGuardedEqual {
588 axes: Vec<TransformWinnerEqualityAxisV0>,
589 input: TransformWinnerEqualityWitnessV0,
590 output: TransformWinnerEqualityWitnessV0,
591 authority: GuardedCascadeWinnerAuthorityV0,
592 },
593}
594
595#[derive(Debug, Clone, PartialEq, Eq, Serialize)]
597#[serde(rename_all = "camelCase")]
598pub struct TransformWinnerEqualityObligationV0 {
599 pub pass_id: &'static str,
600 pub affected_pair: TransformWinnerEqualityAffectedPairV0,
601 pub observation: TransformWinnerEqualityObservationV0,
602}
603
604#[derive(Debug, Clone, Default, PartialEq, Eq)]
605pub struct TransformExecutionPolicyV0 {
606 pub strict_policy: Option<TransformStrictPolicyDescriptorV0>,
607}
608
609impl TransformExecutionPolicyV0 {
610 pub fn for_profile(profile_id: &str) -> Option<Self> {
611 strict_policy_descriptor_for_profile(profile_id).map(|strict_policy| Self {
612 strict_policy: Some(strict_policy),
613 })
614 }
615}
616
617#[derive(Debug, Clone, PartialEq, Eq, Serialize)]
618#[serde(
619 tag = "kind",
620 rename_all = "camelCase",
621 rename_all_fields = "camelCase"
622)]
623pub enum TransformStrictPolicyReasonV0 {
624 RequiredAxisUnavailable {
625 axis: TransformWinnerEqualityAxisV0,
626 },
627 CascadeEnvironmentUnavailable,
628 WinnerChanged {
629 axes: Vec<TransformWinnerEqualityAxisV0>,
630 },
631 ObservationUnavailable {
632 reasons: Vec<TransformWinnerEqualityAbsenceV0>,
633 },
634 UnknownPass,
635 ClosedWorldEvidenceUnavailable,
636 DecisionCoverageIncomplete,
637 ClosedWorldEvidenceIncomplete {
638 missing: Vec<String>,
639 },
640 LivenessNotClosed {
641 symbol: String,
642 from_module: ModuleInstanceKeyV0,
643 via_edge: &'static str,
644 },
645 EvidenceUnavailable,
646 OwnershipNotSeparable {
647 token: String,
648 module_paths: Vec<String>,
649 },
650}
651
652#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Serialize)]
653#[serde(rename_all = "camelCase")]
654#[non_exhaustive]
655pub enum CssModuleTokenCollisionPathScopeV0 {
656 BothPaths,
657 ImportInlineLegacyOnly,
658 LinkedOrderOnly,
659}
660
661impl CssModuleTokenCollisionPathScopeV0 {
662 pub const fn as_wire_label(self) -> &'static str {
663 match self {
664 Self::BothPaths => "bothPaths",
665 Self::ImportInlineLegacyOnly => "importInlineLegacyOnly",
666 Self::LinkedOrderOnly => "linkedOrderOnly",
667 }
668 }
669}
670
671#[derive(Debug, Clone, PartialEq, Eq, Serialize)]
672#[serde(rename_all = "camelCase")]
673#[non_exhaustive]
674pub struct CssModuleTokenOwnershipV0 {
675 pub emitted_token: String,
676 pub module_instances: Vec<ModuleInstanceKeyV0>,
677 pub module_paths: Vec<String>,
678 pub original_names: Vec<String>,
679}
680
681impl CssModuleTokenOwnershipV0 {
682 pub fn new(
683 emitted_token: impl Into<String>,
684 module_instances: Vec<ModuleInstanceKeyV0>,
685 module_paths: Vec<String>,
686 original_names: Vec<String>,
687 ) -> Self {
688 Self {
689 emitted_token: emitted_token.into(),
690 module_instances,
691 module_paths,
692 original_names,
693 }
694 }
695}
696
697#[derive(Debug, Clone, PartialEq, Eq, Serialize)]
698#[serde(rename_all = "camelCase")]
699#[non_exhaustive]
700pub struct CssModuleTokenCollisionV0 {
701 pub emitted_token: String,
702 pub module_instances: Vec<ModuleInstanceKeyV0>,
703 pub module_paths: Vec<String>,
704 pub original_names: Vec<String>,
705 pub observed_emission_paths: Vec<&'static str>,
706 pub path_scope: CssModuleTokenCollisionPathScopeV0,
707}
708
709impl CssModuleTokenCollisionV0 {
710 pub fn new(
711 ownership: CssModuleTokenOwnershipV0,
712 observed_emission_paths: Vec<&'static str>,
713 path_scope: CssModuleTokenCollisionPathScopeV0,
714 ) -> Self {
715 Self {
716 emitted_token: ownership.emitted_token,
717 module_instances: ownership.module_instances,
718 module_paths: ownership.module_paths,
719 original_names: ownership.original_names,
720 observed_emission_paths,
721 path_scope,
722 }
723 }
724}
725
726#[derive(Debug, Clone, PartialEq, Eq, Serialize)]
727#[serde(rename_all = "camelCase")]
728#[non_exhaustive]
729pub struct CssModuleTokenInterfaceMismatchV0 {
730 pub module_instance: ModuleInstanceKeyV0,
731 pub module_path: String,
732 pub original_name: String,
733 pub promised_token: String,
734 pub emitted_token: String,
735}
736
737impl CssModuleTokenInterfaceMismatchV0 {
738 pub fn new(
739 module_instance: ModuleInstanceKeyV0,
740 module_path: impl Into<String>,
741 original_name: impl Into<String>,
742 promised_token: impl Into<String>,
743 emitted_token: impl Into<String>,
744 ) -> Self {
745 Self {
746 module_instance,
747 module_path: module_path.into(),
748 original_name: original_name.into(),
749 promised_token: promised_token.into(),
750 emitted_token: emitted_token.into(),
751 }
752 }
753}
754
755#[derive(Debug, Clone, PartialEq, Eq, Serialize)]
756#[serde(rename_all = "camelCase")]
757#[non_exhaustive]
758pub struct CssModuleTokenOwnershipCensusV0 {
759 pub schema_version: &'static str,
760 pub product: &'static str,
761 pub scope: &'static str,
762 pub emission_path: &'static str,
763 pub complete: bool,
764 pub modeled_preimage_count: usize,
765 pub emitted_token_count: usize,
766 pub token_ownerships: Vec<CssModuleTokenOwnershipV0>,
767 pub module_token_collision_count: usize,
768 pub module_token_collisions: Vec<CssModuleTokenCollisionV0>,
769 pub unattributed_emitted_tokens: Vec<String>,
770 pub interface_mismatches: Vec<CssModuleTokenInterfaceMismatchV0>,
771 pub unavailable_reasons: Vec<String>,
772}
773
774impl CssModuleTokenOwnershipCensusV0 {
775 pub fn new(
776 emission_path: &'static str,
777 modeled_preimage_count: usize,
778 token_ownerships: Vec<CssModuleTokenOwnershipV0>,
779 module_token_collisions: Vec<CssModuleTokenCollisionV0>,
780 unattributed_emitted_tokens: Vec<String>,
781 interface_mismatches: Vec<CssModuleTokenInterfaceMismatchV0>,
782 ) -> Self {
783 let module_token_collision_count = module_token_collisions.len();
784 let emitted_token_count = token_ownerships.len() + unattributed_emitted_tokens.len();
785 Self {
786 schema_version: "0",
787 product: "omena-query.css-module-token-ownership-census",
788 scope: "bundleEmission",
789 emission_path,
790 complete: unattributed_emitted_tokens.is_empty(),
791 modeled_preimage_count,
792 emitted_token_count,
793 token_ownerships,
794 module_token_collision_count,
795 module_token_collisions,
796 unattributed_emitted_tokens,
797 interface_mismatches,
798 unavailable_reasons: Vec::new(),
799 }
800 }
801
802 pub fn unavailable(emission_path: &'static str, reason: impl Into<String>) -> Self {
803 Self {
804 schema_version: "0",
805 product: "omena-query.css-module-token-ownership-census",
806 scope: "bundleEmission",
807 emission_path,
808 complete: false,
809 modeled_preimage_count: 0,
810 emitted_token_count: 0,
811 token_ownerships: Vec::new(),
812 module_token_collision_count: 0,
813 module_token_collisions: Vec::new(),
814 unattributed_emitted_tokens: Vec::new(),
815 interface_mismatches: Vec::new(),
816 unavailable_reasons: vec![reason.into()],
817 }
818 }
819}
820
821#[derive(Debug, Clone, PartialEq, Eq, Serialize)]
822#[serde(rename_all = "camelCase")]
823pub struct TransformStrictPolicyEventV0 {
824 pub pass_id: String,
825 pub reasons: Vec<TransformStrictPolicyReasonV0>,
826}
827
828#[derive(Debug, Clone, Default, PartialEq, Eq, Serialize)]
829#[serde(rename_all = "camelCase")]
830pub struct TransformStrictPolicySummaryV0 {
831 pub profile_id: Option<String>,
832 pub refused_count: usize,
833 pub rolled_back_count: usize,
834 pub refusal_reasons: Vec<TransformStrictPolicyEventV0>,
835 pub rollback_reasons: Vec<TransformStrictPolicyEventV0>,
836}
837
838impl TransformStrictPolicySummaryV0 {
839 pub fn for_profile(profile_id: &str) -> Self {
840 Self {
841 profile_id: Some(profile_id.to_string()),
842 ..Self::default()
843 }
844 }
845
846 pub fn record_refusal(
847 &mut self,
848 pass_id: impl Into<String>,
849 reasons: Vec<TransformStrictPolicyReasonV0>,
850 ) {
851 self.refusal_reasons.push(TransformStrictPolicyEventV0 {
852 pass_id: pass_id.into(),
853 reasons,
854 });
855 self.refused_count = self.refusal_reasons.len();
856 }
857
858 pub fn record_rollback(
859 &mut self,
860 pass_id: impl Into<String>,
861 reasons: Vec<TransformStrictPolicyReasonV0>,
862 ) {
863 self.rollback_reasons.push(TransformStrictPolicyEventV0 {
864 pass_id: pass_id.into(),
865 reasons,
866 });
867 self.rolled_back_count = self.rollback_reasons.len();
868 }
869}
870
871#[derive(Debug, Clone, Copy, Default, PartialEq, Eq)]
872pub struct ClosedWorldAdmissionTierV0;
873
874#[derive(Debug, Clone, PartialEq, Eq, Serialize)]
875#[serde(rename_all = "camelCase")]
876pub struct TransformClosedWorldAdmissionEventV0 {
877 pub pass_id: String,
878 pub module_instance: Option<ModuleInstanceKeyV0>,
879 pub reasons: Vec<TransformStrictPolicyReasonV0>,
880}
881
882#[derive(Debug, Clone, Default, PartialEq, Eq, Serialize)]
883#[serde(rename_all = "camelCase")]
884pub struct TransformClosedWorldAdmissionSummaryV0 {
885 pub refused_count: usize,
886 #[serde(skip_serializing_if = "Option::is_none")]
887 pub evidence_scope: Option<&'static str>,
888 pub refusal_reasons: Vec<TransformClosedWorldAdmissionEventV0>,
889}
890
891impl TransformClosedWorldAdmissionSummaryV0 {
892 pub fn record_refusal(
893 &mut self,
894 pass_id: impl Into<String>,
895 module_instance: Option<ModuleInstanceKeyV0>,
896 reasons: Vec<TransformStrictPolicyReasonV0>,
897 ) {
898 self.refusal_reasons
899 .push(TransformClosedWorldAdmissionEventV0 {
900 pass_id: pass_id.into(),
901 module_instance,
902 reasons,
903 });
904 self.refused_count = self.refusal_reasons.len();
905 }
906}
907
908#[derive(Debug, Clone, PartialEq, Eq, Serialize)]
915#[serde(
916 tag = "kind",
917 rename_all = "camelCase",
918 rename_all_fields = "camelCase"
919)]
920pub enum TransformSemanticGuaranteeTierV0 {
921 L0Observed,
922 WinnerEqualityObserved {
923 axes: Vec<TransformWinnerEqualityAxisV0>,
924 },
925 Absent {
926 reasons: Vec<TransformWinnerEqualityAbsenceV0>,
927 },
928}
929
930impl RollbackReceiptV0 {
931 pub fn preserves_rejected_input(&self) -> bool {
932 self.restorable == RollbackScopeV0::RejectPreservedInput
933 && self.output_preserved_content_signature.as_deref()
934 == Some(self.input_content_signature.as_str())
935 }
936
937 pub fn covers_inverse_patch(
938 &self,
939 inverse_patch_count: usize,
940 input_content_signature: &str,
941 ) -> bool {
942 self.restorable == RollbackScopeV0::InversePatch
943 && self.attempted_mutation_count == Some(inverse_patch_count)
944 && self.input_content_signature == input_content_signature
945 && self.output_preserved_content_signature.is_none()
946 }
947}
948
949#[derive(Debug, Clone, PartialEq, Eq, Serialize)]
950#[serde(
951 tag = "kind",
952 rename_all = "camelCase",
953 rename_all_fields = "camelCase"
954)]
955pub enum TransformDecision {
956 Applied {
957 outcome: TransformPassExecutionOutcomeV0,
958 rollback_receipt: RollbackReceiptV0,
959 #[serde(skip_serializing_if = "Option::is_none")]
960 semantic_guarantee_tier: Option<TransformSemanticGuaranteeTierV0>,
961 #[serde(skip_serializing_if = "Vec::is_empty")]
962 discharge_evidence: Vec<TransformDischargeEvidenceV0>,
963 },
964 NoChange {
965 reason: TransformNoChangeReasonV0,
966 outcome: TransformPassExecutionOutcomeV0,
967 },
968 Blocked {
969 reason: TransformBlockedReasonV0,
970 outcome: TransformPassExecutionOutcomeV0,
971 },
972 Rejected {
973 reason: TransformRejectionReasonV0,
974 outcome: TransformPassExecutionOutcomeV0,
975 rollback_receipt: RollbackReceiptV0,
976 },
977}
978
979impl TransformDecision {
980 pub fn compatibility_outcome(&self) -> &TransformPassExecutionOutcomeV0 {
981 match self {
982 Self::Applied { outcome, .. }
983 | Self::NoChange { outcome, .. }
984 | Self::Blocked { outcome, .. }
985 | Self::Rejected { outcome, .. } => outcome,
986 }
987 }
988
989 pub fn into_compatibility_outcome(self) -> TransformPassExecutionOutcomeV0 {
990 match self {
991 Self::Applied { outcome, .. }
992 | Self::NoChange { outcome, .. }
993 | Self::Blocked { outcome, .. }
994 | Self::Rejected { outcome, .. } => outcome,
995 }
996 }
997
998 pub fn rollback_receipt(&self) -> Option<&RollbackReceiptV0> {
999 match self {
1000 Self::Applied {
1001 rollback_receipt, ..
1002 }
1003 | Self::Rejected {
1004 rollback_receipt, ..
1005 } => Some(rollback_receipt),
1006 Self::NoChange { .. } | Self::Blocked { .. } => None,
1007 }
1008 }
1009
1010 pub fn semantic_guarantee_tier(&self) -> Option<&TransformSemanticGuaranteeTierV0> {
1011 match self {
1012 Self::Applied {
1013 semantic_guarantee_tier,
1014 ..
1015 } => semantic_guarantee_tier.as_ref(),
1016 Self::NoChange { .. } | Self::Blocked { .. } | Self::Rejected { .. } => None,
1017 }
1018 }
1019}
1020
1021#[derive(Debug, Clone, PartialEq, Eq, Serialize)]
1022#[serde(rename_all = "camelCase")]
1023pub struct TransformProvenanceDerivationForestV0 {
1024 pub schema_version: &'static str,
1025 pub product: &'static str,
1026 pub root_count: usize,
1027 pub node_count: usize,
1028 pub nodes: Vec<TransformProvenanceDerivationNodeV0>,
1029}
1030
1031impl TransformProvenanceDerivationForestV0 {
1032 pub fn evidence_graph(&self) -> Result<EvidenceGraphV0, EvidenceGraphBuildErrorV0> {
1033 build_evidence_graph_from_edges_v0(
1034 self.nodes
1035 .iter()
1036 .map(TransformProvenanceDerivationNodeV0::evidence_node_seed),
1037 self.nodes
1038 .iter()
1039 .map(TransformProvenanceDerivationNodeV0::evidence_demand_edge),
1040 )
1041 }
1042}
1043
1044#[derive(Debug, Clone, PartialEq, Eq, Serialize)]
1045#[serde(rename_all = "camelCase")]
1046pub struct TransformProvenanceDerivationNodeV0 {
1047 pub node_index: usize,
1048 pub parent_index: Option<usize>,
1049 pub pass_id: &'static str,
1050 pub status: TransformPassRuntimeStatus,
1051 pub input_byte_len: usize,
1052 pub output_byte_len: usize,
1053 pub source_span_start: usize,
1054 pub source_span_end: usize,
1055 pub generated_span_start: usize,
1056 pub generated_span_end: usize,
1057 pub mutation_spans: Vec<TransformProvenanceMutationSpanV0>,
1058 pub mutation_count: usize,
1059 pub provenance_preserved: bool,
1060 pub detail: &'static str,
1061}
1062
1063impl TransformProvenanceDerivationNodeV0 {
1064 pub fn evidence_node_key(&self) -> EvidenceNodeKeyV0 {
1065 EvidenceNodeKeyV0::new(
1066 TRANSFORM_PROVENANCE_NODE_EVIDENCE_QUERY_V0,
1067 format!("{}#{}", self.pass_id, self.node_index),
1068 )
1069 }
1070
1071 pub fn evidence_node_seed(&self) -> EvidenceNodeSeedV0 {
1072 EvidenceNodeSeedV0::new(
1073 self.evidence_node_key(),
1074 vec![
1075 ["pass:", self.pass_id].concat(),
1076 ["detail:", self.detail].concat(),
1077 ["mutationCount:", self.mutation_count.to_string().as_str()].concat(),
1078 [
1079 "provenancePreserved:",
1080 self.provenance_preserved.to_string().as_str(),
1081 ]
1082 .concat(),
1083 ],
1084 GuaranteeKindV0::for_label_less_family(),
1085 )
1086 }
1087
1088 pub fn evidence_demand_edge(&self) -> EvidenceDemandEdgeV0 {
1089 EvidenceDemandEdgeV0::new(
1090 TRANSFORM_PROVENANCE_NODE_EVIDENCE_QUERY_V0,
1091 self.evidence_node_key(),
1092 TRANSFORM_EVIDENCE_EDGE_KIND_V0,
1093 )
1094 }
1095}
1096
1097#[derive(Debug, Clone, PartialEq, Eq, Serialize)]
1098#[serde(rename_all = "camelCase")]
1099pub struct TransformProvenanceMutationSpanV0 {
1100 pub source_span_start: usize,
1101 pub source_span_end: usize,
1102 pub generated_span_start: usize,
1103 pub generated_span_end: usize,
1104 #[serde(skip_serializing_if = "Option::is_none")]
1105 pub node_key: Option<StableNodeKeyV0>,
1106}
1107
1108#[derive(Debug, Clone, Copy, Default, PartialEq, Eq, Serialize)]
1113#[serde(rename_all = "camelCase")]
1114pub struct TransformLexCacheSpliceTelemetryV0 {
1115 pub splice_hit_count: u64,
1117 pub full_relex_fallback_count: u64,
1119 pub window_derivation_fallback_count: u64,
1121 pub full_output_window_fallback_count: u64,
1123 pub token_offset_fallback_count: u64,
1125}
1126
1127#[derive(Debug, Clone, Copy, Default, PartialEq, Eq, Serialize)]
1130#[serde(rename_all = "camelCase")]
1131#[non_exhaustive]
1132pub struct TransformStructuralIrTransactionTelemetryV0 {
1133 pub transaction_commit_count: u64,
1134 pub ir_metadata_refresh_count: u64,
1135 pub ir_transaction_commit_count: u64,
1136 pub ir_materialization_count: u64,
1137 pub ir_mutation_count: u64,
1138}
1139
1140#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize)]
1141#[serde(rename_all = "camelCase")]
1142pub enum TransformSemanticObservationKeyAxisV0 {
1143 Selector,
1144 Property,
1145 Context,
1146}
1147
1148#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize)]
1149#[serde(rename_all = "camelCase")]
1150pub enum TransformSemanticObservationValueAxisV0 {
1151 Value,
1152 Important,
1153}
1154
1155#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize)]
1156#[serde(rename_all = "camelCase")]
1157pub enum TransformSemanticObservationOrderingRuleV0 {
1158 SourceOrder,
1159 ImportantPrecedence,
1160}
1161
1162#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize)]
1163#[serde(rename_all = "camelCase")]
1164pub enum TransformSemanticUnobservedAxisV0 {
1165 InterSelectorSpecificityCompetition,
1166 CascadeLayerOrder,
1167 Origin,
1168 ScopeProximity,
1169 DomDependentMatching,
1170 Inheritance,
1171 CustomPropertyEnvironment,
1172 AnimationAndTransition,
1173}
1174
1175#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize)]
1176#[serde(rename_all = "camelCase")]
1177pub enum TransformSemanticPreservationClaimScopeV0 {
1178 ObservedSurfaceOnly,
1179}
1180
1181#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize)]
1182#[serde(rename_all = "camelCase")]
1183pub enum TransformSemanticPreservationVocabularyReviewV0 {
1184 DeferredUntilFullCascadeObservation,
1185}
1186
1187#[derive(Debug, Clone, PartialEq, Eq, Serialize)]
1189#[serde(rename_all = "camelCase")]
1190pub struct TransformSemanticObservationSurfaceV0 {
1191 pub key_axes: Vec<TransformSemanticObservationKeyAxisV0>,
1192 pub value_axes: Vec<TransformSemanticObservationValueAxisV0>,
1193 pub ordering_rules: Vec<TransformSemanticObservationOrderingRuleV0>,
1194 pub unobserved_axes: Vec<TransformSemanticUnobservedAxisV0>,
1195 pub claim_scope: TransformSemanticPreservationClaimScopeV0,
1196 pub vocabulary_review: TransformSemanticPreservationVocabularyReviewV0,
1197}
1198
1199#[derive(Debug, Clone, PartialEq, Eq, Serialize)]
1200#[serde(rename_all = "camelCase")]
1201pub struct TransformSemanticPreservationTelemetryV0 {
1202 pub observed_pass_count: u64,
1203 pub preserved_pass_count: u64,
1204 pub blocked_pass_count: u64,
1205 pub observed_surface: TransformSemanticObservationSurfaceV0,
1206}
1207
1208#[derive(Debug, Clone, Default, PartialEq, Eq, Serialize)]
1209#[serde(rename_all = "camelCase")]
1210pub struct TransformDischargeLedgerTelemetryV0 {
1211 pub lookup_count: u64,
1212 pub matched_lookup_count: u64,
1213 pub accepted_stamp_count: u64,
1214 pub blocked_lookup_count: u64,
1215}
1216
1217#[derive(Debug, Clone, PartialEq, Eq, Serialize)]
1218#[serde(rename_all = "camelCase")]
1219pub struct TransformExecutionSummaryV0 {
1220 pub schema_version: &'static str,
1221 pub product: &'static str,
1222 pub input_byte_len: usize,
1223 pub output_byte_len: usize,
1224 pub requested_pass_ids: Vec<&'static str>,
1225 pub ordered_pass_ids: Vec<&'static str>,
1226 pub executed_pass_ids: Vec<&'static str>,
1227 pub planned_only_pass_ids: Vec<&'static str>,
1228 pub mutation_count: usize,
1229 pub provenance_preserved: bool,
1230 pub output_css: String,
1231 pub css_module_evaluation: Option<TransformModuleEvaluationV0>,
1232 pub css_import_inlines: Vec<TransformImportInlineV0>,
1233 pub css_module_composes_exports: Vec<TransformCssModuleComposesResolutionV0>,
1234 pub design_token_routes: Vec<TransformDesignTokenRouteV0>,
1235 pub semantic_removals: Vec<TransformSemanticRemovalV0>,
1236 #[serde(skip_serializing_if = "Option::is_none")]
1237 pub module_qualified_shake: Option<TransformModuleQualifiedShakeSummaryV0>,
1238 pub cascade_proof_obligations: TransformCascadeProofObligationReportV0,
1239 #[serde(skip_serializing_if = "Vec::is_empty")]
1240 pub winner_equality_obligations: Vec<TransformWinnerEqualityObligationV0>,
1241 pub provenance_derivation_forest: TransformProvenanceDerivationForestV0,
1242 pub structural_ir_transaction_telemetry: TransformStructuralIrTransactionTelemetryV0,
1243 pub semantic_preservation_telemetry: TransformSemanticPreservationTelemetryV0,
1244 pub discharge_ledger_telemetry: TransformDischargeLedgerTelemetryV0,
1245 pub strict_policy: TransformStrictPolicySummaryV0,
1246 pub closed_world_admission: TransformClosedWorldAdmissionSummaryV0,
1247 pub decisions: Vec<TransformDecision>,
1248 pub outcomes: Vec<TransformPassExecutionOutcomeV0>,
1249 pub pass_plan: TransformPassPlanV0,
1250}
1251
1252#[derive(Debug, Clone, PartialEq, Eq, Serialize)]
1253#[serde(rename_all = "camelCase")]
1254pub struct TransformModuleQualifiedShakeSummaryV0 {
1255 pub module_instance: ModuleInstanceKeyV0,
1256 pub removed_count: usize,
1257}
1258
1259#[derive(Debug, Clone, PartialEq, Eq, Serialize)]
1260#[serde(
1261 tag = "kind",
1262 rename_all = "camelCase",
1263 rename_all_fields = "camelCase"
1264)]
1265pub enum TransformModuleQualifiedExecutionErrorV0 {
1266 UnknownModuleInstance {
1267 module_instance: ModuleInstanceKeyV0,
1268 },
1269}
1270
1271#[derive(Debug, Clone, PartialEq, Eq, Serialize)]
1272#[serde(rename_all = "camelCase")]
1273pub struct TransformCascadeProofObligationReportV0 {
1274 pub schema_version: &'static str,
1275 pub product: &'static str,
1276 pub obligation_count: usize,
1277 pub accepted_count: usize,
1278 pub blocked_count: usize,
1279 pub checked_pass_ids: Vec<&'static str>,
1280 pub obligations: Vec<TransformCascadeProofObligationV0>,
1281}
1282
1283#[derive(Debug, Clone, PartialEq, Eq, Serialize)]
1284#[serde(rename_all = "camelCase")]
1285pub struct TransformCascadeProofObligationV0 {
1286 pub pass_id: &'static str,
1287 pub proof_product: &'static str,
1288 pub accepted: bool,
1289 pub blocked_reason: Option<String>,
1290 pub provenance_preserved: bool,
1291 pub cascade_safe_witness: String,
1292 pub source_span_start: Option<usize>,
1293 pub source_span_end: Option<usize>,
1294 pub checked_obligations: Vec<&'static str>,
1295 #[serde(skip_serializing_if = "Option::is_none")]
1296 pub canonical_smt_input: Option<CanonicalSmtInputV0>,
1297 #[serde(skip_serializing_if = "Option::is_none")]
1298 pub discharge_ledger_lookup: Option<DischargeLedgerLookupV0>,
1299 #[serde(skip_serializing_if = "Option::is_none")]
1300 pub discharge_evidence: Option<TransformDischargeEvidenceV0>,
1301 pub proof_payload: Value,
1302}
1303
1304#[derive(Debug, Clone, PartialEq, Eq, Serialize)]
1305#[serde(rename_all = "camelCase")]
1306pub struct TransformSemanticRemovalV0 {
1307 pub pass_id: &'static str,
1308 pub symbol_kind: &'static str,
1309 pub name: String,
1310 pub source_span_start: usize,
1311 pub source_span_end: usize,
1312 pub reason: &'static str,
1313 pub certainty: &'static str,
1314 pub derivation_steps: Vec<&'static str>,
1315}
1316
1317#[derive(Debug, Clone, PartialEq, Eq)]
1318pub(crate) struct TransformSemanticRemovalCandidate {
1319 pub(crate) symbol_kind: &'static str,
1320 pub(crate) name: String,
1321 pub(crate) source_span_start: usize,
1322 pub(crate) source_span_end: usize,
1323 pub(crate) reason: &'static str,
1324}
1325
1326impl TransformSemanticRemovalCandidate {
1327 pub(crate) fn into_public(self, pass_id: &'static str) -> TransformSemanticRemovalV0 {
1328 TransformSemanticRemovalV0 {
1329 pass_id,
1330 symbol_kind: self.symbol_kind,
1331 name: self.name,
1332 source_span_start: self.source_span_start,
1333 source_span_end: self.source_span_end,
1334 reason: self.reason,
1335 certainty: "high",
1336 derivation_steps: vec![
1337 "closedStyleWorld",
1338 "reachableRootSetComputed",
1339 "symbolNotMarkedReachable",
1340 "sourceRangeRemoved",
1341 ],
1342 }
1343 }
1344}
1345
1346#[derive(Debug, Clone, PartialEq, Eq, Serialize)]
1347#[serde(rename_all = "camelCase")]
1348pub struct TransformIncrementalExecutionSummaryV0 {
1349 pub schema_version: &'static str,
1350 pub product: &'static str,
1351 pub incremental_engine: &'static str,
1352 pub query_model: &'static str,
1353 pub reuse_policy: &'static str,
1354 pub reused_previous_execution: bool,
1355 pub incremental_plan: IncrementalComputationPlanV0,
1356 pub next_snapshot: IncrementalSnapshotV0,
1357 pub execution: TransformExecutionSummaryV0,
1358 pub ready_surfaces: Vec<&'static str>,
1359}
1360
1361#[derive(Debug, Clone, PartialEq, Eq, Serialize)]
1362#[serde(rename_all = "camelCase")]
1363pub struct TransformCascadeSafetyFuzzCaseV0 {
1364 pub seed: u64,
1365 pub pass_count: usize,
1366}
1367
1368#[derive(Debug, Clone, PartialEq, Eq, Serialize)]
1369#[serde(rename_all = "camelCase")]
1370pub struct TransformCascadeSafetyFuzzResultV0 {
1371 pub seed: u64,
1372 pub pass_count: usize,
1373 pub requested_pass_ids: Vec<&'static str>,
1374 pub executed_pass_ids: Vec<&'static str>,
1375 pub output_byte_len: usize,
1376 pub output_token_count: usize,
1377 pub output_error_count: usize,
1378 pub provenance_node_count: usize,
1379 pub passed: bool,
1380}
1381
1382#[derive(Debug, Clone, PartialEq, Eq, Serialize)]
1383#[serde(rename_all = "camelCase")]
1384pub struct TransformFuzzSeedReportV0 {
1385 pub schema_version: &'static str,
1386 pub product: &'static str,
1387 pub case_count: usize,
1388 pub passed_count: usize,
1389 pub failed_count: usize,
1390 pub results: Vec<TransformCascadeSafetyFuzzResultV0>,
1391}
1392
1393#[derive(Debug, Clone, Default, PartialEq, Eq, Deserialize, Serialize)]
1394#[serde(default, rename_all = "camelCase")]
1395pub struct TransformExecutionContextV0 {
1396 pub drop_dark_mode_media_queries: bool,
1397 pub supports_target_capability: Option<SupportsTargetCapabilityV0>,
1398 pub vendor_prefix_policy: Option<TransformVendorPrefixPolicyV0>,
1399 pub reachable_class_names: Vec<String>,
1400 pub reachable_keyframe_names: Vec<String>,
1401 pub reachable_value_names: Vec<String>,
1402 pub reachable_custom_property_names: Vec<String>,
1403 pub scss_module_evaluation: Option<TransformModuleEvaluationV0>,
1404 pub less_module_evaluation: Option<TransformModuleEvaluationV0>,
1405 pub import_inlines: Vec<TransformImportInlineV0>,
1406 pub class_name_rewrites: Vec<TransformClassNameRewriteV0>,
1407 pub css_module_composes_resolutions: Vec<TransformCssModuleComposesResolutionV0>,
1408 pub css_module_value_resolutions: Vec<TransformCssModuleValueResolutionV0>,
1409 pub design_token_routes: Vec<TransformDesignTokenRouteV0>,
1410 #[serde(default, skip_serializing_if = "Option::is_none")]
1413 pub cascade_environment: Option<TransformCascadeEnvironmentV0>,
1414}
1415
1416#[derive(Debug, Clone, Default, PartialEq, Eq, Deserialize, Serialize)]
1417#[serde(default, rename_all = "camelCase")]
1418pub struct TransformCascadeEnvironmentV0 {
1419 pub stylesheet_source_order_base: u32,
1422 pub declarations: Vec<TransformCascadeEnvironmentDeclarationV0>,
1423}
1424
1425#[derive(Debug, Clone, PartialEq, Eq, Deserialize, Serialize)]
1426#[serde(rename_all = "camelCase")]
1427pub struct TransformCascadeEnvironmentDeclarationV0 {
1428 pub declaration_id: String,
1429 pub selector: String,
1430 pub property: String,
1431 pub value: String,
1432 pub origin: CascadeOriginV0,
1433 pub important: bool,
1434 #[serde(default, skip_serializing_if = "Option::is_none")]
1435 pub layer_rank: Option<i32>,
1436 #[serde(default, skip_serializing_if = "Option::is_none")]
1437 pub scope_proximity: Option<u32>,
1438 pub source_order: u32,
1439}
1440
1441#[derive(Debug, Clone, Copy, PartialEq, Eq, Deserialize, Serialize)]
1442#[serde(rename_all = "camelCase")]
1443pub struct TransformVendorPrefixPolicyV0 {
1444 pub webkit: bool,
1445 pub moz: bool,
1446 pub ms: bool,
1447}
1448
1449impl TransformVendorPrefixPolicyV0 {
1450 pub const fn none() -> Self {
1451 Self {
1452 webkit: false,
1453 moz: false,
1454 ms: false,
1455 }
1456 }
1457
1458 pub const fn conservative() -> Self {
1459 Self {
1460 webkit: true,
1461 moz: true,
1462 ms: true,
1463 }
1464 }
1465
1466 pub const fn is_empty(self) -> bool {
1467 !(self.webkit || self.moz || self.ms)
1468 }
1469
1470 pub fn allows_prefix(self, prefixed_name: &str) -> bool {
1471 if prefixed_name.starts_with("-webkit-") {
1472 return self.webkit;
1473 }
1474 if prefixed_name.starts_with("-moz-") {
1475 return self.moz;
1476 }
1477 if prefixed_name.starts_with("-ms-") {
1478 return self.ms;
1479 }
1480 true
1481 }
1482}
1483
1484#[derive(Debug, Clone, PartialEq, Eq, Deserialize, Serialize)]
1485#[serde(rename_all = "camelCase")]
1486pub struct TransformModuleEvaluationV0 {
1487 pub evaluator: String,
1488 #[serde(default, skip_serializing_if = "Option::is_none")]
1489 pub product_output_source: Option<String>,
1490 pub evaluated_css: String,
1491 #[serde(default, skip_serializing_if = "Option::is_none")]
1492 pub native_edit_output: Option<String>,
1493 #[serde(default, skip_serializing_if = "Vec::is_empty")]
1494 pub native_replacements: Vec<TransformModuleEvaluationNativeReplacementV0>,
1495 #[serde(default, skip_serializing_if = "Vec::is_empty")]
1496 pub native_edits: Vec<TransformModuleEvaluationNativeEditV0>,
1497 #[serde(default, skip_serializing_if = "Option::is_none")]
1498 pub oracle: Option<TransformModuleEvaluationOracleV0>,
1499}
1500
1501impl TransformModuleEvaluationV0 {
1502 pub fn declares_native_product_output(&self) -> bool {
1503 self.product_output_source
1504 .as_deref()
1505 .is_some_and(|source| source == "nativeEditOutput")
1506 }
1507
1508 pub fn oracle_allows_native_product_output(&self) -> bool {
1517 self.oracle.as_ref().is_some_and(|oracle| {
1518 oracle.mode == "oracleOnly"
1519 && oracle.divergence_count == 0
1520 && oracle.all_legacy_declaration_values_preserved
1521 })
1522 }
1523
1524 pub fn may_consume_native_product_output(&self) -> bool {
1525 self.declares_native_product_output() && self.oracle_allows_native_product_output()
1526 }
1527
1528 pub fn native_output_matches_retained_oracle(&self, native_output: &str) -> bool {
1533 self.oracle
1534 .as_ref()
1535 .is_some_and(|_| native_output == self.evaluated_css)
1536 }
1537}
1538
1539#[derive(Debug, Clone, PartialEq, Eq, Deserialize, Serialize)]
1540#[serde(rename_all = "camelCase")]
1541pub struct TransformModuleEvaluationNativeReplacementV0 {
1542 pub name: String,
1543 pub start: usize,
1544 pub end: usize,
1545 pub text: String,
1546 #[serde(default, skip_serializing_if = "Option::is_none")]
1547 pub rendered_value: Option<String>,
1548 pub abstract_value: AbstractCssValueV0,
1549 pub abstract_value_kind: String,
1550}
1551
1552#[derive(Debug, Clone, PartialEq, Eq, Deserialize, Serialize)]
1553#[serde(rename_all = "camelCase")]
1554pub struct TransformModuleEvaluationNativeEditV0 {
1555 pub start: usize,
1556 pub end: usize,
1557 pub replacement: String,
1558 pub edit_kind: String,
1559 #[serde(default, skip_serializing_if = "Option::is_none")]
1560 pub abstract_value: Option<AbstractCssValueV0>,
1561 #[serde(default, skip_serializing_if = "Option::is_none")]
1562 pub abstract_value_kind: Option<String>,
1563}
1564
1565#[derive(Debug, Clone, Default, PartialEq, Eq, Deserialize, Serialize)]
1566#[serde(default, rename_all = "camelCase")]
1567pub struct TransformModuleEvaluationOracleV0 {
1568 pub mode: String,
1569 pub product_output_source: String,
1570 pub legacy_declaration_value_count: usize,
1571 pub abstract_value_count: usize,
1572 pub exact_value_count: usize,
1573 pub raw_value_count: usize,
1574 pub bottom_value_count: usize,
1575 pub top_value_count: usize,
1576 pub divergence_count: usize,
1577 pub all_legacy_declaration_values_preserved: bool,
1578 pub native_replacement_count: usize,
1579 pub native_replacement_legacy_reflection_count: usize,
1580 pub native_replacement_legacy_unreflected_count: usize,
1581 pub native_value_reference_count: usize,
1582 pub native_resolved_value_count: usize,
1583 pub native_raw_value_count: usize,
1584 pub native_top_value_count: usize,
1585 pub native_cycle_count: usize,
1586 pub native_fuel_exhausted_count: usize,
1587 pub native_unresolved_reference_count: usize,
1588 pub native_unsupported_dynamic_count: usize,
1589}
1590
1591#[derive(Debug, Clone, PartialEq, Eq, Deserialize, Serialize)]
1592#[serde(rename_all = "camelCase")]
1593pub struct TransformImportInlineV0 {
1594 pub import_source: String,
1595 pub replacement_css: String,
1596}
1597
1598#[derive(Debug, Clone, PartialEq, Eq)]
1599pub struct TransformLessInlineLiteralPlaceholderV0 {
1600 pub placeholder: String,
1601 pub literal_css: String,
1602}
1603
1604#[derive(Debug, Clone, PartialEq, Eq, Deserialize, Serialize)]
1605#[serde(rename_all = "camelCase")]
1606pub struct TransformClassNameRewriteV0 {
1607 pub original_name: String,
1608 pub rewritten_name: String,
1609}
1610
1611#[derive(Debug, Clone, PartialEq, Eq, Deserialize, Serialize)]
1620#[serde(rename_all = "camelCase")]
1621#[non_exhaustive]
1622pub struct TransformModuleCssModuleContextV0 {
1623 pub module_instance: ModuleInstanceKeyV0,
1624 pub class_name_rewrites: Vec<TransformClassNameRewriteV0>,
1625 pub composes_resolutions: Vec<TransformCssModuleComposesResolutionV0>,
1626}
1627
1628impl TransformModuleCssModuleContextV0 {
1629 pub fn new(module_instance: ModuleInstanceKeyV0) -> Self {
1630 Self {
1631 module_instance,
1632 class_name_rewrites: Vec::new(),
1633 composes_resolutions: Vec::new(),
1634 }
1635 }
1636
1637 pub fn with_class_name_rewrites(
1638 mut self,
1639 class_name_rewrites: Vec<TransformClassNameRewriteV0>,
1640 ) -> Self {
1641 self.class_name_rewrites = class_name_rewrites;
1642 self
1643 }
1644
1645 pub fn with_composes_resolutions(
1646 mut self,
1647 composes_resolutions: Vec<TransformCssModuleComposesResolutionV0>,
1648 ) -> Self {
1649 self.composes_resolutions = composes_resolutions;
1650 self
1651 }
1652}
1653
1654#[derive(Debug, Clone, PartialEq, Eq, Deserialize, Serialize)]
1655#[serde(rename_all = "camelCase")]
1656pub struct TransformCssModuleComposesResolutionV0 {
1657 pub local_class_name: String,
1658 pub exported_class_names: Vec<String>,
1659}
1660
1661#[derive(Debug, Clone, PartialEq, Eq, Deserialize, Serialize)]
1662#[serde(rename_all = "camelCase")]
1663pub struct TransformCssModuleValueResolutionV0 {
1664 pub local_name: String,
1665 pub resolved_value: String,
1666}
1667
1668#[derive(Debug, Clone, PartialEq, Eq, Deserialize, Serialize)]
1669#[serde(rename_all = "camelCase")]
1670pub struct TransformDesignTokenRouteV0 {
1671 pub token_name: String,
1672 pub routed_value: String,
1673}
1674
1675#[cfg(test)]
1676mod evidence_graph_tests {
1677 use super::*;
1678 use omena_cascade::{
1679 CascadeKey, CascadeValue, LayerOrdinal, OpenWorldTieEvidence, Specificity,
1680 cascade_property, normalized_layer_rank,
1681 };
1682
1683 fn winner_equality_test_declaration(
1684 id: &str,
1685 value: &str,
1686 source_order: u32,
1687 ) -> CascadeDeclaration {
1688 CascadeDeclaration {
1689 id: id.to_string(),
1690 property: "color".to_string(),
1691 value: CascadeValue::Literal(value.to_string()),
1692 key: CascadeKey::new(
1693 CascadeLevel::AuthorNormal,
1694 normalized_layer_rank(false, LayerOrdinal::new(0)),
1695 0,
1696 Specificity::new(0, 1, 0),
1697 source_order,
1698 ),
1699 open_world_tie_evidence: OpenWorldTieEvidence::NONE,
1700 specificity_exactness: omena_cascade::SpecificityExactnessV0::Exact,
1701 }
1702 }
1703
1704 #[test]
1705 fn winner_equality_witness_consumes_the_cascade_authority_outcome() -> Result<(), String> {
1706 let outcome = cascade_property(
1707 [
1708 winner_equality_test_declaration("earlier", "red", 0),
1709 winner_equality_test_declaration("later", "blue", 1),
1710 ],
1711 "color",
1712 );
1713 let witness = TransformWinnerEqualityWitnessV0::from_cascade_outcome(&outcome)
1714 .ok_or_else(|| "the closed cascade should have a definite winner".to_string())?;
1715
1716 assert_eq!(witness.winner.id, "later");
1717 assert_eq!(
1718 witness.proof,
1719 CascadeProof::from_declaration(&witness.winner)
1720 );
1721 Ok(())
1722 }
1723
1724 #[test]
1725 fn winner_equality_witness_stays_absent_for_non_definite_outcomes() {
1726 assert!(
1727 TransformWinnerEqualityWitnessV0::from_cascade_outcome(&CascadeOutcome::Top).is_none()
1728 );
1729 assert!(
1730 TransformWinnerEqualityWitnessV0::from_cascade_outcome(&CascadeOutcome::Inherit)
1731 .is_none()
1732 );
1733 }
1734
1735 #[test]
1736 fn winner_equality_trust_records_name_covered_axes() -> Result<(), serde_json::Error> {
1737 let tier = TransformSemanticGuaranteeTierV0::WinnerEqualityObserved {
1738 axes: vec![
1739 TransformWinnerEqualityAxisV0::CascadeLevel,
1740 TransformWinnerEqualityAxisV0::LayerRank,
1741 ],
1742 };
1743
1744 assert_eq!(
1745 serde_json::to_value(tier)?,
1746 serde_json::json!({
1747 "kind": "winnerEqualityObserved",
1748 "axes": ["cascadeLevel", "layerRank"]
1749 })
1750 );
1751 Ok(())
1752 }
1753
1754 #[test]
1755 fn winner_equality_absence_names_the_undriven_level() -> Result<(), serde_json::Error> {
1756 let tier = TransformSemanticGuaranteeTierV0::Absent {
1757 reasons: vec![TransformWinnerEqualityAbsenceV0 {
1758 axis: TransformWinnerEqualityAxisV0::CascadeLevel,
1759 reason: TransformWinnerEqualityAbsenceReasonV0::DriverUnavailable {
1760 level: Some(CascadeLevel::Animation),
1761 },
1762 }],
1763 };
1764
1765 assert_eq!(
1766 serde_json::to_value(tier)?,
1767 serde_json::json!({
1768 "kind": "absent",
1769 "reasons": [{
1770 "axis": "cascadeLevel",
1771 "reason": {
1772 "kind": "driverUnavailable",
1773 "level": "animation"
1774 }
1775 }]
1776 })
1777 );
1778 Ok(())
1779 }
1780
1781 #[test]
1782 fn transform_outcome_evidence_graph_preserves_public_shape() -> Result<(), serde_json::Error> {
1783 let outcome = TransformPassExecutionOutcomeV0 {
1784 pass_id: "number-compression",
1785 status: TransformPassRuntimeStatus::Applied,
1786 input_byte_len: 32,
1787 output_byte_len: 28,
1788 mutation_count: 1,
1789 provenance_preserved: true,
1790 detail: "fixture pass",
1791 };
1792
1793 let before = serde_json::to_value(&outcome)?;
1794 let node = outcome.evidence_node_seed();
1795 let graph = build_evidence_graph_from_edges_v0([node], [outcome.evidence_demand_edge()])
1796 .map_err(|_| serde::ser::Error::custom("outcome edge must target its node"))?;
1797 let after = serde_json::to_value(&outcome)?;
1798
1799 assert_eq!(before, after);
1800 assert_eq!(graph.nodes.len(), 1);
1801 assert_eq!(graph.nodes[0].key.input_identity, "number-compression");
1802 assert_eq!(graph.nodes[0].guarantee, GuaranteeKindV0::Floor);
1803 assert!(
1804 graph.nodes[0]
1805 .provenance
1806 .iter()
1807 .any(|item| item == "mutationCount:1")
1808 );
1809 Ok(())
1810 }
1811
1812 #[test]
1813 fn transform_derivation_forest_evidence_graph_preserves_public_shape()
1814 -> Result<(), serde_json::Error> {
1815 let forest = TransformProvenanceDerivationForestV0 {
1816 schema_version: "0",
1817 product: "omena-transform-passes.provenance-derivation-forest",
1818 root_count: 1,
1819 node_count: 1,
1820 nodes: vec![TransformProvenanceDerivationNodeV0 {
1821 node_index: 0,
1822 parent_index: None,
1823 pass_id: "comment-strip",
1824 status: TransformPassRuntimeStatus::Applied,
1825 input_byte_len: 48,
1826 output_byte_len: 36,
1827 source_span_start: 0,
1828 source_span_end: 12,
1829 generated_span_start: 0,
1830 generated_span_end: 0,
1831 mutation_spans: Vec::new(),
1832 mutation_count: 1,
1833 provenance_preserved: true,
1834 detail: "fixture derivation",
1835 }],
1836 };
1837
1838 let before = serde_json::to_value(&forest)?;
1839 let graph = forest
1840 .evidence_graph()
1841 .map_err(|_| serde::ser::Error::custom("forest edge must target its node"))?;
1842 let after = serde_json::to_value(&forest)?;
1843
1844 assert_eq!(before, after);
1845 assert_eq!(graph.nodes.len(), 1);
1846 assert_eq!(graph.nodes[0].key.input_identity, "comment-strip#0");
1847 assert_eq!(graph.nodes[0].guarantee, GuaranteeKindV0::Floor);
1848 Ok(())
1849 }
1850}