From 39e81a86c305a61080ff47d5f549cd9774cfbc53 Mon Sep 17 00:00:00 2001 From: Seongho Bae Date: Mon, 3 Aug 2026 12:25:32 +0900 Subject: [PATCH 1/2] ops: schedule hourly PR review autofix --- .github/workflows/hourly-pr-review-fix.yml | 29 ++++++++++++++++++++++ 1 file changed, 29 insertions(+) create mode 100644 .github/workflows/hourly-pr-review-fix.yml diff --git a/.github/workflows/hourly-pr-review-fix.yml b/.github/workflows/hourly-pr-review-fix.yml new file mode 100644 index 000000000..2576c14aa --- /dev/null +++ b/.github/workflows/hourly-pr-review-fix.yml @@ -0,0 +1,29 @@ +name: Hourly PR Review Fix Loop + +on: + schedule: + # Avoid the top of the hour, where GitHub documents higher schedule delay. + - cron: "37 * * * *" + workflow_dispatch: + +# The reusable workflow cannot elevate permissions granted by this caller. +permissions: + actions: write + contents: read + issues: write + pull-requests: read + statuses: read + +jobs: + dispatch_review_fixes: + # Keep the implementation centralized; this repository owns only the cadence. + uses: ContextualWisdomLab/.github/.github/workflows/pr-review-fix-scheduler.yml@5983b41ace75040c1d81818171ca7d0f3653254e + with: + target_repository: ContextualWisdomLab/fast-mlsirm + base_branch: main + dry_run: false + max_prs: "50" + max_dispatches: "1" + retry_hours: "1" + canonical_ref: main + secrets: inherit From 8efbf56706bb8dd954ec31ef984fb38d161a7afd Mon Sep 17 00:00:00 2001 From: Seongho Bae Date: Mon, 3 Aug 2026 12:25:51 +0900 Subject: [PATCH 2/2] test: pin hourly central autofix caller --- tests/test_hourly_pr_review_fix_workflow.py | 57 +++++++++++++++++++++ 1 file changed, 57 insertions(+) create mode 100644 tests/test_hourly_pr_review_fix_workflow.py diff --git a/tests/test_hourly_pr_review_fix_workflow.py b/tests/test_hourly_pr_review_fix_workflow.py new file mode 100644 index 000000000..51c1e381e --- /dev/null +++ b/tests/test_hourly_pr_review_fix_workflow.py @@ -0,0 +1,57 @@ +"""Contract tests for the thin hourly PR-review autofix caller.""" + +from __future__ import annotations + +from pathlib import Path + + +_WORKFLOW = Path(".github/workflows/hourly-pr-review-fix.yml") +_CENTRAL_SHA = "5983b41ace75040c1d81818171ca7d0f3653254e" + + +def _workflow_text() -> str: + """Read the repository-local cadence-only workflow as UTF-8 text.""" + return _WORKFLOW.read_text(encoding="utf-8") + + +def test_hourly_caller_uses_an_off_peak_hourly_schedule(): + """The requested hourly cadence runs away from the congested hour boundary.""" + text = _workflow_text() + assert 'cron: "37 * * * *"' in text + assert "workflow_dispatch:" in text + + +def test_hourly_caller_reuses_the_pinned_central_scheduler(): + """No repository-local autofix implementation may drift from org governance.""" + text = _workflow_text() + assert ( + "uses: ContextualWisdomLab/.github/.github/workflows/" + f"pr-review-fix-scheduler.yml@{_CENTRAL_SHA}" + ) in text + assert "runs-on:" not in text + assert "steps:" not in text + + +def test_hourly_caller_targets_only_fast_mlsirm_with_bounded_dispatch(): + """Each hourly sweep dispatches at most one same-repository autofix candidate.""" + text = _workflow_text() + assert "target_repository: ContextualWisdomLab/fast-mlsirm" in text + assert "base_branch: main" in text + assert 'max_dispatches: "1"' in text + assert 'retry_hours: "1"' in text + assert "secrets: inherit" in text + + +def test_hourly_caller_grants_only_scheduler_required_permissions(): + """The caller exposes no broader token permissions than the central contract.""" + text = _workflow_text() + for permission in ( + "actions: write", + "contents: read", + "issues: write", + "pull-requests: read", + "statuses: read", + ): + assert permission in text + for forbidden in ("contents: write", "pull-requests: write", "id-token: write"): + assert forbidden not in text