SniperGold_ML/docs/P3_S11_EVENT_CONTRACT_REPAIR.md

10 KiB

P3-S.11 EVENT CONTRACT REPAIR — SNIPERGOLD_ML (F1)

Date       : 2026-08-22
Session    : P3-S.11 — F1 EVENT CONTRACT REPAIR (first implementation phase
             of the frozen canonical architecture, P3-S.10).
Status     : IMPLEMENTED — tests first, contract enforced, consumers audited,
             regression green. No F2/F3/F4/F5/ML changes.
Baseline   : P3_S10_CHECKPOINT_SHA 64160bd91bf1c223f931405bbe416206d0de747e
Contract   : docs/SNIPERGOLD_CANONICAL_SETUP_CONTRACT_v1.md (frozen)
Adjudication: docs/P3_S10_OWNER_ADJUDICATION.md (OD-3 validity, OD-4 conflict)
Test report: ml/p3/smc_semantic/output/p3_s11_event_contract_report.json
Human verification : CANCELLED. No AUC/PF/profit/backtest used.

A. Architecture contract (implemented)

Canonical EVENT (frozen §K/§M + OD-3):

  EVENT { ts, dir, valid_until, superseded, source }

  Liquidity Sweep : EVENT;  W_sweep = 40 M15 bars (justified, InpSeqWindow).
  CHoCH/MSS       : EVENT;  W_choch = 40 M15 bars (justified, legacy gate).
  active          : onset <= r <= onset + W   (EXPIRED at age W+1).
  superseded      : a newer onset of the same type replaced it (permanent;
                    the older event never reactivates).
  chain           : sweep onset <= CHoCH onset <= sweep onset + W_sweep,
                    both fresh at the decision bar r, directions equal.

Implemented in the ML-path EA (AlgoForge_Backtest_Baseline.mq5):
  - AFEventSweep / AFEventChoch structs (ts, dir, valid_until, superseded,
    source) synced from the UNCHANGED detector state at each closed M15 bar.
  - AFBT_SweepActive / AFBT_ChochActive / AFBT_ChainValid helpers.
  - f9 (choch_confirms) and the f18 event-sensitive confluence legs now
    consume EVENTS with validity + supersession + chain bound.

B. Bugs addressed

BUG-P3S2-001  Liquidity Sweep stale consumer:
              f9/f18 read g_swpDir/g_swpBar (persistent state) WITHOUT an age
              bound; a sweep hundreds of bars old still added confluence.
BUG-P3S3-001  CHoCH stale consumer:
              f9 read g_chochDir/g_chochBar without expiry (34.7% stale in f9,
              58.0% stale in the f18 +15 leg per P3-S.3 audit).
D-12         no freshness window in Engine 2 / feature path for sweep/CHoCH
              event consumers (repaired at the FEATURE level in F1; the
              Engine-2 agent path is stateless by construction, P3-S.7 S-ST,
              and is F3 scope).

C. Before behavior

EA ComputeMLFeatures (before F1):
  f7 = (g_swpBar>=0 && (tc-1-g_swpBar)<=SEQ_WINDOW) ? g_swpDir : 0   (P3-S.0, kept)
  f8 = g_chochDir                                                  (STATE, kept)
  f9 = (g_chochDir!=0 && g_chochBar>=g_swpBar && g_chochDir==g_swpDir) ? 1 : 0
       ^ NO validity window on sweep or CHoCH; NO upper chain bound
       (BUG-P3S2-001 / BUG-P3S3-001)
  f18: if(g_swpDir!=0) cb+=15;                      // stale sweep adds +15
       if(g_chochDir!=0 && g_chochDir==g_swpDir) cb+=15;  // stale chain adds +15
       if((g_swpDir==1&&g_bias>0)||(g_swpDir==-1&&g_bias<0)) cb+=15;  // stale

D. New event contract (implemented in the EA)

struct AFEventSweep { int bar; int dir; int valid_until; bool superseded;
                      string source; }          // source = "DetectLiquidityGrabs"
