Skip to content

Commit 2646f46

Browse files
hyperpolymathclaude
andcommitted
feat(panicbot): PA024 InputBoundary + PA025 MutationGap mappings
Add category mappings for the two remaining v2.5.0 categories: - PA024 InputBoundary: static-analysis/input-boundary, 0.72 conf, Control tier, Partial fixability - PA025 MutationGap: static-analysis/mutation-gap, 0.80 conf, Substitute tier, Partial fixability Update test_all_categories_have_unique_rule_ids to 25 categories. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
1 parent adbac33 commit 2646f46

2 files changed

Lines changed: 30 additions & 2 deletions

File tree

bots/panicbot/src/translator.rs

Lines changed: 27 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
//! Core responsibility: map each `WeakPoint` from the scanner output into a
55
//! `Finding` struct with appropriate:
66
//! - Fleet category (e.g., "static-analysis/unsafe-code")
7-
//! - Rule ID (canonical PA001–PA023 pattern for dedup with Hypatia findings)
7+
//! - Rule ID (canonical PA001–PA025 pattern for dedup with Hypatia findings)
88
//! - Triangle tier (Eliminate / Substitute / Control)
99
//! - Confidence score (honest assessment of detection accuracy)
1010
//! - Fixability (whether automated remediation is possible)
@@ -261,6 +261,30 @@ pub fn category_mapping(category: &str) -> Option<CategoryMapping> {
261261
default_confidence: 0.85,
262262
fixability: Fixability::Yes,
263263
}),
264+
// PA024 — input boundary: unchecked deserialization of CBOR/MessagePack (serde_cbor,
265+
// ciborium, rmp_serde in Rust), JSON.parse without try-catch (JavaScript), JSON3.read
266+
// without error handling (Julia). Confidence 0.72 — per-file heuristics have false
267+
// positives when error handling is in the call site rather than the same file.
268+
"InputBoundary" => Some(CategoryMapping {
269+
fleet_category: "static-analysis/input-boundary",
270+
rule_id: "PA024",
271+
rule_name: "Unguarded input boundary",
272+
triangle_tier: TriangleTier::Control,
273+
default_confidence: 0.72,
274+
fixability: Fixability::Partial,
275+
}),
276+
// PA025 — mutation gap: test suites with no mutation-test tooling or no assertion
277+
// diversity. Rust projects without cargo-mutants config, Elixir without StreamData/
278+
// ExUnitProperties, Julia @testset with only type-check assertions. Confidence 0.80 —
279+
// absent tooling is factual; assertion diversity heuristic has modest FP rate.
280+
"MutationGap" => Some(CategoryMapping {
281+
fleet_category: "static-analysis/mutation-gap",
282+
rule_id: "PA025",
283+
rule_name: "Mutation coverage gap",
284+
triangle_tier: TriangleTier::Substitute,
285+
default_confidence: 0.80,
286+
fixability: Fixability::Partial,
287+
}),
264288
_ => None,
265289
}
266290
}
@@ -604,6 +628,7 @@ mod tests {
604628
"UnsafeTypeCoercion", "UncheckedAllocation", "UnboundedLoop", "BlockingIO",
605629
"DeadlockPotential", "DynamicCodeExecution", "InsecureProtocol",
606630
"InfiniteRecursion", "ProofDrift", "CryptoMisuse", "SupplyChain",
631+
"InputBoundary", "MutationGap",
607632
];
608633

609634
let mut rule_ids = std::collections::HashSet::new();
@@ -616,6 +641,6 @@ mod tests {
616641
cat
617642
);
618643
}
619-
assert_eq!(rule_ids.len(), 23);
644+
assert_eq!(rule_ids.len(), 25);
620645
}
621646
}

bots/panicbot/tests/translator_test.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,8 @@ fn test_all_23_categories_have_mappings() {
6969
"ProofDrift",
7070
"CryptoMisuse",
7171
"SupplyChain",
72+
"InputBoundary",
73+
"MutationGap",
7274
];
7375

7476
for cat in &categories {
@@ -387,6 +389,7 @@ fn test_all_confidence_values_in_valid_range() {
387389
"UnsafeTypeCoercion", "UncheckedAllocation", "UnboundedLoop", "BlockingIO",
388390
"DeadlockPotential", "DynamicCodeExecution", "InsecureProtocol",
389391
"InfiniteRecursion", "ProofDrift", "CryptoMisuse", "SupplyChain",
392+
"InputBoundary", "MutationGap",
390393
];
391394

392395
for cat in &categories {

0 commit comments

Comments
 (0)