Skip to main content

ta_benchmarks/
catalogue_report.rs

1//! Diagnostic evidence parsing and human report projection for Catalogue measurements.
2
3use crate::catalogue_cases::measurement_coverage;
4use crate::catalogue_evidence::{
5    clean, BenchmarkRow, ValidatedCatalogueEvidence, C_DIRECT_MODE, INPUT_LENGTHS, PYTHON_MODE,
6    RUST_CALLER_MODE, RUST_OWNED_MODE, RUST_PREPARED_MODE, RUST_STREAMING_MODE,
7};
8use crate::catalogue_statistics::validate_positive_timing_evidence;
9use crate::pattern_shapes::PATTERN_SHAPES;
10use serde_json::Value;
11use std::cmp::Ordering;
12use std::collections::{BTreeMap, BTreeSet};
13use std::fs;
14
15use std::path::Path;
16#[derive(Clone, Debug, PartialEq)]
17pub struct DiagnosticEvidence {
18    pub captured_at_utc: String,
19    pub baseline_commit: String,
20    pub final_commit: String,
21    pub commands: BTreeMap<String, String>,
22    pub environment: BTreeMap<String, String>,
23    pub tickets: Vec<DiagnosticTicket>,
24}
25
26#[derive(Clone, Debug, PartialEq)]
27pub struct DiagnosticTicket {
28    pub ticket: u64,
29    pub ranked_hypotheses: Vec<Value>,
30    pub profile_or_compiler_evidence: Value,
31    pub criterion_comparisons: Vec<Value>,
32    pub semantic_comparisons: Vec<Value>,
33    pub required_neighbor_coverage: Vec<Value>,
34}
35
36#[derive(Clone, Debug, PartialEq)]
37pub struct CriterionDiagnostics {
38    pub pre_commit: String,
39    pub final_commit: String,
40    pub environment: BTreeMap<String, String>,
41    pub measurements: Vec<CriterionDiagnosticMeasurement>,
42}
43
44#[derive(Clone, Debug, PartialEq)]
45pub struct CriterionDiagnosticMeasurement {
46    pub ticket: u64,
47    pub case_id: String,
48    pub role: String,
49    pub revision: String,
50    pub command: String,
51    pub cwd: String,
52    pub benchmark_id: String,
53    pub timed_boundary: String,
54    pub sample_count: usize,
55    pub observations_per_iteration: usize,
56    pub median_ns: f64,
57    pub ci95_lower_ns: f64,
58    pub ci95_upper_ns: f64,
59    pub throughput_observations_per_second: f64,
60}
61
62#[derive(Clone, Debug, PartialEq)]
63pub struct CycleRegressionEvidence {
64    pub command: String,
65    pub cwd: String,
66    pub os: String,
67    pub arch: String,
68    pub cpu: String,
69    pub seam: String,
70    pub measurements: Vec<CycleMeasurement>,
71    pub comparisons: Vec<CycleComparison>,
72}
73
74#[derive(Clone, Debug, PartialEq)]
75pub struct CycleMeasurement {
76    pub indicator: String,
77    pub input_length: usize,
78    pub variant: String,
79    pub source_provenance: String,
80    pub sample_count: usize,
81    pub median_ns: f64,
82    pub ci95_lower_ns: f64,
83    pub ci95_upper_ns: f64,
84    pub throughput_observations_per_second: f64,
85}
86
87#[derive(Clone, Debug, PartialEq)]
88pub struct CycleComparison {
89    pub indicator: String,
90    pub input_length: usize,
91    pub before_variant: String,
92    pub after_variant: String,
93    pub cursor_vs_baseline_percent: f64,
94    pub after_vs_baseline_percent: f64,
95    pub source_proof: String,
96    pub disposition: String,
97}
98
99pub fn read_diagnostic_evidence(path: &Path) -> Result<DiagnosticEvidence, String> {
100    let input =
101        fs::read_to_string(path).map_err(|error| format!("read {}: {error}", path.display()))?;
102    parse_diagnostic_evidence(&input)
103}
104
105pub fn parse_diagnostic_evidence(input: &str) -> Result<DiagnosticEvidence, String> {
106    let root: Value = serde_json::from_str(input)
107        .map_err(|error| format!("diagnostic evidence JSON: {error}"))?;
108    if json_string(&root, "schema")? != "fast-ta.issue-57-62.diagnostic-evidence.v1" {
109        return Err("unsupported diagnostic evidence schema".to_owned());
110    }
111    let baseline_revision = json_object(&root, "baseline_revision")?;
112    let final_revision = json_object(&root, "final_revision")?;
113    let commands = json_string_map(json_object(&root, "commands")?, "commands")?;
114    let environment = json_scalar_map(json_object(&root, "environment")?, "environment")?;
115    let artifacts = json_array(&root, "artifacts")?;
116    for required in [
117        "issue_57_62_criterion_diagnostics.json",
118        "issue_57_62_semantic_pre.tsv",
119        "issue_57_62_semantic_final.tsv",
120    ] {
121        if !artifacts.iter().any(|artifact| {
122            artifact
123                .get("path")
124                .and_then(Value::as_str)
125                .is_some_and(|path| path.ends_with(required))
126        }) {
127            return Err(format!(
128                "diagnostic evidence is missing artifact {required}"
129            ));
130        }
131    }
132    let mut tickets = Vec::new();
133    for value in json_array(&root, "tickets")? {
134        let ticket = json_u64(value, "ticket")?;
135        let ranked_hypotheses = json_array(value, "ranked_hypotheses")?.to_vec();
136        if !(3..=5).contains(&ranked_hypotheses.len()) {
137            return Err(format!(
138                "issue {ticket} must contain 3 to 5 ranked hypotheses"
139            ));
140        }
141        for (index, hypothesis) in ranked_hypotheses.iter().enumerate() {
142            if json_u64(hypothesis, "rank")? != index as u64 + 1 {
143                return Err(format!(
144                    "issue {ticket} hypotheses are not consecutively ranked"
145                ));
146            }
147            for key in ["hypothesis", "prediction", "status", "evidence"] {
148                json_nonempty_string(hypothesis, key)?;
149            }
150        }
151        let profile = value
152            .get("profile_or_compiler_evidence")
153            .filter(|candidate| candidate.is_object())
154            .ok_or_else(|| format!("issue {ticket} is missing profile/compiler evidence"))?
155            .clone();
156        for key in [
157            "artifact",
158            "artifact_sha256",
159            "benchmark_command",
160            "profile_command",
161            "benchmark_id",
162            "case",
163            "cwd",
164        ] {
165            json_nonempty_string(&profile, key)?;
166        }
167        let criterion_comparisons =
168            json_array(value, "criterion_same_session_comparisons")?.to_vec();
169        let semantic_comparisons =
170            json_array(value, "semantic_same_run_rust_c_comparisons")?.to_vec();
171        let required_neighbor_coverage = json_array(value, "required_neighbor_coverage")?.to_vec();
172        if criterion_comparisons.is_empty()
173            || semantic_comparisons.is_empty()
174            || required_neighbor_coverage.is_empty()
175        {
176            return Err(format!(
177                "issue {ticket} is missing Criterion, semantic, or neighboring-workload evidence"
178            ));
179        }
180        for comparison in &criterion_comparisons {
181            if json_u64(comparison, "ticket")? != ticket {
182                return Err(format!(
183                    "issue {ticket} contains a cross-ticket Criterion row"
184                ));
185            }
186            for key in ["case_id", "role", "disposition"] {
187                json_nonempty_string(comparison, key)?;
188            }
189            for key in [
190                "pre_median_ns",
191                "final_median_ns",
192                "change_percent",
193                "speedup",
194                "noise_gate_percent",
195            ] {
196                json_numeric(comparison, key)?;
197            }
198        }
199        for semantic in &semantic_comparisons {
200            if json_u64(semantic, "ticket")? != ticket {
201                return Err(format!(
202                    "issue {ticket} contains a cross-ticket semantic row"
203                ));
204            }
205            json_nonempty_string(semantic, "case_id")?;
206            json_nonempty_string(semantic, "disposition")?;
207            json_u64(semantic, "input_length")?;
208            json_bool(semantic, "input_checksum_match")?;
209            json_bool(semantic, "output_checksum_match")?;
210            for revision in ["pre", "final"] {
211                format_json_timing(json_object(semantic, &format!("{revision}_fast_ta"))?)?;
212                format_json_timing(json_object(semantic, &format!("{revision}_ta_lib_c"))?)?;
213                json_numeric(semantic, &format!("{revision}_rust_over_c"))?;
214            }
215        }
216        for neighbor in &required_neighbor_coverage {
217            json_nonempty_string(neighbor, "workload")?;
218            json_nonempty_string(neighbor, "status")?;
219        }
220        tickets.push(DiagnosticTicket {
221            ticket,
222            ranked_hypotheses,
223            profile_or_compiler_evidence: profile,
224            criterion_comparisons,
225            semantic_comparisons,
226            required_neighbor_coverage,
227        });
228    }
229    let actual = tickets
230        .iter()
231        .map(|ticket| ticket.ticket)
232        .collect::<BTreeSet<_>>();
233    let expected = (57_u64..=62).collect::<BTreeSet<_>>();
234    if actual != expected || tickets.len() != expected.len() {
235        return Err(
236            "diagnostic evidence must contain issues 57 through 62 exactly once".to_owned(),
237        );
238    }
239    tickets.sort_by_key(|ticket| ticket.ticket);
240    Ok(DiagnosticEvidence {
241        captured_at_utc: json_nonempty_string(&root, "captured_at_utc")?,
242        baseline_commit: json_nonempty_string(baseline_revision, "commit")?,
243        final_commit: json_nonempty_string(final_revision, "commit")?,
244        commands,
245        environment,
246        tickets,
247    })
248}
249
250pub fn read_criterion_diagnostics(path: &Path) -> Result<CriterionDiagnostics, String> {
251    let input =
252        fs::read_to_string(path).map_err(|error| format!("read {}: {error}", path.display()))?;
253    parse_criterion_diagnostics(&input)
254}
255
256pub fn parse_criterion_diagnostics(input: &str) -> Result<CriterionDiagnostics, String> {
257    let root: Value = serde_json::from_str(input)
258        .map_err(|error| format!("Criterion diagnostics JSON: {error}"))?;
259    if json_string(&root, "schema")? != "fast-ta.issue-57-62.criterion-diagnostics.v1" {
260        return Err("unsupported Criterion diagnostics schema".to_owned());
261    }
262    let mut measurements = Vec::new();
263    for value in json_array(&root, "measurements")? {
264        let median = json_object(value, "median")?;
265        let measurement = CriterionDiagnosticMeasurement {
266            ticket: json_u64(value, "ticket")?,
267            case_id: json_nonempty_string(value, "case_id")?,
268            role: json_nonempty_string(value, "role")?,
269            revision: json_nonempty_string(value, "revision")?,
270            command: json_nonempty_string(value, "command")?,
271            cwd: json_nonempty_string(value, "cwd")?,
272            benchmark_id: json_nonempty_string(value, "benchmark_id")?,
273            timed_boundary: json_nonempty_string(value, "timed_boundary")?,
274            sample_count: json_u64(value, "sample_count")? as usize,
275            observations_per_iteration: json_u64(value, "observations_per_iteration")? as usize,
276            median_ns: json_f64(median, "point_estimate_ns")?,
277            ci95_lower_ns: json_f64(median, "ci95_lower_ns")?,
278            ci95_upper_ns: json_f64(median, "ci95_upper_ns")?,
279            throughput_observations_per_second: json_f64(
280                value,
281                "throughput_observations_per_second",
282            )?,
283        };
284        if !(57..=62).contains(&measurement.ticket)
285            || !matches!(measurement.revision.as_str(), "pre" | "final")
286        {
287            return Err("Criterion measurement has unsupported ticket or revision".to_owned());
288        }
289        validate_positive_timing_evidence(
290            measurement.median_ns,
291            measurement.ci95_lower_ns,
292            measurement.ci95_upper_ns,
293            measurement.throughput_observations_per_second,
294            measurement.sample_count,
295            measurement.observations_per_iteration,
296        )
297        .map_err(|error| format!("Criterion {}: {error}", measurement.case_id))?;
298        measurements.push(measurement);
299    }
300    if measurements.is_empty() {
301        return Err("Criterion diagnostics has no measurements".to_owned());
302    }
303    let grouped = measurements
304        .iter()
305        .map(|measurement| {
306            (
307                measurement.ticket,
308                measurement.case_id.as_str(),
309                measurement.revision.as_str(),
310            )
311        })
312        .collect::<BTreeSet<_>>();
313    for measurement in &measurements {
314        let other = if measurement.revision == "pre" {
315            "final"
316        } else {
317            "pre"
318        };
319        if !grouped.contains(&(measurement.ticket, measurement.case_id.as_str(), other)) {
320            return Err(format!(
321                "Criterion {} is missing its {other} measurement",
322                measurement.case_id
323            ));
324        }
325    }
326    let mut comparison_keys = BTreeSet::new();
327    for comparison in json_array(&root, "comparisons")? {
328        let ticket = json_u64(comparison, "ticket")?;
329        let case_id = json_nonempty_string(comparison, "case_id")?;
330        if !comparison_keys.insert((ticket, case_id.clone())) {
331            return Err(format!("duplicate Criterion comparison for {case_id}"));
332        }
333        let pre = measurements
334            .iter()
335            .find(|measurement| {
336                measurement.ticket == ticket
337                    && measurement.case_id == case_id
338                    && measurement.revision == "pre"
339            })
340            .ok_or_else(|| format!("Criterion comparison {case_id} has no pre measurement"))?;
341        let final_measurement = measurements
342            .iter()
343            .find(|measurement| {
344                measurement.ticket == ticket
345                    && measurement.case_id == case_id
346                    && measurement.revision == "final"
347            })
348            .ok_or_else(|| format!("Criterion comparison {case_id} has no final measurement"))?;
349        if json_f64(comparison, "pre_median_ns")? != pre.median_ns
350            || json_f64(comparison, "final_median_ns")? != final_measurement.median_ns
351        {
352            return Err(format!(
353                "Criterion comparison {case_id} medians do not match its measurements"
354            ));
355        }
356        json_nonempty_string(comparison, "disposition")?;
357    }
358    if comparison_keys.len() * 2 != grouped.len() {
359        return Err("Criterion comparisons do not cover every measurement pair".to_owned());
360    }
361    Ok(CriterionDiagnostics {
362        pre_commit: json_nonempty_string(json_object(&root, "pre_revision")?, "commit")?,
363        final_commit: json_nonempty_string(json_object(&root, "final_revision")?, "commit")?,
364        environment: json_scalar_map(json_object(&root, "environment")?, "environment")?,
365        measurements,
366    })
367}
368
369pub fn read_cycle_regression(path: &Path) -> Result<CycleRegressionEvidence, String> {
370    let input =
371        fs::read_to_string(path).map_err(|error| format!("read {}: {error}", path.display()))?;
372    parse_cycle_regression(&input)
373}
374
375pub fn parse_cycle_regression(input: &str) -> Result<CycleRegressionEvidence, String> {
376    let mut run = None;
377    let mut measurements = Vec::new();
378    let mut comparisons = Vec::new();
379    for (index, line) in input
380        .lines()
381        .enumerate()
382        .filter(|(_, line)| !line.is_empty())
383    {
384        let value: Value = serde_json::from_str(line)
385            .map_err(|error| format!("cycle regression JSONL row {}: {error}", index + 1))?;
386        match json_nonempty_string(&value, "record_type")?.as_str() {
387            "run" => {
388                if run.is_some() {
389                    return Err("cycle regression has multiple run records".to_owned());
390                }
391                if json_string(&value, "schema")? != "fast-ta.issue61.cycle-regression.v1" {
392                    return Err("unsupported cycle regression schema".to_owned());
393                }
394                let host = json_object(&value, "host")?;
395                run = Some((
396                    json_nonempty_string(&value, "command")?,
397                    json_nonempty_string(&value, "cwd")?,
398                    json_nonempty_string(host, "os")?,
399                    json_nonempty_string(host, "arch")?,
400                    json_nonempty_string(host, "cpu")?,
401                    json_nonempty_string(&value, "seam")?,
402                ));
403            }
404            "measurement" => {
405                let ci = json_array(&value, "median_95ci_ns")?;
406                if ci.len() != 2 {
407                    return Err("cycle measurement CI must have two bounds".to_owned());
408                }
409                let measurement = CycleMeasurement {
410                    indicator: json_nonempty_string(&value, "indicator")?,
411                    input_length: json_u64(&value, "size")? as usize,
412                    variant: json_nonempty_string(&value, "variant")?,
413                    source_provenance: json_nonempty_string(&value, "source_provenance")?,
414                    sample_count: json_u64(&value, "samples")? as usize,
415                    median_ns: json_f64(&value, "median_ns")?,
416                    ci95_lower_ns: ci[0]
417                        .as_f64()
418                        .ok_or_else(|| "cycle CI lower bound is not numeric".to_owned())?,
419                    ci95_upper_ns: ci[1]
420                        .as_f64()
421                        .ok_or_else(|| "cycle CI upper bound is not numeric".to_owned())?,
422                    throughput_observations_per_second: json_f64(
423                        &value,
424                        "throughput_observations_per_second",
425                    )?,
426                };
427                validate_positive_timing_evidence(
428                    measurement.median_ns,
429                    measurement.ci95_lower_ns,
430                    measurement.ci95_upper_ns,
431                    measurement.throughput_observations_per_second,
432                    measurement.sample_count,
433                    measurement.input_length,
434                )
435                .map_err(|error| format!("cycle {}: {error}", measurement.indicator))?;
436                measurements.push(measurement);
437            }
438            "comparison" => comparisons.push(CycleComparison {
439                indicator: json_nonempty_string(&value, "indicator")?,
440                input_length: json_u64(&value, "size")? as usize,
441                before_variant: json_nonempty_string(&value, "before_variant")?,
442                after_variant: json_nonempty_string(&value, "after_variant")?,
443                cursor_vs_baseline_percent: json_f64(&value, "cursor_vs_b156ac1_median_percent")?,
444                after_vs_baseline_percent: json_f64(&value, "after_vs_b156ac1_percent")?,
445                source_proof: json_nonempty_string(&value, "after_source_proof")?,
446                disposition: json_nonempty_string(&value, "disposition")?,
447            }),
448            other => return Err(format!("unsupported cycle record type {other:?}")),
449        }
450    }
451    let (command, cwd, os, arch, cpu, seam) =
452        run.ok_or_else(|| "cycle regression has no run record".to_owned())?;
453    if measurements.is_empty() || comparisons.is_empty() {
454        return Err("cycle regression is missing measurements or comparisons".to_owned());
455    }
456    for comparison in &comparisons {
457        for variant in ["b156ac1_modulo", comparison.before_variant.as_str()] {
458            if !measurements.iter().any(|measurement| {
459                measurement.indicator == comparison.indicator
460                    && measurement.input_length == comparison.input_length
461                    && measurement.variant == variant
462            }) {
463                return Err(format!(
464                    "cycle comparison {} {} is missing variant {variant}",
465                    comparison.indicator, comparison.input_length
466                ));
467            }
468        }
469    }
470    Ok(CycleRegressionEvidence {
471        command,
472        cwd,
473        os,
474        arch,
475        cpu,
476        seam,
477        measurements,
478        comparisons,
479    })
480}
481
482fn json_array<'a>(value: &'a Value, key: &str) -> Result<&'a [Value], String> {
483    value
484        .get(key)
485        .and_then(Value::as_array)
486        .map(Vec::as_slice)
487        .ok_or_else(|| format!("JSON value is missing array field {key:?}"))
488}
489
490fn json_object<'a>(value: &'a Value, key: &str) -> Result<&'a Value, String> {
491    value
492        .get(key)
493        .filter(|value| value.is_object())
494        .ok_or_else(|| format!("JSON value is missing object field {key:?}"))
495}
496
497fn json_string_map(value: &Value, name: &str) -> Result<BTreeMap<String, String>, String> {
498    value
499        .as_object()
500        .expect("json_object checked the value")
501        .iter()
502        .map(|(key, value)| {
503            value
504                .as_str()
505                .filter(|value| !value.is_empty())
506                .map(|value| (key.clone(), value.to_owned()))
507                .ok_or_else(|| format!("{name}.{key} must be a non-empty string"))
508        })
509        .collect()
510}
511
512fn json_scalar_map(value: &Value, name: &str) -> Result<BTreeMap<String, String>, String> {
513    value
514        .as_object()
515        .expect("json_object checked the value")
516        .iter()
517        .map(|(key, value)| {
518            let rendered = match value {
519                Value::String(value) if !value.is_empty() => value.clone(),
520                Value::Number(value) => value.to_string(),
521                Value::Bool(value) => value.to_string(),
522                _ => return Err(format!("{name}.{key} must be a non-empty scalar")),
523            };
524            Ok((key.clone(), rendered))
525        })
526        .collect()
527}
528
529#[derive(Clone, Debug, PartialEq)]
530pub struct PlatformQualification {
531    pub artifact: String,
532    pub platform: String,
533    pub precision: String,
534    pub runtime: String,
535    pub profile: String,
536    pub cpu: String,
537    pub os: String,
538    pub commit: String,
539    pub workflow_run_id: String,
540    pub workflow_run_url: String,
541    pub workflow_job: String,
542    pub active_backend: String,
543    pub feature_flags: String,
544    pub measurements: Vec<QualificationMeasurement>,
545}
546
547#[derive(Clone, Debug, PartialEq)]
548pub struct QualificationMeasurement {
549    pub mode: String,
550    pub backend: String,
551    pub input_length: usize,
552    pub equivalent_to_scalar: bool,
553    pub semantic_status: String,
554    pub timing_status: String,
555    pub median_ns: f64,
556    pub ci95_lower_ns: f64,
557    pub ci95_upper_ns: f64,
558    pub throughput_observations_per_second: f64,
559    pub sample_count: usize,
560    pub timed_boundary: String,
561}
562
563pub fn read_platform_qualification(path: &Path) -> Result<PlatformQualification, String> {
564    let input =
565        fs::read_to_string(path).map_err(|error| format!("read {}: {error}", path.display()))?;
566    parse_platform_qualification(&input, &path.display().to_string())
567}
568
569pub fn parse_platform_qualification(
570    input: &str,
571    artifact: &str,
572) -> Result<PlatformQualification, String> {
573    let mut metadata = None;
574    let mut has_aggregate_validation = false;
575    let mut validated_backends = BTreeSet::new();
576    let mut measurements = Vec::new();
577    for (index, line) in input
578        .lines()
579        .enumerate()
580        .filter(|(_, line)| !line.is_empty())
581    {
582        let value: Value = serde_json::from_str(line)
583            .map_err(|error| format!("{artifact} JSONL row {}: {error}", index + 1))?;
584        match json_string(&value, "record")?.as_str() {
585            "metadata" => {
586                if metadata.is_some() {
587                    return Err(format!("{artifact} has more than one metadata record"));
588                }
589                let active_backend = value
590                    .get("active_backend")
591                    .and_then(Value::as_str)
592                    .or_else(|| value.get("simd_backend").and_then(Value::as_str))
593                    .ok_or_else(|| format!("{artifact} metadata is missing a runtime backend"))?
594                    .to_owned();
595                let feature_flags = value
596                    .get("features")
597                    .and_then(Value::as_str)
598                    .filter(|features| !features.is_empty())
599                    .map(str::to_owned)
600                    .or_else(|| {
601                        let cargo = value
602                            .get("cargo_features")?
603                            .as_str()
604                            .filter(|features| !features.is_empty())?;
605                        let target = value
606                            .get("target_features")?
607                            .as_str()
608                            .filter(|features| !features.is_empty())?;
609                        Some(format!("cargo_features={cargo}; target_features={target}"))
610                    })
611                    .or_else(|| {
612                        let flags = ["scalar_feature_flags", "simd_feature_flags"]
613                            .into_iter()
614                            .map(|key| {
615                                value
616                                    .get(key)
617                                    .and_then(Value::as_str)
618                                    .filter(|flag| !flag.is_empty())
619                                    .map(|flag| format!("{key}={flag}"))
620                            })
621                            .collect::<Option<Vec<_>>>()?;
622                        Some(flags.join("; "))
623                    })
624                    .ok_or_else(|| {
625                        format!("{artifact} metadata is missing string field \"features\"")
626                    })?;
627                let profile = value
628                    .get("profile")
629                    .and_then(Value::as_str)
630                    .or_else(|| value.get("rust_profile").and_then(Value::as_str))
631                    .filter(|profile| !profile.is_empty())
632                    .ok_or_else(|| {
633                        format!("{artifact} metadata is missing string field \"profile\"")
634                    })?
635                    .to_owned();
636                metadata = Some((
637                    json_string(&value, "platform")?,
638                    json_nonempty_string(&value, "precision")?,
639                    json_string(&value, "runtime")?,
640                    profile,
641                    json_string(&value, "cpu")?,
642                    json_nonempty_string(&value, "os")?,
643                    json_string(&value, "commit")?,
644                    json_identifier(&value, "workflow_run_id")?,
645                    json_string(&value, "workflow_run_url")?,
646                    json_identifier_alias(&value, "workflow_job", "workflow_job_id")?,
647                    active_backend,
648                    feature_flags,
649                ));
650            }
651            "measurement" => {
652                let measurement = QualificationMeasurement {
653                    mode: json_string(&value, "mode")?,
654                    backend: json_string(&value, "backend")?,
655                    input_length: json_u64(&value, "input_length")? as usize,
656                    equivalent_to_scalar: json_bool(&value, "equivalent_to_scalar")?,
657                    semantic_status: json_string(&value, "semantic_status")?,
658                    timing_status: json_string(&value, "timing_status")?,
659                    median_ns: json_f64(&value, "median_ns")?,
660                    ci95_lower_ns: json_f64(&value, "ci95_lower_ns")?,
661                    ci95_upper_ns: json_f64(&value, "ci95_upper_ns")?,
662                    throughput_observations_per_second: json_f64(
663                        &value,
664                        "throughput_observations_per_second",
665                    )?,
666                    sample_count: json_u64(&value, "sample_count")? as usize,
667                    timed_boundary: json_string(&value, "timed_boundary")?,
668                };
669                if !INPUT_LENGTHS.contains(&measurement.input_length) {
670                    return Err(format!(
671                        "{artifact} has unsupported input length {}",
672                        measurement.input_length
673                    ));
674                }
675                validate_positive_timing_evidence(
676                    measurement.median_ns,
677                    measurement.ci95_lower_ns,
678                    measurement.ci95_upper_ns,
679                    measurement.throughput_observations_per_second,
680                    measurement.sample_count,
681                    measurement.input_length,
682                )
683                .map_err(|error| format!("{artifact} measurement row {}: {error}", index + 1))?;
684                measurements.push(measurement);
685            }
686            "validation" => match validate_qualification_validation(&value, artifact, index + 1)? {
687                Some(backend) if !validated_backends.insert(backend.clone()) => {
688                    return Err(format!(
689                        "{artifact} has duplicate validation records for backend {backend:?}"
690                    ));
691                }
692                Some(_) => {}
693                None if has_aggregate_validation => {
694                    return Err(format!(
695                        "{artifact} has more than one aggregate validation record"
696                    ));
697                }
698                None => has_aggregate_validation = true,
699            },
700            other => return Err(format!("{artifact} has unsupported record type {other:?}")),
701        }
702    }
703    if !has_aggregate_validation && validated_backends.is_empty() {
704        return Err(format!("{artifact} has no validation records"));
705    }
706    let (
707        platform,
708        precision,
709        runtime,
710        profile,
711        cpu,
712        os,
713        commit,
714        workflow_run_id,
715        workflow_run_url,
716        workflow_job,
717        active_backend,
718        feature_flags,
719    ) = metadata.ok_or_else(|| format!("{artifact} has no metadata record"))?;
720    if measurements.is_empty() {
721        return Err(format!("{artifact} has no measurement records"));
722    }
723    for measurement in &measurements {
724        let is_direct_c =
725            measurement.backend == "ta-lib-c" && measurement.mode == "direct C caller-owned";
726        let needs_backend_validation = measurement.equivalent_to_scalar && !is_direct_c;
727        if needs_backend_validation
728            && !has_aggregate_validation
729            && !validated_backends.contains(&measurement.backend)
730        {
731            return Err(format!(
732                "{artifact} reports scalar equivalence for backend {:?} without a matching validation record",
733                measurement.backend
734            ));
735        }
736    }
737    Ok(PlatformQualification {
738        artifact: artifact.to_owned(),
739        platform,
740        precision,
741        runtime,
742        cpu,
743        os,
744        profile,
745        commit,
746        workflow_run_id,
747        workflow_run_url,
748        workflow_job,
749        active_backend,
750        feature_flags,
751        measurements,
752    })
753}
754
755fn json_string(value: &Value, key: &str) -> Result<String, String> {
756    value
757        .get(key)
758        .and_then(Value::as_str)
759        .map(str::to_owned)
760        .ok_or_else(|| format!("JSON record is missing string field {key:?}"))
761}
762
763fn json_nonempty_string(value: &Value, key: &str) -> Result<String, String> {
764    let parsed = json_string(value, key)?;
765    if parsed.is_empty() {
766        return Err(format!("JSON record has empty string field {key:?}"));
767    }
768    Ok(parsed)
769}
770
771fn json_u64(value: &Value, key: &str) -> Result<u64, String> {
772    value
773        .get(key)
774        .and_then(Value::as_u64)
775        .ok_or_else(|| format!("JSON record is missing integer field {key:?}"))
776}
777
778fn json_identifier(value: &Value, key: &str) -> Result<String, String> {
779    match value.get(key) {
780        Some(Value::String(value)) if !value.is_empty() => Ok(value.clone()),
781        Some(Value::Number(value)) if value.is_u64() => Ok(value.to_string()),
782        _ => Err(format!(
783            "JSON record is missing string or integer field {key:?}"
784        )),
785    }
786}
787
788fn json_identifier_alias(value: &Value, key: &str, alias: &str) -> Result<String, String> {
789    json_identifier(value, key).or_else(|_| json_identifier(value, alias))
790}
791
792fn json_f64(value: &Value, key: &str) -> Result<f64, String> {
793    value
794        .get(key)
795        .and_then(Value::as_f64)
796        .ok_or_else(|| format!("JSON record is missing numeric field {key:?}"))
797}
798
799fn validate_qualification_validation(
800    value: &Value,
801    artifact: &str,
802    row_number: usize,
803) -> Result<Option<String>, String> {
804    let invalid = |reason: &str| format!("{artifact} validation row {row_number} {reason}");
805    if value.get("exact_scalar_equivalence").is_some() {
806        for key in [
807            "public_boundary",
808            "exact_scalar_equivalence",
809            "error_semantics_verified",
810            "mismatched_length_error_equal_to_scalar",
811            "non_finite_error_equal_to_scalar",
812        ] {
813            if !json_bool(value, key)? {
814                return Err(invalid(&format!("has {key}=false")));
815            }
816        }
817        let backend = json_nonempty_string(value, "backend")?;
818        let observed_backend = json_string(value, "observed_backend")?;
819        if backend != observed_backend {
820            return Err(invalid("did not observe its requested backend"));
821        }
822        for key in ["precision", "mode"] {
823            if json_string(value, key)?.is_empty() {
824                return Err(invalid(&format!("has empty {key}")));
825            }
826        }
827        return Ok(Some(backend));
828    } else if value.get("errors_match_scalar").is_some() {
829        for key in [
830            "public_boundary",
831            "unequal_lengths_verified",
832            "non_finite_verified",
833            "short_output_verified",
834            "errors_match_scalar",
835        ] {
836            if !json_bool(value, key)? {
837                return Err(invalid(&format!("has {key}=false")));
838            }
839        }
840        let backend = json_nonempty_string(value, "backend")?;
841        for key in [
842            "unequal_lengths_error",
843            "non_finite_error",
844            "short_output_error",
845        ] {
846            if json_string(value, key)?.is_empty() {
847                return Err(invalid(&format!("has empty {key}")));
848            }
849        }
850        return Ok(Some(backend));
851    } else {
852        for key in ["unequal_lengths_verified", "non_finite_verified"] {
853            if !json_bool(value, key)? {
854                return Err(invalid(&format!("has {key}=false")));
855            }
856        }
857        for key in [
858            "scalar_unequal_lengths_error",
859            "scalar_non_finite_error",
860            "simd_unequal_lengths_error",
861            "simd_non_finite_error",
862        ] {
863            if json_string(value, key)?.is_empty() {
864                return Err(invalid(&format!("has empty {key}")));
865            }
866        }
867    }
868    Ok(None)
869}
870
871fn json_bool(value: &Value, key: &str) -> Result<bool, String> {
872    value
873        .get(key)
874        .and_then(Value::as_bool)
875        .ok_or_else(|| format!("JSON record is missing boolean field {key:?}"))
876}
877
878pub fn render_report(rows: &[BenchmarkRow]) -> Result<String, String> {
879    if rows.is_empty() {
880        return Err(
881            "cannot render an Indicator Catalogue matrix report without raw rows".to_owned(),
882        );
883    }
884    let first = &rows[0];
885    let mut report =
886        String::from("Pinned representative Indicator Catalogue performance matrix\n\n");
887    report.push_str(&format!(
888        "TA-Lib {} ({}) | Python {} binding {} / core {} | NumPy {} | float {}-bit\n",
889        first.ta_lib_version,
890        first.ta_lib_revision,
891        first.python_version,
892        first.python_binding_version,
893        first.python_ta_lib_version,
894        first.numpy_version,
895        first.float_width
896    ));
897    report.push_str(&format!(
898        "Commit {} (dirty: {}) | {} | {} {} | {}\n",
899        first.commit, first.dirty, first.cpu, first.os, first.arch, first.rustc
900    ));
901    report.push_str(if first.dirty {
902        "Run classification: diagnostic only; a dirty run cannot replace the canonical baseline.\n"
903    } else {
904        "Run classification: clean reference run; completeness and publication status follow.\n"
905    });
906    report.push_str("95% intervals are deterministic bootstrap confidence intervals for the median (10,000 resamples). Outliers use Tukey's 1.5 IQR fences. Rust/C ratios below use only same-run caller-owned rows with identical case, parameters, fixture, and input length.\n\n");
907    let coverage = measurement_coverage()?;
908    report.push_str(&format!(
909        "Executable measurement coverage: {}/{} implemented Indicator Definitions ({:.1}%); {} implemented definitions are not measured by this representative matrix.\n\n",
910        coverage.measured_count,
911        coverage.implemented_count,
912        coverage.measured_percent(),
913        coverage.unmeasured_count
914    ));
915    report.push_str("| Family | Measured | Implemented |\n|---|---:|---:|\n");
916    for (family, measured, implemented) in coverage.measured_by_family() {
917        report.push_str(&format!("| {family} | {measured} | {implemented} |\n"));
918    }
919    report.push('\n');
920
921    report.push_str("Representative matrix\n\n| Family | Definition | Parameters | Output |\n|---|---|---|---|\n");
922    let mut matrix = BTreeSet::new();
923    for row in rows {
924        matrix.insert((
925            row.indicator_family.clone(),
926            row.case_id.clone(),
927            row.parameters.clone(),
928            format!(
929                "{} x{}",
930                row.output_kind,
931                row.output_arity
932                    .map_or_else(|| "NA".to_owned(), |value| value.to_string())
933            ),
934        ));
935    }
936    for (family, case_id, parameters, output) in matrix {
937        report.push_str(&format!(
938            "| {family} | {case_id} | {parameters} | {output} |\n"
939        ));
940    }
941
942    let case_ids = rows
943        .iter()
944        .map(|row| row.case_id.as_str())
945        .collect::<BTreeSet<_>>();
946    report.push_str("\nPattern Recognition execution-shape coverage\n\n| Definition | Execution shape | Rationale |\n|---|---|---|\n");
947    for shape in PATTERN_SHAPES {
948        if case_ids.contains(shape.case_id) {
949            report.push_str(&format!(
950                "| {} | {} | {} |\n",
951                shape.case_id, shape.execution_shape, shape.rationale
952            ));
953        }
954    }
955
956    let pairs = primary_pairs(rows);
957    report.push_str("\nSame-run geometric Rust/C caller-owned summary\n\n| Input | Mode | Comparable cases | Geometric Rust/C latency ratio | Semantics |\n|---:|---|---:|---:|---|\n");
958    for input_length in INPUT_LENGTHS {
959        let ratios = pairs
960            .iter()
961            .filter(|pair| pair.input_length == input_length)
962            .map(|pair| pair.ratio)
963            .collect::<Vec<_>>();
964        if ratios.is_empty() {
965            report.push_str(&format!("| {input_length} | {RUST_CALLER_MODE} vs {C_DIRECT_MODE} | 0 | unavailable | no comparable measured pairs |\n"));
966        } else {
967            let geometric =
968                (ratios.iter().map(|ratio| ratio.ln()).sum::<f64>() / ratios.len() as f64).exp();
969            report.push_str(&format!("| {input_length} | {RUST_CALLER_MODE} vs {C_DIRECT_MODE} | {} | {geometric:.3}x | comparable only |\n", ratios.len()));
970        }
971    }
972
973    report.push_str("\nLarge-throughput optimization ordering\n\n| Rank | Definition | Rust/C latency ratio | Disposition |\n|---:|---|---:|---|\n");
974    let mut large = pairs
975        .into_iter()
976        .filter(|pair| pair.input_length == 65_536)
977        .collect::<Vec<_>>();
978    large.sort_by(|left, right| {
979        right
980            .ratio
981            .partial_cmp(&left.ratio)
982            .unwrap_or(Ordering::Equal)
983            .then_with(|| left.case_id.cmp(&right.case_id))
984    });
985    if large.is_empty() {
986        report.push_str("| - | - | unavailable | no comparable measured pairs |\n");
987    } else {
988        for (index, pair) in large.iter().enumerate() {
989            let disposition = if pair.ratio > 1.05 {
990                "remaining comparative gap above 5%"
991            } else if pair.ratio < 0.95 {
992                "fast-ta faster"
993            } else {
994                "parity band"
995            };
996            report.push_str(&format!(
997                "| {} | {} | {:.3}x | {disposition} |\n",
998                index + 1,
999                pair.case_id,
1000                pair.ratio
1001            ));
1002        }
1003    }
1004
1005    report.push_str("\nDetailed raw-row projection\n\n| Definition | Input | Implementation | Mode | Semantic | Comparison | Median | 95% CI | Throughput | Output Range |\n|---|---:|---|---|---|---|---:|---:|---:|---:|\n");
1006    let mut ordered = rows.to_vec();
1007    ordered.sort_by(|left, right| {
1008        left.case_id
1009            .cmp(&right.case_id)
1010            .then_with(|| left.input_length.cmp(&right.input_length))
1011            .then_with(|| left.implementation.cmp(&right.implementation))
1012            .then_with(|| left.mode.cmp(&right.mode))
1013    });
1014    for row in &ordered {
1015        let (median, ci, throughput) = if let Some(stats) = &row.stats {
1016            (
1017                format!("{:.3} us", stats.median_ns / 1_000.0),
1018                format!(
1019                    "[{:.3}, {:.3}] us",
1020                    stats.ci95_lower_ns / 1_000.0,
1021                    stats.ci95_upper_ns / 1_000.0
1022                ),
1023                format!(
1024                    "{:.3} Mobs/s",
1025                    stats.throughput_observations_per_second / 1.0e6
1026                ),
1027            )
1028        } else {
1029            (
1030                "unavailable".to_owned(),
1031                clean(&row.timing_reason),
1032                "unavailable".to_owned(),
1033            )
1034        };
1035        let range = match (row.output_begin, row.output_count) {
1036            (Some(begin), Some(count)) => format!("{begin}..{}", begin + count),
1037            _ => "unavailable".to_owned(),
1038        };
1039        let semantic = if row.semantic_reason.is_empty() {
1040            row.semantic_status.clone()
1041        } else {
1042            format!("{}: {}", row.semantic_status, clean(&row.semantic_reason))
1043        };
1044        let comparison = if row.comparison_reason.is_empty() {
1045            row.comparison_status.clone()
1046        } else {
1047            format!(
1048                "{}: {}",
1049                row.comparison_status,
1050                clean(&row.comparison_reason)
1051            )
1052        };
1053        report.push_str(&format!(
1054            "| {} | {} | {} | {} | {} | {} | {} | {} | {} | {} |\n",
1055            row.case_id,
1056            row.input_length,
1057            row.implementation,
1058            row.mode,
1059            semantic,
1060            comparison,
1061            median,
1062            ci,
1063            throughput,
1064            range
1065        ));
1066    }
1067
1068    report.push_str("\nSuppressed or unavailable results\n\n");
1069    let failures = ordered
1070        .iter()
1071        .filter(|row| row.semantic_status != "verified" || row.timing_status != "measured")
1072        .collect::<Vec<_>>();
1073    if failures.is_empty() {
1074        report.push_str("None. Every matrix row passed semantic verification before timing.\n");
1075    } else {
1076        for row in failures {
1077            report.push_str(&format!(
1078                "- {}/{}/{}: semantic={} ({}) timing={} ({})\n",
1079                row.case_id,
1080                row.input_length,
1081                row.mode,
1082                row.semantic_status,
1083                clean(&row.semantic_reason),
1084                row.timing_status,
1085                clean(&row.timing_reason)
1086            ));
1087        }
1088    }
1089    Ok(report)
1090}
1091
1092/// Renders the canonical comparison from evidence that already passed publication policy.
1093pub fn render_validated_report_with_comparison(
1094    evidence: &ValidatedCatalogueEvidence,
1095    baseline: &ValidatedCatalogueEvidence,
1096    diagnostic_evidence: &DiagnosticEvidence,
1097    criterion_diagnostics: &CriterionDiagnostics,
1098    cycle_regression: &CycleRegressionEvidence,
1099    platform_qualifications: &[PlatformQualification],
1100) -> Result<String, String> {
1101    render_report_with_comparison(
1102        evidence.rows(),
1103        baseline.rows(),
1104        diagnostic_evidence,
1105        criterion_diagnostics,
1106        cycle_regression,
1107        platform_qualifications,
1108    )
1109}
1110
1111fn render_report_with_comparison(
1112    rows: &[BenchmarkRow],
1113    baseline_rows: &[BenchmarkRow],
1114    diagnostic_evidence: &DiagnosticEvidence,
1115    criterion_diagnostics: &CriterionDiagnostics,
1116    cycle_regression: &CycleRegressionEvidence,
1117    platform_qualifications: &[PlatformQualification],
1118) -> Result<String, String> {
1119    if baseline_rows.is_empty() {
1120        return Err("clean pre-optimization baseline rows are required".to_owned());
1121    }
1122    if baseline_rows.iter().any(|row| row.dirty) {
1123        return Err("the canonical pre-optimization baseline must be clean".to_owned());
1124    }
1125    if criterion_diagnostics.pre_commit != diagnostic_evidence.baseline_commit
1126        || criterion_diagnostics.final_commit != diagnostic_evidence.final_commit
1127    {
1128        return Err("diagnostic and Criterion revision provenance do not match".to_owned());
1129    }
1130    let platform_set = platform_qualifications
1131        .iter()
1132        .map(|qualification| {
1133            (
1134                qualification.platform.as_str(),
1135                qualification.precision.as_str(),
1136            )
1137        })
1138        .collect::<BTreeSet<_>>();
1139    let required_platforms = [
1140        ("x86_64", "f64"),
1141        ("x86_64", "f32"),
1142        ("aarch64", "f64"),
1143        ("aarch64", "f32"),
1144        ("wasm32-unknown-unknown", "f64"),
1145    ]
1146    .into_iter()
1147    .collect::<BTreeSet<_>>();
1148    if platform_qualifications.len() != 5 || platform_set != required_platforms {
1149        return Err(
1150            "exactly x86 f64/f32, AArch64 f64/f32, and WASM f64 qualifications are required"
1151                .to_owned(),
1152        );
1153    }
1154    let report = render_report(rows)?;
1155    let marker = "\nDetailed raw-row projection\n";
1156    let (summary, details) = report
1157        .split_once(marker)
1158        .ok_or_else(|| "generated report is missing the detailed-row marker".to_owned())?;
1159    let first = rows
1160        .first()
1161        .ok_or_else(|| "cannot render a comparison report without raw rows".to_owned())?;
1162    let baseline_first = baseline_rows
1163        .first()
1164        .ok_or_else(|| "clean pre-optimization baseline rows are required".to_owned())?;
1165    let mut comparison = String::new();
1166
1167    let verified = rows
1168        .iter()
1169        .filter(|row| row.semantic_status == "verified")
1170        .count();
1171    let measured = rows
1172        .iter()
1173        .filter(|row| row.timing_status == "measured")
1174        .count();
1175    let sample_counts = rows
1176        .iter()
1177        .filter_map(|row| row.stats.as_ref().map(|stats| stats.sample_count))
1178        .collect::<BTreeSet<_>>();
1179    let clean_run = rows.iter().all(|row| !row.dirty);
1180    comparison.push_str(
1181        "\nRun completeness and semantic gate\n\n| Raw rows | Semantic verified | Measured | Sample counts | Provenance |\n|---:|---:|---:|---|---|\n",
1182    );
1183    comparison.push_str(&format!(
1184        "| {} | {verified} | {measured} | {} | {} |\n",
1185        rows.len(),
1186        sample_counts
1187            .iter()
1188            .map(usize::to_string)
1189            .collect::<Vec<_>>()
1190            .join(", "),
1191        if clean_run {
1192            "clean canonical final run"
1193        } else {
1194            "dirty diagnostic run"
1195        }
1196    ));
1197    comparison.push_str(&format!(
1198        "\nCanonical comparison baseline\n\nThe committed clean pre-optimization matrix is the sole comparison baseline: commit {} (dirty: {}), {} rows, {} on {} {}. The historical post-scalar dirty diagnostic is not an input to this report.\n",
1199        baseline_first.commit,
1200        baseline_first.dirty,
1201        baseline_rows.len(),
1202        clean(&baseline_first.cpu),
1203        clean(&baseline_first.os),
1204        clean(&baseline_first.arch)
1205    ));
1206
1207    let current_pairs = primary_pairs(rows);
1208    let current_by_case = current_pairs
1209        .iter()
1210        .cloned()
1211        .map(|pair| ((pair.case_id.clone(), pair.input_length), pair))
1212        .collect::<BTreeMap<_, _>>();
1213
1214    comparison.push_str(
1215        "\nPer-case caller-owned Rust/C latency ratios\n\n| Definition | 256 | 4,096 | 65,536 | 65,536 disposition |\n|---|---:|---:|---:|---|\n",
1216    );
1217    let case_ids = current_pairs
1218        .iter()
1219        .map(|pair| pair.case_id.clone())
1220        .collect::<BTreeSet<_>>();
1221    for case_id in case_ids {
1222        let ratios = INPUT_LENGTHS.map(|input_length| {
1223            current_by_case
1224                .get(&(case_id.clone(), input_length))
1225                .map(|pair| pair.ratio)
1226        });
1227        let large_disposition = match ratios[2] {
1228            Some(ratio) if ratio > 1.05 => "remaining gap above the 5% band",
1229            Some(ratio) if ratio < 0.95 => "fast-ta faster",
1230            Some(_) => "parity band",
1231            None => "unavailable",
1232        };
1233        comparison.push_str(&format!(
1234            "| {case_id} | {} | {} | {} | {large_disposition} |\n",
1235            format_ratio(ratios[0]),
1236            format_ratio(ratios[1]),
1237            format_ratio(ratios[2])
1238        ));
1239    }
1240
1241    comparison.push_str(
1242        "\nExecution-path cost summaries\n\nRatios are geometric path/C latency indices over matching cases. Only the caller-owned Rust/C row is a kernel comparison; the other rows expose distinct public or user-facing costs.\n\n| Input | Path | Cases | Geometric path/C ratio | Interpretation |\n|---:|---|---:|---:|---|\n",
1243    );
1244    let paths = [
1245        (
1246            "fast-ta",
1247            RUST_OWNED_MODE,
1248            "Owned Compact Output",
1249            "API-owned compact allocation included",
1250        ),
1251        (
1252            "fast-ta",
1253            RUST_CALLER_MODE,
1254            "caller-owned Rust/C kernel",
1255            "primary comparable kernel seam",
1256        ),
1257        (
1258            "fast-ta",
1259            RUST_PREPARED_MODE,
1260            "Prepared reuse",
1261            "preparation and caller output allocation excluded",
1262        ),
1263        (
1264            "fast-ta",
1265            RUST_STREAMING_MODE,
1266            "Streaming reset plus ticks",
1267            "separate stateful execution cost",
1268        ),
1269        (
1270            "TA-Lib Python",
1271            PYTHON_MODE,
1272            "official Python NumPy API",
1273            "user-facing API-owned output cost",
1274        ),
1275    ];
1276    for input_length in INPUT_LENGTHS {
1277        for (implementation, mode, label, interpretation) in paths {
1278            let ratios = path_ratios(rows, implementation, mode, input_length);
1279            if ratios.is_empty() {
1280                comparison.push_str(&format!(
1281                    "| {input_length} | {label} | 0 | unavailable | {interpretation} |\n"
1282                ));
1283            } else {
1284                comparison.push_str(&format!(
1285                    "| {input_length} | {label} | {} | {:.3}x | {interpretation} |\n",
1286                    ratios.len(),
1287                    geometric_mean(&ratios)
1288                ));
1289            }
1290        }
1291    }
1292
1293    comparison.push_str(&format!(
1294        "\nDurable issue 57–62 diagnostic evidence\n\nGenerated only from the diagnostic and Criterion JSON artifacts. The retired optimization-evidence TSV is not a numeric or narrative source. Capture: {}. Baseline revision: `{}`. Final diagnostic revision: `{}`.\n\nDiagnostic environment: {}.\n\nExact top-level reproduction commands\n\n| Purpose | Command |\n|---|---|\n",
1295        clean(&diagnostic_evidence.captured_at_utc),
1296        diagnostic_evidence.baseline_commit,
1297        diagnostic_evidence.final_commit,
1298        diagnostic_evidence
1299            .environment
1300            .iter()
1301            .map(|(key, value)| format!("{key}={}", clean(value)))
1302            .collect::<Vec<_>>()
1303            .join("; ")
1304    ));
1305    for (purpose, command) in &diagnostic_evidence.commands {
1306        comparison.push_str(&format!("| {} | `{}` |\n", clean(purpose), clean(command)));
1307    }
1308    for ticket in &diagnostic_evidence.tickets {
1309        let profile = &ticket.profile_or_compiler_evidence;
1310        comparison.push_str(&format!(
1311            "\nIssue {} diagnostic record\n\nPre-change sampled/compiler artifact: `{}` (`sha256:{}`). Benchmark ID: `{}`. Working directory: `{}`.\n\n- Benchmark command: `{}`\n- Capture command: `{}`\n",
1312            ticket.ticket,
1313            clean(&json_nonempty_string(profile, "artifact")?),
1314            clean(&json_nonempty_string(profile, "artifact_sha256")?),
1315            clean(&json_nonempty_string(profile, "benchmark_id")?),
1316            clean(&json_nonempty_string(profile, "cwd")?),
1317            clean(&json_nonempty_string(profile, "benchmark_command")?),
1318            clean(&json_nonempty_string(profile, "profile_command")?)
1319        ));
1320        if let Ok(hot_leaves) = json_array(profile, "ranked_hot_leaves") {
1321            comparison.push_str(
1322                "\nPre-change sampled hot leaves\n\n| Rank | Symbol | Samples |\n|---:|---|---:|\n",
1323            );
1324            for (index, leaf) in hot_leaves.iter().enumerate() {
1325                comparison.push_str(&format!(
1326                    "| {} | {} | {} |\n",
1327                    index + 1,
1328                    clean(&json_nonempty_string(leaf, "symbol")?),
1329                    json_u64(leaf, "samples")?
1330                ));
1331            }
1332        }
1333        if let Some(compiler) = profile.get("compiler_evidence") {
1334            comparison.push_str(&format!(
1335                "\nCompiler/objdump evidence: `{}` (`sha256:{}`). Command: `{}`. Finding: {}. Instruction count: {}; packed f64 add/divide: {}/{}; scalar validation load sites: {}.\n",
1336                clean(&json_nonempty_string(compiler, "artifact")?),
1337                clean(&json_nonempty_string(compiler, "artifact_sha256")?),
1338                clean(&json_nonempty_string(compiler, "command")?),
1339                clean(&json_nonempty_string(compiler, "finding")?),
1340                json_u64(compiler, "instruction_count")?,
1341                json_u64(compiler, "packed_f64_add_instructions")?,
1342                json_u64(compiler, "packed_f64_divide_instructions")?,
1343                json_u64(compiler, "scalar_validation_load_sites")?
1344            ));
1345        }
1346        comparison.push_str(
1347            "\nRanked falsifiable hypotheses\n\n| Rank | Hypothesis | Prediction | Status | Evidence |\n|---:|---|---|---|---|\n",
1348        );
1349        for hypothesis in &ticket.ranked_hypotheses {
1350            comparison.push_str(&format!(
1351                "| {} | {} | {} | {} | {} |\n",
1352                json_u64(hypothesis, "rank")?,
1353                clean(&json_nonempty_string(hypothesis, "hypothesis")?),
1354                clean(&json_nonempty_string(hypothesis, "prediction")?),
1355                clean(&json_nonempty_string(hypothesis, "status")?),
1356                clean(&json_nonempty_string(hypothesis, "evidence")?)
1357            ));
1358        }
1359        comparison.push_str(
1360            "\nRequired target and neighboring-workload dispositions\n\n| Workload | Disposition |\n|---|---|\n",
1361        );
1362        for neighbor in &ticket.required_neighbor_coverage {
1363            comparison.push_str(&format!(
1364                "| {} | {} |\n",
1365                clean(&json_nonempty_string(neighbor, "workload")?),
1366                clean(&json_nonempty_string(neighbor, "status")?)
1367            ));
1368        }
1369    }
1370
1371    comparison.push_str(&format!(
1372        "\nCriterion same-session before/after diagnostics\n\nAll values are parsed from the durable Criterion JSON. Environment: {}.\n\n| Ticket | Workload / role | Exact command and provenance | Pre median [95% CI] / throughput | Final median [95% CI] / throughput | Change | Disposition |\n|---:|---|---|---:|---:|---:|---|\n",
1373        criterion_diagnostics
1374            .environment
1375            .iter()
1376            .map(|(key, value)| format!("{key}={}", clean(value)))
1377            .collect::<Vec<_>>()
1378            .join("; ")
1379    ));
1380    let criterion_keys = criterion_diagnostics
1381        .measurements
1382        .iter()
1383        .map(|measurement| (measurement.ticket, measurement.case_id.as_str()))
1384        .collect::<BTreeSet<_>>();
1385    for (ticket_number, case_id) in criterion_keys {
1386        let pre = criterion_diagnostics
1387            .measurements
1388            .iter()
1389            .find(|measurement| {
1390                measurement.ticket == ticket_number
1391                    && measurement.case_id == case_id
1392                    && measurement.revision == "pre"
1393            })
1394            .expect("validated pre Criterion pair");
1395        let final_measurement = criterion_diagnostics
1396            .measurements
1397            .iter()
1398            .find(|measurement| {
1399                measurement.ticket == ticket_number
1400                    && measurement.case_id == case_id
1401                    && measurement.revision == "final"
1402            })
1403            .expect("validated final Criterion pair");
1404        let disposition = diagnostic_evidence
1405            .tickets
1406            .iter()
1407            .find(|ticket| ticket.ticket == ticket_number)
1408            .and_then(|ticket| {
1409                ticket
1410                    .criterion_comparisons
1411                    .iter()
1412                    .find(|value| value.get("case_id").and_then(Value::as_str) == Some(case_id))
1413            })
1414            .and_then(|value| value.get("disposition"))
1415            .and_then(Value::as_str)
1416            .ok_or_else(|| {
1417                format!("issue {ticket_number} {case_id} has no diagnostic disposition")
1418            })?;
1419        let change = (final_measurement.median_ns / pre.median_ns - 1.0) * 100.0;
1420        comparison.push_str(&format!(
1421            "| {ticket_number} | {} / {} | `{}`<br>cwd `{}`<br>benchmark `{}`<br>{} samples; {} | {:.3} us [{:.3}, {:.3}] / {:.3} Mobs/s | {:.3} us [{:.3}, {:.3}] / {:.3} Mobs/s | {change:+.1}% | {} |\n",
1422            clean(case_id),
1423            clean(&pre.role),
1424            clean(&pre.command),
1425            clean(&pre.cwd),
1426            clean(&pre.benchmark_id),
1427            pre.sample_count,
1428            clean(&pre.timed_boundary),
1429            pre.median_ns / 1_000.0,
1430            pre.ci95_lower_ns / 1_000.0,
1431            pre.ci95_upper_ns / 1_000.0,
1432            pre.throughput_observations_per_second / 1.0e6,
1433            final_measurement.median_ns / 1_000.0,
1434            final_measurement.ci95_lower_ns / 1_000.0,
1435            final_measurement.ci95_upper_ns / 1_000.0,
1436            final_measurement.throughput_observations_per_second / 1.0e6,
1437            clean(disposition)
1438        ));
1439    }
1440
1441    comparison.push_str(
1442        "\nSame-run semantic Rust/C pairs\n\nThese values and checksums are parsed from the semantic pair records embedded in the durable diagnostic JSON.\n\n| Ticket | Definition | Input | Revision | fast-ta median [95% CI] / throughput | TA-Lib C median [95% CI] / throughput | Rust/C | Checksums / disposition |\n|---:|---|---:|---|---:|---:|---:|---|\n",
1443    );
1444    for ticket in &diagnostic_evidence.tickets {
1445        for semantic in &ticket.semantic_comparisons {
1446            for revision in ["pre", "final"] {
1447                let rust = json_object(semantic, &format!("{revision}_fast_ta"))?;
1448                let c = json_object(semantic, &format!("{revision}_ta_lib_c"))?;
1449                let ratio = json_numeric(semantic, &format!("{revision}_rust_over_c"))?;
1450                comparison.push_str(&format!(
1451                    "| {} | {} | {} | {revision} | {} | {} | {:.3}x | input_match={}; output_match={}; {} |\n",
1452                    ticket.ticket,
1453                    clean(&json_nonempty_string(semantic, "case_id")?),
1454                    json_u64(semantic, "input_length")?,
1455                    format_json_timing(rust)?,
1456                    format_json_timing(c)?,
1457                    ratio,
1458                    json_bool(semantic, "input_checksum_match")?,
1459                    json_bool(semantic, "output_checksum_match")?,
1460                    clean(&json_nonempty_string(semantic, "disposition")?)
1461                ));
1462            }
1463        }
1464    }
1465
1466    comparison.push_str(&format!(
1467        "\nIssue 61 Hilbert cycle regression control\n\nCommand: `{}`. Working directory: `{}`. Host: {} / {} / {}. Timed seam: {}.\n\n| Indicator | Input | Cursor pre median [95% CI] / throughput | Final clean-revert median [95% CI] / throughput | Cursor vs baseline | Final vs baseline | Source proof and disposition |\n|---|---:|---:|---:|---:|---:|---|\n",
1468        clean(&cycle_regression.command),
1469        clean(&cycle_regression.cwd),
1470        clean(&cycle_regression.cpu),
1471        clean(&cycle_regression.os),
1472        clean(&cycle_regression.arch),
1473        clean(&cycle_regression.seam)
1474    ));
1475    for cycle_comparison in &cycle_regression.comparisons {
1476        let before = cycle_regression
1477            .measurements
1478            .iter()
1479            .find(|measurement| {
1480                measurement.indicator == cycle_comparison.indicator
1481                    && measurement.input_length == cycle_comparison.input_length
1482                    && measurement.variant == cycle_comparison.before_variant
1483            })
1484            .expect("validated cycle pre measurement");
1485        let after = cycle_regression
1486            .measurements
1487            .iter()
1488            .find(|measurement| {
1489                measurement.indicator == cycle_comparison.indicator
1490                    && measurement.input_length == cycle_comparison.input_length
1491                    && measurement.variant == "b156ac1_modulo"
1492            })
1493            .expect("validated cycle final measurement");
1494        comparison.push_str(&format!(
1495            "| {} | {} | {} | {} | {:+.1}% | {:+.1}% | {} — {} |\n",
1496            clean(&cycle_comparison.indicator),
1497            cycle_comparison.input_length,
1498            format_cycle_timing(before),
1499            format_cycle_timing(after),
1500            cycle_comparison.cursor_vs_baseline_percent,
1501            cycle_comparison.after_vs_baseline_percent,
1502            clean(&cycle_comparison.source_proof),
1503            clean(&cycle_comparison.disposition)
1504        ));
1505    }
1506
1507    let baseline_by_row = baseline_rows
1508        .iter()
1509        .map(|row| (comparison_row_key(row), row))
1510        .collect::<BTreeMap<_, _>>();
1511    let mut changes = rows
1512        .iter()
1513        .filter_map(|current| {
1514            let baseline = baseline_by_row.get(&comparison_row_key(current))?;
1515            let before = baseline.stats.as_ref()?;
1516            let after = current.stats.as_ref()?;
1517            let change = (after.median_ns / before.median_ns - 1.0) * 100.0;
1518            (change.abs() > 5.0).then_some((*baseline, current, change))
1519        })
1520        .collect::<Vec<_>>();
1521    changes.sort_by(|left, right| {
1522        left.1
1523            .case_id
1524            .cmp(&right.1.case_id)
1525            .then_with(|| left.1.input_length.cmp(&right.1.input_length))
1526            .then_with(|| left.1.implementation.cmp(&right.1.implementation))
1527            .then_with(|| left.1.mode.cmp(&right.1.mode))
1528    });
1529    comparison.push_str(&format!(
1530        "\nComplete >5% clean pre/final classification\n\n{} matching raw rows changed by more than 5%. This list is exhaustive for measured rows shared by the two committed clean artifacts. An investigation classification is not a same-run causal claim; the matrices were separate clean runs, and external C/Python movement is retained as a control.\n\n| Definition | Input | Implementation | Mode | Pre median | Final median | Change | Classification |\n|---|---:|---|---|---:|---:|---:|---|\n",
1531        changes.len()
1532    ));
1533    for (baseline, current, change) in changes {
1534        let before = baseline.stats.as_ref().expect("change row has stats");
1535        let after = current.stats.as_ref().expect("change row has stats");
1536        comparison.push_str(&format!(
1537            "| {} | {} | {} | {} | {:.3} us | {:.3} us | {change:+.1}% | {} |\n",
1538            current.case_id,
1539            current.input_length,
1540            current.implementation,
1541            current.mode,
1542            before.median_ns / 1_000.0,
1543            after.median_ns / 1_000.0,
1544            clean_change_classification(current, change)
1545        ));
1546    }
1547
1548    comparison.push_str(
1549        "\nRuntime platform qualification from committed JSONL\n\nThese rows are parsed from the named JSONL artifacts only after their validation records and numeric timing evidence pass schema checks. Speedup is scalar median divided by the matching backend median only when mode, precision, input size, and timed boundary match. A value below 1x means the accelerated backend was slower on this runner. Rows without a scalar measurement at the same boundary are not compared.\n\n| Artifact | Platform | Precision | Profile / features | Runtime / CPU / OS | Active backend | Equivalence | Workflow provenance | Commit |\n|---|---|---|---|---|---|---|---|---|\n",
1550    );
1551    for qualification in platform_qualifications {
1552        let equivalent = qualification.measurements.iter().all(|measurement| {
1553            measurement.equivalent_to_scalar
1554                && measurement.semantic_status == "verified"
1555                && measurement.timing_status == "measured"
1556        });
1557        comparison.push_str(&format!(
1558            "| {} | {} | {} | {} / {} | {} / {} / {} | {} | {} | run [{}]({}), job {} | {} |\n",
1559            clean(&qualification.artifact),
1560            clean(&qualification.platform),
1561            clean(&qualification.precision),
1562            clean(&qualification.profile),
1563            clean(&qualification.feature_flags),
1564            clean(&qualification.runtime),
1565            clean(&qualification.cpu),
1566            clean(&qualification.os),
1567            clean(&qualification.active_backend),
1568            if equivalent {
1569                "all measurement and validation rows verified"
1570            } else {
1571                "qualification contains an unverified row"
1572            },
1573            qualification.workflow_run_id,
1574            clean(&qualification.workflow_run_url),
1575            qualification.workflow_job,
1576            qualification.commit
1577        ));
1578    }
1579    comparison.push_str(
1580        "\n| Platform | Precision | Input | Mode | Backend | Median [95% CI] | Throughput | Speedup vs matching scalar | Disposition |\n|---|---|---:|---|---|---:|---:|---:|---|\n",
1581    );
1582    for qualification in platform_qualifications {
1583        let mut measurements = qualification.measurements.iter().collect::<Vec<_>>();
1584        measurements.sort_by(|left, right| {
1585            left.input_length
1586                .cmp(&right.input_length)
1587                .then_with(|| left.mode.cmp(&right.mode))
1588                .then_with(|| left.backend.cmp(&right.backend))
1589        });
1590        for measurement in measurements {
1591            let scalar = qualification.measurements.iter().find(|candidate| {
1592                candidate.mode == measurement.mode
1593                    && candidate.input_length == measurement.input_length
1594                    && candidate.backend == "scalar"
1595                    && candidate.timed_boundary == measurement.timed_boundary
1596            });
1597            let speedup = scalar.map(|scalar| scalar.median_ns / measurement.median_ns);
1598            let disposition = qualification_disposition(measurement, speedup);
1599            comparison.push_str(&format!(
1600                "| {} | {} | {} | {} | {} | {:.3} us [{:.3}, {:.3}] | {:.3} Mobs/s | {} | {disposition} |\n",
1601                clean(&qualification.platform),
1602                clean(&qualification.precision),
1603                measurement.input_length,
1604                clean(&measurement.mode),
1605                clean(&measurement.backend),
1606                measurement.median_ns / 1_000.0,
1607                measurement.ci95_lower_ns / 1_000.0,
1608                measurement.ci95_upper_ns / 1_000.0,
1609                measurement.throughput_observations_per_second / 1.0e6,
1610                format_ratio(speedup)
1611            ));
1612        }
1613    }
1614
1615    comparison.push_str(
1616        "\nValidation and allocation boundaries\n\nThe Rust matrix timings retain public finite-input validation, capacity, Output Range, and validation-before-mutation contracts. Validation and computation were not timed separately in the catalogue matrix; the direct C row is a comparative kernel reference, not evidence that Rust validation should be removed.\n\n| Implementation | Mode | Timed allocation/boundary evidence from raw rows |\n|---|---|---|\n",
1617    );
1618    let boundaries = rows
1619        .iter()
1620        .map(|row| {
1621            (
1622                row.implementation.clone(),
1623                row.mode.clone(),
1624                row.timed_boundary.clone(),
1625            )
1626        })
1627        .collect::<BTreeSet<_>>();
1628    for (implementation, mode, boundary) in boundaries {
1629        comparison.push_str(&format!(
1630            "| {implementation} | {mode} | {} |\n",
1631            clean(&boundary)
1632        ));
1633    }
1634
1635    comparison.push_str(&format!(
1636        "\nFinal AArch64 qualification\n\nThe clean final matrix exercised the public TYPPRICE caller-owned path on {} / {} with architecture `{}` and commit {}. This is the only AArch64 timing claim; scalar fallback remains available. x86_64 and WASM claims above come only from their committed runtime JSONL artifacts.\n",
1637        clean(&first.cpu),
1638        clean(&first.os),
1639        clean(&first.arch),
1640        first.commit
1641    ));
1642
1643    Ok(format!("{summary}{comparison}{marker}{details}"))
1644}
1645
1646fn json_numeric(value: &Value, key: &str) -> Result<f64, String> {
1647    value
1648        .get(key)
1649        .and_then(|value| {
1650            value
1651                .as_f64()
1652                .or_else(|| value.as_str().and_then(|value| value.parse().ok()))
1653        })
1654        .filter(|value| value.is_finite())
1655        .ok_or_else(|| format!("JSON value is missing finite numeric field {key:?}"))
1656}
1657
1658fn format_json_timing(value: &Value) -> Result<String, String> {
1659    Ok(format!(
1660        "{:.3} us [{:.3}, {:.3}] / {:.3} Mobs/s",
1661        json_numeric(value, "median_ns")? / 1_000.0,
1662        json_numeric(value, "ci95_lower_ns")? / 1_000.0,
1663        json_numeric(value, "ci95_upper_ns")? / 1_000.0,
1664        json_numeric(value, "throughput_observations_per_second")? / 1.0e6
1665    ))
1666}
1667
1668fn format_cycle_timing(value: &CycleMeasurement) -> String {
1669    format!(
1670        "{:.3} us [{:.3}, {:.3}] / {:.3} Mobs/s",
1671        value.median_ns / 1_000.0,
1672        value.ci95_lower_ns / 1_000.0,
1673        value.ci95_upper_ns / 1_000.0,
1674        value.throughput_observations_per_second / 1.0e6
1675    )
1676}
1677
1678fn comparison_row_key(
1679    row: &BenchmarkRow,
1680) -> (String, String, String, String, usize, String, usize) {
1681    (
1682        row.implementation.clone(),
1683        row.case_id.clone(),
1684        row.mode.clone(),
1685        row.parameters.clone(),
1686        row.input_length,
1687        row.fixture.clone(),
1688        row.float_width,
1689    )
1690}
1691
1692fn clean_change_classification(row: &BenchmarkRow, change: f64) -> &'static str {
1693    if row.implementation != "fast-ta" {
1694        return "external C/Python reference-path movement between clean runs; retained as host/run control, not attributed to fast-ta source";
1695    }
1696    if row.mode == RUST_STREAMING_MODE {
1697        return "untouched Streaming neighbor; batch optimization does not explain this clean cross-run movement; no causal claim";
1698    }
1699    if row.case_id == "CDLDOJI" && change > 5.0 {
1700        return "investigated clean regression: batch-only, source-correlated with migration to the shared single-setting helper; unresolved";
1701    }
1702    if row.case_id == "HT_DCPHASE" && change > 5.0 {
1703        return "investigated clean large-input regression despite ring-wrap source change; unresolved";
1704    }
1705    if change < -5.0 {
1706        return "clean batch improvement; targeted kernel work or shared SIMD finite-slice validation applies";
1707    }
1708    "clean batch regression above 5%; classified as unresolved"
1709}
1710
1711fn qualification_disposition(
1712    measurement: &QualificationMeasurement,
1713    speedup: Option<f64>,
1714) -> &'static str {
1715    if !measurement.equivalent_to_scalar || measurement.semantic_status != "verified" {
1716        "invalid for performance comparison: equivalence not verified"
1717    } else if measurement.backend == "scalar" {
1718        "scalar reference"
1719    } else if let Some(speedup) = speedup {
1720        if speedup > 1.05 {
1721            "practical benefit on this runner"
1722        } else if speedup < 0.95 {
1723            "slower than scalar on this runner; no practical benefit"
1724        } else {
1725            "within the 5% band on this runner"
1726        }
1727    } else {
1728        "no matching scalar row with the same timed boundary"
1729    }
1730}
1731
1732fn format_ratio(ratio: Option<f64>) -> String {
1733    ratio.map_or_else(|| "unavailable".to_owned(), |ratio| format!("{ratio:.3}x"))
1734}
1735
1736fn geometric_mean(ratios: &[f64]) -> f64 {
1737    (ratios.iter().map(|ratio| ratio.ln()).sum::<f64>() / ratios.len() as f64).exp()
1738}
1739
1740fn path_ratios(
1741    rows: &[BenchmarkRow],
1742    implementation: &str,
1743    mode: &str,
1744    input_length: usize,
1745) -> Vec<f64> {
1746    type Key = (String, String, usize, String, String);
1747    let mut c = BTreeMap::<Key, f64>::new();
1748    for row in rows {
1749        if row.implementation != "TA-Lib C"
1750            || row.mode != C_DIRECT_MODE
1751            || row.input_length != input_length
1752            || row.semantic_status != "verified"
1753            || row.timing_status != "measured"
1754        {
1755            continue;
1756        }
1757        if let Some(stats) = &row.stats {
1758            c.insert(
1759                (
1760                    row.case_id.clone(),
1761                    row.parameters.clone(),
1762                    row.input_length,
1763                    row.fixture.clone(),
1764                    row.input_checksum.clone(),
1765                ),
1766                stats.median_ns,
1767            );
1768        }
1769    }
1770    rows.iter()
1771        .filter(|row| {
1772            row.implementation == implementation
1773                && row.mode == mode
1774                && row.input_length == input_length
1775                && row.semantic_status == "verified"
1776                && row.timing_status == "measured"
1777        })
1778        .filter_map(|row| {
1779            let stats = row.stats.as_ref()?;
1780            let key = (
1781                row.case_id.clone(),
1782                row.parameters.clone(),
1783                row.input_length,
1784                row.fixture.clone(),
1785                row.input_checksum.clone(),
1786            );
1787            c.get(&key).map(|c_ns| stats.median_ns / c_ns)
1788        })
1789        .collect()
1790}
1791
1792#[derive(Clone, Debug)]
1793struct PrimaryPair {
1794    case_id: String,
1795    input_length: usize,
1796    ratio: f64,
1797}
1798
1799fn primary_pairs(rows: &[BenchmarkRow]) -> Vec<PrimaryPair> {
1800    type Key = (String, String, usize, String, String);
1801    let mut rust = BTreeMap::<Key, f64>::new();
1802    let mut c = BTreeMap::<Key, f64>::new();
1803    for row in rows {
1804        if row.semantic_status != "verified"
1805            || row.timing_status != "measured"
1806            || row.comparison_status != "comparable"
1807        {
1808            continue;
1809        }
1810        let Some(stats) = &row.stats else { continue };
1811        let key = (
1812            row.case_id.clone(),
1813            row.parameters.clone(),
1814            row.input_length,
1815            row.fixture.clone(),
1816            row.input_checksum.clone(),
1817        );
1818        if row.implementation == "fast-ta" && row.mode == RUST_CALLER_MODE {
1819            rust.insert(key, stats.median_ns);
1820        } else if row.implementation == "TA-Lib C" && row.mode == C_DIRECT_MODE {
1821            c.insert(key, stats.median_ns);
1822        }
1823    }
1824    rust.into_iter()
1825        .filter_map(|(key, rust_ns)| {
1826            c.get(&key).map(|c_ns| PrimaryPair {
1827                case_id: key.0,
1828                input_length: key.2,
1829                ratio: rust_ns / c_ns,
1830            })
1831        })
1832        .collect()
1833}