From c634c2bbfaf60bfee6d1d9412b96121d82914e1c Mon Sep 17 00:00:00 2001 From: InfoSecHack Date: Tue, 2 Jun 2026 12:45:54 -0500 Subject: [PATCH] Wire path overcounting runner to helper --- ...th_overcounting_shared_uncertainty_demo.sh | 19 ++++++++++++------- ..._overcounting_shared_uncertainty_runner.py | 7 +++++++ 2 files changed, 19 insertions(+), 7 deletions(-) diff --git a/scripts/run_path_overcounting_shared_uncertainty_demo.sh b/scripts/run_path_overcounting_shared_uncertainty_demo.sh index 0ea9a1e..cbebb5e 100755 --- a/scripts/run_path_overcounting_shared_uncertainty_demo.sh +++ b/scripts/run_path_overcounting_shared_uncertainty_demo.sh @@ -50,6 +50,11 @@ esac mkdir -p "$OUT_ABS" +"$REPO_ROOT/scripts/group_inconclusive_uncertainty.py" \ + --findings "$FIXTURE_DIR/findings.json" \ + --expected-groups "$FIXTURE_DIR/expected_uncertainty_groups.json" \ + --out "$OUT_ABS/uncertainty-groups.json" + python - "$FIXTURE_DIR" "$OUT_ABS" <<'PY' from __future__ import annotations @@ -63,7 +68,7 @@ out_dir = Path(sys.argv[2]) naive = json.loads((fixture_dir / "naive_candidates.json").read_text()) findings_doc = json.loads((fixture_dir / "findings.json").read_text()) -groups_doc = json.loads((fixture_dir / "expected_uncertainty_groups.json").read_text()) +groups_doc = json.loads((out_dir / "uncertainty-groups.json").read_text()) binding = json.loads((fixture_dir / "binding_metadata.json").read_text()) candidate_count = len(naive["candidate_paths"]) @@ -75,10 +80,7 @@ ordered_verdicts = { "precondition_only": verdicts.get("precondition_only", 0), "inconclusive": verdicts.get("inconclusive", 0), } -groups = { - group["uncertainty_class"]: len(group["finding_ids"]) - for group in groups_doc["groups"] -} +groups = groups_doc["groups"] primary_class = "shared_passrole_target_resource_scope_unknown" replay_status = findings_doc["replay_equivalence_status"] replay_status_human = replay_status.replace("_", " ") @@ -105,8 +107,11 @@ verdict_summary = { uncertainty_summary = { "fixture_id": groups_doc["fixture_id"], "groups": groups, - "top_uncertainty_class": primary_class, - "top_uncertainty_count": groups[primary_class], + "group_details": groups_doc["group_details"], + "report_only": groups_doc["report_only"], + "top_uncertainty_class": groups_doc["top_uncertainty_class"], + "top_uncertainty_count": groups_doc["top_uncertainty_count"], + "non_claims": groups_doc["non_claims"], "reviewer_decision": "Do not treat all 23 as independent validated risks. Resolve the primary evidence gap first.", } diff --git a/tests/test_path_overcounting_shared_uncertainty_runner.py b/tests/test_path_overcounting_shared_uncertainty_runner.py index a55ce87..b60ff39 100644 --- a/tests/test_path_overcounting_shared_uncertainty_runner.py +++ b/tests/test_path_overcounting_shared_uncertainty_runner.py @@ -69,6 +69,7 @@ def test_runner_uncertainty_group_counts(tmp_path: Path) -> None: assert result.returncode == 0, result.stderr groups = json.loads((output_dir / "uncertainty-groups.json").read_text()) + assert groups["report_only"] is True assert groups["groups"] == { "shared_passrole_target_resource_scope_unknown": 8, "shared_boundary_context_unresolved": 2, @@ -76,6 +77,12 @@ def test_runner_uncertainty_group_counts(tmp_path: Path) -> None: } assert groups["top_uncertainty_class"] == "shared_passrole_target_resource_scope_unknown" assert groups["top_uncertainty_count"] == 8 + assert {group["uncertainty_class"]: group["count"] for group in groups["group_details"]} == groups["groups"] + assert groups["non_claims"]["does_not_mutate_findings"] is True + assert groups["non_claims"]["does_not_change_verdicts"] is True + assert groups["non_claims"]["does_not_infer_exploitability"] is True + assert groups["non_claims"]["does_not_claim_replay_equivalence"] is True + assert groups["non_claims"]["requires_aws_credentials"] is False def test_runner_summary_preserves_safety_and_replay_boundary(tmp_path: Path) -> None: