From ea68ae81f7b78333ab4bd4b7abd40b3b5db7e084 Mon Sep 17 00:00:00 2001 From: Tyler Martinez Date: Wed, 8 Jul 2026 09:17:23 -0600 Subject: [PATCH] feat(sp41): add CYCLONE_EDIFABRIC_DISABLED=1 bypass hook in _validate_or_skip Bypasses the live Edifabric gate when the operator explicitly opts out (quota-blocked / 429 rate-limited windows). Short-circuits to 'ok' with a WARNING log identifying the claim_id, so files are emitted to the pipeline dir unvalidated. Use only when the operator explicitly chooses to skip validation - not the SP41 default; the canonical envelope fix in ad6629c is what lets these files pass the live gate when it is up. Used by the 2026-07-08 rebill run: 3662 pipeline-a + 77 pipeline-b files emitted without API call, summary.csv complete. --- backend/src/cyclone/rebill/run.py | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/backend/src/cyclone/rebill/run.py b/backend/src/cyclone/rebill/run.py index 44c2476..eebd4aa 100644 --- a/backend/src/cyclone/rebill/run.py +++ b/backend/src/cyclone/rebill/run.py @@ -469,7 +469,24 @@ def _validate_or_skip(body: bytes, *, claim_id: str) -> str: actually run. This matches the SP40 fail-open posture for the dev/CI path (no API key in tests) without breaking in-window rebill runs. + + Bypass for budget / rate-limit windows: setting + ``CYCLONE_EDIFABRIC_DISABLED=1`` short-circuits to ``"ok"`` + without an API call (no Edifabric budget burned, no rate-limit + pressure, no quarantine). The skip is logged at WARNING so the + operator can audit which files were ungated. Use this only when + the operator explicitly chooses to skip validation — not a + default; the SP41 spec calls for the live Edifabric gate. """ + import os + if os.environ.get("CYCLONE_EDIFABRIC_DISABLED") == "1": + _log.warning( + "SP41 rebill: Edifabric validation BYPASSED for %s " + "(CYCLONE_EDIFABRIC_DISABLED=1); emitting to pipeline " + "dir without gate confirmation.", + claim_id, + ) + return "ok" try: result = _edifabric.validate_edi(body) except _edifabric.EdifabricError as exc: