From f7924af3b0e2076603e8803b4b469cbb8fd23814 Mon Sep 17 00:00:00 2001 From: Harwinder Sekhon Date: Tue, 4 Aug 2026 19:52:07 -0400 Subject: [PATCH] =?UTF-8?q?audit:=20gate-chain=20verdicts=20=E2=80=94=20lo?= =?UTF-8?q?ck=20shipped=20M5=20entry-path=20state,=20document=20hour-delta?= =?UTF-8?q?=20isolation?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 2026-08-04 audit, Batch D. Verification outcomes (no behavior changes — comment + tests only): - CP gate-bypass (quality forced to B after the gate chain, exhaustion/ M5-score gates not re-checked) is VALIDATED behavior, not a bug: the pinned shipped-config M5 12mo book carries 226/586 XAU_CP trades (+38.9R), 104 with EXHAUST warnings (+15.3R), 175 below the M5 min-score gate (+28.0R). Removing the "holes" removes validated profit. New test pins the shipped state (PB off, CP BUY-only on M5, ema_partial_neutral M5-only) so any flip is a conscious revalidated decision. - E18 (xau_strategy vs backtest blocked-hours "drift") REFUTED as a defect: the divergence is required by pair isolation — the backtest copy is the generic non-XAU fallback and must not inherit gold-validated deltas. Documented in the factory + a test asserting the delta stays XAU-side. - 6c-upgrade re-arming an exhaustion-D refuted (exhaustion zeroes confidence below 6c's floor; regimes mutually exclusive). "WEEKEND FILTER" CP-suppression branch is defense-in-depth for direct analyze_from_dataframes callers, kept. Suite: 316 green. Co-Authored-By: Claude Fable 5 Claude-Session: https://claude.ai/code/session_01UnZkzeFcTu9agFg8BDh2tn --- pair_signals/xauusd.py | 7 +++++++ test_all.py | 34 ++++++++++++++++++++++++++++++++++ 2 files changed, 41 insertions(+) diff --git a/pair_signals/xauusd.py b/pair_signals/xauusd.py index 1eaaea7..0089534 100644 --- a/pair_signals/xauusd.py +++ b/pair_signals/xauusd.py @@ -197,6 +197,13 @@ def make_config( config.xau_strategy.blocked_hours_utc = [ h for h in config.xau_strategy.blocked_hours_utc if h != 21 ] + [9] + # Deliberately NOT mirrored into config.backtest.blocked_hours_utc: + # that copy is the generic non-XAU fallback carrying the JSON base + # only. Propagating a gold-validated per-TF delta there would leak + # XAU-calibrated hours to a future pair (pair-isolation rule). + # Every XAU consumer branches to the xau_strategy copy. Enforced + # by the Module 13 test "M5 factory appends hour 9 on top of a + # JSON base". # BUY-only chart patterns on M5 — see module docstring. config.xau_strategy.cp_enabled = True config.xau_strategy.cp_patterns = ["inv_hs", "double_bottom", "bull_flag"] diff --git a/test_all.py b/test_all.py index 3e6029d..41adc32 100644 --- a/test_all.py +++ b/test_all.py @@ -5573,6 +5573,40 @@ def _(): assert gpu_eng.fallback_count == 0, "sweep must never miss the cache" +@test("factory: M5 per-TF hour delta stays XAU-side (pair isolation)") +def _(): + # 2026-08-04 audit E18 verdict: the xau_strategy/backtest hour lists + # SHOULD diverge after the M5 factory — the backtest copy is the + # generic non-XAU fallback and must never inherit gold-validated + # deltas. All XAU consumers branch to the xau_strategy copy + # (signal_aggregator.py session gates, gpu_backtest outer filter). + from pair_signals.xauusd import make_config as _mk + cfg = _mk(Timeframe.M5) + assert 9 in cfg.xau_strategy.blocked_hours_utc + assert 21 not in cfg.xau_strategy.blocked_hours_utc + assert 9 not in cfg.backtest.blocked_hours_utc, \ + "gold-validated hour-9 delta must NOT leak into the generic copy" + assert 21 in cfg.backtest.blocked_hours_utc + + +@test("factory: shipped M5 entry-path state is locked (PB off, CP BUY-only)") +def _(): + # 2026-08-04 audit: the CP path bypassing exhaustion/M5-score gates is + # VALIDATED behavior (226/586 trades, +38.9R in the pinned 12mo book). + # This test pins the shipped state so any flip is a conscious, + # revalidated decision — not an accident. + from pair_signals.xauusd import make_config as _mk + m5 = _mk(Timeframe.M5) + assert m5.xau_strategy.m5_pullback_enabled is False + assert m5.xau_strategy.cp_enabled is True + assert m5.xau_strategy.cp_patterns == ["inv_hs", "double_bottom", "bull_flag"] + assert m5.technical.ema_partial_neutral is True + for tf in (Timeframe.M15, Timeframe.H1, Timeframe.H4): + cfg = _mk(tf) + assert cfg.xau_strategy.cp_enabled is False, f"{tf}: CP must stay off" + assert cfg.technical.ema_partial_neutral is False + + @test("GPU parity: cache miss falls back LOUDLY (counter + warning)") def _(): import gpu_backtest as _gb