use crate::domain::{Finding, OracleKind, OracleStrength, RelatedTest};

use super::{array_field, escape, field, number_field};

const PRESENTATION_TEXT_CLASS: &str = "presentation_text";
const CONFIG_POLICY_CLASS: &str = "config_or_policy_constant";
const GROUP_REASON_DECL_LITERAL: &str = "declaration_and_literal_same_text_constant";
const GROUP_REASON_OWNER: &str = "constant_owner_identity";
const GROUP_REASON_CONFIG_POLICY: &str = "same_config_policy_constant";
const VISIBILITY_UNKNOWN_CATEGORY: &str = "presentation_text_visibility_unknown";
const VISIBILITY_UNKNOWN_REPAIR_ROUTE: &str = "trace_string_constant_to_output_or_snapshot_test";
const CONFIG_POLICY_FLOW_UNKNOWN_CATEGORY: &str = "config_policy_flow_unknown";
const CONFIG_POLICY_FLOW_UNKNOWN_REPAIR_ROUTE: &str =
    "trace_constant_to_output_schema_validation_or_behavior_sink";
const OPAQUE_CONFIG_LOOKUP_CATEGORY: &str = "opaque_config_lookup";
const OPAQUE_CONFIG_LOOKUP_REPAIR_ROUTE: &str =
    "add_fixture_backed_support_for_opaque_config_lookup";

pub(super) struct FindingAlignmentReport {
    summary: FindingAlignmentSummary,
    items: Vec<FindingAlignmentItem>,
}

struct FindingAlignmentSummary {
    raw_signals: usize,
    canonical_items: usize,
    aligned_raw_findings: usize,
    unaligned_raw_findings: usize,
    duplicate_groups_total: usize,
    actionable_gaps: usize,
    already_observed: usize,
    internal_no_action: usize,
    static_limitations: usize,
    unknown: usize,
    calibrated_supported: usize,
    uncalibrated: usize,
    repair_route_coverage: usize,
    actionable_items_without_repair_route: usize,
    verify_command_coverage: usize,
    actionable_items_without_verify_command: usize,
    presentation_text_total: usize,
    presentation_text_user_visible: usize,
    presentation_text_observed: usize,
    presentation_text_unobserved: usize,
    presentation_text_internal_only: usize,
    presentation_text_visibility_unknown: usize,
    presentation_text_observer_unknown: usize,
    presentation_text_duplicate_groups: usize,
    presentation_text_actionable_snapshot: usize,
    presentation_text_actionable_output_repairs: usize,
    presentation_text_no_action: usize,
    presentation_text_static_limitations: usize,
    config_policy_constant_total: usize,
    config_policy_user_visible: usize,
    config_policy_observed: usize,
    config_policy_unobserved: usize,
    config_policy_internal_only: usize,
    config_policy_flow_unknown: usize,
    config_policy_observer_unknown: usize,
    config_policy_duplicate_groups: usize,
    config_policy_actionable_output_observer: usize,
    config_policy_actionable_behavior_discriminator: usize,
    config_policy_no_action: usize,
    config_policy_static_limitations: usize,
    config_policy_repair_route_coverage: usize,
    config_policy_verify_command_coverage: usize,
}

struct FindingAlignmentItem {
    canonical_gap_id: String,
    canonical_item_kind: String,
    evidence_class: String,
    gap_state: String,
    actionability: String,
    raw_group_size: usize,
    group_reason: String,
    primary_anchor: Option<FindingAlignmentPrimaryAnchor>,
    raw_spans: Vec<FindingAlignmentRawSpan>,
    why: String,
    recommended_repair: String,
    repair_route: Option<FindingAlignmentRepairRoute>,
    related_test: Option<FindingAlignmentRelatedTest>,
    verify_command: String,
    static_limitations: Vec<FindingAlignmentStaticLimitation>,
    confidence: FindingAlignmentConfidence,
    raw_findings: Vec<FindingAlignmentRawFinding>,
    presentation_text: Option<FindingAlignmentPresentationText>,
    config_policy: Option<FindingAlignmentConfigPolicy>,
}

struct FindingAlignmentRawFinding {
    file: String,
    line: usize,
    kind: String,
    expression: String,
    probe_kind: String,
    source_id: String,
    evidence_record_ref: String,
}

struct FindingAlignmentPrimaryAnchor {
    file: String,
    line: usize,
    kind: String,
    source_id: String,
    reason: String,
}

struct FindingAlignmentRawSpan {
    file: String,
    start_line: usize,
    end_line: usize,
    kind: String,
    source_id: String,
}

struct FindingAlignmentStaticLimitation {
    category: String,
    repair_route: String,
    user_actionability: String,
}

struct FindingAlignmentConfidence {
    basis: String,
    notes: Vec<String>,
}

struct FindingAlignmentRelatedTest {
    name: String,
    file: String,
    line: usize,
}

struct FindingAlignmentRepairRoute {
    repair_kind: String,
    target_test_type: String,
    suggested_assertion: String,
}

struct FindingAlignmentPresentationText {
    constant_name: String,
    text_literal: Option<String>,
    visibility: String,
    observer: String,
    actionability: String,
    source_kind: String,
    canonical_group_reason: String,
    recommended_observer: String,
    repair_kind: String,
    target_test_type: String,
    suggested_assertion: String,
}

struct FindingAlignmentConfigPolicy {
    constant: String,
    role: String,
    source_kind: String,
    visibility: String,
    observer: String,
    actionability: String,
    repair_kind: String,
    target_test_type: String,
    suggested_assertion: String,
}

struct PresentationTextClassification {
    canonical_item_kind: String,
    gap_state: String,
    actionability: String,
    why: String,
    recommended_repair: String,
    related_test: Option<FindingAlignmentRelatedTest>,
    static_limitations: Vec<FindingAlignmentStaticLimitation>,
    confidence: FindingAlignmentConfidence,
    visibility: String,
    observer: String,
    presentation_actionability: String,
    recommended_observer: String,
    repair_kind: String,
    target_test_type: String,
    suggested_assertion: String,
}

struct ConfigPolicyClassification {
    canonical_item_kind: String,
    gap_state: String,
    actionability: String,
    why: String,
    recommended_repair: String,
    related_test: Option<FindingAlignmentRelatedTest>,
    static_limitations: Vec<FindingAlignmentStaticLimitation>,
    confidence: FindingAlignmentConfidence,
    role: String,
    visibility: String,
    observer: String,
    config_actionability: String,
    repair_kind: String,
    target_test_type: String,
    suggested_assertion: String,
}

struct PresentationTextSink {
    recommended_observer: &'static str,
    repair_target: &'static str,
    description: &'static str,
    target_test_type: &'static str,
    assertion_subject: &'static str,
}

struct ConfigPolicySink {
    role: &'static str,
    repair_target: &'static str,
    description: &'static str,
    actionability: &'static str,
    repair_kind: &'static str,
    target_test_type: &'static str,
    assertion_subject: &'static str,
}

#[derive(Clone)]
struct PresentationTextDeclaration {
    constant_name: String,
    inline_literal: Option<String>,
}

pub(super) fn report_for_findings(findings: &[Finding]) -> Option<FindingAlignmentReport> {
    let mut used = vec![false; findings.len()];
    let mut items = Vec::new();

    for (index, finding) in findings.iter().enumerate() {
        if used[index] {
            continue;
        }

        if let Some(declaration) = parse_config_policy_declaration(&finding.probe.expression) {
            let mut raw_indices = vec![index];
            if declaration.inline_literal.is_none()
                && finding.probe.expression.trim_end().ends_with('=')
                && let Some(literal_index) = adjacent_literal_index(findings, &used, index)
            {
                raw_indices.push(literal_index);
            }

            used[index] = true;
            for raw_index in raw_indices.iter().skip(1) {
                used[*raw_index] = true;
            }

            let source_findings = raw_indices
                .iter()
                .map(|raw_index| &findings[*raw_index])
                .collect::<Vec<_>>();
            let classification =
                classify_config_policy_constant(&declaration.constant_name, &source_findings);
            let raw_findings = raw_indices
                .iter()
                .map(|raw_index| raw_finding_for(&findings[*raw_index]))
                .collect::<Vec<_>>();
            items.push(config_policy_item(
                &declaration.constant_name,
                raw_findings,
                classification,
            ));
            continue;
        }

        let Some(declaration) = parse_presentation_text_declaration(&finding.probe.expression)
        else {
            continue;
        };

        let mut raw_indices = vec![index];
        let literal = declaration.inline_literal.clone().or_else(|| {
            adjacent_literal_index(findings, &used, index).map(|literal_index| {
                raw_indices.push(literal_index);
                parse_string_literal(&findings[literal_index].probe.expression).unwrap_or_default()
            })
        });

        used[index] = true;
        for raw_index in raw_indices.iter().skip(1) {
            used[*raw_index] = true;
        }

        let source_findings = raw_indices
            .iter()
            .map(|raw_index| &findings[*raw_index])
            .collect::<Vec<_>>();
        let classification =
            classify_presentation_text(&declaration.constant_name, &source_findings);
        let raw_findings = raw_indices
            .iter()
            .map(|raw_index| raw_finding_for(&findings[*raw_index]))
            .collect::<Vec<_>>();
        items.push(presentation_text_item(
            &declaration.constant_name,
            literal,
            raw_findings,
            classification,
        ));
    }

    if items.is_empty() {
        return None;
    }

    let summary = summary_for(findings.len(), &items);
    Some(FindingAlignmentReport { summary, items })
}

pub(super) fn report_json(out: &mut String, report: &FindingAlignmentReport, indent: usize) {
    let sp = "  ".repeat(indent);
    out.push_str(&format!("{sp}{{\n"));
    field(out, indent + 1, "scope", "supported_classes", true);
    array_field(
        out,
        indent + 1,
        "supported_evidence_classes",
        &[
            PRESENTATION_TEXT_CLASS.to_string(),
            CONFIG_POLICY_CLASS.to_string(),
        ],
        true,
    );
    out.push_str(&format!("{}\"summary\": ", "  ".repeat(indent + 1)));
    summary_json(out, &report.summary);
    out.push_str(",\n");
    out.push_str(&format!("{}\"items\": [\n", "  ".repeat(indent + 1)));
    for (index, item) in report.items.iter().enumerate() {
        item_json(out, item, indent + 2);
        if index + 1 != report.items.len() {
            out.push(',');
        }
        out.push('\n');
    }
    out.push_str(&format!("{}]\n", "  ".repeat(indent + 1)));
    out.push_str(&format!("{sp}}}"));
}

fn summary_for(raw_signals: usize, items: &[FindingAlignmentItem]) -> FindingAlignmentSummary {
    let presentation_items = items
        .iter()
        .filter(|item| item.evidence_class == PRESENTATION_TEXT_CLASS)
        .collect::<Vec<_>>();
    let config_policy_items = items
        .iter()
        .filter(|item| item.evidence_class == CONFIG_POLICY_CLASS)
        .collect::<Vec<_>>();

    let overall = overall_alignment_counts(items);
    let presentation = presentation_text_counts(&presentation_items);
    let config_policy = config_policy_counts(&config_policy_items);

    FindingAlignmentSummary {
        raw_signals,
        canonical_items: items.len(),
        aligned_raw_findings: overall.aligned_raw_findings,
        unaligned_raw_findings: raw_signals.saturating_sub(overall.aligned_raw_findings),
        duplicate_groups_total: overall.duplicate_groups_total,
        actionable_gaps: overall.actionable_gaps,
        already_observed: overall.already_observed,
        internal_no_action: overall.internal_no_action,
        static_limitations: overall.static_limitations,
        unknown: overall.unknown,
        calibrated_supported: overall.calibrated_supported,
        uncalibrated: overall.uncalibrated,
        repair_route_coverage: overall.repair_route_coverage,
        actionable_items_without_repair_route: overall.actionable_items_without_repair_route,
        verify_command_coverage: overall.verify_command_coverage,
        actionable_items_without_verify_command: overall.actionable_items_without_verify_command,
        presentation_text_total: presentation.total,
        presentation_text_user_visible: presentation.user_visible,
        presentation_text_observed: presentation.observed,
        presentation_text_unobserved: presentation.unobserved,
        presentation_text_internal_only: presentation.internal_only,
        presentation_text_visibility_unknown: presentation.visibility_unknown,
        presentation_text_observer_unknown: presentation.observer_unknown,
        presentation_text_duplicate_groups: presentation.duplicate_groups,
        presentation_text_actionable_snapshot: presentation.actionable_output_repairs,
        presentation_text_actionable_output_repairs: presentation.actionable_output_repairs,
        presentation_text_no_action: presentation.no_action,
        presentation_text_static_limitations: presentation.static_limitations,
        config_policy_constant_total: config_policy.total,
        config_policy_user_visible: config_policy.user_visible,
        config_policy_observed: config_policy.observed,
        config_policy_unobserved: config_policy.unobserved,
        config_policy_internal_only: config_policy.internal_only,
        config_policy_flow_unknown: config_policy.flow_unknown,
        config_policy_observer_unknown: config_policy.observer_unknown,
        config_policy_duplicate_groups: config_policy.duplicate_groups,
        config_policy_actionable_output_observer: config_policy.actionable_output_observer,
        config_policy_actionable_behavior_discriminator: config_policy
            .actionable_behavior_discriminator,
        config_policy_no_action: config_policy.no_action,
        config_policy_static_limitations: config_policy.static_limitations,
        config_policy_repair_route_coverage: config_policy.repair_route_coverage,
        config_policy_verify_command_coverage: config_policy.verify_command_coverage,
    }
}

struct OverallAlignmentCounts {
    aligned_raw_findings: usize,
    duplicate_groups_total: usize,
    actionable_gaps: usize,
    already_observed: usize,
    internal_no_action: usize,
    static_limitations: usize,
    unknown: usize,
    calibrated_supported: usize,
    uncalibrated: usize,
    repair_route_coverage: usize,
    actionable_items_without_repair_route: usize,
    verify_command_coverage: usize,
    actionable_items_without_verify_command: usize,
}

fn overall_alignment_counts(items: &[FindingAlignmentItem]) -> OverallAlignmentCounts {
    let aligned_raw_findings = items
        .iter()
        .map(|item| item.raw_findings.len())
        .sum::<usize>();
    let duplicate_groups_total = items
        .iter()
        .filter(|item| item.raw_findings.len() > 1)
        .count();
    let actionable_gaps = items
        .iter()
        .filter(|item| item.gap_state == "actionable")
        .count();
    let already_observed = items
        .iter()
        .filter(|item| item.gap_state == "already_observed")
        .count();
    let internal_no_action = items
        .iter()
        .filter(|item| item.gap_state == "internal_only")
        .count();
    let static_limitations = items
        .iter()
        .filter(|item| item.gap_state == "static_limitation")
        .count();
    let unknown = items
        .iter()
        .filter(|item| item.gap_state == "unknown")
        .count();
    let calibrated_supported = items
        .iter()
        .filter(|item| item.confidence.basis == "calibrated")
        .count();
    let uncalibrated = items.len().saturating_sub(calibrated_supported);
    let repair_route_coverage = items
        .iter()
        .filter(|item| item.gap_state == "actionable")
        .filter(|item| item_has_repair_route(item))
        .count();
    let verify_command_coverage = items
        .iter()
        .filter(|item| item.gap_state == "actionable")
        .filter(|item| item_has_verify_command(item))
        .count();

    OverallAlignmentCounts {
        aligned_raw_findings,
        duplicate_groups_total,
        actionable_gaps,
        already_observed,
        internal_no_action,
        static_limitations,
        unknown,
        calibrated_supported,
        uncalibrated,
        repair_route_coverage,
        actionable_items_without_repair_route: actionable_gaps
            .saturating_sub(repair_route_coverage),
        verify_command_coverage,
        actionable_items_without_verify_command: actionable_gaps
            .saturating_sub(verify_command_coverage),
    }
}

struct PresentationTextCounts {
    total: usize,
    user_visible: usize,
    observed: usize,
    unobserved: usize,
    internal_only: usize,
    visibility_unknown: usize,
    observer_unknown: usize,
    duplicate_groups: usize,
    actionable_output_repairs: usize,
    no_action: usize,
    static_limitations: usize,
}

fn presentation_text_counts(items: &[&FindingAlignmentItem]) -> PresentationTextCounts {
    let visibility_unknown = items
        .iter()
        .filter(|item| {
            item.presentation_text
                .as_ref()
                .is_some_and(|text| text.visibility == "unknown")
        })
        .count();
    let user_visible = items
        .iter()
        .filter(|item| {
            item.presentation_text
                .as_ref()
                .is_some_and(|text| text.visibility == "user_visible")
        })
        .count();
    let observed = items
        .iter()
        .filter(|item| item.gap_state == "already_observed")
        .count();
    let unobserved = items
        .iter()
        .filter(|item| {
            item.presentation_text
                .as_ref()
                .is_some_and(|text| text.visibility == "user_visible" && text.observer == "none")
        })
        .count();
    let internal_only = items
        .iter()
        .filter(|item| item.gap_state == "internal_only")
        .count();
    let observer_unknown = items
        .iter()
        .filter(|item| {
            item.presentation_text
                .as_ref()
                .is_some_and(|text| text.observer == "unknown")
        })
        .count();
    let duplicate_groups = items
        .iter()
        .filter(|item| {
            item.presentation_text.as_ref().is_some_and(|text| {
                text.canonical_group_reason == GROUP_REASON_DECL_LITERAL
                    && item.raw_findings.len() > 1
            })
        })
        .count();
    let actionable_output_repairs = items
        .iter()
        .filter(|item| {
            item.presentation_text
                .as_ref()
                .is_some_and(|text| text.actionability == "add_output_observer")
        })
        .count();
    let no_action = items
        .iter()
        .filter(|item| {
            item.presentation_text.as_ref().is_some_and(|text| {
                text.actionability == "already_observed"
                    || text.actionability == "no_action_internal"
            })
        })
        .count();
    let static_limitations = items
        .iter()
        .filter(|item| item.gap_state == "static_limitation")
        .count();

    PresentationTextCounts {
        total: items.len(),
        user_visible,
        observed,
        unobserved,
        internal_only,
        visibility_unknown,
        observer_unknown,
        duplicate_groups,
        actionable_output_repairs,
        no_action,
        static_limitations,
    }
}

struct ConfigPolicyCounts {
    total: usize,
    user_visible: usize,
    observed: usize,
    unobserved: usize,
    internal_only: usize,
    flow_unknown: usize,
    observer_unknown: usize,
    duplicate_groups: usize,
    actionable_output_observer: usize,
    actionable_behavior_discriminator: usize,
    no_action: usize,
    static_limitations: usize,
    repair_route_coverage: usize,
    verify_command_coverage: usize,
}

fn config_policy_counts(items: &[&FindingAlignmentItem]) -> ConfigPolicyCounts {
    let user_visible = items
        .iter()
        .filter(|item| {
            item.config_policy
                .as_ref()
                .is_some_and(|config| config.visibility == "user_visible")
        })
        .count();
    let observed = items
        .iter()
        .filter(|item| item.gap_state == "already_observed")
        .count();
    let unobserved = items
        .iter()
        .filter(|item| {
            item.config_policy.as_ref().is_some_and(|config| {
                config.visibility == "user_visible" && config.observer == "none"
            })
        })
        .count();
    let internal_only = items
        .iter()
        .filter(|item| item.gap_state == "internal_only")
        .count();
    let flow_unknown = items
        .iter()
        .filter(|item| {
            item.static_limitations
                .iter()
                .any(|limitation| limitation.category == CONFIG_POLICY_FLOW_UNKNOWN_CATEGORY)
        })
        .count();
    let observer_unknown = items
        .iter()
        .filter(|item| {
            item.config_policy
                .as_ref()
                .is_some_and(|config| config.observer == "unknown")
        })
        .count();
    let duplicate_groups = items
        .iter()
        .filter(|item| {
            item.group_reason == GROUP_REASON_CONFIG_POLICY && item.raw_findings.len() > 1
        })
        .count();
    let actionable_output_observer = items
        .iter()
        .filter(|item| {
            item.config_policy
                .as_ref()
                .is_some_and(|config| config.actionability == "add_output_observer")
        })
        .count();
    let actionable_behavior_discriminator = items
        .iter()
        .filter(|item| {
            item.config_policy
                .as_ref()
                .is_some_and(|config| config.actionability == "add_behavior_discriminator")
        })
        .count();
    let no_action = items
        .iter()
        .filter(|item| {
            item.config_policy.as_ref().is_some_and(|config| {
                config.actionability == "already_observed"
                    || config.actionability == "no_action_internal"
            })
        })
        .count();
    let static_limitations = items
        .iter()
        .filter(|item| item.gap_state == "static_limitation")
        .count();
    let repair_route_coverage = items
        .iter()
        .filter(|item| item.gap_state == "actionable")
        .filter(|item| {
            !item.recommended_repair.is_empty()
                && item
                    .config_policy
                    .as_ref()
                    .is_some_and(|config| config.repair_kind != "unknown")
        })
        .count();
    let verify_command_coverage = items
        .iter()
        .filter(|item| item.gap_state == "actionable")
        .filter(|item| !item.verify_command.is_empty() && item.verify_command != "unknown")
        .count();

    ConfigPolicyCounts {
        total: items.len(),
        user_visible,
        observed,
        unobserved,
        internal_only,
        flow_unknown,
        observer_unknown,
        duplicate_groups,
        actionable_output_observer,
        actionable_behavior_discriminator,
        no_action,
        static_limitations,
        repair_route_coverage,
        verify_command_coverage,
    }
}

fn presentation_text_item(
    constant_name: &str,
    text_literal: Option<String>,
    raw_findings: Vec<FindingAlignmentRawFinding>,
    classification: PresentationTextClassification,
) -> FindingAlignmentItem {
    let group_reason = if raw_findings.len() > 1 {
        GROUP_REASON_DECL_LITERAL
    } else {
        GROUP_REASON_OWNER
    };
    let primary_anchor = primary_anchor_for(&raw_findings, group_reason);
    let raw_spans = raw_spans_for(&raw_findings);
    let repair_route = repair_route_for(
        &classification.gap_state,
        &classification.repair_kind,
        &classification.target_test_type,
        &classification.suggested_assertion,
    );
    debug_assert!(
        classification.gap_state != "actionable" || repair_route.is_some(),
        "actionable finding alignment item must carry a concrete repair route"
    );

    FindingAlignmentItem {
        canonical_gap_id: format!("presentation_text::{constant_name}"),
        canonical_item_kind: classification.canonical_item_kind,
        evidence_class: PRESENTATION_TEXT_CLASS.to_string(),
        gap_state: classification.gap_state,
        actionability: classification.actionability,
        raw_group_size: raw_findings.len(),
        group_reason: group_reason.to_string(),
        primary_anchor,
        raw_spans,
        why: classification.why,
        recommended_repair: classification.recommended_repair,
        repair_route,
        related_test: classification.related_test,
        verify_command: "cargo xtask evidence-quality-scorecard".to_string(),
        static_limitations: classification.static_limitations,
        confidence: classification.confidence,
        raw_findings,
        presentation_text: Some(FindingAlignmentPresentationText {
            constant_name: constant_name.to_string(),
            text_literal,
            visibility: classification.visibility,
            observer: classification.observer,
            actionability: classification.presentation_actionability,
            source_kind: "const_decl".to_string(),
            canonical_group_reason: group_reason.to_string(),
            recommended_observer: classification.recommended_observer,
            repair_kind: classification.repair_kind,
            target_test_type: classification.target_test_type,
            suggested_assertion: classification.suggested_assertion,
        }),
        config_policy: None,
    }
}

fn config_policy_item(
    constant_name: &str,
    raw_findings: Vec<FindingAlignmentRawFinding>,
    classification: ConfigPolicyClassification,
) -> FindingAlignmentItem {
    let group_reason = if raw_findings.len() > 1 {
        GROUP_REASON_DECL_LITERAL
    } else {
        GROUP_REASON_OWNER
    };
    let primary_anchor = primary_anchor_for(&raw_findings, group_reason);
    let raw_spans = raw_spans_for(&raw_findings);
    let repair_route = repair_route_for(
        &classification.gap_state,
        &classification.repair_kind,
        &classification.target_test_type,
        &classification.suggested_assertion,
    );
    debug_assert!(
        classification.gap_state != "actionable" || repair_route.is_some(),
        "actionable finding alignment item must carry a concrete repair route"
    );

    FindingAlignmentItem {
        canonical_gap_id: format!("config_or_policy_constant::{constant_name}"),
        canonical_item_kind: classification.canonical_item_kind,
        evidence_class: CONFIG_POLICY_CLASS.to_string(),
        gap_state: classification.gap_state,
        actionability: classification.actionability,
        raw_group_size: raw_findings.len(),
        group_reason: group_reason.to_string(),
        primary_anchor,
        raw_spans,
        why: classification.why,
        recommended_repair: classification.recommended_repair,
        repair_route,
        related_test: classification.related_test,
        verify_command: "cargo xtask evidence-quality-scorecard".to_string(),
        static_limitations: classification.static_limitations,
        confidence: classification.confidence,
        raw_findings,
        presentation_text: None,
        config_policy: Some(FindingAlignmentConfigPolicy {
            constant: constant_name.to_string(),
            role: classification.role,
            source_kind: "const_decl".to_string(),
            visibility: classification.visibility,
            observer: classification.observer,
            actionability: classification.config_actionability,
            repair_kind: classification.repair_kind,
            target_test_type: classification.target_test_type,
            suggested_assertion: classification.suggested_assertion,
        }),
    }
}

fn classify_presentation_text(
    constant_name: &str,
    raw_findings: &[&Finding],
) -> PresentationTextClassification {
    let source_file = raw_findings
        .first()
        .map(|finding| finding.probe.location.file.display().to_string())
        .unwrap_or_default();

    if is_internal_only_text(constant_name, &source_file) {
        return internal_only_classification();
    }

    if let Some(sink) = visible_sink_for(constant_name, &source_file) {
        if let Some((observer, related_test)) = observer_for_findings(raw_findings) {
            return observed_classification(sink, observer, related_test);
        }

        return actionable_output_classification(sink, constant_name);
    }

    visibility_unknown_classification()
}

fn visibility_unknown_classification() -> PresentationTextClassification {
    PresentationTextClassification {
        canonical_item_kind: "limitation".to_string(),
        gap_state: "static_limitation".to_string(),
        actionability: "inspect_visibility".to_string(),
        why: "Changed presentation text could not be traced to or away from a user-visible output sink.".to_string(),
        recommended_repair:
            "Trace the string constant to a rendered output path or confirm it is internal-only."
                .to_string(),
        related_test: None,
        static_limitations: vec![FindingAlignmentStaticLimitation {
            category: VISIBILITY_UNKNOWN_CATEGORY.to_string(),
            repair_route: VISIBILITY_UNKNOWN_REPAIR_ROUTE.to_string(),
            user_actionability: "unknown_until_visibility_known".to_string(),
        }],
        confidence: FindingAlignmentConfidence {
            basis: "fixture_backed".to_string(),
            notes: vec![
                "Visibility-unknown presentation text is benchmark-pinned; no user test debt is claimed without an output sink.".to_string(),
            ],
        },
        visibility: "unknown".to_string(),
        observer: "unknown".to_string(),
        presentation_actionability: "static_limitation_visibility_unknown".to_string(),
        recommended_observer: "unknown".to_string(),
        repair_kind: "inspect_visibility".to_string(),
        target_test_type: "unknown".to_string(),
        suggested_assertion:
            "Trace the constant to a supported output sink before adding or updating tests."
                .to_string(),
    }
}

fn internal_only_classification() -> PresentationTextClassification {
    PresentationTextClassification {
        canonical_item_kind: "no_action".to_string(),
        gap_state: "internal_only".to_string(),
        actionability: "no_action".to_string(),
        why: "Changed label is confined to an internal proof, policy, or config-only path in fixture-backed scope.".to_string(),
        recommended_repair: "No user test action.".to_string(),
        related_test: None,
        static_limitations: vec![],
        confidence: FindingAlignmentConfidence {
            basis: "fixture_backed".to_string(),
            notes: vec![
                "Internal-only presentation labels are benchmark-pinned as no-action evidence, not user-visible output debt.".to_string(),
            ],
        },
        visibility: "internal_only".to_string(),
        observer: "none".to_string(),
        presentation_actionability: "no_action_internal".to_string(),
        recommended_observer: "none".to_string(),
        repair_kind: "no_action".to_string(),
        target_test_type: "none".to_string(),
        suggested_assertion: "No user-facing assertion is recommended for this internal label."
            .to_string(),
    }
}

fn actionable_output_classification(
    sink: PresentationTextSink,
    constant_name: &str,
) -> PresentationTextClassification {
    let recommended_repair = format!(
        "Add or update a {} for {constant_name}.",
        sink.repair_target,
    );
    let suggested_assertion = format!(
        "Assert {} includes the {constant_name} text.",
        sink.assertion_subject,
    );

    PresentationTextClassification {
        canonical_item_kind: "gap".to_string(),
        gap_state: "actionable".to_string(),
        actionability: "add_output_observer".to_string(),
        why: format!(
            "Changed text flows to {} and no supported output observer is found.",
            sink.description
        ),
        recommended_repair,
        related_test: None,
        static_limitations: vec![],
        confidence: FindingAlignmentConfidence {
            basis: "fixture_backed".to_string(),
            notes: vec![
                "Visible unobserved presentation text is actionable only for supported sink patterns.".to_string(),
            ],
        },
        visibility: "user_visible".to_string(),
        observer: "none".to_string(),
        presentation_actionability: "add_output_observer".to_string(),
        recommended_observer: sink.recommended_observer.to_string(),
        repair_kind: "output_observer".to_string(),
        target_test_type: sink.target_test_type.to_string(),
        suggested_assertion,
    }
}

fn observed_classification(
    sink: PresentationTextSink,
    observer: &'static str,
    related_test: FindingAlignmentRelatedTest,
) -> PresentationTextClassification {
    PresentationTextClassification {
        canonical_item_kind: "observed".to_string(),
        gap_state: "already_observed".to_string(),
        actionability: "already_observed".to_string(),
        why: format!(
            "Changed text flows to {} and a supported {observer} observer covers it.",
            sink.description
        ),
        recommended_repair: "No new RIPR action.".to_string(),
        related_test: Some(related_test),
        static_limitations: vec![],
        confidence: FindingAlignmentConfidence {
            basis: "fixture_backed".to_string(),
            notes: vec![
                "Observed presentation text stays visible as evidence without becoming a user repair.".to_string(),
            ],
        },
        visibility: "user_visible".to_string(),
        observer: observer.to_string(),
        presentation_actionability: "already_observed".to_string(),
        recommended_observer: observer.to_string(),
        repair_kind: "no_action".to_string(),
        target_test_type: observer.to_string(),
        suggested_assertion: format!(
            "Existing {observer} observer already covers the {}.",
            sink.description
        ),
    }
}

fn classify_config_policy_constant(
    constant_name: &str,
    raw_findings: &[&Finding],
) -> ConfigPolicyClassification {
    let source_file = raw_findings
        .first()
        .map(|finding| finding.probe.location.file.display().to_string())
        .unwrap_or_default();

    if is_internal_only_config_policy(constant_name, &source_file) {
        return internal_config_policy_classification();
    }

    if is_opaque_config_policy_lookup(constant_name, &source_file) {
        return config_policy_limitation_classification(
            OPAQUE_CONFIG_LOOKUP_CATEGORY,
            OPAQUE_CONFIG_LOOKUP_REPAIR_ROUTE,
            "Changed config or policy constant is routed through an unsupported lookup helper.",
            "Add fixture-backed support for this lookup shape before claiming visibility or observer debt.",
            "unknown_until_lookup_supported",
        );
    }

    if let Some(sink) = config_policy_visible_sink_for(constant_name, &source_file) {
        if let Some((observer, related_test)) = observer_for_findings(raw_findings) {
            return observed_config_policy_classification(sink, observer, related_test);
        }

        return actionable_config_policy_classification(sink, constant_name);
    }

    config_policy_limitation_classification(
        CONFIG_POLICY_FLOW_UNKNOWN_CATEGORY,
        CONFIG_POLICY_FLOW_UNKNOWN_REPAIR_ROUTE,
        "Changed config or policy constant could not be traced to or away from a supported output, schema, validation, or behavior sink.",
        "Trace the constant to a supported output, schema, validation, or behavior sink before claiming user test debt.",
        "unknown_until_config_flow_known",
    )
}

fn internal_config_policy_classification() -> ConfigPolicyClassification {
    ConfigPolicyClassification {
        canonical_item_kind: "no_action".to_string(),
        gap_state: "internal_only".to_string(),
        actionability: "no_action_internal".to_string(),
        why: "Changed constant is confined to internal allowlist, proof, or policy metadata in fixture-backed scope.".to_string(),
        recommended_repair: "No user test action.".to_string(),
        related_test: None,
        static_limitations: vec![],
        confidence: FindingAlignmentConfidence {
            basis: "fixture_backed".to_string(),
            notes: vec![
                "Internal config or policy metadata is benchmark-pinned as no-action evidence, not user test debt.".to_string(),
            ],
        },
        role: "internal_policy_metadata".to_string(),
        visibility: "internal_only".to_string(),
        observer: "none".to_string(),
        config_actionability: "no_action_internal".to_string(),
        repair_kind: "no_action".to_string(),
        target_test_type: "none".to_string(),
        suggested_assertion:
            "No user-facing assertion is recommended for this internal policy constant."
                .to_string(),
    }
}

fn actionable_config_policy_classification(
    sink: ConfigPolicySink,
    constant_name: &str,
) -> ConfigPolicyClassification {
    let recommended_repair = format!(
        "Add or update a {} for {constant_name}.",
        sink.repair_target
    );
    let suggested_assertion = format!(
        "Assert {} includes the {constant_name} value or selected behavior.",
        sink.assertion_subject
    );

    ConfigPolicyClassification {
        canonical_item_kind: "gap".to_string(),
        gap_state: "actionable".to_string(),
        actionability: sink.actionability.to_string(),
        why: format!(
            "Changed config or policy constant flows to {} and no supported observer or discriminator is found.",
            sink.description
        ),
        recommended_repair,
        related_test: None,
        static_limitations: vec![],
        confidence: FindingAlignmentConfidence {
            basis: "fixture_backed".to_string(),
            notes: vec![
                "Visible unobserved config or policy constants are actionable only for supported sink patterns.".to_string(),
            ],
        },
        role: sink.role.to_string(),
        visibility: "user_visible".to_string(),
        observer: "none".to_string(),
        config_actionability: sink.actionability.to_string(),
        repair_kind: sink.repair_kind.to_string(),
        target_test_type: sink.target_test_type.to_string(),
        suggested_assertion,
    }
}

fn observed_config_policy_classification(
    sink: ConfigPolicySink,
    observer: &'static str,
    related_test: FindingAlignmentRelatedTest,
) -> ConfigPolicyClassification {
    ConfigPolicyClassification {
        canonical_item_kind: "observed".to_string(),
        gap_state: "already_observed".to_string(),
        actionability: "already_observed".to_string(),
        why: format!(
            "Changed config or policy constant flows to {} and a supported {observer} observer covers it.",
            sink.description
        ),
        recommended_repair: "No new RIPR action.".to_string(),
        related_test: Some(related_test),
        static_limitations: vec![],
        confidence: FindingAlignmentConfidence {
            basis: "fixture_backed".to_string(),
            notes: vec![
                "Observed config or policy constants stay visible as evidence without becoming user repair work.".to_string(),
            ],
        },
        role: sink.role.to_string(),
        visibility: "user_visible".to_string(),
        observer: observer.to_string(),
        config_actionability: "already_observed".to_string(),
        repair_kind: "no_action".to_string(),
        target_test_type: observer.to_string(),
        suggested_assertion: format!(
            "Existing {observer} observer already covers the {}.",
            sink.description
        ),
    }
}

fn config_policy_limitation_classification(
    category: &str,
    repair_route: &str,
    why: &str,
    recommended_repair: &str,
    user_actionability: &str,
) -> ConfigPolicyClassification {
    ConfigPolicyClassification {
        canonical_item_kind: "limitation".to_string(),
        gap_state: "static_limitation".to_string(),
        actionability: "inspect_config_flow".to_string(),
        why: why.to_string(),
        recommended_repair: recommended_repair.to_string(),
        related_test: None,
        static_limitations: vec![FindingAlignmentStaticLimitation {
            category: category.to_string(),
            repair_route: repair_route.to_string(),
            user_actionability: user_actionability.to_string(),
        }],
        confidence: FindingAlignmentConfidence {
            basis: "fixture_backed".to_string(),
            notes: vec![
                "Config/policy unknowns are benchmark-pinned as named limitations; no user test debt is claimed without supported sink evidence.".to_string(),
            ],
        },
        role: "unknown".to_string(),
        visibility: "unknown".to_string(),
        observer: "unknown".to_string(),
        config_actionability: "inspect_config_flow".to_string(),
        repair_kind: "inspect_config_flow".to_string(),
        target_test_type: "unknown".to_string(),
        suggested_assertion:
            "Trace the constant to a supported output or behavior sink before adding tests."
                .to_string(),
    }
}

fn visible_sink_for(constant_name: &str, file: &str) -> Option<PresentationTextSink> {
    let file = normalize_token_text(file);

    if name_has_token(constant_name, "HELP")
        && (file.contains("help") || file.contains("cli") || file.contains("command"))
    {
        return Some(PresentationTextSink {
            recommended_observer: "cli_help_output",
            repair_target: "help-output snapshot assertion",
            description: "CLI help output",
            target_test_type: "help_output_snapshot",
            assertion_subject: "CLI help output",
        });
    }

    if name_has_token(constant_name, "REPORT") && file.contains("report") {
        return Some(PresentationTextSink {
            recommended_observer: "report_render",
            repair_target: "report-render or golden-output test",
            description: "rendered report output",
            target_test_type: "report_render_or_golden",
            assertion_subject: "the rendered report output",
        });
    }

    if (name_has_token(constant_name, "TABLE") || name_has_token(constant_name, "DISPLAY"))
        && (file.contains("table") || file.contains("display") || file.contains("render"))
    {
        return Some(PresentationTextSink {
            recommended_observer: "table_render",
            repair_target: "table-render or golden-output test",
            description: "rendered table output",
            target_test_type: "table_render_or_golden",
            assertion_subject: "the rendered table output",
        });
    }

    None
}

fn config_policy_visible_sink_for(constant_name: &str, file: &str) -> Option<ConfigPolicySink> {
    let file = normalize_token_text(file);

    if (name_has_token(constant_name, "SCHEMA") || name_has_token(constant_name, "FIELD"))
        && file.contains("schema")
    {
        return Some(ConfigPolicySink {
            role: "schema_field_label",
            repair_target: "schema-render or golden-output test",
            description: "rendered schema output",
            actionability: "add_output_observer",
            repair_kind: "output_observer",
            target_test_type: "schema_render_or_golden",
            assertion_subject: "the rendered schema output",
        });
    }

    if (name_has_token(constant_name, "REPORT")
        || (name_has_token(constant_name, "POLICY") && name_has_token(constant_name, "LABEL")))
        && file.contains("report")
    {
        return Some(ConfigPolicySink {
            role: "rendered_policy_label",
            repair_target: "report-render or golden-output test",
            description: "rendered report output",
            actionability: "add_output_observer",
            repair_kind: "output_observer",
            target_test_type: "report_render_or_golden",
            assertion_subject: "the rendered report output",
        });
    }

    if (name_has_token(constant_name, "CONFIG") || name_has_token(constant_name, "SETTING"))
        && (file.contains("settings") || file.contains("output") || file.contains("render"))
    {
        return Some(ConfigPolicySink {
            role: "rendered_config_label",
            repair_target: "config-output, snapshot, or golden-output test",
            description: "rendered config output",
            actionability: "add_output_observer",
            repair_kind: "output_observer",
            target_test_type: "config_output_or_golden",
            assertion_subject: "the rendered config output",
        });
    }

    if (name_has_token(constant_name, "THRESHOLD")
        || name_has_token(constant_name, "SELECTOR")
        || name_has_token(constant_name, "VALIDATION"))
        && (file.contains("validation") || file.contains("routing") || file.contains("selector"))
    {
        return Some(ConfigPolicySink {
            role: "behavior_selector",
            repair_target: "behavior discriminator test",
            description: "observable validation or routing behavior",
            actionability: "add_behavior_discriminator",
            repair_kind: "behavior_discriminator",
            target_test_type: "validation_behavior",
            assertion_subject: "the selected behavior",
        });
    }

    None
}

fn is_internal_only_text(constant_name: &str, file: &str) -> bool {
    let file = normalize_token_text(file);
    name_has_token(constant_name, "INTERNAL")
        || name_has_token(constant_name, "PROOF")
        || name_has_token(constant_name, "POLICY")
        || name_has_token(constant_name, "CONFIG")
        || file.contains("proof")
        || file.contains("policy")
        || file.contains("config")
        || file.contains("internal")
}

fn is_internal_only_config_policy(constant_name: &str, file: &str) -> bool {
    let file = normalize_token_text(file);
    name_has_token(constant_name, "INTERNAL")
        || name_has_token(constant_name, "ALLOWLIST")
        || name_has_token(constant_name, "DENYLIST")
        || name_has_token(constant_name, "PROOF")
        || file.contains("internal")
        || file.contains("allowlist")
        || file.contains("denylist")
        || file.contains("proof")
}

fn is_opaque_config_policy_lookup(constant_name: &str, file: &str) -> bool {
    let file = normalize_token_text(file);
    name_has_token(constant_name, "OPAQUE")
        || file.contains("registry")
        || file.contains("lookup")
        || file.contains("dynamic")
}

fn observer_for_findings(
    raw_findings: &[&Finding],
) -> Option<(&'static str, FindingAlignmentRelatedTest)> {
    raw_findings
        .iter()
        .flat_map(|finding| finding.related_tests.iter())
        .filter_map(|test| {
            observer_for_related_test(test).map(|(rank, observer)| (rank, observer, test))
        })
        .min_by_key(|(rank, _, _)| *rank)
        .map(|(_, observer, test)| (observer, related_test_for(test)))
}

fn repair_route_for(
    gap_state: &str,
    repair_kind: &str,
    target_test_type: &str,
    suggested_assertion: &str,
) -> Option<FindingAlignmentRepairRoute> {
    if gap_state != "actionable" {
        return None;
    }

    if route_field_is_missing(repair_kind)
        || route_field_is_missing(target_test_type)
        || suggested_assertion.trim().is_empty()
    {
        return None;
    }

    Some(FindingAlignmentRepairRoute {
        repair_kind: repair_kind.to_string(),
        target_test_type: target_test_type.to_string(),
        suggested_assertion: suggested_assertion.to_string(),
    })
}

fn item_has_repair_route(item: &FindingAlignmentItem) -> bool {
    item.repair_route.as_ref().is_some_and(|route| {
        !route_field_is_missing(&route.repair_kind)
            && !route_field_is_missing(&route.target_test_type)
            && !route.suggested_assertion.trim().is_empty()
    })
}

fn item_has_verify_command(item: &FindingAlignmentItem) -> bool {
    !verify_command_is_missing(&item.verify_command)
}

fn verify_command_is_missing(value: &str) -> bool {
    let value = value.trim();
    value.is_empty() || value == "unknown" || value == "verify_command_unknown"
}

fn route_field_is_missing(value: &str) -> bool {
    let value = value.trim();
    value.is_empty() || value == "unknown" || value == "none" || value == "no_action"
}

fn observer_for_related_test(test: &RelatedTest) -> Option<(u8, &'static str)> {
    let text = normalize_token_text(&format!("{} {}", test.name, test.file.display()));
    let strong_oracle = matches!(
        test.oracle_strength,
        OracleStrength::Strong | OracleStrength::Medium
    );

    if strong_oracle && text.contains("golden") {
        return Some((0, "golden"));
    }

    if test.oracle_kind == OracleKind::Snapshot || (strong_oracle && text.contains("snapshot")) {
        return Some((1, "snapshot"));
    }

    if strong_oracle && (text.contains("help_output") || text.contains("help")) {
        return Some((2, "cli_help_output"));
    }

    if strong_oracle && (text.contains("report") || text.contains("markdown")) {
        return Some((3, "report_render"));
    }

    if strong_oracle && text.contains("schema") {
        return Some((4, "schema_render"));
    }

    if strong_oracle && (text.contains("config") || text.contains("settings")) {
        return Some((5, "config_output"));
    }

    if strong_oracle && (text.contains("validation") || text.contains("routing")) {
        return Some((6, "validation_behavior"));
    }

    if strong_oracle && (text.contains("table") || text.contains("display")) {
        return Some((7, "table_render"));
    }

    None
}

fn related_test_for(test: &RelatedTest) -> FindingAlignmentRelatedTest {
    FindingAlignmentRelatedTest {
        name: test.name.clone(),
        file: test.file.display().to_string(),
        line: test.line,
    }
}

fn name_has_token(name: &str, token: &str) -> bool {
    name.to_ascii_uppercase()
        .split('_')
        .any(|part| part == token)
}

fn normalize_token_text(text: &str) -> String {
    text.chars()
        .map(|ch| {
            if ch.is_ascii_alphanumeric() {
                ch.to_ascii_lowercase()
            } else {
                '_'
            }
        })
        .collect()
}

fn raw_finding_for(finding: &Finding) -> FindingAlignmentRawFinding {
    FindingAlignmentRawFinding {
        file: finding.probe.location.file.display().to_string(),
        line: finding.probe.location.line,
        kind: finding.class.as_str().to_string(),
        expression: finding.probe.expression.clone(),
        probe_kind: finding.probe.family.as_str().to_string(),
        source_id: finding.probe.id.0.clone(),
        evidence_record_ref: finding.id.clone(),
    }
}

fn primary_anchor_for(
    raw_findings: &[FindingAlignmentRawFinding],
    group_reason: &str,
) -> Option<FindingAlignmentPrimaryAnchor> {
    raw_findings
        .first()
        .map(|finding| FindingAlignmentPrimaryAnchor {
            file: finding.file.clone(),
            line: finding.line,
            kind: finding.kind.clone(),
            source_id: finding.source_id.clone(),
            reason: primary_anchor_reason(group_reason).to_string(),
        })
}

fn primary_anchor_reason(group_reason: &str) -> &'static str {
    match group_reason {
        GROUP_REASON_DECL_LITERAL => "declaration_line_for_grouped_constant",
        GROUP_REASON_OWNER => "constant_owner_line",
        GROUP_REASON_CONFIG_POLICY => "config_policy_owner_line",
        _ => "first_raw_finding_in_canonical_item",
    }
}

fn raw_spans_for(raw_findings: &[FindingAlignmentRawFinding]) -> Vec<FindingAlignmentRawSpan> {
    raw_findings
        .iter()
        .map(|finding| FindingAlignmentRawSpan {
            file: finding.file.clone(),
            start_line: finding.line,
            end_line: finding.line,
            kind: finding.kind.clone(),
            source_id: finding.source_id.clone(),
        })
        .collect()
}

fn adjacent_literal_index(
    findings: &[Finding],
    used: &[bool],
    declaration_index: usize,
) -> Option<usize> {
    let declaration = &findings[declaration_index];
    findings
        .iter()
        .enumerate()
        .filter(|(index, _)| *index != declaration_index && !used[*index])
        .filter(|(_, candidate)| candidate.probe.location.file == declaration.probe.location.file)
        .filter(|(_, candidate)| {
            candidate.probe.location.line == declaration.probe.location.line
                || candidate.probe.location.line == declaration.probe.location.line + 1
        })
        .find_map(|(index, candidate)| {
            parse_string_literal(&candidate.probe.expression).map(|_| index)
        })
}

fn parse_config_policy_declaration(expression: &str) -> Option<PresentationTextDeclaration> {
    let trimmed = expression.trim();
    let const_pos = trimmed.find("const ")?;
    if const_pos > 0
        && trimmed[..const_pos]
            .chars()
            .last()
            .is_some_and(|ch| ch.is_alphanumeric() || ch == '_')
    {
        return None;
    }

    let after_const = &trimmed[const_pos + "const ".len()..];
    let name_end = after_const
        .find(|ch: char| !(ch.is_ascii_alphanumeric() || ch == '_'))
        .unwrap_or(after_const.len());
    let constant_name = &after_const[..name_end];
    if constant_name.is_empty() || !is_config_policy_constant_name(constant_name) {
        return None;
    }

    let after_name = after_const[name_end..].trim_start();
    let after_colon = after_name.strip_prefix(':')?.trim_start();
    let equals_pos = after_colon.find('=')?;
    let after_equals = after_colon[equals_pos + 1..].trim_start();
    Some(PresentationTextDeclaration {
        constant_name: constant_name.to_string(),
        inline_literal: parse_string_literal(after_equals),
    })
}

fn parse_presentation_text_declaration(expression: &str) -> Option<PresentationTextDeclaration> {
    let trimmed = expression.trim();
    let const_pos = trimmed.find("const ")?;
    if const_pos > 0
        && trimmed[..const_pos]
            .chars()
            .last()
            .is_some_and(|ch| ch.is_alphanumeric() || ch == '_')
    {
        return None;
    }

    let after_const = &trimmed[const_pos + "const ".len()..];
    let name_end = after_const
        .find(|ch: char| !(ch.is_ascii_alphanumeric() || ch == '_'))
        .unwrap_or(after_const.len());
    let constant_name = &after_const[..name_end];
    if constant_name.is_empty() || !is_presentation_text_constant_name(constant_name) {
        return None;
    }

    let after_name = after_const[name_end..].trim_start();
    let after_colon = after_name.strip_prefix(':')?.trim_start();
    let equals_pos = after_colon.find('=')?;
    let ty = after_colon[..equals_pos].trim();
    if !matches!(ty, "&str" | "&'static str") {
        return None;
    }

    let after_equals = after_colon[equals_pos + 1..].trim_start();
    Some(PresentationTextDeclaration {
        constant_name: constant_name.to_string(),
        inline_literal: parse_string_literal(after_equals),
    })
}

fn is_config_policy_constant_name(name: &str) -> bool {
    let upper = name.to_ascii_uppercase();
    [
        "CONFIG",
        "SETTING",
        "SETTINGS",
        "POLICY",
        "ALLOWLIST",
        "DENYLIST",
        "SCHEMA",
        "FIELD",
        "THRESHOLD",
        "SELECTOR",
        "VALIDATION",
        "ROUTING",
        "ROUTE",
        "OPAQUE",
    ]
    .iter()
    .any(|marker| upper.split('_').any(|part| part == *marker))
}

fn is_presentation_text_constant_name(name: &str) -> bool {
    let upper = name.to_ascii_uppercase();
    [
        "TEXT",
        "LABEL",
        "LABELS",
        "HELP",
        "TITLE",
        "MESSAGE",
        "DESCRIPTION",
        "REPORT",
        "DISPLAY",
        "HEADER",
        "FOOTER",
    ]
    .iter()
    .any(|marker| upper.split('_').any(|part| part == *marker))
}

fn parse_string_literal(expression: &str) -> Option<String> {
    let start = expression.find('"')?;
    let mut value = String::new();
    let mut escaped = false;

    for ch in expression[start + 1..].chars() {
        if escaped {
            match ch {
                'n' => value.push('\n'),
                'r' => value.push('\r'),
                't' => value.push('\t'),
                '"' => value.push('"'),
                '\\' => value.push('\\'),
                other => {
                    value.push('\\');
                    value.push(other);
                }
            }
            escaped = false;
            continue;
        }

        match ch {
            '\\' => escaped = true,
            '"' => return Some(value),
            other => value.push(other),
        }
    }

    None
}

fn summary_json(out: &mut String, summary: &FindingAlignmentSummary) {
    let ratio = if summary.canonical_items == 0 {
        0.0
    } else {
        summary.raw_signals as f64 / summary.canonical_items as f64
    };
    out.push_str(&format!(
        "{{\"raw_signals\":{},\"canonical_items\":{},\"aligned_raw_findings\":{},\"unaligned_raw_findings\":{},\"raw_to_canonical_ratio\":{ratio:.2},\"duplicate_groups_total\":{},\"actionable_gaps\":{},\"already_observed\":{},\"internal_no_action\":{},\"static_limitations\":{},\"unknown\":{},\"calibrated_supported\":{},\"uncalibrated\":{},\"repair_route_coverage\":{},\"actionable_items_without_repair_route\":{},\"verify_command_coverage\":{},\"actionable_items_without_verify_command\":{},\"presentation_text_total\":{},\"presentation_text_user_visible\":{},\"presentation_text_observed\":{},\"presentation_text_unobserved\":{},\"presentation_text_internal_only\":{},\"presentation_text_visibility_unknown\":{},\"presentation_text_observer_unknown\":{},\"presentation_text_duplicate_groups\":{},\"presentation_text_actionable_snapshot\":{},\"presentation_text_actionable_output_repairs\":{},\"presentation_text_no_action\":{},\"presentation_text_static_limitations\":{},\"config_policy_constant_total\":{},\"config_policy_user_visible\":{},\"config_policy_observed\":{},\"config_policy_unobserved\":{},\"config_policy_internal_only\":{},\"config_policy_flow_unknown\":{},\"config_policy_observer_unknown\":{},\"config_policy_duplicate_groups\":{},\"config_policy_actionable_output_observer\":{},\"config_policy_actionable_behavior_discriminator\":{},\"config_policy_no_action\":{},\"config_policy_static_limitations\":{},\"config_policy_repair_route_coverage\":{},\"config_policy_verify_command_coverage\":{}}}",
        summary.raw_signals,
        summary.canonical_items,
        summary.aligned_raw_findings,
        summary.unaligned_raw_findings,
        summary.duplicate_groups_total,
        summary.actionable_gaps,
        summary.already_observed,
        summary.internal_no_action,
        summary.static_limitations,
        summary.unknown,
        summary.calibrated_supported,
        summary.uncalibrated,
        summary.repair_route_coverage,
        summary.actionable_items_without_repair_route,
        summary.verify_command_coverage,
        summary.actionable_items_without_verify_command,
        summary.presentation_text_total,
        summary.presentation_text_user_visible,
        summary.presentation_text_observed,
        summary.presentation_text_unobserved,
        summary.presentation_text_internal_only,
        summary.presentation_text_visibility_unknown,
        summary.presentation_text_observer_unknown,
        summary.presentation_text_duplicate_groups,
        summary.presentation_text_actionable_snapshot,
        summary.presentation_text_actionable_output_repairs,
        summary.presentation_text_no_action,
        summary.presentation_text_static_limitations,
        summary.config_policy_constant_total,
        summary.config_policy_user_visible,
        summary.config_policy_observed,
        summary.config_policy_unobserved,
        summary.config_policy_internal_only,
        summary.config_policy_flow_unknown,
        summary.config_policy_observer_unknown,
        summary.config_policy_duplicate_groups,
        summary.config_policy_actionable_output_observer,
        summary.config_policy_actionable_behavior_discriminator,
        summary.config_policy_no_action,
        summary.config_policy_static_limitations,
        summary.config_policy_repair_route_coverage,
        summary.config_policy_verify_command_coverage
    ));
}

fn item_json(out: &mut String, item: &FindingAlignmentItem, indent: usize) {
    let sp = "  ".repeat(indent);
    out.push_str(&format!("{sp}{{\n"));
    field(
        out,
        indent + 1,
        "canonical_gap_id",
        &item.canonical_gap_id,
        true,
    );
    field(
        out,
        indent + 1,
        "canonical_item_kind",
        &item.canonical_item_kind,
        true,
    );
    field(
        out,
        indent + 1,
        "evidence_class",
        &item.evidence_class,
        true,
    );
    field(out, indent + 1, "gap_state", &item.gap_state, true);
    field(out, indent + 1, "actionability", &item.actionability, true);
    number_field(out, indent + 1, "raw_group_size", item.raw_group_size, true);
    field(out, indent + 1, "group_reason", &item.group_reason, true);
    primary_anchor_json(out, item.primary_anchor.as_ref(), indent + 1);
    out.push_str(",\n");
    raw_spans_json(out, &item.raw_spans, indent + 1);
    out.push_str(",\n");
    field(out, indent + 1, "why", &item.why, true);
    field(
        out,
        indent + 1,
        "recommended_repair",
        &item.recommended_repair,
        true,
    );
    repair_route_json(out, item.repair_route.as_ref(), indent + 1);
    out.push_str(",\n");
    related_test_json(out, item.related_test.as_ref(), indent + 1);
    out.push_str(",\n");
    field(
        out,
        indent + 1,
        "verify_command",
        &item.verify_command,
        true,
    );
    static_limitations_json(out, &item.static_limitations, indent + 1);
    out.push_str(",\n");
    confidence_json(out, &item.confidence, indent + 1);
    out.push_str(",\n");
    raw_findings_json(out, &item.raw_findings, indent + 1);
    out.push_str(",\n");
    presentation_text_json(out, item.presentation_text.as_ref(), indent + 1);
    out.push_str(",\n");
    config_policy_json(out, item.config_policy.as_ref(), indent + 1);
    out.push('\n');
    out.push_str(&format!("{sp}}}"));
}

fn repair_route_json(
    out: &mut String,
    repair_route: Option<&FindingAlignmentRepairRoute>,
    indent: usize,
) {
    out.push_str(&format!("{}\"repair_route\": ", "  ".repeat(indent)));
    let Some(repair_route) = repair_route else {
        out.push_str("null");
        return;
    };
    out.push_str("{\n");
    field(
        out,
        indent + 1,
        "repair_kind",
        &repair_route.repair_kind,
        true,
    );
    field(
        out,
        indent + 1,
        "target_test_type",
        &repair_route.target_test_type,
        true,
    );
    field(
        out,
        indent + 1,
        "suggested_assertion",
        &repair_route.suggested_assertion,
        false,
    );
    out.push_str(&format!("{}}}", "  ".repeat(indent)));
}

fn related_test_json(
    out: &mut String,
    related_test: Option<&FindingAlignmentRelatedTest>,
    indent: usize,
) {
    out.push_str(&format!("{}\"related_test\": ", "  ".repeat(indent)));
    if let Some(test) = related_test {
        out.push_str("{\n");
        field(out, indent + 1, "name", &test.name, true);
        field(out, indent + 1, "file", &test.file, true);
        number_field(out, indent + 1, "line", test.line, false);
        out.push_str(&format!("{}}}", "  ".repeat(indent)));
    } else {
        out.push_str("null");
    }
}

fn static_limitations_json(
    out: &mut String,
    limitations: &[FindingAlignmentStaticLimitation],
    indent: usize,
) {
    out.push_str(&format!(
        "{}\"static_limitations\": [\n",
        "  ".repeat(indent)
    ));
    for (index, limitation) in limitations.iter().enumerate() {
        let sp = "  ".repeat(indent + 1);
        out.push_str(&format!("{sp}{{\n"));
        field(out, indent + 2, "category", &limitation.category, true);
        field(
            out,
            indent + 2,
            "repair_route",
            &limitation.repair_route,
            true,
        );
        field(
            out,
            indent + 2,
            "user_actionability",
            &limitation.user_actionability,
            false,
        );
        out.push_str(&format!("{sp}}}"));
        if index + 1 != limitations.len() {
            out.push(',');
        }
        out.push('\n');
    }
    out.push_str(&format!("{}]", "  ".repeat(indent)));
}

fn confidence_json(out: &mut String, confidence: &FindingAlignmentConfidence, indent: usize) {
    out.push_str(&format!("{}\"confidence\": {{\n", "  ".repeat(indent)));
    field(out, indent + 1, "basis", &confidence.basis, true);
    array_field(out, indent + 1, "notes", &confidence.notes, false);
    out.push_str(&format!("{}}}", "  ".repeat(indent)));
}

fn primary_anchor_json(
    out: &mut String,
    primary_anchor: Option<&FindingAlignmentPrimaryAnchor>,
    indent: usize,
) {
    out.push_str(&format!("{}\"primary_anchor\": ", "  ".repeat(indent)));
    let Some(anchor) = primary_anchor else {
        out.push_str("null");
        return;
    };
    out.push_str("{\n");
    field(out, indent + 1, "file", &anchor.file, true);
    number_field(out, indent + 1, "line", anchor.line, true);
    field(out, indent + 1, "kind", &anchor.kind, true);
    field(out, indent + 1, "source_id", &anchor.source_id, true);
    field(out, indent + 1, "reason", &anchor.reason, false);
    out.push_str(&format!("{}}}", "  ".repeat(indent)));
}

fn raw_spans_json(out: &mut String, raw_spans: &[FindingAlignmentRawSpan], indent: usize) {
    out.push_str(&format!("{}\"raw_spans\": [\n", "  ".repeat(indent)));
    for (index, span) in raw_spans.iter().enumerate() {
        let sp = "  ".repeat(indent + 1);
        out.push_str(&format!("{sp}{{\n"));
        field(out, indent + 2, "file", &span.file, true);
        number_field(out, indent + 2, "start_line", span.start_line, true);
        number_field(out, indent + 2, "end_line", span.end_line, true);
        field(out, indent + 2, "kind", &span.kind, true);
        field(out, indent + 2, "source_id", &span.source_id, false);
        out.push_str(&format!("{sp}}}"));
        if index + 1 != raw_spans.len() {
            out.push(',');
        }
        out.push('\n');
    }
    out.push_str(&format!("{}]", "  ".repeat(indent)));
}

fn raw_findings_json(out: &mut String, raw_findings: &[FindingAlignmentRawFinding], indent: usize) {
    out.push_str(&format!("{}\"raw_findings\": [\n", "  ".repeat(indent)));
    for (index, finding) in raw_findings.iter().enumerate() {
        let sp = "  ".repeat(indent + 1);
        out.push_str(&format!("{sp}{{\n"));
        field(out, indent + 2, "file", &finding.file, true);
        number_field(out, indent + 2, "line", finding.line, true);
        field(out, indent + 2, "kind", &finding.kind, true);
        field(out, indent + 2, "expression", &finding.expression, true);
        field(out, indent + 2, "probe_kind", &finding.probe_kind, true);
        field(out, indent + 2, "source_id", &finding.source_id, true);
        field(
            out,
            indent + 2,
            "evidence_record_ref",
            &finding.evidence_record_ref,
            false,
        );
        out.push_str(&format!("{sp}}}"));
        if index + 1 != raw_findings.len() {
            out.push(',');
        }
        out.push('\n');
    }
    out.push_str(&format!("{}]", "  ".repeat(indent)));
}

fn presentation_text_json(
    out: &mut String,
    presentation_text: Option<&FindingAlignmentPresentationText>,
    indent: usize,
) {
    out.push_str(&format!("{}\"presentation_text\": ", "  ".repeat(indent)));
    let Some(presentation_text) = presentation_text else {
        out.push_str("null");
        return;
    };
    out.push_str("{\n");
    field(
        out,
        indent + 1,
        "constant_name",
        &presentation_text.constant_name,
        true,
    );
    out.push_str(&format!("{}\"text_literal\": ", "  ".repeat(indent + 1)));
    if let Some(text_literal) = &presentation_text.text_literal {
        out.push_str(&format!("\"{}\",\n", escape(text_literal)));
    } else {
        out.push_str("null,\n");
    }
    field(
        out,
        indent + 1,
        "visibility",
        &presentation_text.visibility,
        true,
    );
    field(
        out,
        indent + 1,
        "observer",
        &presentation_text.observer,
        true,
    );
    field(
        out,
        indent + 1,
        "actionability",
        &presentation_text.actionability,
        true,
    );
    field(
        out,
        indent + 1,
        "source_kind",
        &presentation_text.source_kind,
        true,
    );
    field(
        out,
        indent + 1,
        "canonical_group_reason",
        &presentation_text.canonical_group_reason,
        true,
    );
    field(
        out,
        indent + 1,
        "recommended_observer",
        &presentation_text.recommended_observer,
        true,
    );
    field(
        out,
        indent + 1,
        "repair_kind",
        &presentation_text.repair_kind,
        true,
    );
    field(
        out,
        indent + 1,
        "target_test_type",
        &presentation_text.target_test_type,
        true,
    );
    field(
        out,
        indent + 1,
        "suggested_assertion",
        &presentation_text.suggested_assertion,
        false,
    );
    out.push_str(&format!("{}}}", "  ".repeat(indent)));
}

fn config_policy_json(
    out: &mut String,
    config_policy: Option<&FindingAlignmentConfigPolicy>,
    indent: usize,
) {
    out.push_str(&format!("{}\"config_policy\": ", "  ".repeat(indent)));
    let Some(config_policy) = config_policy else {
        out.push_str("null");
        return;
    };
    out.push_str("{\n");
    field(out, indent + 1, "constant", &config_policy.constant, true);
    field(out, indent + 1, "role", &config_policy.role, true);
    field(
        out,
        indent + 1,
        "source_kind",
        &config_policy.source_kind,
        true,
    );
    field(
        out,
        indent + 1,
        "visibility",
        &config_policy.visibility,
        true,
    );
    field(out, indent + 1, "observer", &config_policy.observer, true);
    field(
        out,
        indent + 1,
        "actionability",
        &config_policy.actionability,
        true,
    );
    field(
        out,
        indent + 1,
        "repair_kind",
        &config_policy.repair_kind,
        true,
    );
    field(
        out,
        indent + 1,
        "target_test_type",
        &config_policy.target_test_type,
        true,
    );
    field(
        out,
        indent + 1,
        "suggested_assertion",
        &config_policy.suggested_assertion,
        false,
    );
    out.push_str(&format!("{}}}", "  ".repeat(indent)));
}

#[cfg(test)]
mod tests {
    use super::{
        GROUP_REASON_DECL_LITERAL, GROUP_REASON_OWNER, parse_presentation_text_declaration,
        parse_string_literal, report_for_findings, verify_command_is_missing,
    };
    use crate::domain::{
        ActivationEvidence, Confidence, DeltaKind, ExposureClass, Finding, OracleKind,
        OracleStrength, Probe, ProbeFamily, ProbeId, RelatedTest, RevealEvidence, RiprEvidence,
        SourceLocation, StageEvidence, StageState,
    };

    #[test]
    fn groups_const_declaration_and_adjacent_literal() -> Result<(), String> {
        let findings = vec![
            finding_at(
                "decl",
                46,
                ExposureClass::Exposed,
                ProbeFamily::FieldConstruction,
                "pub const APPLE_M3_AIR_DEVICE_LABELS_TEXT: &str =",
            ),
            finding_at(
                "literal",
                47,
                ExposureClass::StaticUnknown,
                ProbeFamily::StaticUnknown,
                "\"apple-m3-air-cpu-neon = M3 MacBook Air Apple CPU/NEON lane\";",
            ),
        ];

        let report = report_for_findings(&findings)
            .ok_or_else(|| "presentation text should align".to_string())?;
        assert_eq!(report.summary.raw_signals, 2);
        assert_eq!(report.summary.canonical_items, 1);
        assert_eq!(report.summary.aligned_raw_findings, 2);
        assert_eq!(report.summary.static_limitations, 1);
        let item = &report.items[0];
        assert_eq!(
            item.canonical_gap_id,
            "presentation_text::APPLE_M3_AIR_DEVICE_LABELS_TEXT"
        );
        assert_eq!(item.raw_group_size, 2);
        assert_eq!(item.group_reason, GROUP_REASON_DECL_LITERAL);
        let primary_anchor = item
            .primary_anchor
            .as_ref()
            .ok_or_else(|| "grouped item should expose a primary anchor".to_string())?;
        assert_eq!(primary_anchor.file, "src/device_labels.rs");
        assert_eq!(primary_anchor.line, 46);
        assert_eq!(primary_anchor.kind, "exposed");
        assert_eq!(
            primary_anchor.source_id,
            "probe:src_device_labels_rs:46:decl"
        );
        assert_eq!(
            primary_anchor.reason,
            "declaration_line_for_grouped_constant"
        );
        assert_eq!(item.raw_spans.len(), 2);
        assert_eq!(item.raw_spans[0].start_line, 46);
        assert_eq!(item.raw_spans[0].end_line, 46);
        assert_eq!(item.raw_spans[1].start_line, 47);
        assert_eq!(item.raw_spans[1].end_line, 47);
        assert_eq!(item.gap_state, "static_limitation");
        assert_eq!(item.actionability, "inspect_visibility");
        let presentation_text = presentation_text_for(item)?;
        assert_eq!(
            presentation_text.text_literal.as_deref(),
            Some("apple-m3-air-cpu-neon = M3 MacBook Air Apple CPU/NEON lane")
        );
        Ok(())
    }

    #[test]
    fn canonical_id_is_stable_across_line_movement() -> Result<(), String> {
        let before = vec![
            finding_at(
                "before-decl",
                42,
                ExposureClass::Exposed,
                ProbeFamily::FieldConstruction,
                "pub const HELP_MOVED_LABEL: &str =",
            ),
            finding_at(
                "before-literal",
                43,
                ExposureClass::StaticUnknown,
                ProbeFamily::StaticUnknown,
                "\"Help label\";",
            ),
        ];
        let after = vec![
            finding_at(
                "after-decl",
                57,
                ExposureClass::Exposed,
                ProbeFamily::FieldConstruction,
                "pub const HELP_MOVED_LABEL: &str =",
            ),
            finding_at(
                "after-literal",
                58,
                ExposureClass::StaticUnknown,
                ProbeFamily::StaticUnknown,
                "\"Help label\";",
            ),
        ];

        let before_report =
            report_for_findings(&before).ok_or_else(|| "before should align".to_string())?;
        let after_report =
            report_for_findings(&after).ok_or_else(|| "after should align".to_string())?;

        assert_eq!(
            before_report.items[0].canonical_gap_id,
            after_report.items[0].canonical_gap_id
        );
        assert_eq!(
            after_report.items[0].canonical_gap_id,
            "presentation_text::HELP_MOVED_LABEL"
        );
        Ok(())
    }

    #[test]
    fn similar_text_in_different_constants_does_not_collide() -> Result<(), String> {
        let findings = vec![
            finding_at(
                "first-decl",
                31,
                ExposureClass::Exposed,
                ProbeFamily::FieldConstruction,
                "pub const APPLE_DEVICE_LABEL: &str =",
            ),
            finding_at(
                "first-literal",
                32,
                ExposureClass::StaticUnknown,
                ProbeFamily::StaticUnknown,
                "\"Apple CPU/NEON lane\";",
            ),
            finding_at(
                "second-decl",
                35,
                ExposureClass::Exposed,
                ProbeFamily::FieldConstruction,
                "pub const APPLE_REPORT_LABEL: &str =",
            ),
            finding_at(
                "second-literal",
                36,
                ExposureClass::StaticUnknown,
                ProbeFamily::StaticUnknown,
                "\"Apple CPU/NEON lane\";",
            ),
        ];

        let report = report_for_findings(&findings)
            .ok_or_else(|| "presentation text should align".to_string())?;

        assert_eq!(report.summary.canonical_items, 2);
        assert_eq!(
            report.items[0].canonical_gap_id,
            "presentation_text::APPLE_DEVICE_LABEL"
        );
        assert_eq!(
            report.items[1].canonical_gap_id,
            "presentation_text::APPLE_REPORT_LABEL"
        );
        Ok(())
    }

    #[test]
    fn string_literal_without_text_constant_does_not_create_item() {
        let findings = vec![finding_at(
            "literal",
            47,
            ExposureClass::StaticUnknown,
            ProbeFamily::StaticUnknown,
            "\"apple-m3-air-cpu-neon = M3 MacBook Air Apple CPU/NEON lane\";",
        )];

        assert!(report_for_findings(&findings).is_none());
    }

    #[test]
    fn non_presentation_string_constant_does_not_create_item() {
        let findings = vec![finding_at(
            "decl",
            12,
            ExposureClass::Exposed,
            ProbeFamily::FieldConstruction,
            "pub const CACHE_KEY: &str = \"apple-m3-air-cpu-neon\";",
        )];

        assert!(report_for_findings(&findings).is_none());
    }

    #[test]
    fn declaration_without_literal_uses_owner_identity_group() -> Result<(), String> {
        let findings = vec![finding_at(
            "decl",
            31,
            ExposureClass::Exposed,
            ProbeFamily::FieldConstruction,
            "pub const APPLE_DEVICE_LABEL: &str =",
        )];

        let report = report_for_findings(&findings)
            .ok_or_else(|| "presentation text should align".to_string())?;

        assert_eq!(report.items[0].raw_group_size, 1);
        assert_eq!(report.items[0].group_reason, GROUP_REASON_OWNER);
        assert_eq!(
            report.items[0]
                .primary_anchor
                .as_ref()
                .map(|anchor| anchor.reason.as_str()),
            Some("constant_owner_line")
        );
        assert_eq!(report.items[0].raw_spans.len(), 1);
        assert!(
            presentation_text_for(&report.items[0])?
                .text_literal
                .is_none()
        );
        Ok(())
    }

    #[test]
    fn visible_help_text_without_supported_observer_is_actionable() -> Result<(), String> {
        let lexical_only = related_test(
            "mentions_help_label_without_observer",
            "tests/help_labels.rs",
            17,
            OracleKind::Unknown,
            OracleStrength::None,
        );
        let findings = vec![
            finding_in_file_with_related(
                "src/help.rs",
                "decl",
                18,
                ExposureClass::Exposed,
                ProbeFamily::FieldConstruction,
                "pub const HELP_DEVICE_LABEL: &str =",
                vec![lexical_only],
            ),
            finding_in_file(
                "src/help.rs",
                "literal",
                19,
                ExposureClass::WeaklyExposed,
                ProbeFamily::StaticUnknown,
                "\"Device label\";",
            ),
        ];

        let report = report_for_findings(&findings)
            .ok_or_else(|| "visible help text should align".to_string())?;
        let item = &report.items[0];

        assert_eq!(report.summary.actionable_gaps, 1);
        assert_eq!(report.summary.repair_route_coverage, 1);
        assert_eq!(report.summary.actionable_items_without_repair_route, 0);
        assert_eq!(report.summary.static_limitations, 0);
        assert_eq!(item.canonical_item_kind, "gap");
        assert_eq!(item.gap_state, "actionable");
        assert_eq!(item.actionability, "add_output_observer");
        let repair_route = repair_route_for_item(item)?;
        assert_eq!(repair_route.repair_kind, "output_observer");
        assert_eq!(repair_route.target_test_type, "help_output_snapshot");
        assert_eq!(
            repair_route.suggested_assertion,
            "Assert CLI help output includes the HELP_DEVICE_LABEL text."
        );
        let presentation_text = presentation_text_for(item)?;
        assert_eq!(presentation_text.visibility, "user_visible");
        assert_eq!(presentation_text.observer, "none");
        assert_eq!(presentation_text.recommended_observer, "cli_help_output");
        assert_eq!(
            item.recommended_repair,
            "Add or update a help-output snapshot assertion for HELP_DEVICE_LABEL."
        );
        assert_eq!(presentation_text.repair_kind, "output_observer");
        assert_eq!(presentation_text.target_test_type, "help_output_snapshot");
        assert_eq!(
            presentation_text.suggested_assertion,
            "Assert CLI help output includes the HELP_DEVICE_LABEL text."
        );
        assert!(item.related_test.is_none());
        assert!(!item.recommended_repair.contains("mutation"));
        Ok(())
    }

    #[test]
    fn visible_report_text_with_golden_observer_is_already_observed() -> Result<(), String> {
        let golden = related_test(
            "report_golden_observes_label",
            "tests/golden/report_output.rs",
            22,
            OracleKind::Snapshot,
            OracleStrength::Strong,
        );
        let findings = vec![
            finding_in_file_with_related(
                "src/report.rs",
                "decl",
                27,
                ExposureClass::Exposed,
                ProbeFamily::FieldConstruction,
                "pub const REPORT_DEVICE_LABEL: &str =",
                vec![golden],
            ),
            finding_in_file(
                "src/report.rs",
                "literal",
                28,
                ExposureClass::Exposed,
                ProbeFamily::StaticUnknown,
                "\"Report label\";",
            ),
        ];

        let report = report_for_findings(&findings)
            .ok_or_else(|| "visible report text should align".to_string())?;
        let item = &report.items[0];

        assert_eq!(report.summary.already_observed, 1);
        assert_eq!(report.summary.actionable_gaps, 0);
        assert_eq!(item.canonical_item_kind, "observed");
        assert_eq!(item.gap_state, "already_observed");
        assert_eq!(item.actionability, "already_observed");
        let presentation_text = presentation_text_for(item)?;
        assert_eq!(presentation_text.visibility, "user_visible");
        assert_eq!(presentation_text.observer, "golden");
        assert_eq!(presentation_text.actionability, "already_observed");
        assert_eq!(presentation_text.repair_kind, "no_action");
        assert_eq!(presentation_text.target_test_type, "golden");
        assert_eq!(
            presentation_text.suggested_assertion,
            "Existing golden observer already covers the rendered report output."
        );
        assert_eq!(
            item.related_test.as_ref().map(|test| test.name.as_str()),
            Some("report_golden_observes_label")
        );
        assert_eq!(item.recommended_repair, "No new RIPR action.");
        Ok(())
    }

    #[test]
    fn internal_only_label_is_no_action() -> Result<(), String> {
        let findings = vec![
            finding_in_file(
                "src/proof_lanes.rs",
                "decl",
                12,
                ExposureClass::Exposed,
                ProbeFamily::FieldConstruction,
                "pub const INTERNAL_PROOF_LANE_LABEL: &str =",
            ),
            finding_in_file(
                "src/proof_lanes.rs",
                "literal",
                13,
                ExposureClass::StaticUnknown,
                ProbeFamily::StaticUnknown,
                "\"internal proof lane\";",
            ),
        ];

        let report = report_for_findings(&findings)
            .ok_or_else(|| "internal label should align".to_string())?;
        let item = &report.items[0];

        assert_eq!(report.summary.internal_no_action, 1);
        assert_eq!(report.summary.static_limitations, 0);
        assert_eq!(item.canonical_item_kind, "no_action");
        assert_eq!(item.gap_state, "internal_only");
        assert_eq!(item.actionability, "no_action");
        let presentation_text = presentation_text_for(item)?;
        assert_eq!(presentation_text.visibility, "internal_only");
        assert_eq!(presentation_text.observer, "none");
        assert_eq!(presentation_text.actionability, "no_action_internal");
        assert_eq!(presentation_text.repair_kind, "no_action");
        assert_eq!(presentation_text.target_test_type, "none");
        assert_eq!(
            presentation_text.suggested_assertion,
            "No user-facing assertion is recommended for this internal label."
        );
        assert!(item.static_limitations.is_empty());
        Ok(())
    }

    #[test]
    fn help_named_text_without_supported_sink_stays_visibility_unknown() -> Result<(), String> {
        let findings = vec![finding_in_file(
            "src/opaque.rs",
            "decl",
            33,
            ExposureClass::Exposed,
            ProbeFamily::FieldConstruction,
            "pub const HELP_DEVICE_LABEL: &str = \"Device label\";",
        )];

        let report = report_for_findings(&findings)
            .ok_or_else(|| "opaque help label should align".to_string())?;
        let item = &report.items[0];

        assert_eq!(report.summary.static_limitations, 1);
        assert_eq!(item.gap_state, "static_limitation");
        assert_eq!(item.actionability, "inspect_visibility");
        let presentation_text = presentation_text_for(item)?;
        assert_eq!(presentation_text.visibility, "unknown");
        assert_eq!(presentation_text.observer, "unknown");
        assert_eq!(presentation_text.repair_kind, "inspect_visibility");
        assert_eq!(presentation_text.target_test_type, "unknown");
        assert_eq!(
            presentation_text.suggested_assertion,
            "Trace the constant to a supported output sink before adding or updating tests."
        );
        assert_eq!(
            item.static_limitations
                .first()
                .map(|limitation| limitation.category.as_str()),
            Some("presentation_text_visibility_unknown")
        );
        Ok(())
    }

    #[test]
    fn internal_policy_metadata_is_no_action() -> Result<(), String> {
        let findings = vec![
            finding_in_file(
                "src/policy.rs",
                "decl",
                14,
                ExposureClass::Exposed,
                ProbeFamily::FieldConstruction,
                "pub const INTERNAL_POLICY_LABEL: &str =",
            ),
            finding_in_file(
                "src/policy.rs",
                "literal",
                15,
                ExposureClass::StaticUnknown,
                ProbeFamily::StaticUnknown,
                "\"internal policy label\";",
            ),
        ];

        let report = report_for_findings(&findings)
            .ok_or_else(|| "internal policy constant should align".to_string())?;
        let item = &report.items[0];
        let config_policy = config_policy_for(item)?;

        assert_eq!(report.summary.canonical_items, 1);
        assert_eq!(report.summary.internal_no_action, 1);
        assert_eq!(report.summary.config_policy_constant_total, 1);
        assert_eq!(report.summary.config_policy_internal_only, 1);
        assert_eq!(report.summary.config_policy_duplicate_groups, 0);
        assert_eq!(
            item.canonical_gap_id,
            "config_or_policy_constant::INTERNAL_POLICY_LABEL"
        );
        assert_eq!(
            item.primary_anchor
                .as_ref()
                .map(|anchor| (anchor.line, anchor.reason.as_str())),
            Some((14, "declaration_line_for_grouped_constant"))
        );
        assert_eq!(item.raw_spans.len(), 2);
        assert_eq!(item.group_reason, GROUP_REASON_DECL_LITERAL);
        assert_eq!(item.raw_group_size, 2);
        assert_eq!(item.gap_state, "internal_only");
        assert_eq!(item.actionability, "no_action_internal");
        assert_eq!(config_policy.role, "internal_policy_metadata");
        assert_eq!(config_policy.visibility, "internal_only");
        assert_eq!(config_policy.repair_kind, "no_action");
        assert!(item.presentation_text.is_none());
        Ok(())
    }

    #[test]
    fn rendered_policy_label_without_observer_is_actionable() -> Result<(), String> {
        let findings = vec![
            finding_in_file(
                "src/report_config.rs",
                "decl",
                22,
                ExposureClass::Exposed,
                ProbeFamily::FieldConstruction,
                "pub const REPORT_POLICY_LABEL: &str =",
            ),
            finding_in_file(
                "src/report_config.rs",
                "literal",
                23,
                ExposureClass::WeaklyExposed,
                ProbeFamily::StaticUnknown,
                "\"Policy label\";",
            ),
        ];

        let report = report_for_findings(&findings)
            .ok_or_else(|| "rendered policy label should align".to_string())?;
        let item = &report.items[0];
        let config_policy = config_policy_for(item)?;

        assert_eq!(report.summary.actionable_gaps, 1);
        assert_eq!(report.summary.repair_route_coverage, 1);
        assert_eq!(report.summary.actionable_items_without_repair_route, 0);
        assert_eq!(report.summary.verify_command_coverage, 1);
        assert_eq!(report.summary.actionable_items_without_verify_command, 0);
        assert_eq!(report.summary.config_policy_user_visible, 1);
        assert_eq!(report.summary.config_policy_unobserved, 1);
        assert_eq!(report.summary.config_policy_actionable_output_observer, 1);
        assert_eq!(report.summary.config_policy_repair_route_coverage, 1);
        assert_eq!(report.summary.config_policy_verify_command_coverage, 1);
        assert_eq!(item.canonical_item_kind, "gap");
        assert_eq!(item.gap_state, "actionable");
        assert_eq!(item.actionability, "add_output_observer");
        let repair_route = repair_route_for_item(item)?;
        assert_eq!(repair_route.repair_kind, "output_observer");
        assert_eq!(repair_route.target_test_type, "report_render_or_golden");
        assert_eq!(
            repair_route.suggested_assertion,
            "Assert the rendered report output includes the REPORT_POLICY_LABEL value or selected behavior."
        );
        assert_eq!(config_policy.role, "rendered_policy_label");
        assert_eq!(config_policy.visibility, "user_visible");
        assert_eq!(config_policy.observer, "none");
        assert_eq!(config_policy.repair_kind, "output_observer");
        assert_eq!(config_policy.target_test_type, "report_render_or_golden");
        assert!(!item.recommended_repair.contains("mutation"));
        Ok(())
    }

    #[test]
    fn behavior_selector_without_discriminator_is_actionable() -> Result<(), String> {
        let findings = vec![
            finding_in_file(
                "src/validation_selector.rs",
                "decl",
                40,
                ExposureClass::Exposed,
                ProbeFamily::FieldConstruction,
                "pub const VALIDATION_SELECTOR: &str =",
            ),
            finding_in_file(
                "src/validation_selector.rs",
                "literal",
                41,
                ExposureClass::WeaklyExposed,
                ProbeFamily::StaticUnknown,
                "\"strict\";",
            ),
        ];

        let report = report_for_findings(&findings)
            .ok_or_else(|| "behavior selector should align".to_string())?;
        let item = &report.items[0];
        let config_policy = config_policy_for(item)?;

        assert_eq!(report.summary.raw_signals, 2);
        assert_eq!(report.summary.canonical_items, 1);
        assert_eq!(report.summary.actionable_gaps, 1);
        assert_eq!(report.summary.config_policy_user_visible, 1);
        assert_eq!(report.summary.config_policy_unobserved, 1);
        assert_eq!(
            report
                .summary
                .config_policy_actionable_behavior_discriminator,
            1
        );
        assert_eq!(report.summary.config_policy_repair_route_coverage, 1);
        assert_eq!(report.summary.config_policy_verify_command_coverage, 1);
        assert_eq!(
            item.canonical_gap_id,
            "config_or_policy_constant::VALIDATION_SELECTOR"
        );
        assert_eq!(item.group_reason, GROUP_REASON_DECL_LITERAL);
        assert_eq!(item.raw_group_size, 2);
        assert_eq!(item.canonical_item_kind, "gap");
        assert_eq!(item.gap_state, "actionable");
        assert_eq!(item.actionability, "add_behavior_discriminator");
        let repair_route = repair_route_for_item(item)?;
        assert_eq!(repair_route.repair_kind, "behavior_discriminator");
        assert_eq!(repair_route.target_test_type, "validation_behavior");
        assert_eq!(
            repair_route.suggested_assertion,
            "Assert the selected behavior includes the VALIDATION_SELECTOR value or selected behavior."
        );
        assert_eq!(config_policy.role, "behavior_selector");
        assert_eq!(config_policy.visibility, "user_visible");
        assert_eq!(config_policy.observer, "none");
        assert_eq!(config_policy.actionability, "add_behavior_discriminator");
        assert_eq!(config_policy.repair_kind, "behavior_discriminator");
        assert_eq!(config_policy.target_test_type, "validation_behavior");
        assert!(!item.recommended_repair.contains("mutation"));
        Ok(())
    }

    #[test]
    fn behavior_selector_with_discriminator_is_already_observed() -> Result<(), String> {
        let validation_observer = related_test(
            "validation_behavior_selects_strict_mode",
            "tests/validation_behavior.rs",
            28,
            OracleKind::RelationalCheck,
            OracleStrength::Strong,
        );
        let findings = vec![
            finding_in_file_with_related(
                "src/validation_selector.rs",
                "decl",
                52,
                ExposureClass::Exposed,
                ProbeFamily::FieldConstruction,
                "pub const ROUTING_SELECTOR: &str =",
                vec![validation_observer],
            ),
            finding_in_file(
                "src/validation_selector.rs",
                "literal",
                53,
                ExposureClass::Exposed,
                ProbeFamily::StaticUnknown,
                "\"strict\";",
            ),
        ];

        let report = report_for_findings(&findings)
            .ok_or_else(|| "observed behavior selector should align".to_string())?;
        let item = &report.items[0];
        let config_policy = config_policy_for(item)?;

        assert_eq!(report.summary.raw_signals, 2);
        assert_eq!(report.summary.canonical_items, 1);
        assert_eq!(report.summary.actionable_gaps, 0);
        assert_eq!(report.summary.already_observed, 1);
        assert_eq!(report.summary.config_policy_user_visible, 1);
        assert_eq!(report.summary.config_policy_observed, 1);
        assert_eq!(report.summary.config_policy_no_action, 1);
        assert_eq!(item.canonical_item_kind, "observed");
        assert_eq!(item.gap_state, "already_observed");
        assert_eq!(item.actionability, "already_observed");
        assert!(item.repair_route.is_none());
        assert_eq!(config_policy.role, "behavior_selector");
        assert_eq!(config_policy.visibility, "user_visible");
        assert_eq!(config_policy.observer, "validation_behavior");
        assert_eq!(config_policy.actionability, "already_observed");
        assert_eq!(config_policy.repair_kind, "no_action");
        assert_eq!(config_policy.target_test_type, "validation_behavior");
        assert_eq!(
            item.related_test.as_ref().map(|test| test.name.as_str()),
            Some("validation_behavior_selects_strict_mode")
        );
        Ok(())
    }

    #[test]
    fn actionable_canonical_items_require_repair_routes() -> Result<(), String> {
        let findings = vec![
            finding_in_file(
                "src/help.rs",
                "help-decl",
                18,
                ExposureClass::Exposed,
                ProbeFamily::FieldConstruction,
                "pub const HELP_DEVICE_LABEL: &str =",
            ),
            finding_in_file(
                "src/help.rs",
                "help-literal",
                19,
                ExposureClass::WeaklyExposed,
                ProbeFamily::StaticUnknown,
                "\"Device label\";",
            ),
            finding_in_file(
                "src/validation.rs",
                "validation-decl",
                40,
                ExposureClass::Exposed,
                ProbeFamily::FieldConstruction,
                "pub const VALIDATION_THRESHOLD: i32 = 7;",
            ),
        ];

        let report = report_for_findings(&findings)
            .ok_or_else(|| "actionable items should align".to_string())?;

        assert_eq!(report.summary.actionable_gaps, 2);
        assert_eq!(report.summary.repair_route_coverage, 2);
        assert_eq!(report.summary.actionable_items_without_repair_route, 0);
        assert_eq!(report.summary.verify_command_coverage, 2);
        assert_eq!(report.summary.actionable_items_without_verify_command, 0);
        for item in report
            .items
            .iter()
            .filter(|item| item.gap_state == "actionable")
        {
            let repair_route = repair_route_for_item(item)?;
            assert_ne!(repair_route.repair_kind, "unknown");
            assert_ne!(repair_route.target_test_type, "unknown");
            assert!(!repair_route.suggested_assertion.trim().is_empty());
            assert!(!verify_command_is_missing(&item.verify_command));
            assert!(!item.recommended_repair.contains("mutation"));
        }

        Ok(())
    }

    #[test]
    fn schema_label_with_golden_observer_is_already_observed() -> Result<(), String> {
        let golden = related_test(
            "schema_render_golden_observes_field",
            "tests/golden/schema_output.rs",
            31,
            OracleKind::Snapshot,
            OracleStrength::Strong,
        );
        let findings = vec![
            finding_in_file_with_related(
                "src/schema.rs",
                "decl",
                31,
                ExposureClass::Exposed,
                ProbeFamily::FieldConstruction,
                "pub const SCHEMA_POLICY_FIELD: &str =",
                vec![golden],
            ),
            finding_in_file(
                "src/schema.rs",
                "literal",
                32,
                ExposureClass::Exposed,
                ProbeFamily::StaticUnknown,
                "\"policy\";",
            ),
        ];

        let report = report_for_findings(&findings)
            .ok_or_else(|| "schema policy field should align".to_string())?;
        let item = &report.items[0];
        let config_policy = config_policy_for(item)?;

        assert_eq!(report.summary.already_observed, 1);
        assert_eq!(report.summary.config_policy_observed, 1);
        assert_eq!(report.summary.config_policy_no_action, 1);
        assert_eq!(item.canonical_item_kind, "observed");
        assert_eq!(item.gap_state, "already_observed");
        assert_eq!(config_policy.role, "schema_field_label");
        assert_eq!(config_policy.visibility, "user_visible");
        assert_eq!(config_policy.observer, "golden");
        assert_eq!(config_policy.repair_kind, "no_action");
        assert_eq!(
            item.related_test.as_ref().map(|test| test.name.as_str()),
            Some("schema_render_golden_observes_field")
        );
        Ok(())
    }

    #[test]
    fn cross_file_config_flow_stays_named_limitation() -> Result<(), String> {
        let findings = vec![
            finding_in_file(
                "src/config_labels.rs",
                "decl",
                44,
                ExposureClass::Exposed,
                ProbeFamily::FieldConstruction,
                "pub const CONFIG_TABLE_LABEL: &str =",
            ),
            finding_in_file(
                "src/config_labels.rs",
                "literal",
                45,
                ExposureClass::StaticUnknown,
                ProbeFamily::StaticUnknown,
                "\"Config table label\";",
            ),
        ];

        let report = report_for_findings(&findings)
            .ok_or_else(|| "config flow unknown should align".to_string())?;
        let item = &report.items[0];
        let config_policy = config_policy_for(item)?;

        assert_eq!(report.summary.static_limitations, 1);
        assert_eq!(report.summary.config_policy_flow_unknown, 1);
        assert_eq!(report.summary.config_policy_observer_unknown, 1);
        assert_eq!(report.summary.config_policy_static_limitations, 1);
        assert_eq!(item.gap_state, "static_limitation");
        assert_eq!(item.actionability, "inspect_config_flow");
        assert_eq!(config_policy.visibility, "unknown");
        assert_eq!(config_policy.observer, "unknown");
        assert_eq!(
            item.static_limitations
                .first()
                .map(|limitation| limitation.category.as_str()),
            Some("config_policy_flow_unknown")
        );
        Ok(())
    }

    #[test]
    fn opaque_config_lookup_stays_named_limitation() -> Result<(), String> {
        let findings = vec![
            finding_in_file(
                "src/config_registry.rs",
                "decl",
                58,
                ExposureClass::Exposed,
                ProbeFamily::FieldConstruction,
                "pub const OPAQUE_CONFIG_LABEL: &str =",
            ),
            finding_in_file(
                "src/config_registry.rs",
                "literal",
                59,
                ExposureClass::StaticUnknown,
                ProbeFamily::StaticUnknown,
                "\"Opaque label\";",
            ),
        ];

        let report = report_for_findings(&findings)
            .ok_or_else(|| "opaque config lookup should align".to_string())?;
        let item = &report.items[0];
        let config_policy = config_policy_for(item)?;

        assert_eq!(report.summary.static_limitations, 1);
        assert_eq!(item.gap_state, "static_limitation");
        assert_eq!(config_policy.visibility, "unknown");
        assert_eq!(config_policy.repair_kind, "inspect_config_flow");
        assert_eq!(
            item.static_limitations
                .first()
                .map(|limitation| limitation.category.as_str()),
            Some("opaque_config_lookup")
        );
        assert!(!item.recommended_repair.contains("mutation"));
        Ok(())
    }

    #[test]
    fn parses_presentation_text_const_declaration() -> Result<(), String> {
        let declaration = parse_presentation_text_declaration(
            "pub const APPLE_M3_AIR_DEVICE_LABELS_TEXT: &str = \"value\";",
        )
        .ok_or_else(|| "declaration should parse".to_string())?;

        assert_eq!(declaration.constant_name, "APPLE_M3_AIR_DEVICE_LABELS_TEXT");
        assert_eq!(declaration.inline_literal.as_deref(), Some("value"));
        Ok(())
    }

    #[test]
    fn parses_escaped_string_literal() {
        assert_eq!(
            parse_string_literal("\"Help \\\"quoted\\\" label\";").as_deref(),
            Some("Help \"quoted\" label")
        );
    }

    fn finding_at(
        id_suffix: &str,
        line: usize,
        class: ExposureClass,
        family: ProbeFamily,
        expression: &str,
    ) -> Finding {
        finding_in_file(
            "src/device_labels.rs",
            id_suffix,
            line,
            class,
            family,
            expression,
        )
    }

    fn finding_in_file(
        file: &str,
        id_suffix: &str,
        line: usize,
        class: ExposureClass,
        family: ProbeFamily,
        expression: &str,
    ) -> Finding {
        finding_in_file_with_related(file, id_suffix, line, class, family, expression, vec![])
    }

    fn finding_in_file_with_related(
        file: &str,
        id_suffix: &str,
        line: usize,
        class: ExposureClass,
        family: ProbeFamily,
        expression: &str,
        related_tests: Vec<RelatedTest>,
    ) -> Finding {
        let probe_id = format!("probe:src_device_labels_rs:{line}:{id_suffix}");
        Finding {
            id: probe_id.clone(),
            probe: Probe {
                id: ProbeId(probe_id),
                location: SourceLocation::new(file, line, 1),
                owner: None,
                family,
                delta: DeltaKind::Value,
                before: None,
                after: None,
                expression: expression.to_string(),
                expected_sinks: vec![],
                required_oracles: vec![],
            },
            class,
            ripr: RiprEvidence {
                reach: stage("presentation text raw signal"),
                infect: stage("presentation text raw signal"),
                propagate: stage("presentation text raw signal"),
                reveal: RevealEvidence {
                    observe: stage("presentation text raw signal"),
                    discriminate: stage("presentation text raw signal"),
                },
            },
            confidence: 0.2,
            evidence: vec![],
            missing: vec![],
            flow_sinks: vec![],
            activation: ActivationEvidence::default(),
            stop_reasons: vec![],
            related_tests,
            recommended_next_step: None,
            language: None,
            language_status: None,
            owner_kind: None,
            static_limit_kind: None,
        }
    }

    fn related_test(
        name: &str,
        file: &str,
        line: usize,
        oracle_kind: OracleKind,
        oracle_strength: OracleStrength,
    ) -> RelatedTest {
        RelatedTest {
            name: name.to_string(),
            file: file.into(),
            line,
            oracle: None,
            oracle_kind,
            oracle_strength,
        }
    }

    fn presentation_text_for(
        item: &super::FindingAlignmentItem,
    ) -> Result<&super::FindingAlignmentPresentationText, String> {
        item.presentation_text
            .as_ref()
            .ok_or_else(|| "item should include presentation_text".to_string())
    }

    fn config_policy_for(
        item: &super::FindingAlignmentItem,
    ) -> Result<&super::FindingAlignmentConfigPolicy, String> {
        item.config_policy
            .as_ref()
            .ok_or_else(|| "item should include config_policy".to_string())
    }

    fn repair_route_for_item(
        item: &super::FindingAlignmentItem,
    ) -> Result<&super::FindingAlignmentRepairRoute, String> {
        item.repair_route
            .as_ref()
            .ok_or_else(|| "actionable item should include repair_route".to_string())
    }

    fn stage(summary: &str) -> StageEvidence {
        StageEvidence::new(StageState::Unknown, Confidence::Low, summary)
    }
}
