From a7f8a3cb1ee71b545f75528eacdca5a0ba7e6f07 Mon Sep 17 00:00:00 2001 From: Joe Harris Date: Sun, 11 Oct 2026 09:30:40 -0400 Subject: [PATCH 1/3] fix(ci): remove dead merge_group heavy-tier branch --- .github/workflows/ci.yml | 1 - scripts/heavy_tier_needed.py | 7 +------ tests/README.md | 3 +-- tests/unit/scripts/test_heavy_tier_needed.py | 17 +++++------------ 4 files changed, 7 insertions(+), 21 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index ebc54e3020..ad06aecc5b 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -215,7 +215,6 @@ jobs: set -euo pipefail python scripts/heavy_tier_needed.py \ --decision-in ci-path-decision.json \ - --event "${{ github.event_name }}" \ --base-ref "${{ github.event.pull_request.base.sha }}" \ --github-output "$GITHUB_OUTPUT" \ --summary "$GITHUB_STEP_SUMMARY" diff --git a/scripts/heavy_tier_needed.py b/scripts/heavy_tier_needed.py index 5b7b9a6658..8164f91596 100644 --- a/scripts/heavy_tier_needed.py +++ b/scripts/heavy_tier_needed.py @@ -12,7 +12,6 @@ PREDICATE_REPO_PATH = "_project/scripts/soundness_paths.py" POLICY_PATHS = (PREDICATE_REPO_PATH, ".github/soundness-paths.txt") -MERGE_GROUP_EVENT = "merge_group" class HeavyTierError(RuntimeError): @@ -119,7 +118,6 @@ def soundness_touched( def heavy_needed( decision: dict[str, Any], - event: str, base_ref: str, repo_root: Path, read_base: Callable[[str, Path], dict[str, str]] | None = None, @@ -137,8 +135,6 @@ def heavy_needed( needs_code_ci = decision["needs_code_ci"] if not needs_code_ci: return {"heavy_needed": False, "reason": "not a code-routed tree; the light lane already covers it"} - if event == MERGE_GROUP_EVENT: - return {"heavy_needed": True, "reason": "merge_group runs keep the full tier on every code-routed tree"} if decision["packaging_needed"]: return {"heavy_needed": True, "reason": "packaging paths touched (packaging carve-out)"} touched, reason = soundness_touched(changed, base_ref, repo_root, read_base, read_pr) @@ -157,7 +153,6 @@ def _write_github_output(path: Path, needed: bool) -> None: def main(argv: list[str] | None = None) -> int: parser = argparse.ArgumentParser() parser.add_argument("--decision-in", type=Path, default=None) - parser.add_argument("--event", default=os.environ.get("GITHUB_EVENT_NAME", "")) parser.add_argument("--base-ref", default=os.environ.get("GITHUB_BASE_REF", "origin/develop")) parser.add_argument("--repo-root", type=Path, default=Path.cwd()) parser.add_argument("--github-output", type=Path, default=None) @@ -177,7 +172,7 @@ def main(argv: list[str] | None = None) -> int: if not isinstance(decision, dict): result = {"heavy_needed": True, "reason": "lookup failed closed: decision is not an object"} else: - result = heavy_needed(decision, args.event, args.base_ref, args.repo_root) + result = heavy_needed(decision, args.base_ref, args.repo_root) needed = bool(result["heavy_needed"]) reason = str(result["reason"]) diff --git a/tests/README.md b/tests/README.md index 23c3de2a7e..3f188d1170 100644 --- a/tests/README.md +++ b/tests/README.md @@ -193,8 +193,7 @@ The standard gates are intentionally split by the risk they are meant to catch: blocking routine PRs. The `medium-test` job in `.github/workflows/ci.yml` runs `make test-medium`, -but only when the heavy tier is needed: code-routed runs where the event is -`merge_group` or the change touches soundness paths or packaging +but only for code-routed pull requests that touch soundness paths or packaging (`scripts/heavy_tier_needed.py` reports `heavy-needed == 'true'`). Ordinary code-change PRs skip it, so do not assume medium coverage ran on a routine PR. Its marker selection excludes slow, stress, resource-heavy, and live diff --git a/tests/unit/scripts/test_heavy_tier_needed.py b/tests/unit/scripts/test_heavy_tier_needed.py index 289d2dc6b0..d3ea565120 100644 --- a/tests/unit/scripts/test_heavy_tier_needed.py +++ b/tests/unit/scripts/test_heavy_tier_needed.py @@ -34,7 +34,6 @@ def _decision(paths: list[str]) -> dict: def _classify(paths: list[str], base: dict[str, str], pr: dict[str, str]) -> dict: return heavy.heavy_needed( _decision(paths), - "pull_request", "base", REPO_ROOT, read_base=lambda *_: base, @@ -47,7 +46,7 @@ def test_real_base_policy_does_not_expand_an_ordinary_code_change( ) -> None: repo, base_head, _pr_head = _snapshot_repo(tmp_path, policy_sources) assert subprocess.check_output(["git", "-C", str(repo), "remote"], text=True) == "" - result = heavy.heavy_needed(_decision(["benchbox/core/platform_registry.py"]), "pull_request", base_head, repo) + result = heavy.heavy_needed(_decision(["benchbox/core/platform_registry.py"]), base_head, repo) assert result["heavy_needed"] is False, result["reason"] @@ -193,7 +192,7 @@ def test_invalid_policy_copies_fail_closed(policy_sources: dict[str, str], bad_c def test_unreadable_base_ref_fails_closed() -> None: - result = heavy.heavy_needed(_decision(["ordinary.py"]), "pull_request", "refs/heads/not-present", REPO_ROOT) + result = heavy.heavy_needed(_decision(["ordinary.py"]), "refs/heads/not-present", REPO_ROOT) assert result["heavy_needed"] is True assert "failed closed" in result["reason"] @@ -236,13 +235,7 @@ def test_invalid_cli_decisions_publish_the_safe_direction(tmp_path: Path, raw: s assert output.read_text().strip() == "heavy-needed=true" -def test_event_and_packaging_carve_outs_preserve_the_full_tier() -> None: - assert heavy.heavy_needed(_decision([]), "merge_group", "absent", REPO_ROOT)["heavy_needed"] is True +def test_packaging_carve_out_and_non_code_routing_preserve_the_expected_tier() -> None: decision = {**_decision([]), "packaging_needed": True} - assert heavy.heavy_needed(decision, "pull_request", "absent", REPO_ROOT)["heavy_needed"] is True - assert ( - heavy.heavy_needed({**_decision([]), "needs_code_ci": False}, "pull_request", "absent", REPO_ROOT)[ - "heavy_needed" - ] - is False - ) + assert heavy.heavy_needed(decision, "absent", REPO_ROOT)["heavy_needed"] is True + assert heavy.heavy_needed({**_decision([]), "needs_code_ci": False}, "absent", REPO_ROOT)["heavy_needed"] is False From 83d05fe07a6e58c9b57d2383d7f5fcfbc33dbcfc Mon Sep 17 00:00:00 2001 From: Joe Harris Date: Mon, 12 Oct 2026 10:42:57 -0400 Subject: [PATCH 2/3] fix(ci): drop stale merge_group routing doc test The README no longer documents merge_group-era heavy-tier routing, so the test asserting the old language is obsolete. Removes it as part of the dead branch cleanup. Fixture digest pre-registered in #2917. --- tests/unit/test_standardized_test_commands.py | 11 ----------- 1 file changed, 11 deletions(-) diff --git a/tests/unit/test_standardized_test_commands.py b/tests/unit/test_standardized_test_commands.py index d1ab935397..14b3baf6b1 100644 --- a/tests/unit/test_standardized_test_commands.py +++ b/tests/unit/test_standardized_test_commands.py @@ -408,17 +408,6 @@ def test_makefile_test_medium_uses_five_workers(self): in makefile_content ) - def test_medium_marker_policy_is_documented_with_pr_routing(self): - repo_root = Path(__file__).resolve().parent.parent.parent - readme_content = (repo_root / "tests" / "README.md").read_text() - makefile_content = (repo_root / "Makefile").read_text() - - assert "The `medium-test` job in `.github/workflows/ci.yml` runs `make test-medium`" in readme_content - assert "only when the heavy tier is needed" in readme_content - assert "Ordinary\ncode-change PRs skip it" in readme_content - assert "Product-critical tests that need a different" in readme_content - assert "test-medium:" in makefile_content - def test_every_speed_marker_tier_has_a_ci_consumer(self): from tests.unit.test_marker_strategy import _E2E_QUICK_INCOMPATIBLE, _SPEED_MARKERS From 3a121fafe6c84b4c412936f6d25194d6c55cf552 Mon Sep 17 00:00:00 2001 From: Joe Harris Date: Mon, 12 Oct 2026 11:47:46 -0400 Subject: [PATCH 3/3] fix(ci): keep routing ratchet; reword README, drop unused pre-registration Per oracle review: only one assertion of the medium-tier doc-routing test went stale, so the test is restored and the README reworded to keep the pinned heavy-tier phrase without merge_group. Removes the now-unused pre-registered fixture digest. --- quality/comment-policy.json | 13 ------------- tests/README.md | 3 ++- tests/unit/test_standardized_test_commands.py | 11 +++++++++++ 3 files changed, 13 insertions(+), 14 deletions(-) diff --git a/quality/comment-policy.json b/quality/comment-policy.json index def5f03698..21c80d3170 100644 --- a/quality/comment-policy.json +++ b/quality/comment-policy.json @@ -37908,19 +37908,6 @@ "owner": "comment-cleanup-unit-tests-cli-scripts-rest", "removal": "Remove when the test's subprocess input becomes a static literal or the executable-payload adapter can reconstruct it." }, - { - "path": "tests/unit/test_standardized_test_commands.py", - "symbol": "TestMakefileCommands.test_pr_preflight_fast_tests_creates_classifier_artifacts_when_absent", - "text": "unresolved executable source: make", - "payload": "sha256:ec98147fe1cc42ba021f5d8b6dc1359df9c93cad0014e20a3a538e0368d2fa6a", - "finding_kind": "payload-error", - "kind": "fixture", - "consumer": "tests/unit/test_standardized_test_commands.py", - "necessity": "Pre-registered for the #2905 cleanup, which removes the obsolete merge_group routing doc test from this file and changes its AST digest. Same fixture as above: the test starts a subprocess whose program (make) is assembled at runtime.", - "alternative": "Rewrite the subprocess input as a static literal the checker can parse; that changes the test and was not taken in the cleanup.", - "owner": "comment-cleanup-unit-tests-cli-scripts-rest", - "removal": "Remove when the test's subprocess input becomes a static literal or the executable-payload adapter can reconstruct it." - }, { "path": "tests/unit/test_standardized_test_commands.py", "symbol": "TestMakefileCommands.test_skill_integrity_preflight_selected_lane_failure_propagates", diff --git a/tests/README.md b/tests/README.md index 3f188d1170..cbe63ea929 100644 --- a/tests/README.md +++ b/tests/README.md @@ -193,7 +193,8 @@ The standard gates are intentionally split by the risk they are meant to catch: blocking routine PRs. The `medium-test` job in `.github/workflows/ci.yml` runs `make test-medium`, -but only for code-routed pull requests that touch soundness paths or packaging +but only when the heavy tier is needed: code-routed pull requests that touch +soundness paths or packaging (`scripts/heavy_tier_needed.py` reports `heavy-needed == 'true'`). Ordinary code-change PRs skip it, so do not assume medium coverage ran on a routine PR. Its marker selection excludes slow, stress, resource-heavy, and live diff --git a/tests/unit/test_standardized_test_commands.py b/tests/unit/test_standardized_test_commands.py index 14b3baf6b1..d1ab935397 100644 --- a/tests/unit/test_standardized_test_commands.py +++ b/tests/unit/test_standardized_test_commands.py @@ -408,6 +408,17 @@ def test_makefile_test_medium_uses_five_workers(self): in makefile_content ) + def test_medium_marker_policy_is_documented_with_pr_routing(self): + repo_root = Path(__file__).resolve().parent.parent.parent + readme_content = (repo_root / "tests" / "README.md").read_text() + makefile_content = (repo_root / "Makefile").read_text() + + assert "The `medium-test` job in `.github/workflows/ci.yml` runs `make test-medium`" in readme_content + assert "only when the heavy tier is needed" in readme_content + assert "Ordinary\ncode-change PRs skip it" in readme_content + assert "Product-critical tests that need a different" in readme_content + assert "test-medium:" in makefile_content + def test_every_speed_marker_tier_has_a_ci_consumer(self): from tests.unit.test_marker_strategy import _E2E_QUICK_INCOMPATIBLE, _SPEED_MARKERS