Skip to main content

omena_query/
types.rs

1use super::*;
2use omena_evidence_graph::{
3    EvidenceAnalysisPrecisionV0, EvidenceDemandEdgeV0, EvidenceNodeKeyV0, EvidenceNodeSeedV0,
4    GuaranteeKindV0, build_evidence_graph_from_edges_v0,
5};
6use omena_query_transform_runner::normalize_omena_transform_bundle_path;
7use omena_sif::OmenaSifV1;
8use omena_syntax::ident::{
9    AuthoredPropertyTextV0, CanonicalClassKeyV0, CanonicalCustomPropertyNameV0,
10    CanonicalPropertyKeyV0, CanonicalStandardPropertyNameV0, PropertyNameV0,
11};
12use std::cmp::Ordering;
13use std::collections::{BTreeMap, BTreeSet};
14
15mod runtime_state_serialization;
16#[cfg(test)]
17pub(crate) use runtime_state_serialization::runtime_state_result_certainty_labels;
18pub(crate) use runtime_state_serialization::runtime_state_unknown_activation_declaration_id;
19
20#[derive(Debug, Clone, PartialEq, Serialize)]
21#[serde(rename_all = "camelCase")]
22pub struct DesignSystemMinimumDescriptionV0 {
23    pub schema_version: &'static str,
24    pub product: &'static str,
25    pub layer_marker: &'static str,
26    pub feature_gate: &'static str,
27    pub model_bits: f64,
28    pub residual_bits: f64,
29    pub total_bits: f64,
30    pub unit: &'static str,
31    pub model_class: ModelClassV0,
32    pub rule_count: usize,
33    pub observation_count: usize,
34    pub canonical_form_present: bool,
35    pub cascade_proof_obligation_count: usize,
36    pub sass_namespace_partition: SassNamespaceBitsV0,
37    pub generated_at_iso: &'static str,
38    pub source_pin: SourcePinV0,
39    pub weights_calibration_pin: &'static str,
40    pub weights_version: &'static str,
41    pub semiring_instance: &'static str,
42}
43
44#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize)]
45#[serde(rename_all = "camelCase")]
46pub enum ModelClassV0 {
47    TwoPartUniform,
48    TwoPartMultinomial,
49    Nml,
50}
51
52#[derive(Debug, Clone, PartialEq, Eq, Serialize)]
53#[serde(rename_all = "camelCase")]
54pub struct SassNamespaceBitsV0 {
55    pub namespace_count: usize,
56    pub partition_count: usize,
57    pub deterministic_partition: bool,
58}
59
60#[derive(Debug, Clone, PartialEq, Eq, Serialize)]
61#[serde(rename_all = "camelCase")]
62pub struct SourcePinV0 {
63    pub source_uri: String,
64    pub source_hash: String,
65}
66
67#[derive(Debug, Clone, PartialEq, Serialize)]
68#[serde(rename_all = "camelCase")]
69pub struct CanonicalFormV0 {
70    pub schema_version: &'static str,
71    pub product: &'static str,
72    pub layer_marker: &'static str,
73    pub feature_gate: &'static str,
74    pub pass_id: &'static str,
75    pub before: String,
76    pub canonical_after: String,
77    pub fallback_after: String,
78    pub canonical_matches_fallback: bool,
79    pub mdl_bits: f64,
80    pub ast_size_bits: f64,
81    pub bits_saved_vs_fallback: f64,
82    pub unit: &'static str,
83    pub iteration_count: usize,
84    pub eclass_count: usize,
85    pub enode_count: usize,
86    pub cascade_safe_witness: &'static str,
87    pub egg_analysis_witness: &'static str,
88}
89
90#[derive(Debug, Serialize)]
91#[serde(rename_all = "camelCase")]
92pub struct OmenaQueryBoundarySummaryV0 {
93    pub schema_version: &'static str,
94    pub product: &'static str,
95    pub query_engine_name: &'static str,
96    pub schema_version_policy: OmenaQuerySchemaVersionPolicyV0,
97    pub input_version: String,
98    pub abstract_value_domain: AbstractValueDomainSummaryV0,
99    pub selected_query_adapter_capabilities: SelectedQueryAdapterCapabilitiesV0,
100    pub delegated_fragment_products: Vec<&'static str>,
101    pub expression_semantics_query_count: usize,
102    pub source_resolution_query_count: usize,
103    pub selector_usage_query_count: usize,
104    pub total_query_count: usize,
105    pub ready_surfaces: Vec<&'static str>,
106    pub style_completion_consumer_decisions: Vec<OmenaQueryStyleCompletionConsumerDecisionV0>,
107    pub cme_coupled_surfaces: Vec<&'static str>,
108    pub next_decoupling_targets: Vec<&'static str>,
109}
110
111#[derive(Debug, Clone, PartialEq, Eq, Serialize)]
112#[serde(rename_all = "camelCase")]
113pub struct OmenaQueryStyleCompletionConsumerDecisionV0 {
114    pub consumer: &'static str,
115    pub surface: &'static str,
116    pub decision: &'static str,
117    pub rationale: &'static str,
118}
119
120#[derive(Debug, Clone, PartialEq, Eq, Serialize)]
121#[serde(rename_all = "camelCase")]
122pub struct OmenaQuerySassModuleConformanceReportV0 {
123    pub schema_version: &'static str,
124    pub product: &'static str,
125    pub claim_level: &'static str,
126    pub theorem_claimed: bool,
127    pub normative_source: &'static str,
128    pub modeled_count: usize,
129    pub gap_count: usize,
130    pub decided_out_count: usize,
131    pub policy_count: usize,
132    pub rows: Vec<OmenaQuerySassModuleConformanceRowV0>,
133    pub ready_surfaces: Vec<&'static str>,
134}
135
136#[derive(Debug, Clone, PartialEq, Eq, Serialize)]
137#[serde(rename_all = "camelCase")]
138pub struct OmenaQuerySassModuleConformanceRowV0 {
139    pub key: &'static str,
140    pub category: &'static str,
141    pub status: &'static str,
142    pub normative_anchor: &'static str,
143    pub implementation: &'static str,
144    pub witness: &'static str,
145    pub decision: &'static str,
146}
147
148#[derive(Debug, Serialize)]
149#[serde(rename_all = "camelCase")]
150pub struct OmenaQueryEvaluationRuntimeSummaryV0 {
151    pub schema_version: &'static str,
152    pub product: &'static str,
153    pub input_version: String,
154    pub selected_query_adapter_capabilities: SelectedQueryAdapterCapabilitiesV0,
155    pub runtime_products: Vec<&'static str>,
156    pub source_resolution_expression_count: usize,
157    pub source_resolution_unresolved_expression_count: usize,
158    pub expression_domain_revision: u64,
159    pub expression_domain_graph_count: usize,
160    pub expression_domain_dirty_graph_count: usize,
161    pub expression_domain_reused_graph_count: usize,
162    pub style_document_summary_source: &'static str,
163    pub ready_surfaces: Vec<&'static str>,
164    pub retired_couplings: Vec<&'static str>,
165}
166
167#[derive(Debug, Clone, PartialEq, Eq, Serialize)]
168#[serde(rename_all = "camelCase")]
169pub struct SelectedQueryAdapterCapabilitiesV0 {
170    pub schema_version: &'static str,
171    pub product: &'static str,
172    pub default_candidate_backend: &'static str,
173    pub schema_version_policy: OmenaQuerySchemaVersionPolicyV0,
174    pub schema_version_checks: Vec<OmenaQuerySchemaVersionCheckV0>,
175    pub backend_kinds: Vec<SelectedQueryBackendCapabilityV0>,
176    pub runner_commands: Vec<SelectedQueryRunnerCommandV0>,
177    pub expression_semantics_payload_contracts: Vec<&'static str>,
178    pub required_input_contracts: Vec<&'static str>,
179    pub adapter_readiness: Vec<&'static str>,
180    pub routing_status: &'static str,
181}
182
183#[derive(Debug, Clone, PartialEq, Eq, Serialize)]
184#[serde(rename_all = "camelCase")]
185pub struct OmenaQuerySchemaVersionPolicyV0 {
186    pub schema_version: &'static str,
187    pub product: &'static str,
188    pub current_version: &'static str,
189    pub current_version_label: &'static str,
190    pub accepted_versions: Vec<&'static str>,
191    pub deprecated_versions: Vec<&'static str>,
192    pub rejected_version_policy: &'static str,
193    pub missing_version_policy: &'static str,
194    pub migration_policy: Vec<&'static str>,
195    pub compatibility_gate: &'static str,
196}
197
198#[derive(Debug, Clone, PartialEq, Eq, Serialize)]
199#[serde(rename_all = "camelCase")]
200pub struct OmenaQuerySchemaVersionCheckV0 {
201    pub schema_version: &'static str,
202    pub product: &'static str,
203    pub requested_version: Option<String>,
204    pub current_version: &'static str,
205    pub accepted: bool,
206    pub status: &'static str,
207    pub migration_action: &'static str,
208    pub reason: &'static str,
209}
210
211#[derive(Debug, Clone, PartialEq, Eq, Serialize)]
212#[serde(rename_all = "camelCase")]
213pub struct SelectedQueryBackendCapabilityV0 {
214    pub backend_kind: &'static str,
215    pub source_resolution: bool,
216    pub expression_semantics: bool,
217    pub selector_usage: bool,
218    pub style_semantic_graph: bool,
219}
220
221#[derive(Debug, Clone, PartialEq, Eq, Serialize)]
222#[serde(rename_all = "camelCase")]
223pub struct SelectedQueryRunnerCommandV0 {
224    pub surface: &'static str,
225    pub command: &'static str,
226    pub input_contract: &'static str,
227    pub output_product: &'static str,
228}
229
230#[derive(Debug, Serialize)]
231#[serde(rename_all = "camelCase")]
232pub struct OmenaQueryStyleSemanticGraphBatchOutputV0 {
233    pub schema_version: &'static str,
234    pub product: &'static str,
235    pub cross_file_summary: OmenaQueryCrossFileSummaryV0,
236    pub css_modules_resolution: OmenaQueryCssModulesCrossFileResolutionV0,
237    pub sass_module_resolution: OmenaQuerySassModuleCrossFileResolutionV0,
238    pub graphs: Vec<OmenaQueryStyleSemanticGraphBatchEntryV0>,
239}
240
241#[derive(Debug, Clone, PartialEq, Eq, Serialize)]
242#[serde(rename_all = "camelCase")]
243pub struct OmenaQueryCategoricalDesignSystemCrossProjectSummaryV0 {
244    pub schema_version: &'static str,
245    pub product: &'static str,
246    pub claim_scope: &'static str,
247    pub source_product: &'static str,
248    pub theory_product: &'static str,
249    pub project_count: usize,
250    pub product_path_evidence_ready: bool,
251    pub models: Vec<OmenaQueryCategoricalDesignSystemModelV0>,
252    pub invariant_summary: OmenaQueryCategoricalDesignSystemInvariantSummaryV0,
253    pub deferred_residuals: Vec<&'static str>,
254}
255
256#[derive(Debug, Clone, PartialEq, Eq, Serialize)]
257#[serde(rename_all = "camelCase")]
258pub struct OmenaQueryM4AxisCReadinessSummaryV0 {
259    pub schema_version: &'static str,
260    pub product: &'static str,
261    pub status: &'static str,
262    pub required_edge_kind_count: usize,
263    pub required_edge_kind_counts: Vec<OmenaQueryCrossFileSummaryEdgeKindCountV0>,
264    pub workspace_edge_count: usize,
265    pub issue_63_provenance_round_trip_ready: bool,
266    pub issue_65_summary_edge_equivalence_ready: bool,
267    pub summary_hash_invalidation_ready: bool,
268    pub summary_hash_samples: OmenaQueryM4AxisCSummaryHashSamplesV0,
269    pub checked_surfaces: Vec<&'static str>,
270    pub next_priorities: Vec<&'static str>,
271}
272
273#[derive(Debug, Clone, PartialEq, Eq, Serialize)]
274#[serde(rename_all = "camelCase")]
275pub struct OmenaQueryM4AxisCSummaryHashSamplesV0 {
276    pub baseline: String,
277    pub source_selector_change: String,
278    pub style_edge_change: String,
279    pub package_manifest_change: String,
280}
281
282#[derive(Debug, Serialize)]
283#[serde(rename_all = "camelCase")]
284pub struct OmenaQueryStyleSemanticGraphBatchEntryV0 {
285    pub style_path: String,
286    pub graph: Option<StyleSemanticGraphSummaryV0>,
287}
288
289#[derive(Debug, Clone, PartialEq, Eq, Serialize)]
290#[serde(rename_all = "camelCase")]
291pub struct OmenaQueryCssModulesCrossFileResolutionV0 {
292    pub schema_version: &'static str,
293    pub product: &'static str,
294    pub status: &'static str,
295    pub resolution_scope: &'static str,
296    pub style_count: usize,
297    pub import_edge_count: usize,
298    pub resolved_import_edge_count: usize,
299    pub unresolved_import_edge_count: usize,
300    pub matched_name_count: usize,
301    pub edges: Vec<OmenaQueryCssModulesImportEdgeResolutionV0>,
302    pub composes_closure_edge_count: usize,
303    pub value_closure_edge_count: usize,
304    pub icss_closure_edge_count: usize,
305    pub composes_cycle_count: usize,
306    pub value_cycle_count: usize,
307    pub icss_cycle_count: usize,
308    pub composes_closure_edges: Vec<OmenaQueryCssModulesComposesClosureEdgeV0>,
309    pub value_closure_edges: Vec<OmenaQueryCssModulesValueClosureEdgeV0>,
310    pub icss_closure_edges: Vec<OmenaQueryCssModulesIcssClosureEdgeV0>,
311    pub cycles: Vec<OmenaQueryCssModulesCycleV0>,
312    pub capabilities: OmenaQueryCssModulesCrossFileResolutionCapabilitiesV0,
313    pub next_priorities: Vec<&'static str>,
314}
315
316#[derive(Debug, Clone, PartialEq, Eq, Serialize)]
317#[serde(rename_all = "camelCase")]
318pub struct OmenaQueryCssModulesImportEdgeResolutionV0 {
319    pub from_style_path: String,
320    pub import_kind: &'static str,
321    pub source: String,
322    pub resolved_style_path: Option<String>,
323    pub status: &'static str,
324    pub import_graph_distance: Option<usize>,
325    pub import_graph_order: Option<usize>,
326    pub imported_names: Vec<String>,
327    pub exported_names: Vec<String>,
328    pub matched_names: Vec<String>,
329}
330
331#[derive(Debug, Clone, PartialEq, Eq, Serialize)]
332#[serde(rename_all = "camelCase")]
333pub struct OmenaQueryCssModulesComposesClosureEdgeV0 {
334    pub from_style_path: String,
335    pub owner_selector_name: String,
336    pub target_style_path: String,
337    pub target_selector_name: String,
338    pub depth: usize,
339    pub path: Vec<String>,
340}
341
342#[derive(Debug, Clone, PartialEq, Eq, Serialize)]
343#[serde(rename_all = "camelCase")]
344pub struct OmenaQueryCssModulesValueClosureEdgeV0 {
345    pub from_style_path: String,
346    pub value_name: String,
347    pub target_style_path: String,
348    pub target_value_name: String,
349    pub depth: usize,
350    pub path: Vec<String>,
351}
352
353#[derive(Debug, Clone, PartialEq, Eq, Serialize)]
354#[serde(rename_all = "camelCase")]
355pub struct OmenaQueryCssModulesIcssClosureEdgeV0 {
356    pub from_style_path: String,
357    pub name: String,
358    pub target_style_path: String,
359    pub target_name: String,
360    pub depth: usize,
361    pub path: Vec<String>,
362}
363
364#[derive(Debug, Clone, PartialEq, Eq, Serialize)]
365#[serde(rename_all = "camelCase")]
366pub struct OmenaQueryCssModulesCycleV0 {
367    pub kind: &'static str,
368    pub path: Vec<String>,
369}
370
371#[derive(Debug, Clone, PartialEq, Eq, Serialize)]
372#[serde(rename_all = "camelCase")]
373pub struct OmenaQueryCssModulesCrossFileResolutionCapabilitiesV0 {
374    pub semantic_layer_owned: bool,
375    pub import_source_resolution_ready: bool,
376    pub cross_file_resolution_ready: bool,
377    pub composes_closure_ready: bool,
378    pub composes_name_match_ready: bool,
379    pub value_name_match_ready: bool,
380    pub icss_name_match_ready: bool,
381    pub transitive_closure_ready: bool,
382    pub value_graph_closure_ready: bool,
383    pub icss_export_import_closure_ready: bool,
384    pub cycle_detection_ready: bool,
385}
386
387#[derive(Debug, Clone, PartialEq, Eq, Serialize)]
388#[serde(rename_all = "camelCase")]
389pub struct OmenaQuerySassModuleCrossFileResolutionV0 {
390    pub schema_version: &'static str,
391    pub product: &'static str,
392    pub status: &'static str,
393    pub resolution_scope: &'static str,
394    pub style_count: usize,
395    pub module_edge_count: usize,
396    pub resolved_module_edge_count: usize,
397    pub unresolved_module_edge_count: usize,
398    pub external_module_edge_count: usize,
399    pub symlink_chain_edge_count: usize,
400    pub symlink_chain_link_count: usize,
401    pub configured_module_instance_count: usize,
402    pub edges: Vec<OmenaQuerySassModuleEdgeResolutionV0>,
403    pub graph_closure_edge_count: usize,
404    pub cycle_count: usize,
405    pub visibility_filter_count: usize,
406    pub graph_closure_edges: Vec<OmenaQuerySassModuleGraphClosureEdgeV0>,
407    pub cycles: Vec<OmenaQuerySassModuleCycleV0>,
408    pub capabilities: OmenaQuerySassModuleCrossFileResolutionCapabilitiesV0,
409    pub next_priorities: Vec<&'static str>,
410}
411
412#[derive(Debug, Clone, PartialEq, Eq, Serialize)]
413#[serde(rename_all = "camelCase")]
414pub struct OmenaQuerySassModuleEdgeResolutionV0 {
415    pub from_style_path: String,
416    pub edge_kind: &'static str,
417    pub source: String,
418    pub rule_ordinal: usize,
419    pub namespace_kind: Option<&'static str>,
420    pub namespace: Option<String>,
421    pub forward_prefix: Option<String>,
422    pub visibility_filter_kind: Option<&'static str>,
423    pub visibility_filter_names: Vec<String>,
424    pub resolved_style_path: Option<String>,
425    pub status: &'static str,
426    pub resolution_kind: &'static str,
427    pub candidate_count: usize,
428    pub symlink_chain_link_count: usize,
429    pub symlink_chain_links: Vec<OmenaQuerySymlinkChainLinkV0>,
430    pub configuration_signature: String,
431    pub configuration_variable_count: usize,
432    pub invalid_configuration_variable_names: Vec<String>,
433    pub module_instance_identity_key: Option<String>,
434}
435
436#[derive(Debug, Clone, PartialEq, Eq, Serialize)]
437#[serde(rename_all = "camelCase")]
438pub struct OmenaQuerySymlinkChainLinkV0 {
439    pub link_path: String,
440    pub target_path: String,
441    pub target_was_absolute: bool,
442}
443
444#[derive(Debug, Clone, PartialEq, Eq, Serialize)]
445#[serde(rename_all = "camelCase")]
446pub struct OmenaQuerySassModuleGraphClosureEdgeV0 {
447    pub from_style_path: String,
448    pub target_style_path: String,
449    pub edge_kind: &'static str,
450    pub depth: usize,
451    pub path: Vec<String>,
452    pub namespace_kind: Option<&'static str>,
453    pub namespace: Option<String>,
454    pub forward_prefix: Option<String>,
455    pub visibility_filter_kind: Option<&'static str>,
456    pub visibility_filter_names: Vec<String>,
457    pub configuration_signature: String,
458    pub configuration_variable_count: usize,
459    pub invalid_configuration_variable_names: Vec<String>,
460    pub module_instance_identity_key: Option<String>,
461}
462
463#[derive(Debug, Clone, PartialEq, Eq, Serialize)]
464#[serde(rename_all = "camelCase")]
465pub struct OmenaQuerySassModuleCycleV0 {
466    pub path: Vec<String>,
467}
468
469#[derive(Debug, Clone, PartialEq, Eq, Serialize)]
470#[serde(rename_all = "camelCase")]
471pub struct OmenaQuerySassModuleCrossFileResolutionCapabilitiesV0 {
472    pub omena_parser_module_edge_consumption_ready: bool,
473    pub resolver_backed_source_resolution_ready: bool,
474    pub package_manifest_resolution_ready: bool,
475    pub external_module_filtering_ready: bool,
476    pub graph_closure_ready: bool,
477    pub cycle_detection_ready: bool,
478    pub namespace_show_hide_filter_ready: bool,
479    pub configured_module_instance_identity_ready: bool,
480    pub symlink_chain_metadata_ready: bool,
481}
482
483#[derive(Debug, Clone, Serialize)]
484#[serde(rename_all = "camelCase")]
485pub struct OmenaQueryStyleDocumentSummaryV0 {
486    pub schema_version: &'static str,
487    pub product: &'static str,
488    pub language: &'static str,
489    pub selector_names: Vec<String>,
490    pub custom_property_decl_names: Vec<AuthoredPropertyTextV0>,
491    pub custom_property_ref_names: Vec<AuthoredPropertyTextV0>,
492    pub sass_module_use_sources: Vec<String>,
493    pub sass_module_forward_sources: Vec<String>,
494    pub diagnostic_count: usize,
495}
496
497impl PartialEq for OmenaQueryStyleDocumentSummaryV0 {
498    fn eq(&self, other: &Self) -> bool {
499        self.schema_version == other.schema_version
500            && self.product == other.product
501            && self.language == other.language
502            && self.selector_names == other.selector_names
503            && authored_custom_property_sequences_same(
504                &self.custom_property_decl_names,
505                &other.custom_property_decl_names,
506            )
507            && authored_custom_property_sequences_same(
508                &self.custom_property_ref_names,
509                &other.custom_property_ref_names,
510            )
511            && self.sass_module_use_sources == other.sass_module_use_sources
512            && self.sass_module_forward_sources == other.sass_module_forward_sources
513            && self.diagnostic_count == other.diagnostic_count
514    }
515}
516
517impl Eq for OmenaQueryStyleDocumentSummaryV0 {}
518
519#[derive(Debug, Clone, PartialEq, Eq, Serialize)]
520#[serde(rename_all = "camelCase")]
521pub struct FastFactsV0 {
522    pub schema_version: &'static str,
523    pub product: &'static str,
524    pub tier: &'static str,
525    pub style_path: String,
526    pub language: &'static str,
527    pub selector_count: usize,
528    pub custom_property_count: usize,
529    pub sass_symbol_count: usize,
530    pub module_edge_count: usize,
531    pub parser_error_count: usize,
532}
533
534#[derive(Debug, Clone, PartialEq, Eq, Serialize)]
535#[serde(rename_all = "camelCase")]
536pub struct AnalyzedGraphV0 {
537    pub schema_version: &'static str,
538    pub product: &'static str,
539    pub tier: &'static str,
540    pub style_path: String,
541    pub fast_facts: FastFactsV0,
542    pub graph_kinds: Vec<&'static str>,
543    pub node_count: usize,
544    pub edge_count: usize,
545    pub cycle_count: usize,
546}
547
548#[derive(Debug, Clone, PartialEq, Eq, Serialize)]
549#[serde(rename_all = "camelCase")]
550pub struct StyleEditDistanceSummaryV0 {
551    pub schema_version: &'static str,
552    pub product: &'static str,
553    pub tier: &'static str,
554    pub metric_kind: &'static str,
555    pub claim_level: &'static str,
556    pub public_safety_claim_ready: bool,
557    pub left_style_path: String,
558    pub right_style_path: String,
559    pub left_fast_facts: FastFactsV0,
560    pub right_fast_facts: FastFactsV0,
561    pub left_analyzed_graph: AnalyzedGraphV0,
562    pub right_analyzed_graph: AnalyzedGraphV0,
563    pub selector_delta: usize,
564    pub custom_property_delta: usize,
565    pub sass_symbol_delta: usize,
566    pub module_edge_delta: usize,
567    pub parser_error_delta: usize,
568    pub graph_node_delta: usize,
569    pub graph_edge_delta: usize,
570    pub graph_cycle_delta: usize,
571    pub total_distance: usize,
572}
573
574#[derive(Debug, Clone, PartialEq, Eq, Serialize)]
575#[serde(rename_all = "camelCase")]
576pub struct StyleEditDistanceCascadeMarginBridgeV0 {
577    pub schema_version: &'static str,
578    pub product: &'static str,
579    pub bridge_kind: &'static str,
580    pub claim_level: &'static str,
581    pub theorem_claimed: bool,
582    pub public_safety_claim_ready: bool,
583    pub metric_product: &'static str,
584    pub metric_kind: &'static str,
585    pub margin_product: &'static str,
586    pub margin_kind: &'static str,
587    pub dominant_axis: &'static str,
588    pub edit_distance_total: usize,
589    pub cascade_margin_signed_distance: i64,
590    pub cascade_margin_abs_distance: u64,
591    pub lipschitz_constant_name: &'static str,
592    pub lipschitz_constant: Option<u64>,
593    pub lipschitz_bound: Option<u64>,
594    pub checked: bool,
595    pub calibration_stage: &'static str,
596    pub incremental_priority_input: IncrementalEditDistancePriorityInputV0,
597}
598
599#[derive(Debug, Clone, PartialEq, Eq, Serialize)]
600#[serde(rename_all = "camelCase")]
601pub struct OmenaQueryFragileGuardedWinnerDiagnosticV0 {
602    pub schema_version: &'static str,
603    pub product: &'static str,
604    pub diagnostic_kind: &'static str,
605    pub claim_level: &'static str,
606    pub baseline_winner_declaration_id: String,
607    pub robustness_radius: u32,
608    pub fragile_threshold: u32,
609    pub witness: Vec<omena_cascade::GuardedCascadePerturbationV0>,
610    pub calibration_stage: &'static str,
611    pub public_safety_claim_ready: bool,
612    pub false_alarm_boundary: &'static str,
613    pub message: String,
614}
615
616#[derive(Debug, Clone, PartialEq, Eq, Serialize)]
617#[serde(rename_all = "camelCase")]
618pub struct OmenaQueryCascadeConfidenceV0 {
619    pub schema_version: &'static str,
620    pub product: &'static str,
621    pub feature_gate: &'static str,
622    pub confidence_kind: &'static str,
623    pub claim_level: &'static str,
624    pub theorem_claimed: bool,
625    pub public_safety_claim_ready: bool,
626    pub calibration_stage: &'static str,
627    pub margin_product: &'static str,
628    pub margin_kind: &'static str,
629    pub dominant_axis: &'static str,
630    pub dominant_axis_weight_basis_points: u16,
631    pub sigmoid_temperature_basis_points: u16,
632    pub signed_distance: i64,
633    pub abs_distance: u64,
634    pub confidence_score_basis_points: u16,
635    pub confidence_bucket: &'static str,
636    pub winner_declaration_id: String,
637    pub challenger_declaration_id: Option<String>,
638}
639
640#[derive(Debug, Clone, PartialEq, Eq, Serialize)]
641#[serde(rename_all = "camelCase")]
642pub struct OmenaQueryCustomPropertyAnnotationSummaryV0 {
643    pub schema_version: &'static str,
644    pub product: &'static str,
645    pub style_path: String,
646    pub annotation_count: usize,
647    pub annotations: Vec<OmenaQueryCustomPropertyAnnotationV0>,
648}
649
650#[derive(Debug, Clone, Serialize)]
651#[serde(rename_all = "camelCase")]
652pub struct OmenaQueryCustomPropertyAnnotationV0 {
653    pub name: AuthoredPropertyTextV0,
654    pub property_key: CanonicalCustomPropertyNameV0,
655    pub declaration_count: usize,
656    pub reference_count: usize,
657    pub annotation_kind: &'static str,
658    pub participates_in_fixed_point: bool,
659}
660
661impl PartialEq for OmenaQueryCustomPropertyAnnotationV0 {
662    fn eq(&self, other: &Self) -> bool {
663        self.property_key == other.property_key
664            && self.declaration_count == other.declaration_count
665            && self.reference_count == other.reference_count
666            && self.annotation_kind == other.annotation_kind
667            && self.participates_in_fixed_point == other.participates_in_fixed_point
668    }
669}
670
671impl Eq for OmenaQueryCustomPropertyAnnotationV0 {}
672
673#[derive(Debug, Clone, PartialEq, Eq, Serialize)]
674#[serde(rename_all = "camelCase")]
675pub struct OmenaQueryStyleContextIndexV0 {
676    pub schema_version: &'static str,
677    pub product: &'static str,
678    pub style_path: String,
679    pub language: &'static str,
680    pub context_index_source: &'static str,
681    pub context_index: StyleContextIndexV0,
682}
683
684#[derive(Debug, Clone, PartialEq, Eq, Serialize)]
685#[serde(rename_all = "camelCase")]
686pub struct OmenaQueryConsumerCheckSummaryV0 {
687    pub schema_version: &'static str,
688    pub product: &'static str,
689    pub style_path: String,
690    pub dialect: &'static str,
691    pub token_count: usize,
692    pub parser_error_count: usize,
693    pub class_selector_count: usize,
694    pub custom_property_count: usize,
695    pub keyframe_count: usize,
696    pub ready_surfaces: Vec<&'static str>,
697}
698
699#[derive(Debug, Clone, PartialEq, Eq, Serialize)]
700#[serde(rename_all = "camelCase")]
701pub struct OmenaQueryConsumerBuildSummaryV0 {
702    pub schema_version: &'static str,
703    pub product: &'static str,
704    pub style_path: String,
705    pub dialect: &'static str,
706    pub requested_pass_ids: Vec<String>,
707    pub effective_pass_ids: Vec<String>,
708    pub target_query: Option<OmenaQueryTransformTargetQueryPlanV0>,
709    pub unknown_pass_ids: Vec<String>,
710    pub execution: TransformExecutionSummaryV0,
711    pub semantic_removal_count: usize,
712    #[serde(skip_serializing_if = "Option::is_none")]
713    pub bundle: Option<TransformBundleSourceSummaryV0>,
714    #[serde(skip_serializing_if = "Option::is_none")]
715    pub bundle_emission_path: Option<OmenaQueryBundleEmissionPathV0>,
716    #[serde(skip_serializing_if = "Option::is_none")]
717    pub source_map_v3: Option<OmenaQueryTransformSourceMapV3V0>,
718    #[serde(skip_serializing_if = "Option::is_none")]
719    pub open_world_snapshot: Option<OmenaQueryOpenWorldSnapshotV0>,
720    pub ready_surfaces: Vec<&'static str>,
721}
722
723#[derive(Debug, Clone, Copy, Default, PartialEq, Eq, Deserialize, Serialize)]
724#[serde(rename_all = "camelCase")]
725pub enum OmenaQueryBuildVerificationProfileV0 {
726    #[default]
727    Descriptive,
728    Strict,
729}
730
731#[derive(Debug, Clone, Copy, Default, PartialEq, Eq, Deserialize, Serialize)]
732#[serde(rename_all = "camelCase")]
733pub enum OmenaQueryBundleEmissionPathV0 {
734    #[deprecated(
735        since = "0.5.0",
736        note = "legacy import-inline bundle emission is scheduled for removal before 1.0"
737    )]
738    ImportInlineLegacy,
739    #[default]
740    LinkedOrder,
741}
742
743#[allow(deprecated)]
744impl OmenaQueryBundleEmissionPathV0 {
745    #[deprecated(
746        since = "0.5.0",
747        note = "legacy import-inline bundle emission is scheduled for removal before 1.0"
748    )]
749    pub const fn legacy_compatibility() -> Self {
750        Self::ImportInlineLegacy
751    }
752
753    pub const fn as_wire_label(self) -> &'static str {
754        match self {
755            Self::ImportInlineLegacy => "importInlineLegacy",
756            Self::LinkedOrder => "linkedOrder",
757        }
758    }
759}
760
761#[derive(Debug, Clone, Copy, Default, PartialEq, Eq, Serialize)]
762#[serde(rename_all = "camelCase")]
763pub struct OmenaQueryBuildAdmissionRequirementsV0 {
764    pub refuse_unknown_pass_ids: bool,
765    pub require_closed_world_evidence: bool,
766    pub require_complete_decisions: bool,
767}
768
769impl OmenaQueryBuildAdmissionRequirementsV0 {
770    pub const fn strict() -> Self {
771        Self {
772            refuse_unknown_pass_ids: true,
773            require_closed_world_evidence: true,
774            require_complete_decisions: true,
775        }
776    }
777}
778
779#[derive(Debug, Clone, Default, PartialEq, Eq, Deserialize, Serialize)]
780#[serde(default, rename_all = "camelCase")]
781pub struct OmenaQueryConsumerBuildOptionsV0 {
782    pub verification_profile: OmenaQueryBuildVerificationProfileV0,
783    pub bundle_emission_path: OmenaQueryBundleEmissionPathV0,
784}
785
786#[derive(Debug, Clone, PartialEq, Eq, Serialize)]
787#[serde(rename_all = "camelCase", tag = "kind")]
788pub enum OmenaQueryClosedWorldBlockerV0 {
789    EmptyEntrypoints,
790    MissingEntrypoint {
791        source_path: String,
792    },
793    AmbiguousModulePath {
794        source_path: String,
795    },
796    MissingDependency {
797        source_path: String,
798        import_source: String,
799    },
800    MissingModuleInstance {
801        module: omena_parser::ModuleInstanceKeyV0,
802    },
803    MissingModuleDependency {
804        module: omena_parser::ModuleInstanceKeyV0,
805        dependency: omena_parser::ModuleInstanceKeyV0,
806    },
807    ClosedWorldPassUnavailable {
808        requested_pass_ids: Vec<String>,
809    },
810    UnsupportedDialectEmissionCycle {
811        dialect: OmenaQueryEmissionCycleDialectV0,
812        class: OmenaQueryEmissionCycleClassV0,
813        #[serde(rename = "edgeKinds")]
814        edge_kinds: Vec<TransformBundleEdgeKind>,
815    },
816}
817
818#[derive(Debug, Clone, PartialEq, Eq, Serialize)]
819#[serde(rename_all = "camelCase", tag = "status")]
820pub enum OmenaQueryClosedWorldOutcomeV0 {
821    Closed {
822        bundle: Box<omena_parser::ClosedWorldBundleV0>,
823    },
824    Open {
825        blockers: Vec<OmenaQueryClosedWorldBlockerV0>,
826    },
827}
828
829impl OmenaQueryClosedWorldOutcomeV0 {
830    pub fn bundle(&self) -> Option<&omena_parser::ClosedWorldBundleV0> {
831        match self {
832            Self::Closed { bundle } => Some(bundle.as_ref()),
833            Self::Open { .. } => None,
834        }
835    }
836
837    pub fn blockers(&self) -> &[OmenaQueryClosedWorldBlockerV0] {
838        match self {
839            Self::Closed { .. } => &[],
840            Self::Open { blockers } => blockers,
841        }
842    }
843
844    pub fn is_open(&self) -> bool {
845        matches!(self, Self::Open { .. })
846    }
847}
848
849#[derive(Debug, Clone, PartialEq, Eq, Serialize)]
850#[serde(rename_all = "camelCase")]
851pub struct OmenaQueryBundleArtifactV0 {
852    pub schema_version: &'static str,
853    pub product: &'static str,
854    pub style_path: String,
855    pub emission_path: OmenaQueryBundleEmissionPathV0,
856    pub output_css: String,
857    pub bundle: TransformBundleSourceSummaryV0,
858    pub source_map_v3: OmenaQueryTransformSourceMapV3V0,
859    pub code_split_outputs: Vec<OmenaQueryBundleCodeSplitWorkspacePlanOutputV0>,
860    pub asset_rewrites: Vec<TransformBundleAssetUrlRewriteSummaryV0>,
861    pub per_pass_provenance: Vec<TransformPassExecutionOutcomeV0>,
862    /// Compatibility projection that retains entry-scoped execution fields.
863    ///
864    /// Linked consumers should read `BundleExecutionSummaryV0` from
865    /// `OmenaQueryBundleExecutionScopeEvidenceV0::bundle_execution`. This field
866    /// remains serialized unchanged; deprecation does not alter the wire shape,
867    /// and removal is reserved for a future major release.
868    pub execution: TransformExecutionSummaryV0,
869    pub ready_surfaces: Vec<&'static str>,
870}
871
872#[derive(Debug, Clone, PartialEq, Eq, Serialize)]
873#[serde(rename_all = "camelCase")]
874pub struct OmenaQueryBundleResultV0 {
875    pub artifact: OmenaQueryBundleArtifactV0,
876    pub closed_world_outcome: OmenaQueryClosedWorldOutcomeV0,
877    pub closed_world_decision_parity: OmenaQueryClosedWorldDecisionParityV0,
878}
879
880#[derive(Debug, Clone, PartialEq, Eq, Serialize)]
881#[serde(rename_all = "camelCase")]
882#[non_exhaustive]
883pub struct OmenaQueryBundleTokenOwnershipResultV0 {
884    pub bundle_result: OmenaQueryBundleResultV0,
885    pub ownership_census: omena_query_transform_runner::CssModuleTokenOwnershipCensusV0,
886}
887
888impl OmenaQueryBundleTokenOwnershipResultV0 {
889    pub(crate) fn new(
890        bundle_result: OmenaQueryBundleResultV0,
891        ownership_census: omena_query_transform_runner::CssModuleTokenOwnershipCensusV0,
892    ) -> Self {
893        Self {
894            bundle_result,
895            ownership_census,
896        }
897    }
898}
899
900#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize)]
901#[serde(rename_all = "camelCase")]
902#[non_exhaustive]
903pub enum OmenaQueryExecutionEvidenceScopeV0 {
904    Entry,
905    Bundle,
906}
907
908#[derive(Debug, Clone, PartialEq, Eq, Serialize)]
909#[serde(rename_all = "camelCase")]
910#[non_exhaustive]
911pub struct OmenaQueryExecutionFieldScopeV0 {
912    pub field_name: &'static str,
913    pub scope: OmenaQueryExecutionEvidenceScopeV0,
914    pub derivation: &'static str,
915}
916
917#[derive(Debug, Clone, PartialEq, Eq, Serialize)]
918#[serde(rename_all = "camelCase")]
919#[non_exhaustive]
920pub struct OmenaQueryBundleModuleExecutionByteFactsV0 {
921    pub module_instance: omena_parser::ModuleInstanceKeyV0,
922    pub input_byte_len: usize,
923    pub output_byte_len: usize,
924    pub generated_start: usize,
925    pub generated_end: usize,
926}
927
928#[derive(Debug, Clone, PartialEq, Eq, Serialize)]
929#[serde(rename_all = "camelCase")]
930#[non_exhaustive]
931pub struct OmenaQueryBundleCompositeExecutionByteFactsV0 {
932    pub module_count: usize,
933    pub summed_module_input_byte_len: usize,
934    pub summed_module_output_byte_len: usize,
935    pub inter_module_separator_byte_len: usize,
936    pub materialized_output_byte_len: usize,
937}
938
939#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize)]
940#[serde(rename_all = "camelCase")]
941#[non_exhaustive]
942pub enum OmenaQueryLinkedSourceMapGranularityV0 {
943    CstAnchors,
944    WholeModuleFallback,
945}
946
947#[derive(Debug, Clone, PartialEq, Eq, Serialize)]
948#[serde(rename_all = "camelCase")]
949#[non_exhaustive]
950pub struct OmenaQueryLinkedSourceMapDispositionV0 {
951    pub module_instance: omena_parser::ModuleInstanceKeyV0,
952    pub granularity: OmenaQueryLinkedSourceMapGranularityV0,
953    #[serde(skip_serializing_if = "Option::is_none")]
954    pub fallback_reason: Option<&'static str>,
955    pub segment_count: usize,
956}
957
958/// One linked module's complete transform execution.
959///
960/// Per-module truth remains available because most transform execution fields
961/// have no defensible bundle-level fold.
962#[derive(Debug, Clone, PartialEq, Eq, Serialize)]
963#[serde(rename_all = "camelCase")]
964#[non_exhaustive]
965pub struct BundleModuleExecutionV0 {
966    pub module_instance: omena_parser::ModuleInstanceKeyV0,
967    pub execution: TransformExecutionSummaryV0,
968}
969
970/// Region and count evidence owned by linked bundle materialization.
971///
972/// This type deliberately carries neither CSS text nor a byte total. The
973/// materialized CSS remains on the bundle artifact, and
974/// `OmenaQueryBundleCompositeExecutionByteFactsV0` remains the sole byte
975/// accounting authority.
976#[derive(Debug, Clone, PartialEq, Eq, Serialize)]
977#[serde(rename_all = "camelCase")]
978#[non_exhaustive]
979pub struct BundleEmissionExecutionV0 {
980    pub module_regions: Vec<LinkedEmissionModuleRegionV0>,
981    pub order_entry_regions: Vec<LinkedEmissionOrderEntryRegionV0>,
982    pub emitted_module_count: usize,
983    pub global_order_entry_count: usize,
984}
985
986/// Bundle-level transform execution for the linked emission path.
987///
988/// The aggregate fields are intentionally narrower than
989/// `TransformExecutionSummaryV0`: each one has an authored fold and a product
990/// run where the folded value differs from the entry module. This summary says
991/// nothing about the legacy emission path, and fields without a defensible fold
992/// remain available only through `module_executions`. The current product
993/// corpus bounds which `aggregate_*` fields have witnesses; it is not a claim
994/// that the set is exhaustive. Fold tokens document the intended operation,
995/// but witnesses remain load-bearing: the current corpus distinguishes the
996/// refusal-count sum, while mutation and semantic-removal values happen to make
997/// `sum` and `max` agree.
998#[derive(Debug, Clone, PartialEq, Eq, Serialize)]
999#[serde(rename_all = "camelCase")]
1000#[non_exhaustive]
1001pub struct BundleExecutionSummaryV0 {
1002    pub schema_version: &'static str,
1003    pub product: &'static str,
1004    pub entry_module_instance: omena_parser::ModuleInstanceKeyV0,
1005    pub module_executions: Vec<BundleModuleExecutionV0>,
1006    pub emission_execution: BundleEmissionExecutionV0,
1007    /// Fold: `sum` over each module execution's mutation count.
1008    pub aggregate_mutation_count: usize,
1009    /// Fold: `orderedUnion` over executed pass identifiers in module order.
1010    pub aggregate_executed_pass_ids: Vec<&'static str>,
1011    /// Fold: `sum` over each module execution's semantic removal count.
1012    pub aggregate_semantic_removal_count: usize,
1013    /// Fold: `sum` over each module execution's closed-world refusal count.
1014    pub aggregate_closed_world_refusal_count: usize,
1015}
1016
1017#[derive(Debug, Clone, PartialEq, Eq, Serialize)]
1018#[serde(rename_all = "camelCase")]
1019#[non_exhaustive]
1020pub struct OmenaQueryBundleExecutionScopeEvidenceV0 {
1021    pub schema_version: &'static str,
1022    pub product: &'static str,
1023    pub entry_module_instance: omena_parser::ModuleInstanceKeyV0,
1024    pub field_scopes: Vec<OmenaQueryExecutionFieldScopeV0>,
1025    pub module_executions: Vec<OmenaQueryBundleModuleExecutionByteFactsV0>,
1026    pub bundle_composite: OmenaQueryBundleCompositeExecutionByteFactsV0,
1027    pub bundle_execution: BundleExecutionSummaryV0,
1028    pub source_map_dispositions: Vec<OmenaQueryLinkedSourceMapDispositionV0>,
1029}
1030
1031#[derive(Debug, Clone, PartialEq, Eq, Serialize)]
1032#[serde(rename_all = "camelCase")]
1033#[non_exhaustive]
1034pub struct OmenaQueryBundleExecutionScopeResultV0 {
1035    pub bundle_result: OmenaQueryBundleResultV0,
1036    #[serde(skip_serializing_if = "Option::is_none")]
1037    pub execution_scope: Option<OmenaQueryBundleExecutionScopeEvidenceV0>,
1038    #[serde(skip_serializing_if = "Option::is_none")]
1039    pub reachability_attribution: Option<OmenaQueryModuleReachabilityAttributionReportV0>,
1040}
1041
1042#[derive(Debug, Clone, PartialEq, Eq, Serialize)]
1043#[serde(rename_all = "camelCase")]
1044#[non_exhaustive]
1045pub struct OmenaQueryModuleAttributedBundleResultV0 {
1046    bundle_result: OmenaQueryBundleResultV0,
1047    reachability_attribution: OmenaQueryModuleReachabilityAttributionReportV0,
1048}
1049
1050impl OmenaQueryModuleAttributedBundleResultV0 {
1051    pub(crate) fn new(
1052        bundle_result: OmenaQueryBundleResultV0,
1053        reachability_attribution: OmenaQueryModuleReachabilityAttributionReportV0,
1054    ) -> Self {
1055        Self {
1056            bundle_result,
1057            reachability_attribution,
1058        }
1059    }
1060
1061    pub fn bundle_result(&self) -> &OmenaQueryBundleResultV0 {
1062        &self.bundle_result
1063    }
1064
1065    pub fn reachability_attribution(&self) -> &OmenaQueryModuleReachabilityAttributionReportV0 {
1066        &self.reachability_attribution
1067    }
1068
1069    pub fn into_bundle_result(self) -> OmenaQueryBundleResultV0 {
1070        self.bundle_result
1071    }
1072}
1073
1074#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize)]
1075#[serde(rename_all = "camelCase")]
1076pub struct OmenaQueryClosedWorldDecisionParityV0 {
1077    pub legacy_open_decision: bool,
1078    pub typed_outcome_open: bool,
1079    pub equivalent: bool,
1080}
1081
1082#[derive(Debug, Clone, PartialEq, Eq, Serialize)]
1083#[serde(rename_all = "camelCase")]
1084pub struct OmenaQueryBundleEvidenceGateV0 {
1085    pub name: &'static str,
1086    pub passed: bool,
1087}
1088
1089#[derive(Debug, Clone, PartialEq, Eq, Serialize)]
1090#[serde(rename_all = "camelCase")]
1091pub struct OmenaQueryBundleReachabilityEvidenceV0 {
1092    pub guarantee: GuaranteeKindV0,
1093    pub interpretation: &'static str,
1094    pub module_instances: Vec<omena_parser::ModuleInstanceKeyV0>,
1095    pub closure_hash: String,
1096}
1097
1098#[derive(Debug, Clone, PartialEq, Eq, Serialize)]
1099#[serde(rename_all = "camelCase")]
1100pub struct OmenaQueryBundleEvidenceManifestV0 {
1101    pub schema_version: &'static str,
1102    pub product: &'static str,
1103    pub style_path: String,
1104    pub outcome_status: &'static str,
1105    pub reachability: Option<OmenaQueryBundleReachabilityEvidenceV0>,
1106    pub gates: Vec<OmenaQueryBundleEvidenceGateV0>,
1107    pub blockers: Vec<OmenaQueryClosedWorldBlockerV0>,
1108    pub interface_hashes: Vec<omena_parser::ClosedWorldInterfaceHashEntryV0>,
1109    pub source_precision: Option<omena_parser::ClosedWorldSourcePrecisionSummaryV0>,
1110}
1111
1112#[derive(Debug, Clone, PartialEq, Eq, Serialize)]
1113#[serde(rename_all = "camelCase")]
1114pub struct OmenaQueryBundleWithEvidenceV0 {
1115    #[serde(flatten)]
1116    pub artifact: OmenaQueryBundleArtifactV0,
1117    pub closed_world_outcome: OmenaQueryClosedWorldOutcomeV0,
1118    pub closed_world_decision_parity: OmenaQueryClosedWorldDecisionParityV0,
1119    pub evidence: OmenaQueryBundleEvidenceManifestV0,
1120}
1121
1122#[derive(Debug, Clone, PartialEq, Eq, Serialize)]
1123#[serde(rename_all = "camelCase")]
1124pub struct OmenaQueryBundleCodeSplitWorkspacePlanV0 {
1125    pub schema_version: &'static str,
1126    pub product: &'static str,
1127    pub primary_entry_style_path: String,
1128    pub configured_entry_count: usize,
1129    pub output_count: usize,
1130    pub shared_boundary_count: usize,
1131    pub outputs: Vec<OmenaQueryBundleCodeSplitWorkspacePlanOutputV0>,
1132    pub ready_surfaces: Vec<&'static str>,
1133}
1134
1135#[derive(Debug, Clone, PartialEq, Eq, Serialize)]
1136#[serde(rename_all = "camelCase")]
1137pub struct OmenaQueryBundleCodeSplitWorkspacePlanOutputV0 {
1138    pub source_path: String,
1139    pub is_entry: bool,
1140    pub split_boundary: &'static str,
1141    pub reachable_from_entries: Vec<String>,
1142}
1143
1144#[derive(Debug, Clone, PartialEq, Eq, Serialize)]
1145#[serde(rename_all = "camelCase")]
1146pub struct OmenaQueryTransformPassSummaryV0 {
1147    pub id: &'static str,
1148    pub title: &'static str,
1149    pub reads_semantic_graph: bool,
1150    pub reads_cascade_model: bool,
1151    pub explicit_opt_in_required: bool,
1152    pub dialect_restriction: Option<&'static str>,
1153    pub spec_snapshot: Option<&'static str>,
1154    pub opt_in_policy: Option<&'static str>,
1155}
1156
1157#[derive(Debug, Clone, PartialEq, Serialize)]
1158#[serde(rename_all = "camelCase")]
1159pub struct OmenaQueryTransformPlanSummaryV0 {
1160    pub schema_version: &'static str,
1161    pub product: &'static str,
1162    pub style_path: String,
1163    pub dialect: &'static str,
1164    pub bundle: TransformBundleSourceSummaryV0,
1165    pub target: TransformTargetPlanV0,
1166    pub target_query: Option<OmenaQueryTransformTargetQueryPlanV0>,
1167    pub egg: TransformEggPlanV0,
1168    pub egg_witnesses: Vec<EggRewriteSourceWitnessV0>,
1169    pub custom_property_fixed_point: OmenaQueryCustomPropertyLeastFixedPointSummaryV0,
1170    pub print: TransformPrintArtifactV0,
1171    pub execution: TransformExecutionSummaryV0,
1172    pub semantic_removal_count: usize,
1173    pub combined_plan: TransformPassPlanV0,
1174    pub combined_pass_ids: Vec<&'static str>,
1175    pub combined_violated_dag_edge_count: usize,
1176    pub ready_surfaces: Vec<&'static str>,
1177}
1178
1179#[derive(Debug, Clone, PartialEq, Eq, Serialize)]
1180#[serde(rename_all = "camelCase")]
1181pub struct OmenaQueryTransformExecuteSummaryV0 {
1182    pub schema_version: &'static str,
1183    pub product: &'static str,
1184    pub style_path: String,
1185    pub requested_pass_ids: Vec<String>,
1186    pub unknown_pass_ids: Vec<String>,
1187    pub execution: TransformExecutionSummaryV0,
1188    pub semantic_removal_count: usize,
1189    #[serde(skip_serializing_if = "Option::is_none")]
1190    pub open_world_snapshot: Option<OmenaQueryOpenWorldSnapshotV0>,
1191    pub ready_surfaces: Vec<&'static str>,
1192}
1193
1194#[cfg(feature = "transform-catalog-trace")]
1195#[derive(Debug, Clone, PartialEq, Serialize)]
1196#[serde(rename_all = "camelCase")]
1197pub struct OmenaQueryTransformCatalogTransformExecuteSummaryV0 {
1198    pub schema_version: &'static str,
1199    pub product: &'static str,
1200    pub product_scope: &'static str,
1201    pub default_product_mechanism: bool,
1202    pub global_transform_theorem_claimed: bool,
1203    pub execution: OmenaQueryTransformExecuteSummaryV0,
1204    /// Compatibility field owned by `omena-query` maintainers. Remove not
1205    /// before 1.0, after downstream migration and zero audited non-compat uses.
1206    #[deprecated(
1207        since = "0.4.0",
1208        note = "use transform_catalog_trace(); removal is not before 1.0 and requires downstream migration plus zero audited non-compatibility uses"
1209    )]
1210    pub lawvere_trace: OmenaQueryTransformCatalogModelTraceV0,
1211    pub parallel_plan: OmenaQueryTransformCatalogTransformPassParallelPlanV0,
1212    pub reorderability_certificates: Vec<OmenaQueryTransformCatalogReorderabilityCertificateV0>,
1213    pub differential_witnesses: Vec<OmenaQueryTransformCatalogDifferentialCommutativityWitnessV0>,
1214    pub ready_surfaces: Vec<&'static str>,
1215}
1216
1217/// Pre-1.0 nominal compatibility summary for the former trace surface.
1218/// Owner: `omena-query` maintainers. Removal condition: not before 1.0,
1219/// after downstream migration and zero audited in-repo non-compatibility uses.
1220#[cfg(feature = "transform-catalog-trace")]
1221#[allow(deprecated)]
1222#[deprecated(
1223    since = "0.4.0",
1224    note = "use OmenaQueryTransformCatalogTransformExecuteSummaryV0; removal is not before 1.0 and requires downstream migration plus zero audited non-compatibility uses"
1225)]
1226#[derive(Debug, Clone, PartialEq, Serialize)]
1227#[serde(rename_all = "camelCase")]
1228pub struct OmenaQueryLawvereTransformExecuteSummaryV0 {
1229    pub schema_version: &'static str,
1230    pub product: &'static str,
1231    pub product_scope: &'static str,
1232    pub default_product_mechanism: bool,
1233    pub global_transform_theorem_claimed: bool,
1234    pub execution: OmenaQueryTransformExecuteSummaryV0,
1235    pub lawvere_trace: omena_query_transform_runner::LawvereModelTraceV0,
1236    pub parallel_plan: omena_query_transform_runner::TransformPassParallelPlanV0,
1237    pub reorderability_certificates: Vec<omena_query_transform_runner::ReorderabilityCertificateV0>,
1238    pub differential_witnesses:
1239        Vec<omena_query_transform_runner::LawvereDifferentialCommutativityWitnessV0>,
1240    pub ready_surfaces: Vec<&'static str>,
1241}
1242
1243#[cfg(feature = "transform-catalog-trace")]
1244impl OmenaQueryTransformCatalogTransformExecuteSummaryV0 {
1245    #[allow(deprecated)]
1246    pub fn transform_catalog_trace(&self) -> &OmenaQueryTransformCatalogModelTraceV0 {
1247        transform_catalog_trace_from_legacy_field_v0(self)
1248    }
1249}
1250
1251#[cfg(feature = "transform-catalog-trace")]
1252#[allow(deprecated)]
1253#[deprecated(
1254    since = "0.4.0",
1255    note = "compatibility field adapter owned by omena-query maintainers; removal is not before 1.0 and requires downstream migration plus zero audited non-compatibility uses"
1256)]
1257fn transform_catalog_trace_from_legacy_field_v0(
1258    summary: &OmenaQueryTransformCatalogTransformExecuteSummaryV0,
1259) -> &OmenaQueryTransformCatalogModelTraceV0 {
1260    &summary.lawvere_trace
1261}
1262
1263#[derive(Debug, Clone, PartialEq, Eq, Serialize)]
1264#[serde(rename_all = "camelCase")]
1265pub struct OmenaQueryTransformContextFromSourcesSummaryV0 {
1266    pub schema_version: &'static str,
1267    pub product: &'static str,
1268    pub target_style_path: String,
1269    pub style_count: usize,
1270    pub context: TransformExecutionContextV0,
1271    pub import_inline_count: usize,
1272    pub class_name_rewrite_count: usize,
1273    pub css_module_composes_resolution_count: usize,
1274    pub css_module_value_resolution_count: usize,
1275    pub design_token_route_count: usize,
1276    pub reachable_class_name_count: usize,
1277    pub reachable_keyframe_name_count: usize,
1278    pub reachable_value_name_count: usize,
1279    pub reachable_custom_property_name_count: usize,
1280    pub ready_surfaces: Vec<&'static str>,
1281}
1282
1283#[derive(Debug, Clone, PartialEq, Eq, Serialize)]
1284#[serde(rename_all = "camelCase")]
1285pub struct OmenaQueryTransformContextFromEngineInputSummaryV0 {
1286    pub schema_version: &'static str,
1287    pub product: &'static str,
1288    pub input_version: String,
1289    pub target_style_path: String,
1290    pub closed_world_requested: bool,
1291    pub style_source_count: usize,
1292    pub projection_count: usize,
1293    pub selected_projection_count: usize,
1294    pub import_inline_count: usize,
1295    pub class_name_rewrite_count: usize,
1296    pub css_module_composes_resolution_count: usize,
1297    pub css_module_value_resolution_count: usize,
1298    pub design_token_route_count: usize,
1299    pub reachable_class_name_count: usize,
1300    pub reachable_keyframe_name_count: usize,
1301    pub reachable_value_name_count: usize,
1302    pub reachable_custom_property_name_count: usize,
1303    pub reachability_sources: Vec<OmenaQuerySemanticReachabilitySourceV0>,
1304    pub context: TransformExecutionContextV0,
1305    pub ready_surfaces: Vec<&'static str>,
1306}
1307
1308#[derive(Debug, Clone, PartialEq, Eq, Serialize)]
1309#[serde(rename_all = "camelCase")]
1310pub struct OmenaQuerySemanticReachabilitySourceV0 {
1311    pub graph_id: String,
1312    pub file_path: String,
1313    pub node_id: String,
1314    pub target_style_paths: Vec<String>,
1315    pub value_kind: &'static str,
1316    #[serde(skip_serializing_if = "Option::is_none")]
1317    pub reduced_product: Option<ReducedClassValueProductV0>,
1318    pub selector_names: Vec<String>,
1319    pub certainty: SelectorProjectionCertaintyV0,
1320}
1321
1322#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize)]
1323#[serde(rename_all = "camelCase")]
1324#[non_exhaustive]
1325pub enum OmenaQueryModuleReachabilityAttributionKindV0 {
1326    TargetedProjection,
1327    UnattributedProjectionFanout,
1328    TargetedAndUnattributedProjection,
1329    NoApplicableProjection,
1330}
1331
1332#[derive(Debug, Clone, PartialEq, Eq, Serialize)]
1333#[serde(rename_all = "camelCase")]
1334#[non_exhaustive]
1335pub struct OmenaQueryModuleReachabilityAttributionV0 {
1336    style_path: String,
1337    class_names: Vec<String>,
1338    targeted_projection_count: usize,
1339    unattributed_projection_count: usize,
1340    attribution_kind: OmenaQueryModuleReachabilityAttributionKindV0,
1341}
1342
1343impl OmenaQueryModuleReachabilityAttributionV0 {
1344    pub(crate) fn new(
1345        style_path: String,
1346        class_names: Vec<String>,
1347        targeted_projection_count: usize,
1348        unattributed_projection_count: usize,
1349    ) -> Self {
1350        let attribution_kind = match (
1351            targeted_projection_count > 0,
1352            unattributed_projection_count > 0,
1353        ) {
1354            (true, true) => {
1355                OmenaQueryModuleReachabilityAttributionKindV0::TargetedAndUnattributedProjection
1356            }
1357            (true, false) => OmenaQueryModuleReachabilityAttributionKindV0::TargetedProjection,
1358            (false, true) => {
1359                OmenaQueryModuleReachabilityAttributionKindV0::UnattributedProjectionFanout
1360            }
1361            (false, false) => OmenaQueryModuleReachabilityAttributionKindV0::NoApplicableProjection,
1362        };
1363        Self {
1364            style_path,
1365            class_names,
1366            targeted_projection_count,
1367            unattributed_projection_count,
1368            attribution_kind,
1369        }
1370    }
1371
1372    pub fn style_path(&self) -> &str {
1373        self.style_path.as_str()
1374    }
1375
1376    pub fn class_names(&self) -> &[String] {
1377        self.class_names.as_slice()
1378    }
1379
1380    pub fn targeted_projection_count(&self) -> usize {
1381        self.targeted_projection_count
1382    }
1383
1384    pub fn unattributed_projection_count(&self) -> usize {
1385        self.unattributed_projection_count
1386    }
1387
1388    pub fn attribution_kind(&self) -> OmenaQueryModuleReachabilityAttributionKindV0 {
1389        self.attribution_kind
1390    }
1391
1392    pub fn was_attempted(&self) -> bool {
1393        self.targeted_projection_count > 0 || self.unattributed_projection_count > 0
1394    }
1395}
1396
1397#[derive(Debug, Clone, PartialEq, Eq)]
1398pub(crate) struct OmenaQueryEngineInputModuleAttributionV0 {
1399    declared_class_names_by_style_path: BTreeMap<String, Vec<String>>,
1400    targeted_class_names_by_style_path: BTreeMap<String, Vec<String>>,
1401    targeted_projection_count_by_style_path: BTreeMap<String, usize>,
1402}
1403
1404impl OmenaQueryEngineInputModuleAttributionV0 {
1405    pub(crate) fn new(
1406        declared_class_names_by_style_path: BTreeMap<String, Vec<String>>,
1407        targeted_class_names_by_style_path: BTreeMap<String, Vec<String>>,
1408        targeted_projection_count_by_style_path: BTreeMap<String, usize>,
1409    ) -> Self {
1410        Self {
1411            declared_class_names_by_style_path,
1412            targeted_class_names_by_style_path,
1413            targeted_projection_count_by_style_path,
1414        }
1415    }
1416}
1417
1418#[derive(Debug, Clone, PartialEq, Eq)]
1419#[non_exhaustive]
1420pub struct OmenaQueryEngineInputModuleReachabilityV0 {
1421    summary: OmenaQueryTransformContextFromEngineInputSummaryV0,
1422    known_style_paths: Vec<String>,
1423    declared_class_names_by_style_path: BTreeMap<String, Vec<String>>,
1424    targeted_class_names_by_style_path: BTreeMap<String, Vec<String>>,
1425    targeted_projection_count_by_style_path: BTreeMap<String, usize>,
1426    unattributed_class_names: Vec<String>,
1427    unattributed_projection_count: usize,
1428    projected_class_names: Vec<String>,
1429    projection_summary_evaluation_count: usize,
1430}
1431
1432impl OmenaQueryEngineInputModuleReachabilityV0 {
1433    pub(crate) fn new(
1434        summary: OmenaQueryTransformContextFromEngineInputSummaryV0,
1435        known_style_paths: Vec<String>,
1436        module_attribution: OmenaQueryEngineInputModuleAttributionV0,
1437        unattributed_class_names: Vec<String>,
1438        unattributed_projection_count: usize,
1439        projected_class_names: Vec<String>,
1440    ) -> Self {
1441        let OmenaQueryEngineInputModuleAttributionV0 {
1442            declared_class_names_by_style_path,
1443            targeted_class_names_by_style_path,
1444            targeted_projection_count_by_style_path,
1445        } = module_attribution;
1446        Self {
1447            summary,
1448            known_style_paths,
1449            declared_class_names_by_style_path,
1450            targeted_class_names_by_style_path,
1451            targeted_projection_count_by_style_path,
1452            unattributed_class_names,
1453            unattributed_projection_count,
1454            projected_class_names,
1455            projection_summary_evaluation_count: 1,
1456        }
1457    }
1458
1459    pub fn summary(&self) -> &OmenaQueryTransformContextFromEngineInputSummaryV0 {
1460        &self.summary
1461    }
1462
1463    pub fn context(&self) -> &TransformExecutionContextV0 {
1464        &self.summary.context
1465    }
1466
1467    pub fn into_summary(self) -> OmenaQueryTransformContextFromEngineInputSummaryV0 {
1468        self.summary
1469    }
1470
1471    pub fn projected_class_names(&self) -> &[String] {
1472        self.projected_class_names.as_slice()
1473    }
1474
1475    pub fn projection_summary_evaluation_count(&self) -> usize {
1476        self.projection_summary_evaluation_count
1477    }
1478
1479    pub fn module_attribution(
1480        &self,
1481        style_path: &str,
1482    ) -> OmenaQueryModuleReachabilityAttributionV0 {
1483        let style_path = resolve_omena_query_style_path_against_known(
1484            style_path,
1485            self.known_style_paths.as_slice(),
1486        )
1487        .unwrap_or_else(|| normalize_omena_query_style_path(style_path));
1488        let mut class_names = self.unattributed_class_names.clone();
1489        if let Some(targeted_class_names) = self
1490            .targeted_class_names_by_style_path
1491            .get(style_path.as_str())
1492        {
1493            class_names.extend(targeted_class_names.iter().cloned());
1494        }
1495        class_names.sort();
1496        class_names.dedup();
1497        OmenaQueryModuleReachabilityAttributionV0::new(
1498            style_path.clone(),
1499            class_names,
1500            self.targeted_projection_count_by_style_path
1501                .get(style_path.as_str())
1502                .copied()
1503                .unwrap_or_default(),
1504            self.unattributed_projection_count,
1505        )
1506    }
1507
1508    pub(crate) fn targeted_style_paths(&self) -> impl Iterator<Item = &str> {
1509        self.targeted_projection_count_by_style_path
1510            .keys()
1511            .map(String::as_str)
1512    }
1513
1514    pub(crate) fn flat_class_names_for_style_paths<'a>(
1515        &self,
1516        style_paths: impl IntoIterator<Item = &'a str>,
1517        candidate_class_names: &[String],
1518    ) -> Vec<String> {
1519        let style_paths =
1520            module_attribution_domain_style_paths(style_paths, self.known_style_paths.as_slice());
1521
1522        candidate_class_names
1523            .iter()
1524            .filter(|class_name| {
1525                let mut declared_owner_paths = self
1526                    .declared_class_names_by_style_path
1527                    .iter()
1528                    .filter(|(_, names)| {
1529                        class_name_collection_contains(names.iter().map(String::as_str), class_name)
1530                    })
1531                    .map(|(style_path, _)| style_path);
1532                let Some(first_owner_path) = declared_owner_paths.next() else {
1533                    return true;
1534                };
1535                style_paths.contains(first_owner_path)
1536                    || declared_owner_paths.any(|style_path| style_paths.contains(style_path))
1537            })
1538            .cloned()
1539            .collect::<BTreeSet<_>>()
1540            .into_iter()
1541            .collect()
1542    }
1543}
1544
1545pub(crate) fn normalize_omena_query_style_path(style_path: &str) -> String {
1546    normalize_omena_transform_bundle_path(style_path)
1547}
1548
1549pub(crate) fn resolve_omena_query_style_path_against_known(
1550    style_path: &str,
1551    known_style_paths: &[String],
1552) -> Option<String> {
1553    let normalized = normalize_omena_query_style_path(style_path);
1554    unique_style_path_match(known_style_paths, |known| {
1555        normalize_omena_query_style_path(known) == normalized
1556    })
1557    .or_else(|| {
1558        unique_style_path_match(known_style_paths, |known| {
1559            normalize_omena_query_style_path(known).eq_ignore_ascii_case(normalized.as_str())
1560        })
1561    })
1562    .or_else(|| {
1563        unique_style_path_match(known_style_paths, |known| {
1564            style_path_component_suffix_matches(
1565                normalize_omena_query_style_path(known).as_str(),
1566                normalized.as_str(),
1567                false,
1568            )
1569        })
1570    })
1571    .or_else(|| {
1572        unique_style_path_match(known_style_paths, |known| {
1573            style_path_component_suffix_matches(
1574                normalize_omena_query_style_path(known).as_str(),
1575                normalized.as_str(),
1576                true,
1577            )
1578        })
1579    })
1580}
1581
1582fn attribution_domain_style_paths(style_path: &str, known_style_paths: &[String]) -> Vec<String> {
1583    let normalized = normalize_omena_query_style_path(style_path);
1584    for matches in [
1585        matching_style_paths(known_style_paths, |known| {
1586            normalize_omena_query_style_path(known) == normalized
1587        }),
1588        matching_style_paths(known_style_paths, |known| {
1589            normalize_omena_query_style_path(known).eq_ignore_ascii_case(normalized.as_str())
1590        }),
1591        matching_style_paths(known_style_paths, |known| {
1592            style_path_component_suffix_matches(
1593                normalize_omena_query_style_path(known).as_str(),
1594                normalized.as_str(),
1595                false,
1596            )
1597        }),
1598        matching_style_paths(known_style_paths, |known| {
1599            style_path_component_suffix_matches(
1600                normalize_omena_query_style_path(known).as_str(),
1601                normalized.as_str(),
1602                true,
1603            )
1604        }),
1605    ] {
1606        if !matches.is_empty() {
1607            return matches;
1608        }
1609    }
1610    vec![normalized]
1611}
1612
1613// Admission and placement share this domain so every admitted name either
1614// fans out as ownerless or has at least one matching entry to receive it.
1615fn module_attribution_domain_style_paths<'a>(
1616    style_paths: impl IntoIterator<Item = &'a str>,
1617    known_style_paths: &[String],
1618) -> BTreeSet<String> {
1619    style_paths
1620        .into_iter()
1621        .flat_map(|style_path| attribution_domain_style_paths(style_path, known_style_paths))
1622        .collect()
1623}
1624
1625fn matching_style_paths(
1626    known_style_paths: &[String],
1627    matches: impl Fn(&String) -> bool,
1628) -> Vec<String> {
1629    known_style_paths
1630        .iter()
1631        .filter(|known| matches(known))
1632        .map(|known| normalize_omena_query_style_path(known))
1633        .collect::<BTreeSet<_>>()
1634        .into_iter()
1635        .collect()
1636}
1637
1638fn unique_style_path_match(
1639    known_style_paths: &[String],
1640    matches: impl Fn(&String) -> bool,
1641) -> Option<String> {
1642    let mut matching = known_style_paths.iter().filter(|known| matches(known));
1643    let first = matching.next()?;
1644    matching.next().is_none().then(|| first.clone())
1645}
1646
1647fn style_path_component_suffix_matches(left: &str, right: &str, ignore_case: bool) -> bool {
1648    let left = left.trim_matches('/');
1649    let right = right.trim_matches('/');
1650    let (left, right) = if ignore_case {
1651        (left.to_ascii_lowercase(), right.to_ascii_lowercase())
1652    } else {
1653        (left.to_string(), right.to_string())
1654    };
1655    left == right
1656        || left
1657            .strip_suffix(right.as_str())
1658            .is_some_and(|prefix| prefix.ends_with('/'))
1659        || right
1660            .strip_suffix(left.as_str())
1661            .is_some_and(|prefix| prefix.ends_with('/'))
1662}
1663
1664#[derive(Debug, Clone, PartialEq, Eq, Serialize)]
1665#[serde(rename_all = "camelCase")]
1666#[non_exhaustive]
1667pub struct OmenaQueryModuleReachabilityAttributionReportV0 {
1668    entries: Vec<OmenaQueryModuleReachabilityAttributionV0>,
1669    projection_summary_evaluation_count: usize,
1670    projected_class_names: Vec<String>,
1671    unattributed_class_names: Vec<String>,
1672    flat_class_names: Vec<String>,
1673    attributed_class_names: Vec<String>,
1674    lost_class_names: Vec<String>,
1675    unmatched_target_style_paths: Vec<String>,
1676    attempted_module_count: usize,
1677    attributed_empty_module_count: usize,
1678}
1679
1680impl OmenaQueryModuleReachabilityAttributionReportV0 {
1681    pub(crate) fn from_style_paths<'a>(
1682        attribution: &OmenaQueryEngineInputModuleReachabilityV0,
1683        style_paths: impl IntoIterator<Item = &'a str>,
1684        flat_class_names: &[String],
1685    ) -> Self {
1686        let mut style_paths = module_attribution_domain_style_paths(
1687            style_paths,
1688            attribution.known_style_paths.as_slice(),
1689        )
1690        .into_iter()
1691        .collect::<Vec<_>>();
1692        style_paths.sort();
1693        style_paths.dedup();
1694        let mut entries = style_paths
1695            .iter()
1696            .map(|style_path| attribution.module_attribution(style_path))
1697            .collect::<Vec<_>>();
1698        entries.sort_by(|left, right| left.style_path().cmp(right.style_path()));
1699        entries.dedup_by(|left, right| left.style_path() == right.style_path());
1700
1701        let mut flat_class_names = flat_class_names.to_vec();
1702        flat_class_names.sort();
1703        flat_class_names.dedup();
1704        let directly_attributed_class_names = entries
1705            .iter()
1706            .flat_map(|entry| entry.class_names.iter().cloned())
1707            .collect::<BTreeSet<_>>();
1708        for class_name in &flat_class_names {
1709            if class_name_collection_contains(
1710                directly_attributed_class_names.iter().map(String::as_str),
1711                class_name,
1712            ) {
1713                continue;
1714            }
1715            let declared_owner_paths = attribution
1716                .declared_class_names_by_style_path
1717                .iter()
1718                .filter(|(_, names)| {
1719                    class_name_collection_contains(names.iter().map(String::as_str), class_name)
1720                })
1721                .map(|(style_path, _)| normalize_omena_query_style_path(style_path))
1722                .collect::<BTreeSet<_>>();
1723            for entry in &mut entries {
1724                if declared_owner_paths.is_empty()
1725                    || declared_owner_paths
1726                        .contains(&normalize_omena_query_style_path(entry.style_path.as_str()))
1727                {
1728                    entry.class_names.push(class_name.clone());
1729                    entry.class_names.sort();
1730                    entry.class_names.dedup();
1731                }
1732            }
1733        }
1734
1735        let style_path_set = entries
1736            .iter()
1737            .map(OmenaQueryModuleReachabilityAttributionV0::style_path)
1738            .collect::<BTreeSet<_>>();
1739        let attributed_class_names = entries
1740            .iter()
1741            .flat_map(|entry| entry.class_names.iter().cloned())
1742            .collect::<BTreeSet<_>>()
1743            .into_iter()
1744            .collect::<Vec<_>>();
1745        let unmatched_target_style_paths = attribution
1746            .targeted_style_paths()
1747            .filter(|path| !style_path_set.contains(path))
1748            .map(str::to_string)
1749            .collect::<Vec<_>>();
1750        let attempted_module_count = entries.iter().filter(|entry| entry.was_attempted()).count();
1751        let attributed_empty_module_count = entries
1752            .iter()
1753            .filter(|entry| entry.was_attempted() && entry.class_names.is_empty())
1754            .count();
1755        Self {
1756            entries,
1757            projection_summary_evaluation_count: attribution.projection_summary_evaluation_count(),
1758            projected_class_names: attribution.projected_class_names.clone(),
1759            unattributed_class_names: attribution.unattributed_class_names.clone(),
1760            flat_class_names,
1761            attributed_class_names,
1762            lost_class_names: Vec::new(),
1763            unmatched_target_style_paths,
1764            attempted_module_count,
1765            attributed_empty_module_count,
1766        }
1767    }
1768
1769    pub fn entries(&self) -> &[OmenaQueryModuleReachabilityAttributionV0] {
1770        self.entries.as_slice()
1771    }
1772
1773    pub fn entry_for_style_path(
1774        &self,
1775        style_path: &str,
1776    ) -> Option<&OmenaQueryModuleReachabilityAttributionV0> {
1777        let known_style_paths = self
1778            .entries
1779            .iter()
1780            .map(|entry| entry.style_path().to_string())
1781            .collect::<Vec<_>>();
1782        let style_path =
1783            resolve_omena_query_style_path_against_known(style_path, known_style_paths.as_slice())
1784                .unwrap_or_else(|| normalize_omena_query_style_path(style_path));
1785        self.entries
1786            .binary_search_by(|entry| entry.style_path().cmp(style_path.as_str()))
1787            .ok()
1788            .map(|index| &self.entries[index])
1789    }
1790
1791    pub fn projection_summary_evaluation_count(&self) -> usize {
1792        self.projection_summary_evaluation_count
1793    }
1794
1795    pub fn projected_class_names(&self) -> &[String] {
1796        self.projected_class_names.as_slice()
1797    }
1798
1799    /// Names from source projections that could not be assigned to one style module.
1800    pub fn unattributed_class_names(&self) -> &[String] {
1801        self.unattributed_class_names.as_slice()
1802    }
1803
1804    /// Class names whose declared owners intersect the current build-source domain.
1805    pub fn flat_class_names(&self) -> &[String] {
1806        self.flat_class_names.as_slice()
1807    }
1808
1809    pub fn attributed_class_names(&self) -> &[String] {
1810        self.attributed_class_names.as_slice()
1811    }
1812
1813    /// Always-empty compatibility view for the shared admission/placement domain.
1814    ///
1815    /// This does not establish whether linked output retained every live declaration;
1816    /// emission-level checks own that separate guarantee.
1817    pub fn lost_class_names(&self) -> &[String] {
1818        self.lost_class_names.as_slice()
1819    }
1820
1821    pub fn unmatched_target_style_paths(&self) -> &[String] {
1822        self.unmatched_target_style_paths.as_slice()
1823    }
1824
1825    pub fn attempted_module_count(&self) -> usize {
1826        self.attempted_module_count
1827    }
1828
1829    pub fn attributed_empty_module_count(&self) -> usize {
1830        self.attributed_empty_module_count
1831    }
1832}
1833
1834fn class_name_collection_contains<'a>(
1835    names: impl IntoIterator<Item = &'a str>,
1836    candidate: &str,
1837) -> bool {
1838    let candidate = omena_syntax::ident::ClassNameV0::new(candidate);
1839    names
1840        .into_iter()
1841        .any(|name| omena_syntax::ident::ClassNameV0::new(name).same_as(&candidate))
1842}
1843
1844#[derive(Debug, Clone, PartialEq, Eq, Deserialize, Serialize)]
1845#[serde(rename_all = "camelCase")]
1846pub struct OmenaQueryStyleSourceInputV0 {
1847    pub style_path: String,
1848    pub style_source: String,
1849}
1850
1851#[derive(Debug, Clone, PartialEq, Eq, Deserialize, Serialize)]
1852#[serde(rename_all = "camelCase")]
1853pub struct OmenaQueryExternalSifInputV0 {
1854    pub canonical_url: String,
1855    pub sif: OmenaSifV1,
1856}
1857
1858#[derive(Debug, Clone, PartialEq, Eq, Deserialize, Serialize)]
1859#[serde(rename_all = "camelCase")]
1860pub struct OmenaQuerySourceDocumentInputV0 {
1861    pub source_path: String,
1862    pub source_source: String,
1863    /// Precomputed source syntax facts from the LSP workspace/source index. When
1864    /// present, query consumers can avoid reparsing source text while preserving
1865    /// the existing text-backed fallback for non-indexed callers.
1866    #[serde(default, skip_deserializing, skip_serializing_if = "Option::is_none")]
1867    pub source_syntax_index: Option<OmenaQuerySourceSyntaxIndexV0>,
1868    #[serde(default)]
1869    pub has_unresolved_style_import: bool,
1870}
1871
1872#[derive(Debug, Clone, Serialize)]
1873#[serde(rename_all = "camelCase")]
1874pub struct OmenaQueryOmenaParserStyleFactsV0 {
1875    pub schema_version: &'static str,
1876    pub product: &'static str,
1877    pub dialect: &'static str,
1878    pub class_selector_names: Vec<String>,
1879    pub id_selector_names: Vec<String>,
1880    pub placeholder_selector_names: Vec<String>,
1881    pub keyframe_names: Vec<String>,
1882    pub animation_reference_names: Vec<String>,
1883    pub css_module_value_definition_names: Vec<String>,
1884    pub css_module_value_reference_names: Vec<String>,
1885    pub css_module_value_import_sources: Vec<String>,
1886    pub css_module_value_import_edges: Vec<OmenaQueryCssModuleValueImportEdgeFactV0>,
1887    pub css_module_value_definition_edges: Vec<OmenaQueryCssModuleValueDefinitionEdgeFactV0>,
1888    pub css_module_composes_target_names: Vec<String>,
1889    pub css_module_composes_import_sources: Vec<String>,
1890    pub css_module_composes_edges: Vec<OmenaQueryCssModuleComposesEdgeFactV0>,
1891    pub icss_export_names: Vec<String>,
1892    pub icss_import_local_names: Vec<String>,
1893    pub icss_import_remote_names: Vec<String>,
1894    pub icss_import_sources: Vec<String>,
1895    pub icss_import_edges: Vec<OmenaQueryIcssImportEdgeFactV0>,
1896    pub icss_export_edges: Vec<OmenaQueryIcssExportEdgeFactV0>,
1897    pub variable_names: Vec<String>,
1898    pub sass_symbol_declaration_names: Vec<String>,
1899    pub sass_symbol_reference_names: Vec<String>,
1900    pub sass_symbol_facts: Vec<OmenaQuerySassSymbolFactV0>,
1901    pub sass_symbol_resolution: OmenaQuerySassSymbolResolutionV0,
1902    pub sass_module_use_sources: Vec<String>,
1903    pub sass_module_forward_sources: Vec<String>,
1904    pub sass_module_import_sources: Vec<String>,
1905    pub sass_module_edges: Vec<OmenaQuerySassModuleEdgeFactV0>,
1906    pub custom_property_names: Vec<AuthoredPropertyTextV0>,
1907    pub custom_property_decl_names: Vec<AuthoredPropertyTextV0>,
1908    pub custom_property_ref_names: Vec<AuthoredPropertyTextV0>,
1909    pub at_rule_names: Vec<String>,
1910    pub parser_error_count: usize,
1911}
1912
1913impl PartialEq for OmenaQueryOmenaParserStyleFactsV0 {
1914    fn eq(&self, other: &Self) -> bool {
1915        self.schema_version == other.schema_version
1916            && self.product == other.product
1917            && self.dialect == other.dialect
1918            && self.class_selector_names == other.class_selector_names
1919            && self.id_selector_names == other.id_selector_names
1920            && self.placeholder_selector_names == other.placeholder_selector_names
1921            && self.keyframe_names == other.keyframe_names
1922            && self.animation_reference_names == other.animation_reference_names
1923            && self.css_module_value_definition_names == other.css_module_value_definition_names
1924            && self.css_module_value_reference_names == other.css_module_value_reference_names
1925            && self.css_module_value_import_sources == other.css_module_value_import_sources
1926            && self.css_module_value_import_edges == other.css_module_value_import_edges
1927            && self.css_module_value_definition_edges == other.css_module_value_definition_edges
1928            && self.css_module_composes_target_names == other.css_module_composes_target_names
1929            && self.css_module_composes_import_sources == other.css_module_composes_import_sources
1930            && self.css_module_composes_edges == other.css_module_composes_edges
1931            && self.icss_export_names == other.icss_export_names
1932            && self.icss_import_local_names == other.icss_import_local_names
1933            && self.icss_import_remote_names == other.icss_import_remote_names
1934            && self.icss_import_sources == other.icss_import_sources
1935            && self.icss_import_edges == other.icss_import_edges
1936            && self.icss_export_edges == other.icss_export_edges
1937            && self.variable_names == other.variable_names
1938            && self.sass_symbol_declaration_names == other.sass_symbol_declaration_names
1939            && self.sass_symbol_reference_names == other.sass_symbol_reference_names
1940            && self.sass_symbol_facts == other.sass_symbol_facts
1941            && self.sass_symbol_resolution == other.sass_symbol_resolution
1942            && self.sass_module_use_sources == other.sass_module_use_sources
1943            && self.sass_module_forward_sources == other.sass_module_forward_sources
1944            && self.sass_module_import_sources == other.sass_module_import_sources
1945            && self.sass_module_edges == other.sass_module_edges
1946            && authored_custom_property_sequences_same(
1947                &self.custom_property_names,
1948                &other.custom_property_names,
1949            )
1950            && authored_custom_property_sequences_same(
1951                &self.custom_property_decl_names,
1952                &other.custom_property_decl_names,
1953            )
1954            && authored_custom_property_sequences_same(
1955                &self.custom_property_ref_names,
1956                &other.custom_property_ref_names,
1957            )
1958            && self.at_rule_names == other.at_rule_names
1959            && self.parser_error_count == other.parser_error_count
1960    }
1961}
1962
1963impl Eq for OmenaQueryOmenaParserStyleFactsV0 {}
1964
1965fn authored_custom_property_sequences_same(
1966    left: &[AuthoredPropertyTextV0],
1967    right: &[AuthoredPropertyTextV0],
1968) -> bool {
1969    left.len() == right.len()
1970        && left
1971            .iter()
1972            .zip(right)
1973            .all(|(left, right)| left.to_custom_key() == right.to_custom_key())
1974}
1975
1976#[derive(Debug, Clone, PartialEq, Eq, Serialize)]
1977#[serde(rename_all = "camelCase")]
1978pub struct OmenaQuerySassSymbolFactV0 {
1979    pub kind: &'static str,
1980    pub symbol_kind: &'static str,
1981    pub name: String,
1982    pub role: &'static str,
1983    pub namespace: Option<String>,
1984}
1985
1986#[derive(Debug, Clone, PartialEq, Eq, Serialize)]
1987#[serde(rename_all = "camelCase")]
1988pub struct OmenaQuerySassSymbolResolutionV0 {
1989    pub schema_version: &'static str,
1990    pub product: &'static str,
1991    pub resolution_scope: &'static str,
1992    pub declaration_count: usize,
1993    pub reference_count: usize,
1994    pub resolved_reference_count: usize,
1995    pub unresolved_reference_count: usize,
1996    pub edges: Vec<OmenaQuerySassSymbolResolutionEdgeV0>,
1997    pub capabilities: OmenaQuerySassSymbolResolutionCapabilitiesV0,
1998}
1999
2000#[derive(Debug, Clone, PartialEq, Eq, Serialize)]
2001#[serde(rename_all = "camelCase")]
2002pub struct OmenaQuerySassSymbolResolutionEdgeV0 {
2003    pub symbol_kind: &'static str,
2004    pub name: String,
2005    pub namespace: Option<String>,
2006    pub reference_kind: &'static str,
2007    pub reference_role: &'static str,
2008    pub reference_source_order: usize,
2009    pub declaration_kind: Option<&'static str>,
2010    pub declaration_source_order: Option<usize>,
2011    pub status: &'static str,
2012}
2013
2014#[derive(Debug, Clone, PartialEq, Eq, Serialize)]
2015#[serde(rename_all = "camelCase")]
2016pub struct OmenaQuerySassSymbolResolutionCapabilitiesV0 {
2017    pub same_file_lexical_resolution_ready: bool,
2018    pub declaration_before_reference_ready: bool,
2019    pub unresolved_reference_reporting_ready: bool,
2020    pub cross_file_module_resolution_ready: bool,
2021}
2022
2023#[derive(Debug, Clone, PartialEq, Eq, Serialize)]
2024#[serde(rename_all = "camelCase")]
2025pub struct OmenaQuerySassModuleEdgeFactV0 {
2026    pub kind: &'static str,
2027    pub source: String,
2028    pub namespace_kind: Option<&'static str>,
2029    pub namespace: Option<String>,
2030    pub forward_prefix: Option<String>,
2031    pub visibility_filter_kind: Option<&'static str>,
2032    pub visibility_filter_names: Vec<String>,
2033}
2034
2035#[derive(Debug, Clone, PartialEq, Eq, Serialize)]
2036#[serde(rename_all = "camelCase")]
2037pub struct OmenaQuerySassModuleSourceEdgeV0 {
2038    pub kind: &'static str,
2039    pub source: String,
2040    pub byte_span: ParserByteSpanV0,
2041    pub namespace_kind: Option<&'static str>,
2042    pub namespace: Option<String>,
2043    pub forward_prefix: Option<String>,
2044    pub visibility_filter_kind: Option<&'static str>,
2045    pub visibility_filter_names: Vec<String>,
2046    pub media_qualified: bool,
2047}
2048
2049#[derive(Debug, Clone, PartialEq, Eq, Serialize)]
2050#[serde(rename_all = "camelCase")]
2051pub struct OmenaQueryCssModuleValueImportEdgeFactV0 {
2052    pub remote_name: String,
2053    pub local_name: String,
2054    pub import_source: String,
2055}
2056
2057#[derive(Debug, Clone, PartialEq, Eq, Serialize)]
2058#[serde(rename_all = "camelCase")]
2059pub struct OmenaQueryCssModuleValueDefinitionEdgeFactV0 {
2060    pub definition_name: String,
2061    pub reference_names: Vec<String>,
2062}
2063
2064#[derive(Debug, Clone, PartialEq, Eq, Serialize)]
2065#[serde(rename_all = "camelCase")]
2066pub struct OmenaQueryCssModuleComposesEdgeFactV0 {
2067    pub kind: &'static str,
2068    pub owner_selector_names: Vec<String>,
2069    pub target_names: Vec<String>,
2070    pub import_source: Option<String>,
2071}
2072
2073#[derive(Debug, Clone, PartialEq, Eq, Serialize)]
2074#[serde(rename_all = "camelCase")]
2075pub struct OmenaQueryIcssImportEdgeFactV0 {
2076    pub local_name: String,
2077    pub remote_name: String,
2078    pub import_source: String,
2079}
2080
2081#[derive(Debug, Clone, PartialEq, Eq, Serialize)]
2082#[serde(rename_all = "camelCase")]
2083pub struct OmenaQueryIcssExportEdgeFactV0 {
2084    pub export_name: String,
2085    pub reference_names: Vec<String>,
2086}
2087
2088#[derive(Debug, Clone, Serialize)]
2089#[serde(rename_all = "camelCase")]
2090pub struct OmenaQueryStyleHoverCandidateV0 {
2091    pub kind: &'static str,
2092    pub name: AuthoredPropertyTextV0,
2093    #[serde(skip)]
2094    pub selector_key: Option<CanonicalClassKeyV0>,
2095    #[serde(skip_serializing_if = "Option::is_none")]
2096    pub property_key: Option<CanonicalCustomPropertyNameV0>,
2097    pub range: ParserRangeV0,
2098    pub source: &'static str,
2099    pub namespace: Option<String>,
2100}
2101
2102#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord)]
2103enum OmenaQueryStyleHoverCandidateIdentityRefV0<'candidate> {
2104    Selector(Option<&'candidate CanonicalClassKeyV0>),
2105    CustomProperty(Option<&'candidate CanonicalCustomPropertyNameV0>),
2106    Other,
2107}
2108
2109impl OmenaQueryStyleHoverCandidateV0 {
2110    fn identity(&self) -> OmenaQueryStyleHoverCandidateIdentityRefV0<'_> {
2111        if self.kind == "selector" {
2112            OmenaQueryStyleHoverCandidateIdentityRefV0::Selector(self.selector_key.as_ref())
2113        } else if matches!(
2114            self.kind,
2115            "customPropertyDeclaration" | "customPropertyReference"
2116        ) {
2117            OmenaQueryStyleHoverCandidateIdentityRefV0::CustomProperty(self.property_key.as_ref())
2118        } else {
2119            OmenaQueryStyleHoverCandidateIdentityRefV0::Other
2120        }
2121    }
2122}
2123
2124impl PartialEq for OmenaQueryStyleHoverCandidateV0 {
2125    fn eq(&self, other: &Self) -> bool {
2126        self.kind == other.kind
2127            && self.identity() == other.identity()
2128            && self.range == other.range
2129            && self.source == other.source
2130            && self.namespace == other.namespace
2131    }
2132}
2133
2134impl Eq for OmenaQueryStyleHoverCandidateV0 {}
2135
2136impl Ord for OmenaQueryStyleHoverCandidateV0 {
2137    fn cmp(&self, other: &Self) -> Ordering {
2138        (
2139            self.kind,
2140            self.identity(),
2141            self.range,
2142            self.source,
2143            &self.namespace,
2144        )
2145            .cmp(&(
2146                other.kind,
2147                other.identity(),
2148                other.range,
2149                other.source,
2150                &other.namespace,
2151            ))
2152    }
2153}
2154
2155impl PartialOrd for OmenaQueryStyleHoverCandidateV0 {
2156    fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
2157        Some(self.cmp(other))
2158    }
2159}
2160
2161#[derive(Debug, Clone, PartialEq, Eq, Serialize)]
2162#[serde(rename_all = "camelCase")]
2163pub struct OmenaQueryStyleHoverCandidatesV0 {
2164    pub schema_version: &'static str,
2165    pub product: &'static str,
2166    pub language: &'static str,
2167    pub candidates: Vec<OmenaQueryStyleHoverCandidateV0>,
2168}
2169
2170#[derive(Debug, Clone, PartialEq, Eq, Serialize)]
2171#[serde(rename_all = "camelCase")]
2172pub struct OmenaQueryStyleHoverRenderPartsV0 {
2173    pub schema_version: &'static str,
2174    pub product: &'static str,
2175    pub snippet: String,
2176    pub value: Option<String>,
2177    pub signature: Option<String>,
2178    #[serde(skip_serializing_if = "Vec::is_empty")]
2179    pub property_value_narrowings: Vec<AbstractPropertyValueNarrowingV0>,
2180    pub render_source: &'static str,
2181}
2182
2183#[derive(Debug, Clone, Serialize)]
2184#[serde(rename_all = "camelCase")]
2185pub struct OmenaQueryCascadeNarrowingEvidenceV0 {
2186    pub schema_version: &'static str,
2187    pub product: &'static str,
2188    pub selector: String,
2189    pub selector_class_names: Vec<String>,
2190    pub property_name: AuthoredPropertyTextV0,
2191    pub property_key: CanonicalPropertyKeyV0,
2192    pub condition_context: Vec<String>,
2193    pub declaration_ids: Vec<String>,
2194    pub element_class_iteration: ReducedClassValueProductIterationV0,
2195    pub property_value_narrowing: AbstractPropertyValueNarrowingV0,
2196    #[serde(skip_serializing_if = "Option::is_none")]
2197    pub runtime_state: Option<OmenaQueryRuntimeStateScenarioEvidenceV0>,
2198}
2199
2200impl PartialEq for OmenaQueryCascadeNarrowingEvidenceV0 {
2201    fn eq(&self, other: &Self) -> bool {
2202        self.schema_version == other.schema_version
2203            && self.product == other.product
2204            && self.selector == other.selector
2205            && self.selector_class_names.eq(&other.selector_class_names)
2206            && self.property_key == other.property_key
2207            && self.condition_context == other.condition_context
2208            && self.declaration_ids == other.declaration_ids
2209            && self.element_class_iteration == other.element_class_iteration
2210            && self.property_value_narrowing == other.property_value_narrowing
2211            && self.runtime_state == other.runtime_state
2212    }
2213}
2214
2215impl Eq for OmenaQueryCascadeNarrowingEvidenceV0 {}
2216
2217#[derive(Debug, Clone, PartialEq, Eq, Serialize)]
2218#[serde(rename_all = "camelCase")]
2219pub struct OmenaQueryStaticConditionPruningEvidenceV0 {
2220    pub schema_version: &'static str,
2221    pub product: &'static str,
2222    pub condition_context: Vec<String>,
2223    pub assumption: &'static str,
2224    pub verdict: &'static str,
2225    pub pruned: bool,
2226    pub anchor_context: bool,
2227}
2228
2229/// Why a cascade result could not use a complete named-layer ordering.
2230#[derive(Debug, Clone, PartialEq, Eq, Serialize)]
2231#[serde(rename_all = "camelCase")]
2232pub struct OmenaQueryCascadeLayerTopologyIncompleteV0 {
2233    /// Number of unresolved layer-topology facts observed by the semantic index.
2234    pub unresolved_count: usize,
2235}
2236
2237#[derive(Debug, Clone)]
2238pub struct OmenaQueryRuntimeStateScenarioEvidenceV0 {
2239    pub schema_version: &'static str,
2240    pub product: &'static str,
2241    pub selector: String,
2242    pub selector_class_names: Vec<String>,
2243    pub property_name: AuthoredPropertyTextV0,
2244    pub scenario_join_kind: &'static str,
2245    pub confidence_tier: &'static str,
2246    pub confidence_tier_within_modeled_environment: &'static str,
2247    pub static_boundary: OmenaQueryRuntimeStateStaticBoundaryV0,
2248    pub driver_summaries: Vec<OmenaQueryRuntimeStateDriverSummaryV0>,
2249    pub scenarios: Vec<OmenaQueryRuntimeStateScenarioV0>,
2250    pub static_condition_pruning: Vec<OmenaQueryStaticConditionPruningEvidenceV0>,
2251    pub inline_style_overrides: Vec<OmenaQueryInlineStyleRuntimeOverrideV0>,
2252    pub cascade_layer_topology_incomplete: Option<OmenaQueryCascadeLayerTopologyIncompleteV0>,
2253    pub guarded_winner_authority: Option<omena_cascade::GuardedCascadeWinnerAuthorityV0>,
2254    pub fragile_guarded_winner_diagnostics: Vec<OmenaQueryFragileGuardedWinnerDiagnosticV0>,
2255}
2256
2257impl PartialEq for OmenaQueryRuntimeStateScenarioEvidenceV0 {
2258    fn eq(&self, other: &Self) -> bool {
2259        self.schema_version == other.schema_version
2260            && self.product == other.product
2261            && self.selector == other.selector
2262            && self.selector_class_names == other.selector_class_names
2263            && self
2264                .property_name
2265                .to_property_name()
2266                .same_as(&other.property_name.to_property_name())
2267            && self.scenario_join_kind == other.scenario_join_kind
2268            && self.confidence_tier == other.confidence_tier
2269            && self.confidence_tier_within_modeled_environment
2270                == other.confidence_tier_within_modeled_environment
2271            && self.static_boundary == other.static_boundary
2272            && self.driver_summaries == other.driver_summaries
2273            && self.scenarios == other.scenarios
2274            && self.static_condition_pruning == other.static_condition_pruning
2275            && self.inline_style_overrides == other.inline_style_overrides
2276            && self.cascade_layer_topology_incomplete == other.cascade_layer_topology_incomplete
2277            && self.guarded_winner_authority == other.guarded_winner_authority
2278            && self.fragile_guarded_winner_diagnostics == other.fragile_guarded_winner_diagnostics
2279    }
2280}
2281
2282impl Eq for OmenaQueryRuntimeStateScenarioEvidenceV0 {}
2283
2284#[derive(Debug, Clone, PartialEq, Eq, Serialize)]
2285#[serde(rename_all = "camelCase")]
2286pub struct OmenaQueryRuntimeStateStaticBoundaryV0 {
2287    pub boundary_kind: &'static str,
2288    pub static_value_assuming_no_runtime_override: bool,
2289    pub tracks_dom_mutation: bool,
2290    pub tracks_class_list_mutation: bool,
2291}
2292
2293#[derive(Debug, Clone, PartialEq, Eq, Serialize)]
2294#[serde(rename_all = "camelCase")]
2295pub struct OmenaQueryRuntimeStateDriverSummaryV0 {
2296    pub driver: &'static str,
2297    pub status: &'static str,
2298    pub scenario_count: usize,
2299    pub provenance: Vec<&'static str>,
2300}
2301
2302#[derive(Debug, Clone, PartialEq, Eq)]
2303pub struct OmenaQueryRuntimeStateScenarioV0 {
2304    pub scenario_kind: &'static str,
2305    pub pseudo_state: Option<String>,
2306    pub condition_context: Vec<String>,
2307    pub declaration_ids: Vec<String>,
2308    pub winner_declaration_id: Option<String>,
2309    pub winner_value: Option<String>,
2310    pub property_value_narrowing: AbstractPropertyValueNarrowingV0,
2311}
2312
2313#[derive(Debug, Clone, Serialize)]
2314#[serde(rename_all = "camelCase")]
2315pub struct OmenaQueryInlineStyleRuntimeOverrideV0 {
2316    pub source_path: String,
2317    pub range: ParserRangeV0,
2318    pub property_name: AuthoredPropertyTextV0,
2319    pub value: Option<String>,
2320    pub cascade_tier: &'static str,
2321    /// Whether the static source text ended with a CSS `!important` suffix.
2322    ///
2323    /// This is a source-text observation, not a claim about browser setter behavior.
2324    pub important: bool,
2325    pub static_value: bool,
2326}
2327
2328impl PartialEq for OmenaQueryInlineStyleRuntimeOverrideV0 {
2329    fn eq(&self, other: &Self) -> bool {
2330        self.source_path == other.source_path
2331            && self.range == other.range
2332            && self
2333                .property_name
2334                .to_property_name()
2335                .same_as(&other.property_name.to_property_name())
2336            && self.value == other.value
2337            && self.cascade_tier == other.cascade_tier
2338            && self.important == other.important
2339            && self.static_value == other.static_value
2340    }
2341}
2342
2343impl Eq for OmenaQueryInlineStyleRuntimeOverrideV0 {}
2344
2345impl OmenaQueryInlineStyleRuntimeOverrideV0 {
2346    /// Whether the originating static source text ended with `!important`.
2347    ///
2348    /// The flag describes source syntax, not browser setter behavior.
2349    pub fn important_suffix_present(&self) -> bool {
2350        self.important
2351    }
2352}
2353
2354#[derive(Debug, Clone, PartialEq, Eq, Serialize)]
2355#[serde(rename_all = "camelCase")]
2356pub struct OmenaQueryStyleDiagnosticV0 {
2357    pub code: &'static str,
2358    pub severity: &'static str,
2359    pub provenance: Vec<&'static str>,
2360    pub range: ParserRangeV0,
2361    pub message: String,
2362    #[serde(skip_serializing_if = "Vec::is_empty")]
2363    pub tags: Vec<u8>,
2364    pub create_custom_property: Option<OmenaQueryCreateCustomPropertyActionV0>,
2365    #[serde(skip_serializing_if = "Option::is_none")]
2366    pub cascade_narrowing: Option<OmenaQueryCascadeNarrowingEvidenceV0>,
2367    #[serde(skip_serializing_if = "Option::is_none")]
2368    pub cascade_confidence: Option<OmenaQueryCascadeConfidenceV0>,
2369    #[serde(skip_serializing_if = "Option::is_none")]
2370    pub polynomial_provenance: Option<OmenaQueryPolynomialProvenanceV0>,
2371    #[serde(skip_serializing_if = "Option::is_none")]
2372    pub cross_file_scc: Option<OmenaQueryCrossFileSccEvidenceV0>,
2373}
2374
2375pub type OmenaQueryLinearProvenanceV0 = LinearProvenanceV0<NaturalCountProvenanceSemiringV0>;
2376pub type OmenaQueryPolynomialProvenanceV0 = PolynomialProvenanceV0;
2377
2378pub fn summarize_omena_query_linear_provenance(
2379    provenance: &[&'static str],
2380) -> OmenaQueryLinearProvenanceV0 {
2381    let labels = project_omena_query_diagnostic_provenance_from_evidence_graph(
2382        "linearProvenance",
2383        provenance.to_vec(),
2384    );
2385    summarize_omena_query_linear_provenance_with_support_count(labels.as_slice(), 1)
2386}
2387
2388pub fn summarize_omena_query_linear_provenance_with_support_count(
2389    provenance: &[&'static str],
2390    support_count: u8,
2391) -> OmenaQueryLinearProvenanceV0 {
2392    let path = if support_count == 0 {
2393        LinearProvenancePathV0::unsupported(provenance)
2394    } else {
2395        LinearProvenancePathV0::supported(provenance, support_count)
2396    };
2397    OmenaQueryLinearProvenanceV0::from_composed_paths(&[path])
2398}
2399
2400pub fn summarize_omena_query_polynomial_provenance(
2401    provenance: &[&'static str],
2402) -> OmenaQueryPolynomialProvenanceV0 {
2403    let labels = project_omena_query_diagnostic_provenance_from_evidence_graph(
2404        "polynomialProvenance",
2405        provenance.to_vec(),
2406    );
2407    let linear_provenance = summarize_omena_query_linear_provenance(labels.as_slice());
2408    summarize_polynomial_provenance_from_linear_v0(&linear_provenance, "diagnosticDefaultThreeTier")
2409}
2410
2411pub fn summarize_omena_query_linear_provenance_semiring_laws() -> ProvenanceSemiringLawReportV0 {
2412    verify_provenance_semiring_laws_on_fixtures(
2413        &NaturalCountProvenanceSemiringV0::new(),
2414        &[0, 1, 2, 3],
2415    )
2416}
2417
2418pub fn round_trip_omena_query_linear_provenance_labels(
2419    linear_provenance: &OmenaQueryLinearProvenanceV0,
2420) -> Vec<&'static str> {
2421    linear_provenance.labels()
2422}
2423
2424impl OmenaQueryStyleDiagnosticV0 {
2425    pub fn linear_provenance(&self) -> OmenaQueryLinearProvenanceV0 {
2426        summarize_omena_query_linear_provenance(self.provenance.as_slice())
2427    }
2428
2429    pub fn polynomial_provenance(&self) -> OmenaQueryPolynomialProvenanceV0 {
2430        summarize_omena_query_polynomial_provenance(self.provenance.as_slice())
2431    }
2432}
2433
2434pub(crate) fn apply_omena_query_checker_product_gate_to_style_diagnostics(
2435    diagnostics: &mut [OmenaQueryStyleDiagnosticV0],
2436) {
2437    for diagnostic in diagnostics {
2438        populate_omena_query_checker_product_gate_provenance_from_evidence_graph(
2439            diagnostic.code,
2440            &mut diagnostic.provenance,
2441        );
2442        diagnostic.polynomial_provenance = Some(diagnostic.polynomial_provenance());
2443    }
2444}
2445
2446#[derive(Debug, Clone, PartialEq, Eq, Serialize)]
2447#[serde(rename_all = "camelCase")]
2448pub struct OmenaQueryStyleDiagnosticsForFileV0 {
2449    pub schema_version: &'static str,
2450    pub product: &'static str,
2451    pub file_uri: String,
2452    pub file_kind: &'static str,
2453    pub diagnostic_count: usize,
2454    pub diagnostics: Vec<OmenaQueryStyleDiagnosticV0>,
2455    pub ready_surfaces: Vec<&'static str>,
2456    #[serde(skip_serializing_if = "Option::is_none")]
2457    pub suppression_summary: Option<OmenaQueryDiagnosticSuppressionSummaryV0>,
2458}
2459
2460#[derive(Debug, Clone, PartialEq, Eq, Serialize)]
2461#[serde(rename_all = "camelCase")]
2462pub struct OmenaQueryDiagnosticSuppressionSummaryV0 {
2463    pub original_diagnostic_count: usize,
2464    pub emitted_diagnostic_count: usize,
2465    pub suppressed_diagnostic_count: usize,
2466    pub unused_expect_error_count: usize,
2467    #[serde(default, skip_serializing_if = "Vec::is_empty")]
2468    pub suppression_reasons: Vec<OmenaQueryDiagnosticSuppressionReasonV0>,
2469}
2470
2471#[derive(Debug, Clone, PartialEq, Eq, Serialize)]
2472#[serde(rename_all = "camelCase")]
2473pub struct OmenaQueryDiagnosticSuppressionReasonV0 {
2474    pub directive_kind: &'static str,
2475    pub codes: Vec<String>,
2476    pub reason: String,
2477    pub range: ParserRangeV0,
2478}
2479
2480#[derive(Debug, Clone, Copy, PartialEq, Eq)]
2481pub enum OmenaQueryDiagnosticSuppressionModeV0 {
2482    Apply,
2483    ReportOnly,
2484}
2485
2486impl OmenaQueryDiagnosticSuppressionModeV0 {
2487    pub const fn as_str(self) -> &'static str {
2488        match self {
2489            Self::Apply => "apply",
2490            Self::ReportOnly => "reportOnly",
2491        }
2492    }
2493
2494    pub const fn suppresses_diagnostics(self) -> bool {
2495        matches!(self, Self::Apply)
2496    }
2497}
2498
2499#[derive(Debug, Clone, PartialEq, Eq, Serialize)]
2500#[serde(rename_all = "camelCase")]
2501pub struct OmenaQueryCompletionCandidateV0 {
2502    pub file_uri: String,
2503    pub name: String,
2504    pub kind: &'static str,
2505    pub range: ParserRangeV0,
2506    pub source: &'static str,
2507    #[serde(skip_serializing_if = "Option::is_none")]
2508    pub documentation: Option<String>,
2509}
2510
2511#[derive(Debug, Clone, PartialEq, Eq, Serialize)]
2512#[serde(rename_all = "camelCase")]
2513pub struct OmenaQueryCompletionItemV0 {
2514    pub label: String,
2515    pub insert_text: String,
2516    pub sort_text: String,
2517    pub detail: &'static str,
2518    #[serde(skip_serializing_if = "Option::is_none")]
2519    pub documentation: Option<String>,
2520    pub item_kind: &'static str,
2521    pub ranking_source: &'static str,
2522    pub source: &'static str,
2523}
2524
2525#[derive(Debug, Clone, PartialEq, Eq, Serialize)]
2526#[serde(rename_all = "camelCase")]
2527pub struct OmenaQueryCompletionAtPositionV0 {
2528    pub schema_version: &'static str,
2529    pub product: &'static str,
2530    pub file_uri: String,
2531    pub file_kind: &'static str,
2532    pub query_position: ParserPositionV0,
2533    pub context_kind: &'static str,
2534    pub prefix: Option<String>,
2535    pub is_incomplete: bool,
2536    pub item_count: usize,
2537    pub items: Vec<OmenaQueryCompletionItemV0>,
2538    pub ready_surfaces: Vec<&'static str>,
2539}
2540
2541#[derive(Debug, Clone, PartialEq, Eq, Serialize)]
2542#[serde(rename_all = "camelCase")]
2543pub struct OmenaQueryReferenceLocationV0 {
2544    pub uri: String,
2545    pub range: ParserRangeV0,
2546    pub name: String,
2547    pub role: &'static str,
2548    pub source: &'static str,
2549}
2550
2551#[derive(Debug, Clone, PartialEq, Eq, Serialize)]
2552#[serde(rename_all = "camelCase")]
2553pub struct OmenaQueryRefsForClassV0 {
2554    pub schema_version: &'static str,
2555    pub product: &'static str,
2556    pub selector_name: String,
2557    pub target_style_uri: Option<String>,
2558    pub include_declaration: bool,
2559    pub location_count: usize,
2560    pub locations: Vec<OmenaQueryReferenceLocationV0>,
2561    pub ready_surfaces: Vec<&'static str>,
2562}
2563
2564#[derive(Debug, Clone, PartialEq, Eq, Serialize)]
2565#[serde(rename_all = "camelCase")]
2566pub struct OmenaQueryRenamePlanV0 {
2567    pub schema_version: &'static str,
2568    pub product: &'static str,
2569    pub selector_name: String,
2570    pub new_name: String,
2571    pub target_style_uri: Option<String>,
2572    pub edit_count: usize,
2573    pub edits: Vec<OmenaQueryWorkspaceTextEditV0>,
2574    pub ready_surfaces: Vec<&'static str>,
2575}
2576
2577#[derive(Debug, Clone, PartialEq, Eq, Serialize)]
2578#[serde(rename_all = "camelCase")]
2579pub struct OmenaQueryCodeActionPlanV0 {
2580    pub schema_version: &'static str,
2581    pub product: &'static str,
2582    pub file_uri: String,
2583    pub file_kind: &'static str,
2584    pub action_count: usize,
2585    pub actions: Vec<OmenaQueryCodeActionV0>,
2586    pub ready_surfaces: Vec<&'static str>,
2587}
2588
2589#[derive(Debug, Clone, PartialEq, Eq, Serialize)]
2590#[serde(rename_all = "camelCase")]
2591pub struct OmenaQueryCodeActionV0 {
2592    pub title: String,
2593    pub kind: &'static str,
2594    pub edits: Vec<OmenaQueryWorkspaceTextEditV0>,
2595    pub source: &'static str,
2596}
2597
2598#[derive(Debug, Clone, PartialEq, Eq, Serialize)]
2599#[serde(rename_all = "camelCase")]
2600pub struct OmenaQueryStyleInsightsV0 {
2601    pub schema_version: &'static str,
2602    pub product: &'static str,
2603    pub style_uri: String,
2604    pub insight_count: usize,
2605    pub insights: Vec<OmenaQueryInsightV0>,
2606    pub ready_surfaces: Vec<&'static str>,
2607}
2608
2609#[derive(Debug, Clone, PartialEq, Eq, Serialize)]
2610#[serde(rename_all = "camelCase")]
2611pub struct OmenaQueryInsightV0 {
2612    pub kind: &'static str,
2613    pub title: String,
2614    pub message: String,
2615    pub range: ParserRangeV0,
2616    pub confidence: &'static str,
2617    pub scope: &'static str,
2618    pub source: &'static str,
2619    pub provenance: Vec<&'static str>,
2620    #[serde(skip_serializing_if = "Option::is_none")]
2621    pub primary_edit: Option<OmenaQueryWorkspaceTextEditV0>,
2622    pub shorthand_combinable: Option<OmenaQueryShorthandCombinableV0>,
2623    #[serde(skip_serializing_if = "Option::is_none")]
2624    pub cascade_insight: Option<OmenaQueryCascadeInsightV0>,
2625}
2626
2627#[derive(Debug, Clone, PartialEq, Eq, Serialize)]
2628#[serde(rename_all = "camelCase")]
2629pub struct OmenaQueryShorthandCombinableV0 {
2630    pub shorthand_property: CanonicalStandardPropertyNameV0,
2631    pub longhand_properties: Vec<CanonicalStandardPropertyNameV0>,
2632    pub values: Vec<String>,
2633    pub combined_value: String,
2634    pub declaration_count: usize,
2635}
2636
2637#[derive(Debug, Clone, Serialize)]
2638#[serde(rename_all = "camelCase")]
2639pub struct OmenaQueryCascadeInsightV0 {
2640    pub relationship: &'static str,
2641    pub selector: String,
2642    pub property: AuthoredPropertyTextV0,
2643    pub related_selector: Option<String>,
2644    pub related_property: Option<AuthoredPropertyTextV0>,
2645    pub source_order: u32,
2646    pub related_source_order: Option<u32>,
2647}
2648
2649impl PartialEq for OmenaQueryCascadeInsightV0 {
2650    fn eq(&self, other: &Self) -> bool {
2651        self.relationship == other.relationship
2652            && self.selector == other.selector
2653            && self
2654                .property
2655                .to_property_name()
2656                .same_as(&other.property.to_property_name())
2657            && self.related_selector == other.related_selector
2658            && match (&self.related_property, &other.related_property) {
2659                (Some(left), Some(right)) => {
2660                    left.to_property_name().same_as(&right.to_property_name())
2661                }
2662                (None, None) => true,
2663                (Some(_), None) | (None, Some(_)) => false,
2664            }
2665            && self.source_order == other.source_order
2666            && self.related_source_order == other.related_source_order
2667    }
2668}
2669
2670impl Eq for OmenaQueryCascadeInsightV0 {}
2671
2672#[derive(Debug, Clone, Serialize)]
2673#[serde(rename_all = "camelCase")]
2674pub struct OmenaQueryCascadeAtPositionV0 {
2675    pub schema_version: &'static str,
2676    pub product: &'static str,
2677    pub style_path: String,
2678    pub query_position: ParserPositionV0,
2679    pub status: &'static str,
2680    pub cascade_engine: &'static str,
2681    pub reference_name: Option<String>,
2682    pub reference_range: Option<ParserRangeV0>,
2683    pub winner_declaration_source_order: Option<usize>,
2684    pub winner_declaration_file_path: Option<String>,
2685    pub winner_declaration_range: Option<ParserRangeV0>,
2686    pub winner_context_kind: Option<&'static str>,
2687    /// Opaque cascade ordering token; consumers must not interpret it as a layer-count magnitude.
2688    pub winner_declaration_layer_rank: Option<i32>,
2689    pub winner_declaration_layer_name: Option<String>,
2690    pub candidate_declaration_count: usize,
2691    pub shadowed_declaration_source_orders: Vec<usize>,
2692    pub referenced_declaration_property: Option<AuthoredPropertyTextV0>,
2693    pub referenced_declaration_value: Option<String>,
2694    pub referenced_declaration_computed_value_status: Option<&'static str>,
2695    pub referenced_declaration_computed_value: Option<String>,
2696    pub referenced_declaration_invalid_at_computed_value_time: bool,
2697    pub referenced_declaration_computed_value_indeterminate: bool,
2698    #[serde(skip_serializing_if = "Option::is_none")]
2699    pub referenced_declaration_computed_value_indeterminate_reason: Option<&'static str>,
2700    pub referenced_declaration_computed_value_derivation_steps: Vec<&'static str>,
2701    pub custom_property_fixed_point_iteration_count: usize,
2702    pub custom_property_fixed_point_guaranteed_invalid_count: usize,
2703    pub reference_custom_property_fixed_point_status: Option<&'static str>,
2704    pub reference_custom_property_fixed_point_value: Option<String>,
2705    #[serde(skip_serializing_if = "Option::is_none")]
2706    pub refinement_evidence: Option<CascadeDimensionalRefinementBridgeV0>,
2707    #[serde(skip_serializing_if = "Option::is_none")]
2708    pub categorical_evidence:
2709        Option<omena_query_checker_orchestrator::CategoricalCascadeEvidenceV0>,
2710}
2711
2712impl PartialEq for OmenaQueryCascadeAtPositionV0 {
2713    fn eq(&self, other: &Self) -> bool {
2714        let referenced_property_same = match (
2715            &self.referenced_declaration_property,
2716            &other.referenced_declaration_property,
2717        ) {
2718            (Some(left), Some(right)) => left.to_property_name().same_as(&right.to_property_name()),
2719            (None, None) => true,
2720            (Some(_), None) | (None, Some(_)) => false,
2721        };
2722        self.schema_version == other.schema_version
2723            && self.product == other.product
2724            && self.style_path == other.style_path
2725            && self.query_position == other.query_position
2726            && self.status == other.status
2727            && self.cascade_engine == other.cascade_engine
2728            && self.reference_name == other.reference_name
2729            && self.reference_range == other.reference_range
2730            && self.winner_declaration_source_order == other.winner_declaration_source_order
2731            && self.winner_declaration_file_path == other.winner_declaration_file_path
2732            && self.winner_declaration_range == other.winner_declaration_range
2733            && self.winner_context_kind == other.winner_context_kind
2734            && self.winner_declaration_layer_rank == other.winner_declaration_layer_rank
2735            && self.winner_declaration_layer_name == other.winner_declaration_layer_name
2736            && self.candidate_declaration_count == other.candidate_declaration_count
2737            && self.shadowed_declaration_source_orders == other.shadowed_declaration_source_orders
2738            && referenced_property_same
2739            && self.referenced_declaration_value == other.referenced_declaration_value
2740            && self.referenced_declaration_computed_value_status
2741                == other.referenced_declaration_computed_value_status
2742            && self.referenced_declaration_computed_value
2743                == other.referenced_declaration_computed_value
2744            && self.referenced_declaration_invalid_at_computed_value_time
2745                == other.referenced_declaration_invalid_at_computed_value_time
2746            && self.referenced_declaration_computed_value_indeterminate
2747                == other.referenced_declaration_computed_value_indeterminate
2748            && self.referenced_declaration_computed_value_indeterminate_reason
2749                == other.referenced_declaration_computed_value_indeterminate_reason
2750            && self.referenced_declaration_computed_value_derivation_steps
2751                == other.referenced_declaration_computed_value_derivation_steps
2752            && self.custom_property_fixed_point_iteration_count
2753                == other.custom_property_fixed_point_iteration_count
2754            && self.custom_property_fixed_point_guaranteed_invalid_count
2755                == other.custom_property_fixed_point_guaranteed_invalid_count
2756            && self.reference_custom_property_fixed_point_status
2757                == other.reference_custom_property_fixed_point_status
2758            && self.reference_custom_property_fixed_point_value
2759                == other.reference_custom_property_fixed_point_value
2760            && self.refinement_evidence == other.refinement_evidence
2761            && self.categorical_evidence == other.categorical_evidence
2762    }
2763}
2764
2765impl Eq for OmenaQueryCascadeAtPositionV0 {}
2766
2767#[derive(Debug, Clone, Serialize)]
2768#[serde(rename_all = "camelCase")]
2769pub struct OmenaQueryCreateCustomPropertyActionV0 {
2770    pub uri: String,
2771    pub range: ParserRangeV0,
2772    pub new_text: String,
2773    pub property_name: AuthoredPropertyTextV0,
2774    pub property_key: CanonicalCustomPropertyNameV0,
2775}
2776
2777impl PartialEq for OmenaQueryCreateCustomPropertyActionV0 {
2778    fn eq(&self, other: &Self) -> bool {
2779        self.uri == other.uri
2780            && self.range == other.range
2781            && self.new_text == other.new_text
2782            && self.property_key == other.property_key
2783    }
2784}
2785
2786impl Eq for OmenaQueryCreateCustomPropertyActionV0 {}
2787
2788#[derive(Debug, Clone, PartialEq, Eq, Serialize)]
2789#[serde(rename_all = "camelCase")]
2790pub struct OmenaQuerySourceDiagnosticV0 {
2791    pub code: &'static str,
2792    pub severity: &'static str,
2793    pub provenance: Vec<&'static str>,
2794    pub range: ParserRangeV0,
2795    pub message: String,
2796    #[serde(skip_serializing_if = "Option::is_none")]
2797    pub precision: Option<OmenaQueryAnalysisPrecisionV0>,
2798    #[serde(skip_serializing_if = "Option::is_none")]
2799    pub suggestion: Option<String>,
2800    pub create_selector: Option<OmenaQueryCreateSelectorActionV0>,
2801}
2802
2803impl OmenaQuerySourceDiagnosticV0 {
2804    pub fn linear_provenance(&self) -> OmenaQueryLinearProvenanceV0 {
2805        summarize_omena_query_linear_provenance(self.provenance.as_slice())
2806    }
2807}
2808
2809pub(crate) fn source_diagnostic_precision(
2810    value_domain: &str,
2811    flow_sensitivity: &str,
2812    context_sensitivity: &str,
2813) -> OmenaQueryAnalysisPrecisionV0 {
2814    let precision =
2815        source_diagnostic_precision_node(value_domain, flow_sensitivity, context_sensitivity);
2816    OmenaQueryAnalysisPrecisionV0 {
2817        product: precision.product,
2818        value_domain: precision.value_domain,
2819        flow_sensitivity: precision.flow_sensitivity,
2820        context_sensitivity: precision.context_sensitivity,
2821        revision_axis: precision.revision_axis,
2822    }
2823}
2824
2825pub fn fact_precision_from_evidence_analysis_precision(
2826    precision: &EvidenceAnalysisPrecisionV0,
2827) -> omena_query_core::FactPrecision {
2828    omena_query_core::fact_precision_from_analysis_precision(&OmenaQueryAnalysisPrecisionV0 {
2829        product: precision.product.clone(),
2830        value_domain: precision.value_domain.clone(),
2831        flow_sensitivity: precision.flow_sensitivity.clone(),
2832        context_sensitivity: precision.context_sensitivity.clone(),
2833        revision_axis: precision.revision_axis.clone(),
2834    })
2835}
2836
2837pub(crate) const OMENA_QUERY_TYPE_ORACLE_UNKNOWN_VALUE_DOMAIN: &str = "unknown";
2838pub(crate) const OMENA_QUERY_TSGO_PROVIDER_UNAVAILABLE_PROVENANCE: &str =
2839    "tsgo-provider.unavailable->unknown-precision";
2840
2841pub(crate) fn apply_omena_query_checker_product_gate_to_source_diagnostics(
2842    diagnostics: &mut [OmenaQuerySourceDiagnosticV0],
2843) {
2844    for diagnostic in diagnostics {
2845        populate_omena_query_checker_product_gate_provenance_from_evidence_graph(
2846            diagnostic.code,
2847            &mut diagnostic.provenance,
2848        );
2849    }
2850}
2851
2852pub(crate) fn project_omena_query_provenance_from_evidence_graph(
2853    provenance: &[&'static str],
2854) -> Vec<&'static str> {
2855    let input_identity = provenance.first().copied().unwrap_or("emptyProvenance");
2856    project_omena_query_diagnostic_provenance_from_evidence_graph(
2857        input_identity,
2858        provenance.to_vec(),
2859    )
2860}
2861
2862fn populate_omena_query_checker_product_gate_provenance_from_evidence_graph(
2863    product_diagnostic_code: &str,
2864    provenance: &mut Vec<&'static str>,
2865) {
2866    let gate =
2867        omena_query_checker_orchestrator::gate_omena_query_checker_product_diagnostic_code_v0(
2868            product_diagnostic_code,
2869        );
2870    if !gate.enforcement_passed {
2871        provenance.push("omena-query-checker-orchestrator.product-diagnostic-gate-failed");
2872    } else {
2873        for label in gate.provenance {
2874            if !provenance.contains(&label) {
2875                provenance.push(label);
2876            }
2877        }
2878    }
2879    *provenance = project_omena_query_diagnostic_provenance_from_evidence_graph(
2880        product_diagnostic_code,
2881        provenance.clone(),
2882    );
2883}
2884
2885fn source_diagnostic_precision_node(
2886    value_domain: &str,
2887    flow_sensitivity: &str,
2888    context_sensitivity: &str,
2889) -> EvidenceAnalysisPrecisionV0 {
2890    let precision = EvidenceAnalysisPrecisionV0::new(
2891        "omena-query.analysis-precision",
2892        value_domain,
2893        flow_sensitivity,
2894        context_sensitivity,
2895        "OmenaQuerySourceDiagnosticsForFileV0.input",
2896    );
2897    let Some(node) = project_omena_query_evidence_node(
2898        "sourceDiagnosticPrecision",
2899        value_domain,
2900        &[],
2901        Some(precision.clone()),
2902    ) else {
2903        return precision;
2904    };
2905    node.precision.unwrap_or(precision)
2906}
2907
2908fn project_omena_query_diagnostic_provenance_from_evidence_graph(
2909    input_identity: &str,
2910    provenance: Vec<&'static str>,
2911) -> Vec<&'static str> {
2912    let Some(node) = project_omena_query_evidence_node(
2913        "diagnosticProvenance",
2914        input_identity,
2915        provenance.as_slice(),
2916        None,
2917    ) else {
2918        return provenance;
2919    };
2920    node.provenance
2921        .iter()
2922        .filter_map(|label| {
2923            provenance
2924                .iter()
2925                .copied()
2926                .find(|candidate| *candidate == label.as_str())
2927        })
2928        .collect()
2929}
2930
2931fn project_omena_query_evidence_node(
2932    query_identity: &str,
2933    input_identity: &str,
2934    provenance: &[&'static str],
2935    precision: Option<EvidenceAnalysisPrecisionV0>,
2936) -> Option<omena_evidence_graph::EvidenceNodeV0> {
2937    let key = EvidenceNodeKeyV0::new(query_identity, input_identity);
2938    let Ok(graph) = build_evidence_graph_from_edges_v0(
2939        [EvidenceNodeSeedV0::with_precision(
2940            key.clone(),
2941            provenance
2942                .iter()
2943                .map(|label| (*label).to_string())
2944                .collect(),
2945            precision,
2946            GuaranteeKindV0::for_label_less_family(),
2947        )],
2948        [EvidenceDemandEdgeV0::new(
2949            query_identity,
2950            key,
2951            "diagnostic-evidence",
2952        )],
2953    ) else {
2954        return None;
2955    };
2956    graph.nodes.into_iter().next()
2957}
2958
2959#[derive(Debug, Clone, PartialEq, Eq, Serialize)]
2960#[serde(rename_all = "camelCase")]
2961pub struct OmenaQueryCreateSelectorActionV0 {
2962    pub uri: String,
2963    pub range: ParserRangeV0,
2964    pub new_text: String,
2965    pub selector_name: String,
2966}
2967
2968#[derive(Debug, Clone, PartialEq, Eq, Deserialize, Serialize)]
2969#[serde(rename_all = "camelCase")]
2970pub struct OmenaQuerySourceMissingSelectorDiagnosticCandidateV0 {
2971    pub target_style_uri: String,
2972    pub target_style_source: String,
2973    pub selector_name: String,
2974    pub source_reference_range: ParserRangeV0,
2975}
2976
2977#[derive(Debug, Clone, PartialEq, Eq, Serialize)]
2978#[serde(rename_all = "camelCase")]
2979pub struct OmenaQuerySourceDiagnosticsForFileV0 {
2980    pub schema_version: &'static str,
2981    pub product: &'static str,
2982    pub file_uri: String,
2983    pub file_kind: &'static str,
2984    pub diagnostic_count: usize,
2985    pub diagnostics: Vec<OmenaQuerySourceDiagnosticV0>,
2986    pub ready_surfaces: Vec<&'static str>,
2987}
2988
2989#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Serialize)]
2990#[serde(rename_all = "camelCase")]
2991pub struct OmenaQuerySourceSelectorCandidateV0 {
2992    pub kind: &'static str,
2993    pub name: String,
2994    pub range: ParserRangeV0,
2995    pub source: &'static str,
2996    pub target_style_uri: Option<String>,
2997}
2998
2999#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Serialize)]
3000#[serde(rename_all = "camelCase")]
3001pub struct OmenaQuerySourceSelectorReferenceCandidateV0 {
3002    pub uri: String,
3003    pub kind: &'static str,
3004    pub name: String,
3005    pub range: ParserRangeV0,
3006    pub source: &'static str,
3007    pub target_style_uri: Option<String>,
3008}
3009
3010impl OmenaQuerySourceSelectorReferenceCandidateV0 {
3011    pub fn projection_surface(&self) -> OmenaQuerySourceSelectorReferenceSurfaceV0 {
3012        match self.source {
3013            "omenaTsgoTypeFactProjection" => {
3014                OmenaQuerySourceSelectorReferenceSurfaceV0::OmenaTsgoTypeFactProjection
3015            }
3016            _ => OmenaQuerySourceSelectorReferenceSurfaceV0::OmenaQuerySourceSyntaxIndex,
3017        }
3018    }
3019}
3020
3021#[derive(Debug, Clone, PartialEq, Eq, Serialize)]
3022#[serde(rename_all = "camelCase")]
3023pub struct OmenaQueryStyleSelectorDefinitionV0 {
3024    pub uri: String,
3025    pub name: String,
3026    pub range: ParserRangeV0,
3027}
3028
3029#[derive(Debug, Clone, PartialEq, Eq, Serialize)]
3030#[serde(rename_all = "camelCase")]
3031pub struct OmenaQuerySourceProviderCandidateResolutionV0 {
3032    pub schema_version: &'static str,
3033    pub product: &'static str,
3034    pub matched: Vec<OmenaQuerySourceSelectorCandidateV0>,
3035    pub unresolved: Vec<OmenaQuerySourceSelectorCandidateV0>,
3036}
3037
3038#[derive(Debug, Clone, PartialEq, Eq, Serialize)]
3039#[serde(rename_all = "camelCase")]
3040pub struct OmenaQuerySourceSelectorReferenceEditTargetV0 {
3041    pub uri: String,
3042    pub name: String,
3043    pub range: ParserRangeV0,
3044    pub target_style_uri: Option<String>,
3045}
3046
3047#[derive(Debug, Clone, PartialEq, Eq, Serialize)]
3048#[serde(rename_all = "camelCase")]
3049pub struct OmenaQuerySourceSelectorOccurrenceIndexV0 {
3050    pub schema_version: &'static str,
3051    pub product: &'static str,
3052    pub moniker_count: usize,
3053    pub occurrence_count: usize,
3054    pub workspace_index: OmenaWorkspaceOccurrenceIndexV0,
3055    pub occurrences: Vec<OmenaQuerySourceSelectorOccurrenceV0>,
3056    pub ready_surfaces: Vec<&'static str>,
3057}
3058
3059#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Deserialize, Serialize)]
3060#[serde(rename_all = "camelCase")]
3061pub struct OmenaQuerySourceSelectorOccurrenceV0 {
3062    pub moniker: String,
3063    pub uri: String,
3064    pub selector_name: String,
3065    pub range: ParserRangeV0,
3066    pub kind: OmenaWorkspaceOccurrenceKindV0,
3067    pub role: OmenaWorkspaceOccurrenceRoleV0,
3068    pub source: OmenaWorkspaceOccurrenceSurfaceV0,
3069    pub target_style_uri: Option<String>,
3070    pub rename_target: bool,
3071}
3072
3073#[derive(Debug, Clone, PartialEq, Eq, Serialize)]
3074#[serde(rename_all = "camelCase")]
3075pub struct OmenaQueryCustomPropertyOccurrenceIndexV0 {
3076    pub schema_version: &'static str,
3077    pub product: &'static str,
3078    pub occurrence_count: usize,
3079    pub occurrences: Vec<OmenaQueryCustomPropertyOccurrenceV0>,
3080    pub ready_surfaces: Vec<&'static str>,
3081}
3082
3083#[derive(Debug, Clone, Serialize)]
3084#[serde(rename_all = "camelCase")]
3085pub struct OmenaQueryCustomPropertyOccurrenceV0 {
3086    pub uri: String,
3087    pub name: AuthoredPropertyTextV0,
3088    pub range: ParserRangeV0,
3089    pub byte_span: ParserByteSpanV0,
3090    pub kind: &'static str,
3091    pub has_fallback: bool,
3092    pub source: &'static str,
3093    pub property_key: CanonicalCustomPropertyNameV0,
3094}
3095
3096impl PartialEq for OmenaQueryCustomPropertyOccurrenceV0 {
3097    fn eq(&self, other: &Self) -> bool {
3098        self.uri == other.uri
3099            && self.property_key == other.property_key
3100            && self.range == other.range
3101            && self.byte_span == other.byte_span
3102            && self.kind == other.kind
3103            && self.has_fallback == other.has_fallback
3104            && self.source == other.source
3105    }
3106}
3107
3108impl Eq for OmenaQueryCustomPropertyOccurrenceV0 {}
3109
3110impl Ord for OmenaQueryCustomPropertyOccurrenceV0 {
3111    fn cmp(&self, other: &Self) -> Ordering {
3112        (
3113            &self.uri,
3114            &self.property_key,
3115            self.range,
3116            self.byte_span,
3117            self.kind,
3118            self.has_fallback,
3119            self.source,
3120        )
3121            .cmp(&(
3122                &other.uri,
3123                &other.property_key,
3124                other.range,
3125                other.byte_span,
3126                other.kind,
3127                other.has_fallback,
3128                other.source,
3129            ))
3130    }
3131}
3132
3133impl PartialOrd for OmenaQueryCustomPropertyOccurrenceV0 {
3134    fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
3135        Some(self.cmp(other))
3136    }
3137}
3138
3139#[derive(Debug, Clone, PartialEq, Eq, Deserialize, Serialize)]
3140#[serde(rename_all = "camelCase")]
3141pub struct OmenaWorkspaceOccurrenceIndexV0 {
3142    pub schema_version: &'static str,
3143    pub product: &'static str,
3144    pub moniker_count: usize,
3145    pub occurrence_count: usize,
3146    pub by_moniker: BTreeMap<String, Vec<OmenaWorkspaceOccurrenceV0>>,
3147    pub by_file: BTreeMap<String, Vec<String>>,
3148    pub ready_surfaces: Vec<&'static str>,
3149}
3150
3151#[derive(Debug, Clone, Deserialize, Serialize)]
3152#[serde(rename_all = "camelCase")]
3153pub struct OmenaWorkspaceOccurrenceV0 {
3154    pub moniker: String,
3155    pub uri: String,
3156    pub name: String,
3157    pub range: ParserRangeV0,
3158    pub kind: OmenaWorkspaceOccurrenceKindV0,
3159    pub role: OmenaWorkspaceOccurrenceRoleV0,
3160    pub surface: OmenaWorkspaceOccurrenceSurfaceV0,
3161    #[serde(skip_serializing_if = "Option::is_none")]
3162    pub family: Option<OmenaWorkspaceOccurrenceFamilyV0>,
3163    #[serde(skip_serializing_if = "Option::is_none")]
3164    pub namespace: Option<String>,
3165    #[serde(skip_serializing_if = "Option::is_none")]
3166    pub target_style_uri: Option<String>,
3167    pub rename_target: bool,
3168}
3169
3170impl PartialEq for OmenaWorkspaceOccurrenceV0 {
3171    fn eq(&self, other: &Self) -> bool {
3172        self.cmp(other) == Ordering::Equal
3173    }
3174}
3175
3176impl Eq for OmenaWorkspaceOccurrenceV0 {}
3177
3178impl Ord for OmenaWorkspaceOccurrenceV0 {
3179    fn cmp(&self, other: &Self) -> Ordering {
3180        self.moniker
3181            .cmp(&other.moniker)
3182            .then_with(|| self.uri.cmp(&other.uri))
3183            .then_with(|| workspace_occurrence_name_cmp(self, other))
3184            .then_with(|| self.range.cmp(&other.range))
3185            .then_with(|| self.kind.cmp(&other.kind))
3186            .then_with(|| self.role.cmp(&other.role))
3187            .then_with(|| self.surface.cmp(&other.surface))
3188            .then_with(|| self.family.cmp(&other.family))
3189            .then_with(|| self.namespace.cmp(&other.namespace))
3190            .then_with(|| self.target_style_uri.cmp(&other.target_style_uri))
3191            .then_with(|| self.rename_target.cmp(&other.rename_target))
3192    }
3193}
3194
3195impl PartialOrd for OmenaWorkspaceOccurrenceV0 {
3196    fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
3197        Some(self.cmp(other))
3198    }
3199}
3200
3201fn workspace_occurrence_name_cmp(
3202    left: &OmenaWorkspaceOccurrenceV0,
3203    right: &OmenaWorkspaceOccurrenceV0,
3204) -> Ordering {
3205    let left_is_custom_property =
3206        left.kind.family() == OmenaWorkspaceOccurrenceFamilyV0::CustomProperty;
3207    let right_is_custom_property =
3208        right.kind.family() == OmenaWorkspaceOccurrenceFamilyV0::CustomProperty;
3209    let identity_domain_order = left_is_custom_property.cmp(&right_is_custom_property);
3210    if identity_domain_order != Ordering::Equal {
3211        return identity_domain_order;
3212    }
3213    if left_is_custom_property {
3214        return PropertyNameV0::canonical_custom_key(left.name.clone())
3215            .cmp(&PropertyNameV0::canonical_custom_key(right.name.clone()));
3216    }
3217    left.name.cmp(&right.name)
3218}
3219
3220#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Deserialize, Serialize)]
3221#[serde(rename_all = "camelCase")]
3222pub enum OmenaWorkspaceOccurrenceKindV0 {
3223    SourceSelectorReference,
3224    SourceSelectorPrefixReference,
3225    CustomPropertyDeclaration,
3226    CustomPropertyReference,
3227    SassVariableDeclaration,
3228    SassVariableReference,
3229    SassMixinDeclaration,
3230    SassMixinInclude,
3231    SassFunctionDeclaration,
3232    SassFunctionCall,
3233    SassMixinReference,
3234    SassFunctionReference,
3235    SassSymbolDeclaration,
3236    SassSymbolReference,
3237}
3238
3239impl OmenaWorkspaceOccurrenceKindV0 {
3240    pub fn family(self) -> OmenaWorkspaceOccurrenceFamilyV0 {
3241        match self {
3242            Self::SourceSelectorReference | Self::SourceSelectorPrefixReference => {
3243                OmenaWorkspaceOccurrenceFamilyV0::CssModuleSelector
3244            }
3245            Self::CustomPropertyDeclaration | Self::CustomPropertyReference => {
3246                OmenaWorkspaceOccurrenceFamilyV0::CustomProperty
3247            }
3248            Self::SassVariableDeclaration | Self::SassVariableReference => {
3249                OmenaWorkspaceOccurrenceFamilyV0::Variable
3250            }
3251            Self::SassMixinDeclaration | Self::SassMixinInclude | Self::SassMixinReference => {
3252                OmenaWorkspaceOccurrenceFamilyV0::Mixin
3253            }
3254            Self::SassFunctionDeclaration
3255            | Self::SassFunctionCall
3256            | Self::SassFunctionReference => OmenaWorkspaceOccurrenceFamilyV0::Function,
3257            Self::SassSymbolDeclaration | Self::SassSymbolReference => {
3258                OmenaWorkspaceOccurrenceFamilyV0::Symbol
3259            }
3260        }
3261    }
3262
3263    pub fn as_str(self) -> &'static str {
3264        match self {
3265            Self::SourceSelectorReference => "sourceSelectorReference",
3266            Self::SourceSelectorPrefixReference => "sourceSelectorPrefixReference",
3267            Self::CustomPropertyDeclaration => "customPropertyDeclaration",
3268            Self::CustomPropertyReference => "customPropertyReference",
3269            Self::SassVariableDeclaration => "sassVariableDeclaration",
3270            Self::SassVariableReference => "sassVariableReference",
3271            Self::SassMixinDeclaration => "sassMixinDeclaration",
3272            Self::SassMixinInclude => "sassMixinInclude",
3273            Self::SassMixinReference => "sassMixinReference",
3274            Self::SassFunctionDeclaration => "sassFunctionDeclaration",
3275            Self::SassFunctionCall => "sassFunctionCall",
3276            Self::SassFunctionReference => "sassFunctionReference",
3277            Self::SassSymbolDeclaration => "sassSymbolDeclaration",
3278            Self::SassSymbolReference => "sassSymbolReference",
3279        }
3280    }
3281}
3282
3283#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Deserialize, Serialize)]
3284#[serde(rename_all = "camelCase")]
3285pub enum OmenaWorkspaceOccurrenceRoleV0 {
3286    Definition,
3287    Reference,
3288}
3289
3290impl OmenaWorkspaceOccurrenceRoleV0 {
3291    pub fn as_str(self) -> &'static str {
3292        match self {
3293            Self::Definition => "definition",
3294            Self::Reference => "reference",
3295        }
3296    }
3297}
3298
3299#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Deserialize, Serialize)]
3300#[serde(rename_all = "camelCase")]
3301pub enum OmenaWorkspaceOccurrenceSurfaceV0 {
3302    OmenaQuerySourceSyntaxIndex,
3303    OmenaLspStyleIndex,
3304}
3305
3306impl OmenaWorkspaceOccurrenceSurfaceV0 {
3307    pub fn as_str(self) -> &'static str {
3308        match self {
3309            Self::OmenaQuerySourceSyntaxIndex => "omenaQuerySourceSyntaxIndex",
3310            Self::OmenaLspStyleIndex => "omenaLspStyleIndex",
3311        }
3312    }
3313}
3314
3315#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Deserialize, Serialize)]
3316#[serde(rename_all = "camelCase")]
3317pub enum OmenaWorkspaceOccurrenceFamilyV0 {
3318    CssModuleSelector,
3319    CustomProperty,
3320    Variable,
3321    Mixin,
3322    Function,
3323    Symbol,
3324}
3325
3326impl OmenaWorkspaceOccurrenceFamilyV0 {
3327    pub fn as_str(self) -> &'static str {
3328        match self {
3329            Self::CssModuleSelector => "cssModuleSelector",
3330            Self::CustomProperty => "customProperty",
3331            Self::Variable => "variable",
3332            Self::Mixin => "mixin",
3333            Self::Function => "function",
3334            Self::Symbol => "symbol",
3335        }
3336    }
3337}
3338
3339#[derive(Debug, Clone, PartialEq, Eq, Serialize)]
3340#[serde(rename_all = "camelCase")]
3341pub struct OmenaQueryWorkspaceTextEditV0 {
3342    pub uri: String,
3343    pub range: ParserRangeV0,
3344    pub new_text: String,
3345}
3346
3347#[derive(Debug, Clone, PartialEq, Eq, Serialize)]
3348#[serde(rename_all = "camelCase")]
3349pub struct OmenaQuerySassModuleUseEdgeV0 {
3350    pub source: String,
3351    pub namespace_kind: &'static str,
3352    pub namespace: Option<String>,
3353}
3354
3355#[derive(Debug, Clone, PartialEq, Eq, Serialize)]
3356#[serde(rename_all = "camelCase")]
3357pub struct OmenaQuerySassModuleSourcesV0 {
3358    pub schema_version: &'static str,
3359    pub product: &'static str,
3360    pub module_use_edges: Vec<OmenaQuerySassModuleUseEdgeV0>,
3361    pub module_forward_sources: Vec<String>,
3362}
3363
3364#[derive(Debug, Clone, PartialEq, Eq, Deserialize, Serialize)]
3365#[serde(rename_all = "camelCase")]
3366pub struct OmenaQueryStylePackageManifestV0 {
3367    pub package_json_path: String,
3368    pub package_json_source: String,
3369}
3370
3371#[cfg(test)]
3372mod evidence_graph_projection_tests {
3373    use super::*;
3374
3375    fn custom_property_workspace_occurrence(name: &str) -> OmenaWorkspaceOccurrenceV0 {
3376        OmenaWorkspaceOccurrenceV0 {
3377            moniker: "custom-property:file:///workspace/app.css#--token".to_string(),
3378            uri: "file:///workspace/app.css".to_string(),
3379            name: name.to_string(),
3380            range: ParserRangeV0 {
3381                start: ParserPositionV0 {
3382                    line: 0,
3383                    character: 0,
3384                },
3385                end: ParserPositionV0 {
3386                    line: 0,
3387                    character: 7,
3388                },
3389            },
3390            kind: OmenaWorkspaceOccurrenceKindV0::CustomPropertyDeclaration,
3391            role: OmenaWorkspaceOccurrenceRoleV0::Definition,
3392            surface: OmenaWorkspaceOccurrenceSurfaceV0::OmenaLspStyleIndex,
3393            family: Some(OmenaWorkspaceOccurrenceFamilyV0::CustomProperty),
3394            namespace: None,
3395            target_style_uri: None,
3396            rename_target: true,
3397        }
3398    }
3399
3400    #[test]
3401    fn workspace_occurrence_identity_uses_custom_property_keys_without_changing_wire_name() {
3402        let escaped = custom_property_workspace_occurrence(r"--to\6b en");
3403        let plain = custom_property_workspace_occurrence("--token");
3404
3405        assert_eq!(escaped, plain);
3406        let mut non_custom = plain.clone();
3407        non_custom.kind = OmenaWorkspaceOccurrenceKindV0::SourceSelectorReference;
3408        non_custom.family = Some(OmenaWorkspaceOccurrenceFamilyV0::CssModuleSelector);
3409        assert_eq!(escaped.cmp(&non_custom), plain.cmp(&non_custom));
3410
3411        let mut occurrences = vec![escaped.clone(), plain];
3412        occurrences.sort();
3413        occurrences.dedup();
3414        assert_eq!(occurrences.len(), 1);
3415        let serialized = serde_json::to_value(&escaped).unwrap_or_default();
3416        assert_eq!(serialized["name"], r"--to\6b en");
3417    }
3418
3419    #[test]
3420    fn diagnostic_provenance_projection_preserves_legacy_labels() {
3421        let labels = vec![
3422            "omena-query.source-syntax-index",
3423            "omena-query.style-selector-definitions",
3424        ];
3425
3426        assert_eq!(
3427            project_omena_query_diagnostic_provenance_from_evidence_graph(
3428                "missingSelector",
3429                labels.clone(),
3430            ),
3431            labels
3432        );
3433    }
3434
3435    #[test]
3436    fn checker_product_gate_projection_matches_legacy_extension() {
3437        let code = "missingSelector";
3438        let mut expected = vec![
3439            "omena-query.source-syntax-index",
3440            "omena-query.style-selector-definitions",
3441        ];
3442        let gate =
3443            omena_query_checker_orchestrator::gate_omena_query_checker_product_diagnostic_code_v0(
3444                code,
3445            );
3446        if !gate.enforcement_passed {
3447            expected.push("omena-query-checker-orchestrator.product-diagnostic-gate-failed");
3448        } else {
3449            for label in gate.provenance {
3450                if !expected.contains(&label) {
3451                    expected.push(label);
3452                }
3453            }
3454        }
3455
3456        let mut actual = vec![
3457            "omena-query.source-syntax-index",
3458            "omena-query.style-selector-definitions",
3459        ];
3460        populate_omena_query_checker_product_gate_provenance_from_evidence_graph(code, &mut actual);
3461
3462        assert_eq!(actual, expected);
3463    }
3464
3465    #[test]
3466    fn source_diagnostic_precision_projects_byte_identical_shape() -> Result<(), serde_json::Error>
3467    {
3468        let precision = source_diagnostic_precision(
3469            "classValueResolution",
3470            "sourceSyntaxIndex",
3471            "perSourceReference",
3472        );
3473        let serialized = serde_json::to_value(&precision)?;
3474
3475        assert_eq!(
3476            serialized,
3477            serde_json::json!({
3478                "product": "omena-query.analysis-precision",
3479                "valueDomain": "classValueResolution",
3480                "flowSensitivity": "sourceSyntaxIndex",
3481                "contextSensitivity": "perSourceReference",
3482                "revisionAxis": "OmenaQuerySourceDiagnosticsForFileV0.input"
3483            })
3484        );
3485        Ok(())
3486    }
3487}