mirror of
https://github.com/norandom/OpenUltraSAST.git
synced 2026-10-16 03:49:26 +00:00
feat(model): say when the region cap hid most of the repository
Paid Memberships Pro yields 4,463 regions from 637 files. The default budget examines 500 of them -- 11% of the repository -- and nothing in the output said so. A report whose silence covers the other 89% invites that silence to be read as a clean bill of health. `budget_exhausted` is a different fact and already reported: that is the JUDGE running out on work already collected. This is the work never being collected. Renders in "What could not be analysed" as: only the N highest-ranked of M regions were examined, and nothing above says anything about the rest. 850 tests pass. 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
d63be34451
commit
83adf049be
@@ -152,6 +152,21 @@ def scan_repository(
|
|||||||
# `add_filter("hook", )`. See `mapping.php_hook_callbacks`.
|
# `add_filter("hook", )`. See `mapping.php_hook_callbacks`.
|
||||||
hooks = _hook_callbacks(root, regions)
|
hooks = _hook_callbacks(root, regions)
|
||||||
|
|
||||||
|
# The region cap is a COVERAGE fact, not a tuning knob nobody needs to hear about. Paid Memberships Pro
|
||||||
|
# yields 4,463 regions from 637 files, so a default budget of 500 examines 11% of the repository -- and
|
||||||
|
# a report that does not say so invites its silence to be read as a clean bill of health for the other
|
||||||
|
# 89%. `budget_exhausted` is a different thing: that is the JUDGE running out, this is the work never
|
||||||
|
# being collected at all.
|
||||||
|
if len(ordered_regions) > limits.max_regions:
|
||||||
|
degradations.append(
|
||||||
|
{
|
||||||
|
"stage": "model",
|
||||||
|
"reason": "regions_truncated",
|
||||||
|
"examined": limits.max_regions,
|
||||||
|
"total": len(ordered_regions),
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
# Phase 1: collect the whole scan's questions, for at most `max_regions` regions. Nothing is asked yet.
|
# Phase 1: collect the whole scan's questions, for at most `max_regions` regions. Nothing is asked yet.
|
||||||
work: list[tuple[str, ScanRegion, ArbiterSpec]] = []
|
work: list[tuple[str, ScanRegion, ArbiterSpec]] = []
|
||||||
for region in ordered_regions[: limits.max_regions]:
|
for region in ordered_regions[: limits.max_regions]:
|
||||||
|
|||||||
@@ -436,6 +436,10 @@ _COVERAGE_DEGRADATIONS: dict[str, str] = {
|
|||||||
"files_unparsed": "{count} file(s) could not be parsed and are absent from the graph: {files}.",
|
"files_unparsed": "{count} file(s) could not be parsed and are absent from the graph: {files}.",
|
||||||
"query_failed": "A `{kind}` query failed for {requests} region(s), so those regions were not decided.",
|
"query_failed": "A `{kind}` query failed for {requests} region(s), so those regions were not decided.",
|
||||||
"budget_exhausted": "The model-call budget ran out with {regions_unasked} region(s) still unasked.",
|
"budget_exhausted": "The model-call budget ran out with {regions_unasked} region(s) still unasked.",
|
||||||
|
"regions_truncated": (
|
||||||
|
"Only the **{examined} highest-ranked of {total} regions** were examined. Nothing above says anything "
|
||||||
|
"about the rest of the repository."
|
||||||
|
),
|
||||||
"region_failed": "The region `{path}` could not be arbitrated.",
|
"region_failed": "The region `{path}` could not be arbitrated.",
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -390,3 +390,30 @@ def test_a_query_the_engine_could_not_answer_is_recorded_not_ignored() -> None:
|
|||||||
assert failures, "a query that could not be asked must be reported"
|
assert failures, "a query that could not be asked must be reported"
|
||||||
assert failures[0]["kind"] == "taint"
|
assert failures[0]["kind"] == "taint"
|
||||||
assert result.findings == ()
|
assert result.findings == ()
|
||||||
|
|
||||||
|
|
||||||
|
def test_a_region_cap_that_hides_most_of_a_repository_is_reported() -> None:
|
||||||
|
"""Paid Memberships Pro yields 4,463 regions from 637 files. A default budget of 500 examines 11% of it,
|
||||||
|
and a report that does not say so invites its silence to be read as a clean bill of health for the rest.
|
||||||
|
"""
|
||||||
|
from openultrasast.model.regions import ScanRegion
|
||||||
|
from openultrasast.model.scan import ScanBudget, scan_repository
|
||||||
|
|
||||||
|
class _Backend:
|
||||||
|
def available(self) -> bool:
|
||||||
|
return True
|
||||||
|
|
||||||
|
def build(self, root, *, language=""): # type: ignore[no-untyped-def]
|
||||||
|
from openultrasast.cpg.backend import CpgResult
|
||||||
|
|
||||||
|
return CpgResult(cpg_path=Path("cpg.bin"), run=lambda query, params: [])
|
||||||
|
|
||||||
|
regions = [
|
||||||
|
ScanRegion(path=f"f{n}.py", function="handler", language="python", families=("injection",), rank=0.5, source="entry_point")
|
||||||
|
for n in range(30)
|
||||||
|
]
|
||||||
|
result = scan_repository(Path("."), regions, backend=_Backend(), budget=ScanBudget(max_model_calls=0, max_regions=10))
|
||||||
|
|
||||||
|
truncated = [d for d in result.degradations if d.get("reason") == "regions_truncated"]
|
||||||
|
assert truncated, "the cap hid two thirds of the regions and said nothing"
|
||||||
|
assert truncated[0]["examined"] == 10 and truncated[0]["total"] == 30
|
||||||
|
|||||||
Reference in New Issue
Block a user