# Harvesting candidate detectors from a repo

audience: AI coding agents first. Imperative, BLUF-ordered.

**Core principle: census recurring deterministic check-classes; rank by convergence across INDEPENDENT donors, not occurrences within one donor.**

## When to use
Invoke before adding detectors for a new repo or domain — to find what classes are worth a detector at all.

## Ladder (stop at the first rung that answers the question)
1. **Census, don't assume.** Read actual call sites / patterns. Never infer a class exists from a name — read it.
2. **Group by class, count by DONOR.** A class supported by 1 donor (one file/feature) is a runner, not core. Convergence = independent donors exhibiting the same check, NOT N features within one donor. (kinds-count ≠ donor-count.)
3. **Route each candidate to a band (spec §3).** Decidable syntactic invariant → band-3 candidate. Hard-but-not-decidable → band-2. Already caught by band-1 (check the corpus/bench) → DROP (YAGNI, delete-test-vs-LLM).
4. **Emit candidates**, each: `{class, donors[], proposed_band, decidable?, why}`. A candidate is NOT a detector until it passes `implement`.

## DO NOT
- DO NOT count features within one donor as convergence. // reject: "5 call sites in payments → core" (1 donor).
- DO NOT propose a band-3 detector for a class the LLM band already catches 3/3 — check `bench.py --inventory` + the corpus first.
- DO NOT recommend a detector you have not measured the need for (delete-test-vs-LLM, spec §4).

## Output → hand to `implement`
A ranked candidate list. Coverage targets the taxonomy (`docs/taxonomy/security.md`), not the donor set.

## Pointers
Coverage/extraction model: `docs/specs/2026-06-17-security-gate-design.md` §3–§4. Donor-count rule: it is the project's anti-overfit guard.