struct AFEventChoch { int bar; int dir; int valid_until; bool superseded;
                      string source; }          // source = "ProcessStructure(internal)"

bool AFBT_SweepActive(decisionBar) : bar>=0 && (decisionBar-bar) <= W_sweep
bool AFBT_ChochActive(decisionBar) : bar>=0 && (decisionBar-bar) <= W_choch
bool AFBT_ChainValid(decisionBar)  :
   sweep.dir!=0 && choch.dir!=0
   && AFBT_SweepActive(decisionBar)
   && AFBT_ChochActive(decisionBar)
   && choch.bar >= sweep.bar                       (CHoCH after sweep)
   && (choch.bar - sweep.bar) <= W_sweep           (within sweep chain)
   && choch.dir == sweep.dir                       (directions equal)

Supersession : the stored latest onset IS the active (non-superseded) event;
  older onsets are replaced by construction (DetectLiquidityGrabs b>g_swpBar;
  ProcessStructure overwrites on each qualifying break). Deterministic.

E. Liquidity Sweep repair

Detection (DetectLiquidityGrabs) : UNCHANGED
  - internal swing reference (len=5), grab window 8, wick penetration +
    same-bar close-back, direction by taken side, closed-bar, M15.
Consumers repaired:
  - f9 sweep leg: the chain predicate requires AFBT_SweepActive (age <= 40).
  - f18 +15 sweep legs: gated by swpValid.
  - f7: formula UNCHANGED (P3-S.0 parity baseline; it already applies the
    40-bar validity with the legacy tc-1 frame — see §L known issues).
  - f8: unaffected (STATE feature by contract).
Validity: W_sweep = 40, NOT optimized. Expired at age 41 -> consumer gets
NO VALID SWEEP EVENT (F1-T03).

F. CHoCH repair

Detection (ProcessStructure internal) : UNCHANGED
  - fractal 5/5 internal pivots, close-confirmed break, prior-trend
    precondition, swing confluence gate, M15.
Consumers repaired:
  - f9 choch_confirms: 1 ONLY IF AFBT_ChainValid(decisionBar) — latest
    active sweep AND latest active CHoCH (age <= 40), CHoCH after the sweep
    and within the sweep validity chain (chochBar-swpBar <= 40), directions
    equal. A CHoCH outside the valid sweep chain is INVALID for the
    canonical setup chain (F1-T06); a stale CHoCH no longer confirms
    (F1-T07).
  - f18 +15 chain leg: gated by chochOK (the same chain predicate).
Validity: W_choch = 40, NOT optimized.

G. Consumer audit

EA (AlgoForge_Backtest_Baseline.mq5) — all consumers of g_swpDir/g_swpBar/
g_chochDir/g_chochBar audited:
  f7  (sweep_dir)      : has its own 40-bar validity; UNCHANGED (P3-S.0).
  f8  (choch_dir)      : intentionally a STATE ("last CHoCH") per
                         SMC_CHOCH_MSS_SPEC_v1 S-9; UNCHANGED.
  f9  (choch_confirms) : REPAIRED -> canonical chain (validity+order+bound+dir).
  f18 (confluence)     : REPAIRED -> event legs validity-aware.
  no other consumer reads the raw sweep/CHoCH state in the EA.

Engine 2 (AF_Engine2_Agents.mqh / AF_Engine2_Display.mqh):
  AF_DetectSweep / AF_DetectChoch are per-bar STATELESS functions recomputed
  from closed Engine-1 bars every bar; no persistent event state exists to go
  stale (P3-S.7 S-ST). Not F1 scope (belongs to F3 setup layer).

Python training mirror (train_model.build_features choch_conf):
  STILL the legacy stale semantics — DOCUMENTED (B14), NOT modified in F1.
  The future dataset rebuild (Phase VI) will regenerate features with the
  canonical event semantics.

Conclusion: no secondary consumer bypasses the event contract.

H. Regression tests

New F1 suite: ml/p3/smc_semantic/spec_tests_event_contract.py
  F1-T01 single sweep event (1 EVENT, valid_until, source)
  F1-T02 expiration boundary (valid at +40, EXPIRED at +41)
  F1-T03 sweep consumer expiration (age 43 -> NO VALID SWEEP EVENT)
  F1-T04 new sweep supersedes old (deterministic supersession, no fallback)
  F1-T05 CHoCH inside valid sweep window -> chain VALID (f9=1)
  F1-T06 CHoCH outside sweep validity chain -> INVALID (f9=0; legacy 1)
  F1-T07 CHoCH consumer expiration (age > W_choch -> f9=0)
  F1-T08 no look-ahead (future mutation does not alter past event state)
  F1-T09 persistent condition -> ONE event (no duplicate emission)
  F1-T10 existing P3-S.2 (17/17) + P3-S.3 (20/20) suites PASS (detection
         semantics unchanged)
Result: 8/8 contract cases PASS + regression PASS (report json attached).

I. Historical before/after

Evidence (P3-S.3 audit, historical):
  Sweep stale persistence  : previously ~hundreds of bars (f7 lifecycle
                             fixed in P3-S.0; f9/f18 consumers still stale).
  CHoCH stale usage        : 34.7% of f9 bars stale; 58.0% of the f18 +15
                             leg stale (BUG-P3S3-001).

After F1 (synthetic case set in the F1 report):
  valid event usage        : f9 = 1 only when sweep AND choch fresh and the
                             chain bound holds (F1-T05).
  expired event usage      : consumers receive NO VALID EVENT at age > 40
                             (F1-T03/F1-T07); stale-usage cases eliminated
                             (legacy f9=1 on 4 stale cases -> contract f9=0).
  superseded event usage   : only the latest onset is active; older events
                             permanently superseded (F1-T04).
No profitability metrics used.

J. Evidence preservation

- P3-S.2..P3-S.10 documents untouched (immutable historical evidence).
- Existing P3-S.2/P3-S.3 spec tests unchanged and PASS (F1-T10).
- The frozen contract (SNIPERGOLD_CANONICAL_SETUP_CONTRACT_v1.md) is the
  authority; this repair implements it, it does not redefine it.
- Prior checkpoints preserved (P3-S.6 533c8c6, P3-S.10 64160bd).

K. Explicitly unchanged semantics

Detection formulas:
  - DetectLiquidityGrabs (reference/penetration/close-back/direction/closed-bar)
  - ProcessStructure internal (pivot 5/5, close break, prior trend, swing gate)
  - f7 sweep_dir formula (P3-S.0 parity baseline)
  - f8 choch_dir STATE semantics (contract S-9)
Constants:
  - W_sweep = 40, W_choch = 40 (AF_BT_SEQ_WINDOW) — NOT optimized
  - GRAB_WINDOW=8, INTERNAL_LEN=5, thresholds, ATR, weights, scores — untouched
NOT touched (later phases):
  - F2 Zone Contract (FVG/OB mitigation), F3 Candidate Setup layer,
    F4 MTF/training alignment, F5 Display, ML pipeline, FEATURE_CONTRACT.md.

L. Remaining known issues

1. f7 boundary frame : the P3-S.0 f7 formula uses the legacy frame
   ((tc-1-g_swpBar)<=40, i.e. age<=41), while the F1 helpers use the frozen
   contract frame (age<=40). f7 is UNCHANGED (parity baseline); f9/f18 follow
   the contract. At age 41 a sweep may still show in f7 while f9's sweep leg
   is expired — a documented pre-existing boundary detail, NOT introduced by
   F1. Resolution belongs to the F4/Phase-VI feature alignment.
2. Python training mirror (train_model.build_features choch_conf / f18) still
   encodes the LEGACY stale semantics; the model was trained on that. F1 does
   NOT retrain (B14). A future dataset rebuild (Phase VI) must regenerate
   features with the canonical event semantics and re-validate parity.
3. Engine-2 agents remain per-bar stateless (P3-S.7 S-ST); the setup-layer
   event consumption is F3 scope (P3-S.12+).

End of P3-S.11 F1 event contract repair record. No F2/F3/F4/F5/ML change.