1use super::*;
2
3fn value_distribution_entropy_bits(value_frequencies: &[usize]) -> f64 {
10 let total: usize = value_frequencies.iter().copied().sum();
11 if total == 0 {
12 return 0.0;
13 }
14 let total = total as f64;
15 value_frequencies
16 .iter()
17 .copied()
18 .filter(|&count| count > 0)
19 .map(|count| {
20 let p = count as f64 / total;
21 -p * p.log2()
22 })
23 .sum()
24}
25
26pub fn summarize_omena_query_design_system_minimum_description(
44 source_uri: impl Into<String>,
45 source_hash: impl Into<String>,
46 rule_count: usize,
47 observation_count: usize,
48 value_frequencies: &[usize],
49) -> DesignSystemMinimumDescriptionV0 {
50 let alphabet_size = value_frequencies.iter().filter(|&&count| count > 0).count();
51 let model_bits = if alphabet_size > 1 {
53 rule_count as f64 * (alphabet_size as f64).log2()
54 } else {
55 0.0
56 };
57 let entropy_bits = value_distribution_entropy_bits(value_frequencies);
60 let residual_bits = observation_count as f64 * entropy_bits;
61 let model_class = if alphabet_size > 1 {
62 ModelClassV0::TwoPartMultinomial
63 } else {
64 ModelClassV0::TwoPartUniform
65 };
66 DesignSystemMinimumDescriptionV0 {
67 schema_version: OMENA_QUERY_CURRENT_SCHEMA_VERSION,
68 product: "omena-query.design-system-minimum-description",
69 layer_marker: "mdl-bits",
70 feature_gate: "mdl",
71 model_bits,
72 residual_bits,
73 total_bits: model_bits + residual_bits,
74 unit: "bit",
75 model_class,
76 rule_count,
77 observation_count,
78 canonical_form_present: false,
79 cascade_proof_obligation_count: 0,
80 sass_namespace_partition: SassNamespaceBitsV0 {
81 namespace_count: 0,
82 partition_count: 0,
83 deterministic_partition: true,
84 },
85 generated_at_iso: "deterministic-v0",
86 source_pin: SourcePinV0 {
87 source_uri: source_uri.into(),
88 source_hash: source_hash.into(),
89 },
90 weights_calibration_pin: "uniform-v0",
91 weights_version: "0",
92 semiring_instance: "tropical",
93 }
94}
95
96pub struct OmenaQueryCanonicalFormInput {
97 pub pass_id: &'static str,
98 pub before: String,
99 pub canonical_after: String,
100 pub fallback_after: String,
101 pub mdl_bits: f64,
102 pub ast_size_bits: f64,
103 pub iteration_count: usize,
104 pub eclass_count: usize,
105 pub enode_count: usize,
106}
107
108pub fn summarize_omena_query_canonical_form(
109 input: OmenaQueryCanonicalFormInput,
110) -> CanonicalFormV0 {
111 let canonical_matches_fallback = input.canonical_after == input.fallback_after;
112 let bits_saved_vs_fallback = input.ast_size_bits - input.mdl_bits;
113 CanonicalFormV0 {
114 schema_version: OMENA_QUERY_CURRENT_SCHEMA_VERSION,
115 product: "omena-query.canonical-form",
116 layer_marker: "mdl-bits",
117 feature_gate: "mdl",
118 pass_id: input.pass_id,
119 before: input.before,
120 canonical_after: input.canonical_after,
121 fallback_after: input.fallback_after,
122 canonical_matches_fallback,
123 bits_saved_vs_fallback,
124 mdl_bits: input.mdl_bits,
125 ast_size_bits: input.ast_size_bits,
126 unit: "bit",
127 iteration_count: input.iteration_count,
128 eclass_count: input.eclass_count,
129 enode_count: input.enode_count,
130 cascade_safe_witness: "cascade proof obligation remains conservative",
131 egg_analysis_witness: "extracted canonical form is compared against fallback output",
132 }
133}
134
135pub fn summarize_omena_query_boundary(input: &EngineInputV2) -> OmenaQueryBoundarySummaryV0 {
136 let fragment_bundle = summarize_omena_query_fragment_bundle(input);
137 let expression_semantics_query_count = fragment_bundle.expression_semantics.fragments.len();
138 let source_resolution_query_count = fragment_bundle.source_resolution.fragments.len();
139 let selector_usage_query_count = fragment_bundle.selector_usage.fragments.len();
140
141 OmenaQueryBoundarySummaryV0 {
142 schema_version: OMENA_QUERY_CURRENT_SCHEMA_VERSION,
143 product: "omena-query.boundary",
144 query_engine_name: "omena-query",
145 schema_version_policy: summarize_omena_query_schema_version_policy(),
146 input_version: input.version.clone(),
147 abstract_value_domain: summarize_omena_query_core_abstract_value_domain(),
148 selected_query_adapter_capabilities:
149 summarize_omena_query_selected_query_adapter_capabilities(),
150 delegated_fragment_products: vec![
151 "engine-input-producers.expression-semantics-query-fragments",
152 "engine-input-producers.source-resolution-query-fragments",
153 "omena-resolver.boundary",
154 "omena-resolver.source-resolution-runtime-index",
155 "engine-input-producers.selector-usage-query-fragments",
156 "engine-input-producers.expression-domain-flow-analysis",
157 "engine-input-producers.expression-domain-control-flow-analysis",
158 "engine-input-producers.expression-domain-call-site-flow-analysis",
159 "engine-input-producers.expression-domain-provenance-explanations",
160 "engine-input-producers.expression-domain-reduced-product-iteration",
161 "omena-query.expression-domain-incremental-flow-analysis",
162 "omena-query.expression-domain-selector-projection",
163 "omena-parser.style-facts",
164 "omena-query-checker-orchestrator.cascade-gate",
165 "omena-query-transform-runner.boundary",
166 "omena-transform-bundle.source",
167 "omena-transform-target.plan",
168 "omena-transform-egg.plan",
169 "omena-transform-egg.execution",
170 "omena-transform-print.artifact",
171 "omena-transform-passes.plan",
172 "omena-transform-passes.execution",
173 "omena-cascade.custom-property-least-fixed-point",
174 "omena-semantic.style-context-index",
175 "omena-query.transform-execute",
176 "omena-query.transform-context-from-engine-input",
177 "omena-query.consumer-check-style-source",
178 "omena-query.consumer-build-style-source",
179 "omena-query.evaluation-runtime",
180 "omena-query.fast-facts",
181 "omena-query.analyzed-graph",
182 "omena-query.custom-property-annotations",
183 "omena-query.design-system-minimum-description",
184 ],
185 expression_semantics_query_count,
186 source_resolution_query_count,
187 selector_usage_query_count,
188 total_query_count: expression_semantics_query_count
189 + source_resolution_query_count
190 + selector_usage_query_count,
191 ready_surfaces: vec![
192 "queryFragmentBundle",
193 "abstractValueProjectionContract",
194 "abstractValueReducedProductAlgebra",
195 "sourceResolutionResolverBoundary",
196 "sourceResolutionRuntimeIndex",
197 "expressionDomainFlowAnalysisBoundary",
198 "expressionDomainControlFlowAnalysisBoundary",
199 "expressionDomainCallSiteFlowAnalysisBoundary",
200 "expressionDomainProvenanceExplanations",
201 "expressionDomainReducedProductIteration",
202 "expressionDomainSalsaRuntime",
203 "expressionDomainSelectorProjection",
204 "styleHoverRenderParts",
205 "styleMissingCustomPropertyDiagnostics",
206 "styleDiagnosticsForFile",
207 "sourceDiagnosticsForFile",
208 "crossLanguageDiagnostics",
209 "cascadeAwareDiagnostics",
210 "completionAt",
211 "refsForClass",
212 "renamePlan",
213 "readCascadeAtPosition",
214 "readStyleContextIndex",
215 "readCascadeCustomPropertyLeastFixedPoint",
216 "sourceMissingSelectorDiagnostics",
217 "sourceProviderCandidateResolution",
218 "selectorRenameEditPlanning",
219 "sassSymbolResolutionPrimitives",
220 "sassModuleSourceSelection",
221 "omenaParserStyleFactExtraction",
222 "queryCheckerOrchestratorBoundary",
223 "queryTransformRunnerBoundary",
224 "transformPlanFacade",
225 "transformEggExecutionWitnesses",
226 "transformExecutionRuntime",
227 "transformExecutionRunner",
228 "semanticReachabilityTransformContext",
229 "consumerCheckFacade",
230 "consumerBuildFacade",
231 "consumerTransformPassListFacade",
232 "queryBoundarySummary",
233 "selectedQueryBackendAdapter",
234 "queryEvaluationRuntime",
235 "omenaParserStyleDocumentSummary",
236 "omenaParserPublicContractTypes",
237 "fastFactsV0",
238 "analyzedGraphV0",
239 "customPropertyAnnotations",
240 "designSystemMinimumDescription",
241 ],
242 cme_coupled_surfaces: vec!["EngineInputV2", "producerQueryFragments"],
243 next_decoupling_targets: Vec::new(),
244 }
245}
246
247pub fn summarize_omena_query_evaluation_runtime(
248 input: &EngineInputV2,
249 runtime: &mut OmenaQueryExpressionDomainFlowRuntimeV0,
250) -> OmenaQueryEvaluationRuntimeSummaryV0 {
251 let selected_query_adapter_capabilities =
252 summarize_omena_query_selected_query_adapter_capabilities();
253 let source_resolution_runtime = summarize_omena_query_source_resolution_runtime(input);
254 let expression_domain_runtime =
255 summarize_omena_query_expression_domain_incremental_flow_analysis(input, runtime);
256
257 OmenaQueryEvaluationRuntimeSummaryV0 {
258 schema_version: OMENA_QUERY_CURRENT_SCHEMA_VERSION,
259 product: "omena-query.evaluation-runtime",
260 input_version: input.version.clone(),
261 selected_query_adapter_capabilities,
262 runtime_products: vec![
263 source_resolution_runtime.product,
264 expression_domain_runtime.product,
265 "omena-query.style-document-summary",
266 ],
267 source_resolution_expression_count: source_resolution_runtime.expression_count,
268 source_resolution_unresolved_expression_count: source_resolution_runtime
269 .unresolved_expression_count,
270 expression_domain_revision: expression_domain_runtime.revision,
271 expression_domain_graph_count: expression_domain_runtime.graph_count,
272 expression_domain_dirty_graph_count: expression_domain_runtime.dirty_graph_count,
273 expression_domain_reused_graph_count: expression_domain_runtime.reused_graph_count,
274 style_document_summary_source: "omena-parser.style-facts",
275 ready_surfaces: vec![
276 "selectedQueryBackendAdapter",
277 "sourceResolutionRuntimeIndex",
278 "expressionDomainSalsaRuntime",
279 "expressionDomainSelectorProjection",
280 "omenaParserStyleDocumentSummary",
281 "omenaParserPublicContractTypes",
282 ],
283 retired_couplings: vec![
284 "engineStyleParserStyleDocumentSummary",
285 "engineStyleParserQueryPublicTypes",
286 ],
287 }
288}
289
290pub fn summarize_omena_query_selected_query_adapter_capabilities()
291-> SelectedQueryAdapterCapabilitiesV0 {
292 SelectedQueryAdapterCapabilitiesV0 {
293 schema_version: OMENA_QUERY_CURRENT_SCHEMA_VERSION,
294 product: "omena-query.selected-query-adapter-capabilities",
295 default_candidate_backend: "rust-selected-query",
296 schema_version_policy: summarize_omena_query_schema_version_policy(),
297 schema_version_checks: vec![
298 check_omena_query_schema_version(Some(OMENA_QUERY_CURRENT_SCHEMA_VERSION)),
299 check_omena_query_schema_version(Some(OMENA_QUERY_CURRENT_SCHEMA_VERSION_LABEL)),
300 check_omena_query_schema_version(Some("1")),
301 check_omena_query_schema_version(None),
302 ],
303 backend_kinds: vec![
304 SelectedQueryBackendCapabilityV0 {
305 backend_kind: "typescript-current",
306 source_resolution: false,
307 expression_semantics: false,
308 selector_usage: false,
309 style_semantic_graph: false,
310 },
311 SelectedQueryBackendCapabilityV0 {
312 backend_kind: "rust-source-resolution",
313 source_resolution: true,
314 expression_semantics: false,
315 selector_usage: false,
316 style_semantic_graph: false,
317 },
318 SelectedQueryBackendCapabilityV0 {
319 backend_kind: "rust-expression-semantics",
320 source_resolution: false,
321 expression_semantics: true,
322 selector_usage: false,
323 style_semantic_graph: false,
324 },
325 SelectedQueryBackendCapabilityV0 {
326 backend_kind: "rust-selector-usage",
327 source_resolution: false,
328 expression_semantics: false,
329 selector_usage: true,
330 style_semantic_graph: false,
331 },
332 SelectedQueryBackendCapabilityV0 {
333 backend_kind: "rust-selected-query",
334 source_resolution: true,
335 expression_semantics: true,
336 selector_usage: true,
337 style_semantic_graph: true,
338 },
339 ],
340 runner_commands: vec![
341 SelectedQueryRunnerCommandV0 {
342 surface: "queryEvaluationRuntime",
343 command: "input-omena-query-evaluation-runtime",
344 input_contract: "EngineInputV2 + OmenaQueryExpressionDomainFlowRuntimeV0",
345 output_product: "omena-query.evaluation-runtime",
346 },
347 SelectedQueryRunnerCommandV0 {
348 surface: "sourceResolution",
349 command: "input-source-resolution-canonical-producer",
350 input_contract: "EngineInputV2",
351 output_product: "engine-input-producers.source-resolution-canonical-producer",
352 },
353 SelectedQueryRunnerCommandV0 {
354 surface: "sourceResolutionRuntime",
355 command: "input-omena-resolver-source-resolution-runtime",
356 input_contract: "EngineInputV2",
357 output_product: "omena-resolver.source-resolution-runtime-index",
358 },
359 SelectedQueryRunnerCommandV0 {
360 surface: "expressionSemantics",
361 command: "input-expression-semantics-canonical-producer",
362 input_contract: "EngineInputV2",
363 output_product: "engine-input-producers.expression-semantics-canonical-producer",
364 },
365 SelectedQueryRunnerCommandV0 {
366 surface: "expressionDomainFlowAnalysis",
367 command: "input-expression-domain-flow-analysis",
368 input_contract: "EngineInputV2",
369 output_product: "engine-input-producers.expression-domain-flow-analysis",
370 },
371 SelectedQueryRunnerCommandV0 {
372 surface: "expressionDomainControlFlowAnalysis",
373 command: "input-expression-domain-control-flow-analysis",
374 input_contract: "EngineInputV2",
375 output_product: "engine-input-producers.expression-domain-control-flow-analysis",
376 },
377 SelectedQueryRunnerCommandV0 {
378 surface: "expressionDomainCallSiteFlowAnalysis",
379 command: "input-expression-domain-call-site-flow-analysis",
380 input_contract: "EngineInputV2",
381 output_product: "engine-input-producers.expression-domain-call-site-flow-analysis",
382 },
383 SelectedQueryRunnerCommandV0 {
384 surface: "expressionDomainProvenanceExplanations",
385 command: "input-expression-domain-provenance-explanations",
386 input_contract: "EngineInputV2",
387 output_product: "engine-input-producers.expression-domain-provenance-explanations",
388 },
389 SelectedQueryRunnerCommandV0 {
390 surface: "expressionDomainReducedProductIteration",
391 command: "input-expression-domain-reduced-product-iteration",
392 input_contract: "EngineInputV2",
393 output_product: "engine-input-producers.expression-domain-reduced-product-iteration",
394 },
395 SelectedQueryRunnerCommandV0 {
396 surface: "expressionDomainIncrementalFlowAnalysis",
397 command: "input-expression-domain-incremental-flow-analysis",
398 input_contract: "EngineInputV2 + OmenaQueryExpressionDomainFlowRuntimeV0",
399 output_product: "omena-query.expression-domain-incremental-flow-analysis",
400 },
401 SelectedQueryRunnerCommandV0 {
402 surface: "expressionDomainSelectorProjection",
403 command: "input-expression-domain-selector-projection",
404 input_contract: "EngineInputV2",
405 output_product: "omena-query.expression-domain-selector-projection",
406 },
407 SelectedQueryRunnerCommandV0 {
408 surface: "selectorUsage",
409 command: "input-selector-usage-canonical-producer",
410 input_contract: "EngineInputV2",
411 output_product: "engine-input-producers.selector-usage-canonical-producer",
412 },
413 SelectedQueryRunnerCommandV0 {
414 surface: "omenaParserStyleFacts",
415 command: "omena-parser-style-facts",
416 input_contract: "OmenaParserStyleFactsInputV0",
417 output_product: "omena-parser.style-facts",
418 },
419 SelectedQueryRunnerCommandV0 {
420 surface: "styleSemanticGraph",
421 command: "style-semantic-graph",
422 input_contract: "StyleSemanticGraphInputV0",
423 output_product: "omena-semantic.style-semantic-graph",
424 },
425 SelectedQueryRunnerCommandV0 {
426 surface: "readCascadeAtPosition",
427 command: "read-cascade-at-position",
428 input_contract: "ReadCascadeAtPositionInputV0",
429 output_product: "omena-query.read-cascade-at-position",
430 },
431 SelectedQueryRunnerCommandV0 {
432 surface: "styleDiagnosticsForFile",
433 command: "style-diagnostics-for-file",
434 input_contract: "StyleDiagnosticsForFileInputV0",
435 output_product: "omena-query.diagnostics-for-file",
436 },
437 SelectedQueryRunnerCommandV0 {
438 surface: "sourceDiagnosticsForFile",
439 command: "source-diagnostics-for-file",
440 input_contract: "SourceDiagnosticsForFileInputV0",
441 output_product: "omena-query.diagnostics-for-file",
442 },
443 SelectedQueryRunnerCommandV0 {
444 surface: "completionAt",
445 command: "completion-at",
446 input_contract: "CompletionAtInputV0",
447 output_product: "omena-query.completion-at",
448 },
449 SelectedQueryRunnerCommandV0 {
450 surface: "styleCodeActions",
451 command: "style-code-actions",
452 input_contract: "StyleCodeActionsInputV0",
453 output_product: "omena-query.code-actions",
454 },
455 SelectedQueryRunnerCommandV0 {
456 surface: "refsForClass",
457 command: "refs-for-class",
458 input_contract: "RefsForClassInputV0",
459 output_product: "omena-query.refs-for-class",
460 },
461 SelectedQueryRunnerCommandV0 {
462 surface: "renamePlan",
463 command: "rename-plan",
464 input_contract: "RenamePlanInputV0",
465 output_product: "omena-query.rename-plan",
466 },
467 SelectedQueryRunnerCommandV0 {
468 surface: "readStyleContextIndex",
469 command: "read-style-context-index",
470 input_contract: "ReadStyleContextIndexInputV0",
471 output_product: "omena-query.style-context-index",
472 },
473 SelectedQueryRunnerCommandV0 {
474 surface: "styleSemanticGraphBatch",
475 command: "style-semantic-graph-batch",
476 input_contract: "StyleSemanticGraphBatchInputV0",
477 output_product: "omena-semantic.style-semantic-graph-batch",
478 },
479 SelectedQueryRunnerCommandV0 {
480 surface: "transformPlan",
481 command: "transform-plan",
482 input_contract: "TransformPlanInputV0",
483 output_product: "omena-query.transform-plan",
484 },
485 SelectedQueryRunnerCommandV0 {
486 surface: "transformContext",
487 command: "transform-context",
488 input_contract: "TransformContextInputV0",
489 output_product: "omena-query.transform-context",
490 },
491 SelectedQueryRunnerCommandV0 {
492 surface: "semanticReachabilityTransformContext",
493 command: "transform-context-from-engine-input",
494 input_contract: "EngineInputV2 + targetStylePath + closedStyleWorld",
495 output_product: "omena-query.transform-context-from-engine-input",
496 },
497 SelectedQueryRunnerCommandV0 {
498 surface: "transformExecute",
499 command: "transform-execute",
500 input_contract: "TransformExecuteInputV0",
501 output_product: "omena-query.transform-execute",
502 },
503 SelectedQueryRunnerCommandV0 {
504 surface: "consumerCheckStyleSource",
505 command: "consumer-check-style-source",
506 input_contract: "ConsumerStyleSourceInputV0",
507 output_product: "omena-query.consumer-check-style-source",
508 },
509 SelectedQueryRunnerCommandV0 {
510 surface: "consumerBuildStyleSource",
511 command: "consumer-build-style-source",
512 input_contract: "ConsumerStyleSourceBuildInputV0",
513 output_product: "omena-query.consumer-build-style-source",
514 },
515 SelectedQueryRunnerCommandV0 {
516 surface: "consumerBuildStyleSources",
517 command: "consumer-build-style-sources",
518 input_contract: "ConsumerStyleSourcesBuildInputV0",
519 output_product: "omena-query.consumer-build-style-source",
520 },
521 SelectedQueryRunnerCommandV0 {
522 surface: "consumerTransformPassList",
523 command: "consumer-transform-pass-list",
524 input_contract: "None",
525 output_product: "omena-query.transform-pass-list",
526 },
527 ],
528 expression_semantics_payload_contracts: vec![
529 "valueDomainKind",
530 "valueDomainDerivation",
531 "valueDomainProvenanceTree",
532 ],
533 required_input_contracts: vec![
534 "EngineInputV2",
535 "StyleSemanticGraphInputV0",
536 "ReadCascadeAtPositionInputV0",
537 "StyleDiagnosticsForFileInputV0",
538 "SourceDiagnosticsForFileInputV0",
539 "CompletionAtInputV0",
540 "StyleCodeActionsInputV0",
541 "RefsForClassInputV0",
542 "RenamePlanInputV0",
543 "ReadStyleContextIndexInputV0",
544 "StyleSemanticGraphBatchInputV0",
545 "OmenaParserStyleFactsInputV0",
546 "TransformPlanInputV0",
547 "TransformContextInputV0",
548 "TransformContextFromEngineInputV0",
549 "TransformExecuteInputV0",
550 "ConsumerStyleSourceInputV0",
551 "ConsumerStyleSourceBuildInputV0",
552 "ConsumerStyleSourcesBuildInputV0",
553 ],
554 adapter_readiness: vec![
555 "backendCapabilityMatrix",
556 "canonicalProducerWrapperBoundary",
557 "styleSemanticGraphBridgeBoundary",
558 "runnerCommandContract",
559 "fragmentBundleBoundary",
560 "sourceResolutionRuntimeIndex",
561 "expressionSemanticsDerivationPayload",
562 "expressionDomainFlowAnalysisRunner",
563 "expressionDomainControlFlowAnalysisRunner",
564 "expressionDomainCallSiteFlowAnalysisRunner",
565 "expressionDomainProvenanceExplanationRunner",
566 "expressionDomainSalsaRuntime",
567 "expressionDomainSelectorProjection",
568 "omenaParserStyleFactExtraction",
569 "readCascadeAtPosition",
570 "readCascadeCustomPropertyLeastFixedPoint",
571 "styleDiagnosticsForFileRunner",
572 "sourceDiagnosticsForFileRunner",
573 "completionAtRunner",
574 "styleCodeActionsRunner",
575 "refsForClassRunner",
576 "renamePlanRunner",
577 "readStyleContextIndexRunner",
578 "transformPlanRunner",
579 "transformEggExecutionWitnesses",
580 "transformContextProducer",
581 "semanticReachabilityTransformContext",
582 "transformExecutionRunner",
583 "consumerCheckFacade",
584 "consumerBuildFacade",
585 "consumerTransformPassListFacade",
586 "queryEvaluationRuntime",
587 ],
588 routing_status: "runtimeBacked",
589 }
590}
591
592pub fn summarize_omena_query_schema_version_policy() -> OmenaQuerySchemaVersionPolicyV0 {
593 OmenaQuerySchemaVersionPolicyV0 {
594 schema_version: OMENA_QUERY_CURRENT_SCHEMA_VERSION,
595 product: "omena-query.schema-version-policy",
596 current_version: OMENA_QUERY_CURRENT_SCHEMA_VERSION,
597 current_version_label: OMENA_QUERY_CURRENT_SCHEMA_VERSION_LABEL,
598 accepted_versions: vec![OMENA_QUERY_CURRENT_SCHEMA_VERSION],
599 deprecated_versions: Vec::new(),
600 rejected_version_policy: "rejectUnknownVersionsBeforeExecution",
601 missing_version_policy: "rejectMissingSchemaVersionOnExternalInputs",
602 migration_policy: vec![
603 "new versions require additive reader before writer",
604 "old and new versions must run through the same omena-query facade during migration",
605 "schema gate must include current accepted, missing, label-only, and future-version checks",
606 "breaking payload changes require a new numeric schemaVersion and explicit migration adapter",
607 ],
608 compatibility_gate: "rust/omena-query/adapter-capabilities",
609 }
610}
611
612pub fn check_omena_query_schema_version(
613 requested_version: Option<&str>,
614) -> OmenaQuerySchemaVersionCheckV0 {
615 match requested_version {
616 Some(OMENA_QUERY_CURRENT_SCHEMA_VERSION) => OmenaQuerySchemaVersionCheckV0 {
617 schema_version: OMENA_QUERY_CURRENT_SCHEMA_VERSION,
618 product: "omena-query.schema-version-check",
619 requested_version: Some(OMENA_QUERY_CURRENT_SCHEMA_VERSION.to_string()),
620 current_version: OMENA_QUERY_CURRENT_SCHEMA_VERSION,
621 accepted: true,
622 status: "current",
623 migration_action: "executeCurrentFacade",
624 reason: "requested schemaVersion is the current numeric wire version",
625 },
626 Some(OMENA_QUERY_CURRENT_SCHEMA_VERSION_LABEL) => OmenaQuerySchemaVersionCheckV0 {
627 schema_version: OMENA_QUERY_CURRENT_SCHEMA_VERSION,
628 product: "omena-query.schema-version-check",
629 requested_version: Some(OMENA_QUERY_CURRENT_SCHEMA_VERSION_LABEL.to_string()),
630 current_version: OMENA_QUERY_CURRENT_SCHEMA_VERSION,
631 accepted: false,
632 status: "labelOnlyVersionRejected",
633 migration_action: "sendNumericSchemaVersion",
634 reason: "V0 is a Rust type label; external payloads must use numeric schemaVersion 0",
635 },
636 Some(version) => OmenaQuerySchemaVersionCheckV0 {
637 schema_version: OMENA_QUERY_CURRENT_SCHEMA_VERSION,
638 product: "omena-query.schema-version-check",
639 requested_version: Some(version.to_string()),
640 current_version: OMENA_QUERY_CURRENT_SCHEMA_VERSION,
641 accepted: false,
642 status: "unsupportedVersion",
643 migration_action: "rejectBeforeExecution",
644 reason: "no migration adapter is registered for this schemaVersion",
645 },
646 None => OmenaQuerySchemaVersionCheckV0 {
647 schema_version: OMENA_QUERY_CURRENT_SCHEMA_VERSION,
648 product: "omena-query.schema-version-check",
649 requested_version: None,
650 current_version: OMENA_QUERY_CURRENT_SCHEMA_VERSION,
651 accepted: false,
652 status: "missingVersion",
653 migration_action: "rejectBeforeExecution",
654 reason: "external payloads must carry schemaVersion explicitly",
655 },
656 }
657}