Summary
PR #43 (#6 line-stable suppression) added a per-finding suppression gate in _run_verifier_disposition_writes (src/security_scanner/runtime/scan_all.py). For each finding it calls resolve_existing_disposition, which does a synchronous read_finding_state (get_item) and, on miss, a find_disposition_by_match_key (get_item). This is an N+1 access pattern.
Why it was deferred (not fixed in #43)
The gate guards an Ollama LLM verification call that costs seconds per finding; one extra get_item (~ms) is negligible, and on a hit the gate saves the LLM call entirely. So at current scale the N+1 is not a bottleneck.
Proposed optimization (future)
- Pre-collect all
finding_ids and batch-read FINDING_STATE via the existing _batch_read_finding_states (or a sibling) before the loop, matching in memory.
- The match_key pointers use distinct PKs (
MATCHKEY#<mk>), so they'd need a separate BatchGetItem over the computed keys — design how to fold both reads cleanly.
Acceptance
Origin: PR #43 review thread (gemini-code-assist).
Summary
PR #43 (#6 line-stable suppression) added a per-finding suppression gate in
_run_verifier_disposition_writes(src/security_scanner/runtime/scan_all.py). For each finding it callsresolve_existing_disposition, which does a synchronousread_finding_state(get_item) and, on miss, afind_disposition_by_match_key(get_item). This is an N+1 access pattern.Why it was deferred (not fixed in #43)
The gate guards an Ollama LLM verification call that costs seconds per finding; one extra
get_item(~ms) is negligible, and on a hit the gate saves the LLM call entirely. So at current scale the N+1 is not a bottleneck.Proposed optimization (future)
finding_ids and batch-read FINDING_STATE via the existing_batch_read_finding_states(or a sibling) before the loop, matching in memory.MATCHKEY#<mk>), so they'd need a separateBatchGetItemover the computed keys — design how to fold both reads cleanly.Acceptance
Origin: PR #43 review thread (gemini-code-assist).