repopilot 0.14.0

Local-first CLI for repository audit, architecture risk detection, baseline tracking, and CI-friendly code review.
Documentation
fn priority_label(priority: u8) -> &'static str {
    match priority {
        0 => "P0 - Immediate risk",
        1 => "P1 - High-impact hardening",
        2 => "P2 - Quality and maintainability",
        _ => "P3 - Backlog cleanup",
    }
}

fn sort_ai_plan_clusters(clusters: &mut [RuleCluster<'_>]) {
    clusters.sort_by(|left, right| {
        priority_rank(left)
            .cmp(&priority_rank(right))
            .then_with(|| right.max_score.cmp(&left.max_score))
            .then_with(|| cluster_priority(left).cmp(&cluster_priority(right)))
            .then_with(|| right.severity.cmp(&left.severity))
            .then_with(|| cluster_category_rank(left).cmp(&cluster_category_rank(right)))
            .then_with(|| right.findings.len().cmp(&left.findings.len()))
            .then_with(|| left.rule_id.cmp(right.rule_id))
    });
}

fn cluster_priority(cluster: &RuleCluster<'_>) -> u8 {
    cluster
        .findings
        .iter()
        .map(|finding| legacy_priority_rank(finding))
        .min()
        .unwrap_or(3)
}

fn priority_rank(cluster: &RuleCluster<'_>) -> u8 {
    cluster.priority.rank()
}

fn legacy_priority_rank(finding: &Finding) -> u8 {
    if finding.severity == Severity::Critical
        || (finding.severity == Severity::High && finding.category == FindingCategory::Security)
    {
        0
    } else if finding.severity == Severity::High {
        1
    } else if finding.severity == Severity::Medium {
        2
    } else {
        3
    }
}

fn cluster_category_rank(cluster: &RuleCluster<'_>) -> u8 {
    cluster
        .findings
        .first()
        .map(|finding| category_rank(&finding.category))
        .unwrap_or(u8::MAX)
}