Problem
apply_suppression_policy uses a nested loop over suppressions × findings. For the HLAW-034 scale target of 10k suppressions and 10k findings, this is 100M match checks per assessment run.
Current behavior
for suppression in &policy.suppressions { // O(N)
for annotated in &mut annotated_findings { // O(M)
if suppression_matches_finding(...) { ... }
}
}
Proposed fix
Build selector-keyed indexes before the loop:
BTreeMap<&str, Vec<usize>> from law_id → finding indices
BTreeMap<&str, Vec<usize>> from subject → finding indices
BTreeMap<&str, usize> from finding_id → finding index
Then dispatch by suppression.target.kind to the right index instead of scanning.
Acceptance criteria
- Assessment step handles 10k suppressions × 10k findings without quadratic degradation
- Existing test suite continues to pass with no behavior change
Deferred from
PR #600 — identified during Code Lawyer review as performance-not-correctness, out of scope for HIMP-036.
Problem
apply_suppression_policyuses a nested loop over suppressions × findings. For the HLAW-034 scale target of 10k suppressions and 10k findings, this is 100M match checks per assessment run.Current behavior
Proposed fix
Build selector-keyed indexes before the loop:
BTreeMap<&str, Vec<usize>>from law_id → finding indicesBTreeMap<&str, Vec<usize>>from subject → finding indicesBTreeMap<&str, usize>from finding_id → finding indexThen dispatch by
suppression.target.kindto the right index instead of scanning.Acceptance criteria
Deferred from
PR #600 — identified during Code Lawyer review as performance-not-correctness, out of scope for HIMP-036.