From 0461da0ad5e5a8d75fb6822c8b9882d5c90020c1 Mon Sep 17 00:00:00 2001 From: Paul Calnon Date: Wed, 6 May 2026 00:50:31 -0500 Subject: [PATCH 1/2] =?UTF-8?q?ci(async-audit):=20enable=20Phase=202=20?= =?UTF-8?q?=E2=80=94=20soft-fail=20visibility=20for=20async-route=20audit?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Flips the Phase 1 manual-stage hook to fire on regular commits and adds a CI lane scoped to the same ASYNC ruleset, both as soft-fail (``--exit-zero`` for the hook, ``continue-on-error: true`` for CI). Effect: violations surface as PR annotations and pre-commit warnings without blocking merge or commits. The 3 ASYNC240 violations Phase 0 enumerated (juniper_data/api/app.py:46 and api/routes/health.py:131,132) become visible to anyone touching those files; Phase 3 cleans them up. Phase 4 will drop ``--exit-zero`` (pre-commit) and ``continue-on-error: true`` (CI) so future violations block. First of four Phase 2 enable PRs (data → cascor → canopy → worker). Per the migration plan (juniper-ml notes/ASYNC_ROUTE_AUDIT_HOOK_MIGRATION_PLAN.md §4). Co-Authored-By: Claude Opus 4.7 (1M context) --- .github/workflows/ci.yml | 31 +++++++++++++++++++++++++++++++ .pre-commit-config.yaml | 13 ++++++------- 2 files changed, 37 insertions(+), 7 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 6c7db2f..345fd12 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -121,6 +121,37 @@ jobs: echo "╚════════════════════════════════════════════════════════════╝" python scripts/check_doc_links.py --exclude templates --exclude history --cross-repo skip + # ═══════════════════════════════════════════════════════════════════════════════════════════════ + # Async-route audit (Phase 2 — soft-fail visibility). + # Catches the BUG-JD-10 bug class (sync-blocking calls inside async def + # route handlers). `continue-on-error: true` so violations surface as + # PR annotations without blocking merge. Phase 4 will flip this off. + # See juniper-ml notes/ASYNC_ROUTE_AUDIT_HOOK_MIGRATION_PLAN.md §4. + # ═══════════════════════════════════════════════════════════════════════════════════════════════ + async-route-audit: + name: Async-route audit (BUG-JD-10 class, soft-fail) + runs-on: ubuntu-latest + continue-on-error: true + + steps: + - name: Checkout Code + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 + + - name: Set up Python + uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6.2.0 + with: + python-version: "3.12" + + - name: Install ruff + run: pip install "ruff==0.15.6" + + - name: Run async-route audit + run: | + echo "╔════════════════════════════════════════════════════════════╗" + echo "║ JuniperData - Async-route audit (BUG-JD-10) ║" + echo "╚════════════════════════════════════════════════════════════╝" + ruff check --select ASYNC --output-format=github juniper_data/ + # ═══════════════════════════════════════════════════════════════════════════════════════════════ # Unit Tests: Run unit tests with coverage enforcement # ═══════════════════════════════════════════════════════════════════════════════════════════════ diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 65c0512..94bd64a 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -97,19 +97,18 @@ repos: name: Format with Ruff files: ^juniper_data/.*\.py$ # ───────────────────────────────────────────────────────────────────── - # Async-route audit (Phase 1 wiring — disabled state). + # Async-route audit (Phase 2 — soft-fail visibility). # See juniper-ml notes/ASYNC_ROUTE_AUDIT_HOOK_MIGRATION_PLAN.md. - # `stages: [manual]` keeps this from firing on regular commits. - # Run on demand via: pre-commit run --hook-stage manual ruff-async-audit - # Phase 2 flips this to `stages: [pre-commit, manual]` and adds a - # CI lane (continue-on-error: true) so PRs see violations as - # annotations without blocking merge. Phase 4 is hard-fail. + # `--exit-zero` keeps violations as warnings (won't block commits). + # CI lane in .github/workflows/ci.yml runs the same check with + # `continue-on-error: true` so PRs see annotations without blocking + # merge. Phase 4 will drop both `--exit-zero` and `continue-on-error`. - id: ruff alias: ruff-async-audit name: Async-route audit (BUG-JD-10 class) args: [--select, ASYNC, --exit-zero] files: ^juniper_data/.*\.py$ - stages: [manual] + stages: [pre-commit, manual] # ═══════════════════════════════════════════════════════════════════════════ # Python Type Checking - MyPy From 0b319483e82bf312c8320129614075c2d7bc7bed Mon Sep 17 00:00:00 2001 From: Paul Calnon Date: Wed, 6 May 2026 01:03:11 -0500 Subject: [PATCH 2/2] ci(async-audit): add --exit-zero to CI lane so soft-fail is also visual MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Without ``--exit-zero``, ruff exits 1 when it finds violations, which makes the CI step (and therefore the ``async-route-audit`` job) show as red — even with ``continue-on-error: true`` on the job. The job-level flag prevents the workflow from failing as a whole, but the visual indicator on the PR is still red. Phase 2's intent is "violations surface as annotations, no merge block, no red indicator". ``--exit-zero`` makes the step exit 0 while ``--output-format=github`` still renders the violations as annotations. Belt and suspenders alongside ``continue-on-error``. Phase 4 will drop both ``--exit-zero`` and ``continue-on-error``. Co-Authored-By: Claude Opus 4.7 (1M context) --- .github/workflows/ci.yml | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 345fd12..0fed273 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -150,7 +150,12 @@ jobs: echo "╔════════════════════════════════════════════════════════════╗" echo "║ JuniperData - Async-route audit (BUG-JD-10) ║" echo "╚════════════════════════════════════════════════════════════╝" - ruff check --select ASYNC --output-format=github juniper_data/ + # --exit-zero: same soft-fail contract as the pre-commit hook + # (Phase 2 "violations as warnings, not blockers"). Annotations + # still render via --output-format=github so reviewers see them + # in the PR; the step itself doesn't fail. Phase 4 will drop + # this flag along with `continue-on-error: true` on the job. + ruff check --select ASYNC --exit-zero --output-format=github juniper_data/ # ═══════════════════════════════════════════════════════════════════════════════════════════════ # Unit Tests: Run unit tests with coverage enforcement