mirror of
https://github.com/norandom/OpenUltraSAST.git
synced 2026-10-18 20:49:28 +00:00
perf(model): stop sending 42MB of the same string, and stop enumerating for nobody
Two defects the first whole-repository scan made visible. It ran for 23
minutes over Paid Memberships Pro and decided nothing.
**The batch was 97.5% duplication.** `hookCallbacks` describes the REPOSITORY,
not the region, and I put it in every request when the hook half landed. On a
637-file plugin that is 16,270 characters repeated across 2,500 requests:
taint-requests.json 42.5 MB, of which 41.7 MB is one string over again
Joern parsed that with ujson inside a 2GB heap and the batch died in
ForkJoinPool. The driver reported `query_failed` for all 2,500 regions, which
was the honest answer to a question that never should have been asked that
way. Repository-wide fields are now hoisted to a single `--param`, and only if
they are identical across the whole batch -- a field that genuinely varies per
region stays where it belongs.
**Arbitration spent 737 seconds enumerating candidates nobody would read.**
Candidates exist to be put to the judge, and `scan_region` discards them the
moment there is no judge to put them to -- but the driver enumerated them
first regardless, parsing each region's file once per family. With the budget
at zero model calls that is 2,500 parses whose results are dropped on arrival.
build 264.8s query 401.3s arbitrate 737.3s total 1403s
Nobody should pay for a question nobody will ask.
848 tests pass; gates byte-identical.
Co-Authored-By: Claude Opus 5 (1M context) <[email protected]>
Claude-Session: https://claude.ai/code/session_01T7XD7x5KonMdmGRkp63EQG
This commit is contained in:
co-authored by
Claude Opus 5
parent
a762860b17
commit
7f83977add
@@ -223,15 +223,22 @@ def scan_repository(
|
||||
exhausted = counted is not None and counted.calls >= limits.max_model_calls
|
||||
family = getattr(spec, "family", "")
|
||||
prefetched = CpgResult(cpg_path=cpg.cpg_path, run=_prefetched(rows_by_id.get(rid, [])))
|
||||
judge = None if exhausted else counted
|
||||
try:
|
||||
enumerated = enumerate_candidates(root, region, family, taxonomy=taxonomy)
|
||||
candidates = [{"id": c.id, "text": c.text, "line": c.line} for c in enumerated.candidates]
|
||||
# Candidates exist to be PUT to the judge, and `scan_region` discards them the moment there is
|
||||
# no judge to put them to. Enumerating them anyway costs a parse of the region's file per family
|
||||
# per region: on a 637-file plugin that was 2,500 enumerations and 737 SECONDS of arbitration
|
||||
# over rows that had already been fetched. Nobody should pay for a question nobody will ask.
|
||||
candidates: list[dict[str, object]] = []
|
||||
if judge is not None:
|
||||
enumerated = enumerate_candidates(root, region, family, taxonomy=taxonomy)
|
||||
candidates = [{"id": c.id, "text": c.text, "line": c.line} for c in enumerated.candidates]
|
||||
found = scan_region(
|
||||
prefetched,
|
||||
spec,
|
||||
path=region.path,
|
||||
function=region.function or "",
|
||||
client=None if exhausted else counted,
|
||||
client=judge,
|
||||
model=model,
|
||||
candidates=candidates,
|
||||
# A repository's parameters are not all attacker input -- but an ENTRY POINT's are, by
|
||||
|
||||
Reference in New Issue
Block a user