feat(controls): enrich semantic retrieval query with finding intent + C5 live test
CI / Check (push) Skipped
CI / Check (pull_request) Successful in 5m50s
CI / Detect Changes (pull_request) Skipped
CI / Deploy Agent (pull_request) Skipped
CI / Deploy Dashboard (pull_request) Skipped
CI / Deploy Docs (pull_request) Skipped
CI / Deploy MCP (pull_request) Skipped

Tuning from the C5 live run against the real 2,882-control master corpus. The
semantic pass retrieved on the code region alone, so two findings in one file
(overlapping windows, both md5/password tokens) collapsed onto the SAME controls —
a brute-force finding wrongly matched password-hashing controls.

Fix: build the retrieval query from the finding's title + description + region, so
retrieval keys on what the finding is *about*. The raw region still goes to the
judge for snippet grounding.

Verified live (same fixture, cached corpus index):
- 'Weak password hash (md5)'      -> mc-23149 (eliminate weak unsalted hashes) now RANK 1
- 'Login without brute-force prot' -> newly surfaces mc-19984 (brute_force_protection)
                                      + mc-23186 (account_lockout) — the correct controls,
                                      absent under region-only retrieval.

Also commits the gated live regression test (tests/c5_semantic_live.rs, #[ignore]d,
not run by CI's --lib): ingest-only + full semantic-stamping checks against api-dev.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
Sharang Parnerkar
2026-07-22 09:06:18 +02:00
co-authored by Claude Fable 5
parent 60601d8215
commit 31f1635ee8
3 changed files with 164 additions and 8 deletions
+7 -5
View File
@@ -22,18 +22,20 @@ impl<J: ControlJudge> SemanticControlChecker<J> {
Self { judge }
}
/// Map a code region to the controls it violates. `region_embedding` is the
/// region's embedding (the caller computes it via the LLM); the top-`k`
/// nearest controls in `index` are judged and grounded.
/// Map a code region to the controls it violates. `query_embedding` is the
/// caller-supplied retrieval embedding — typically the finding's intent
/// (title/description) plus the region, so retrieval keys on what the finding
/// is *about*, not just the ambient code. The top-`k` nearest controls in
/// `index` are then judged against the raw `region` and grounded.
pub async fn check(
&self,
index: &ControlIndex,
region: &CandidateRegion,
region_embedding: &[f64],
query_embedding: &[f64],
k: usize,
repo_id: &str,
) -> Vec<Finding> {
let candidates = index.nearest(region_embedding, k);
let candidates = index.nearest(query_embedding, k);
let mut findings = Vec::new();
for spec in &candidates {
let verdict = self.judge.judge(spec, region).await;