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–PA021 pattern for dedup with Hypatia findings)
7+ //! - Rule ID (canonical PA001–PA023 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)
@@ -236,6 +236,31 @@ pub fn category_mapping(category: &str) -> Option<CategoryMapping> {
236236 default_confidence : 0.92 ,
237237 fixability : Fixability :: No ,
238238 } ) ,
239+ // PA022 — cryptographic primitive misuse: MD5/SHA-1 in security contexts
240+ // (password, secret, token, auth, key, credential, hash, sign, verify, encrypt),
241+ // and == comparisons on secret-named variables (timing side-channel).
242+ // Confidence 0.75 — the context-window heuristic works well but has a modest
243+ // false-positive rate when security vocabulary appears nearby for unrelated reasons.
244+ "CryptoMisuse" => Some ( CategoryMapping {
245+ fleet_category : "static-analysis/crypto-misuse" ,
246+ rule_id : "PA022" ,
247+ rule_name : "Cryptographic primitive misuse" ,
248+ triangle_tier : TriangleTier :: Eliminate ,
249+ default_confidence : 0.75 ,
250+ fixability : Fixability :: Partial ,
251+ } ) ,
252+ // PA023 — supply chain integrity: unpinned or unverified dependencies and absent
253+ // lock files. Cargo.toml git deps without rev=, absent Cargo.lock for lib/bin crates,
254+ // Julia Manifest.toml without git-tree-sha1 entries, flake.nix inputs without narHash,
255+ // deno.json import map entries without version pin. These are fixable by adding pins.
256+ "SupplyChain" => Some ( CategoryMapping {
257+ fleet_category : "static-analysis/supply-chain" ,
258+ rule_id : "PA023" ,
259+ rule_name : "Supply chain integrity gap" ,
260+ triangle_tier : TriangleTier :: Eliminate ,
261+ default_confidence : 0.85 ,
262+ fixability : Fixability :: Yes ,
263+ } ) ,
239264 _ => None ,
240265 }
241266}
@@ -578,7 +603,7 @@ mod tests {
578603 "ResourceLeak" , "PathTraversal" , "AtomExhaustion" , "ExcessivePermissions" ,
579604 "UnsafeTypeCoercion" , "UncheckedAllocation" , "UnboundedLoop" , "BlockingIO" ,
580605 "DeadlockPotential" , "DynamicCodeExecution" , "InsecureProtocol" ,
581- "InfiniteRecursion" ,
606+ "InfiniteRecursion" , "ProofDrift" , "CryptoMisuse" , "SupplyChain" ,
582607 ] ;
583608
584609 let mut rule_ids = std:: collections:: HashSet :: new ( ) ;
@@ -591,6 +616,6 @@ mod tests {
591616 cat
592617 ) ;
593618 }
594- assert_eq ! ( rule_ids. len( ) , 20 ) ;
619+ assert_eq ! ( rule_ids. len( ) , 23 ) ;
595620 }
596621}
0 commit comments