mirror of
https://github.com/norandom/OpenUltraSAST.git
synced 2026-10-16 03:49:26 +00:00
fix(scan): prune a tier-zero question unless ITS partition is the incomplete one
The mechanism already existed. A question whose evidence vector says no sink of its family is in reach cannot produce a flow, and tier-zero pruning defers it. That was switched off for the whole scan whenever any of twelve degradation reasons appeared, and a multi-language repository always carries two of them, so the measured plugin arbitrated every question it could ask. Third instance this week of one blast radius, and the invariant written into the design on Monday named it. A prune blocker that names a partition now withholds pruning from that partition questions and from nobody else. cross_partition_semantics_unresolved leaves the blocker set entirely, for the reason it left the integrity gaps: a PHP family sink is PHP, so a second language cannot be why its vector saw none. Measured on Paid Memberships Pro. At 25 regions arbitration falls from 127 questions to 34 with 93 recorded deferred as tier_zero, and 19 findings before and after, identical family by family. At 500 it falls from 2,526 to 406 with 2,120 deferred. It is not sufficient, and that is the useful half. The 500-region run still fails in the same way at the same cost, because 406 questions at roughly one and a half seconds each still exceed the 300-second per-batch ceiling. This lever moved the volume; the ceiling is a separate limit. The census now records what a scan skipped and why, per family, so a cheaper scan and a narrower one stop looking identical: a family whose every question was pruned reports no sink of this family in reach rather than region offered, no question asked. 1,420 tests pass, eighteen skipped. Co-Authored-By: Claude Opus 5 (1M context) <[email protected]> Claude-Session: https://claude.ai/code/session_01EmM1j46qgKMh3zqD1QMwEo
This commit is contained in:
co-authored by
Claude Opus 5
parent
b0500ecfa0
commit
3b6e642433
@@ -97,8 +97,16 @@ def main() -> int:
|
||||
# WHY an outcome is not completed. Counting only the statuses left three separate causes looking
|
||||
# identical, and each one had to be found by reading code rather than by reading the record.
|
||||
"outcome_reason": dict(collections.Counter(f"{q.status}:{q.reason}" for q in result.question_outcomes)),
|
||||
# A question the scan chose not to arbitrate is recorded as skipped, with why. Without this a cheaper
|
||||
# scan and a narrower one look identical, and the whole point of skipping is that it is not the same.
|
||||
"deferred": dict(collections.Counter(item.reason for item in (result.scope.deferred if result.scope else ()))),
|
||||
}
|
||||
|
||||
# A family whose every question was pruned asked nothing, and "nothing to ask" is a different statement
|
||||
# from "never offered". Counting the skips per family is what keeps those apart in the verdict below.
|
||||
deferred_by_family: dict[str, collections.Counter[str]] = collections.defaultdict(collections.Counter)
|
||||
for item in result.scope.deferred if result.scope else ():
|
||||
deferred_by_family[item.identity.family][item.reason] += 1
|
||||
asked = collections.Counter(q.identity.family for q in result.question_outcomes)
|
||||
completed = collections.Counter(q.identity.family for q in result.question_outcomes if q.status == "completed")
|
||||
found: dict[str, list[dict[str, Any]]] = collections.defaultdict(list)
|
||||
@@ -133,9 +141,12 @@ def main() -> int:
|
||||
# job is to say what each family finds reported nothing for a repository that had found a real
|
||||
# SQL injection. A question-outcome count is a statement about bookkeeping; a finding is the
|
||||
# thing being censused, and it cannot be hidden behind the other.
|
||||
"deferred": dict(deferred_by_family.get(family, {})),
|
||||
"verdict": (
|
||||
"establishes findings"
|
||||
if found.get(family)
|
||||
else "no sink of this family in reach"
|
||||
if not asked.get(family) and deferred_by_family.get(family, {}).get("tier_zero")
|
||||
else "region offered, no question asked"
|
||||
if not asked.get(family)
|
||||
else "asked but no question completed"
|
||||
|
||||
Reference in New Issue
Block a user