diff --git a/.jules/bolt.md b/.jules/bolt.md index 8ce7ce8f7..cb5e28231 100644 --- a/.jules/bolt.md +++ b/.jules/bolt.md @@ -77,3 +77,7 @@ ## 2024-11-20 - Optimize multiple tuple generation from a single collection **Learning:** `build_rule_metadata` derives exactly two collections, `owasp` and `cwe`, from the same references. Replacing its two generator traversals with one explicit loop reduces element visits from about 2N to N. Both versions remain O(N), so this is a constant-factor optimization rather than an asymptotic complexity improvement. **Action:** Combine repeated traversal when fixed derived collections share one source, while preserving ordering and classification semantics. Benchmark the production hot path before claiming a material wall-clock improvement. + +## 2024-11-20 - Avoid dictionary lookups and redundant type checking when sorting findings +**Learning:** In `_print_scan_results`, sorting findings using `lambda f: _SEVERITY_ORDER.get(f["severity"], 99)` repeatedly performs dictionary lookups (`f["severity"]` and `_SEVERITY_ORDER.get`) during the sort algorithm. Replacing this with the pre-existing `finding_sort_key` from `appguardrail_core.findings` which provides a consistent, robust `O(1)` sorting key prevents redundant lambda execution and standardizes the sorting logic. This eliminates a small performance bottleneck and reduces code duplication. +**Action:** Replace inline lambda sort keys with established, optimized sort key functions (like `finding_sort_key`) when sorting complex dictionary collections. diff --git a/scanner/cli/appguardrail.py b/scanner/cli/appguardrail.py index 0d853d644..12b4ab891 100644 --- a/scanner/cli/appguardrail.py +++ b/scanner/cli/appguardrail.py @@ -66,6 +66,7 @@ ) from appguardrail_core.external import build_external_scan_plan from appguardrail_core.findings import NON_BLOCKING_CONTEXTS +from appguardrail_core.findings import finding_sort_key from appguardrail_core.findings import is_deploy_blocking as core_is_deploy_blocking from appguardrail_core.findings import normalize_findings from appguardrail_core.language import ( @@ -3044,7 +3045,7 @@ def _scan_file( def _print_scan_results(findings, files_scanned): """Print sorted findings and deploy-gate summary counts.""" - findings.sort(key=lambda f: _SEVERITY_ORDER.get(f["severity"], 99)) + findings.sort(key=finding_sort_key) counts = {"CRITICAL": 0, "HIGH": 0, "WARNING": 0, "INFO": 0} non_blocking = 0