# P3-S.5 ORDER BLOCK FORMAL SPECIFICATION & CODE-CONFORMANCE REPORT ```text Date : 2026-08-22 Session : P3-S.5 — Formal SMC Specification + Code-Conformance Audit (Order Block) Scope : Order Block (OB) — Engine 2 agents C/E (AF_FindOrderBlock), Engine 3 display (AF_CollectOBs), legacy v4.3/v4.4/v4.5 (ProcessStructure RecordOB + v4.5 MTF RecordOB_mtf), legacy entry gate (InpEntryOnFVGorOB / FindEntryOB / Sweep->CHoCH->OB chain). Principle : SPECIFICATION FIRST, CODE AUDIT SECOND Status : NO CODE CHANGES (Phase D) — all findings DOCUMENTED Artifacts : docs/SMC_ORDER_BLOCK_SPEC_v1.md (specification) ml/p3/smc_semantic/spec_tests_order_block.py (+ .json) (tests) ml/p3/smc_semantic/output/spec_tests_order_block_report.json ``` --- ## 0. CHECKPOINT & PROVENANCE (session-start verification) ```text Forge HEAD : 176880f8f3f17afb7e922a48ed953daa22c1515f (P3-S.4) VERIFIED Branch / remote : main == origin/main (176880f) VERIFIED Working tree : CLEAN at start VERIFIED P3-S.4 artifacts : spec/conformance/tests/report/handover INTACT VERIFIED P3-S.3 / P3-S.2 / P3-S.0 / P3-S.1 / P2 checkpoints : in history, intact VERIFIED P2.6 model (SHA-256): 06df8452... (verified by file hash in P3-S.4) VERIFIED HUMAN VERIFICATION : CANCELLED VERIFIED ``` --- ## A. SOURCE MATERIAL (Phase A — inventory & reconciliation) | # | Source | Location | Role | |---|--------|----------|------| | 1 | DESIGN.md (Algo Forge) | docs/DESIGN.md:132-133, 206 | Intent: C agent "OB (opposite bar before a strong move)"; E agent "OB/FVG zones; ZONE + CONFIRMATION = setup"; display "Order Block | AFDispZone (AF_CollectOBs) | MIT filter + dedupe + size >= 0.15xATR" | | 2 | Engine 2 detector | Include\AlgoForge\AF_Engine2_Agents.mqh:293-322 (AF_FindOrderBlock) | opposite-color bar before strong move (body >= 1.5 x avg); zone = full range; NO min size; NO mitigation; returns NEWEST +-1/0; avgN = AF_E2_LOOKBACK_AVG (20) | | 3 | AF_AvgBody | AF_Engine2_Agents.mqh:120-127 | mean |Close-Open| over the last n closed bars | | 4 | Engine 2 C agent | AF_Engine2_Agents.mqh:492-575 | ob = AF_FindOrderBlock(20); mInOb = trap(close, zone +- 0.3 ATR); weight 0.30 | | 5 | Engine 2 E agent | AF_Engine2_Agents.mqh:583-663 | ob = AF_FindOrderBlock(20); mZone (OB/FVG); ZONE + CONFIRMATION setup rule | | 6 | Engine 3 display collector | Include\AlgoForge\AF_Engine2_Display.mqh:199-250 (AF_CollectOBs) | same formation; doji excluded; min 0.15 x ATR; mitigation close-through; dedupe 0.5 x ATR; newest N (default 5) | | 7 | AF_Defines.mqh | Include\AlgoForge\AF_Defines.mqh:57,59,60 | AF_E3_OB_DEFAULT=5; AF_E3_OB_MIN_ATR=0.15; AF_E3_MOVE_BODY=1.5 | | 8 | Engine 3 render/indicator | AF_Engine3_Render.mqh; AF_Engine3_Display.mq5 | OB boxes; inputs (InpShowOB, InpOBCount=5) | | 9 | v4.3/v4.4 indicator | Indicators\Downloads\SniperGold_SMC_ProPlus_v4_3/4_4.mq5 | LEGACY structure-break OB: RecordOB on BOS/CHoCH break (ProcessStructure:400-435); orig = last opposite pivot; scan breakBar->orig for last/highest-volume opposite candle (RecordOB:536-556); full range; min 0.15 x ATR; close-through mitigation (FilterAndDrawOBs:559-567); internal + swing OBs; entry FindEntryOB:976-987 + tap +-1 ATR; +15; Sweep->CHoCH->OB chain | | 10 | v4.5 indicator | SniperGold_SMC_ProPlus_v4_5.mq5 | chart OB identical to v4.4; + MTF OB per-TF (D1/H4/H1) via cache (RecordOB_mtf:385-407; structure-break, InpOBStyle last/volume, 0.15 ATR, close-through mit) | | 11 | FEATURE_CONTRACT | docs/FEATURE_CONTRACT.md | NO OB feature (1 hit = "prOB" in SGMLProb — false positive) | | 12 | EA runtime | Experts\AlgoForge_Backtest_Baseline.mq5 | NO OB computation (hits = OrderSend + comment "tanpa draw/OB/alert") | | 13 | Python training | ml/**/*.py | NO OB (0 hits) | | 14 | P3 docs | docs/P3_2_2_..., docs/P3_2_LABEL_FORENSIC | "breaker" mentioned ONLY as a future concept, outside this session's mandate | | 15 | External references | Indicators\Downloads\SMC Order Block Detector.mq5; XAUUSD_MTF_Liquidity_OB_Reversal (2).mq5 | external indicators, NOT part of the project (no wiring) | **Layer separation:** ```text Intended semantics : OB = opposite bar before a strong move (DESIGN.md); C agent context zone; E agent entry zone (ZONE + CONFIRMATION = setup); display zones with MIT filter + dedupe + min size 0.15xATR. Legacy semantics : v4.3/v4.4/v4.5: OB = opposite candle BEFORE A STRUCTURE BREAK (BOS/CHoCH on swing len=50 / internal len=5); last or highest-volume opposite candle; full range; min 0.15xATR; close-through mitigation; internal + swing OBs; entry chain Sweep->CHoCH->OB within InpSeqWindow. Current semantics : Algo Forge: opposite bar before strong move (1.5 x avg body); zone = full range; Engine 2 = newest-only, NO min size, NO mitigation; display = newest N unmitigated, 0.15xATR min, close-through mit, 0.5xATR dedupe. Training semantics : N/A — OB is not a training feature (no parity target). Display-only : Engine 3 OB boxes; v4.4/v4.5 OB drawing; v4.5 MTF OB. ``` --- ## B. PROJECT SEMANTIC SPECIFICATION (Phase B) Full document: **docs/SMC_ORDER_BLOCK_SPEC_v1.md** (PROJECT SEMANTIC SPECIFICATION — not "universal SMC ground truth"). Spec decision summary: ```text S-1 Formation : opposite-color candle B immediately before strong-move candle M (|body(M)| >= 1.5 x avg body). Canonical current. S-2 Candle selection: B = full opposite candle (Close vs Open); doji excluded; zone = FULL RANGE [Low(B), High(B)]. S-3 Zone boundaries: top = High(B), bot = Low(B); no padding; min size none in definition (0.15 ATR consumer filters, A-1). S-4 Direction : +1 bullish (bearish B + bullish M), -1 bearish, 0 none; direction = move direction. S-5 Structural precondition: NONE (canonical); legacy = BOS/CHoCH (A-2). S-6 Formation timing: observable at M close (B+1 <= t); newest pair (t-1, t); NO 1-bar lag; timestamp = B open. S-7 Closed-bar : all inputs <= t; no future visibility. S-8 Lifecycle : ZONE + FORMATION EVENT; one zone per pair; no event stream. S-9 Mitigation : close-through full fill (Close < Low(B) bull / > High(B) bear); partial/wick NOT mitigation. S-10 Invalidation : NOT MODELED. S-11 Overlap : separate zones per pair; display dedupe 0.5 ATR (A-3). S-12 Breaker : NOT IMPLEMENTED (no code). S-13 Timeframe : Engine 2 per-TF independent; canonical = AMBIGUOUS (A-4). S-14 Consumers : C/E zone membership (newest OB); legacy entry gate (all unmitigated within tap); display; NO ML feature. S-15 Parity : OB NOT an ML feature; PARITY = N/A BY ABSENCE. ``` --- ## C. FORMAL DEFINITIONS (Phase B — extract) ```text avg_body(t) = mean over the newest min(20, t+1) closed bars of |Close-Open|. OB_pair(bar b, prices) with b+1 <= t (both closed), move M = b+1: Bullish OB (dir=+1): Close(M) > Open(M) AND |body(M)| >= 1.5*avg_body AND Close(b) < Open(b) -> zone [Low(b), High(b)] Bearish OB (dir=-1): Close(M) < Open(M) AND |body(M)| >= 1.5*avg_body AND Close(b) > Open(b) -> zone [Low(b), High(b)] One zone per qualifying pair (b, b+1). Zone state (S-9): MITIGATED iff exists j > b with bull: Close(j) < Low(b) / bear: Close(j) > High(b). Canonical consumer query (S-14): the NEWEST zone at decision t (Engine 2) / newest N unmitigated (display/legacy). No invalidation, no age expiry. OB is not a Feature Contract feature (S-15). ``` --- ## D. CURRENT CODE BEHAVIOR (Phase C — code audit) ### D.1 Engine 2 — AF_FindOrderBlock (AF_Engine2_Agents.mqh:293-322) ```mql5 int AF_FindOrderBlock(const AFEngine1MTF &e1,int slot,int avgN,double &zoneHi,double &zoneLo) { zoneHi=0.0; zoneLo=0.0; if(!e1.IsReady(slot)) return 0; int cnt=e1.Count(slot); if(cnt move=idx0) { double bodyPrev=MathAbs(e1.Close(slot,i-1)-e1.Open(slot,i-1)); if(bodyPrev<1.5*avg) continue; // move body >= 1.5 x avg bool upMove=e1.Close(slot,i-1)>e1.Open(slot,i-1); if(upMove) { if(e1.Close(slot,i)e1.Open(slot,i)) // OB candle bullish { zoneHi=e1.High(slot,i); zoneLo=e1.Low(slot,i); return -1; } } } return 0; } ``` Observations: - Formation = opposite-color candle + strong move (body >= 1.5 x avg) — matches S-1. - Zone = full range [Low(i), High(i)] — matches S-2/S-3. - NEWEST pair: OB candle = index 1, move = index 0 (newest closed bar IS eligible as the move) — NO 1-bar lag (S-6). - NO minimum zone size (S-3/A-1), NO mitigation filter (S-9 — BUG-P3S5-001), returns ONLY the newest OB (S-14/A-5). - avgN = 20 (AF_E2_LOOKBACK_AVG) in both callers. ### D.2 Engine 3 display — AF_CollectOBs (AF_Engine2_Display.mqh:199-250) ```mql5 for(int i=0; iOpen(i)); bool prevBear=(Close(obBar)Open(obBar)); if(!prevBear && !prevBull) continue; // doji excluded if(moveUp && prevBear) bull=true; else if(!moveUp && prevBull) bull=false; else continue; top=High(obBar); bot=Low(obBar); if((top-bot)=0; b--) { bull? Closetop -> mit; } if(mit) continue; // dedupe: skip zone within 0.5 x ATR of an existing zone ... } ``` Observations: same formation (S-1); adds doji exclusion (S-2 consistent), min 0.15 x ATR (A-1), close-through mitigation (S-9), 0.5 x ATR dedupe (A-3), newest N unmitigated zones (S-14). Timestamp = Time(obBar) = OB candle (S-6). ### D.3 Legacy v4.3/v4.4 — structure-break OB (v4_4.mq5:400-435, 536-556) ```mql5 // in ProcessStructure, on a bullish break (close[i]>upTarget): int orig=(lastLowBar>=0&&lastLowBar=fromBar;b--) { // break bar -> last pivot bar bool oppo = bull ? (close[b]open[b]); if(!oppo) continue; if(InpVolumeOB){ if(vol[b]>bestVol){bestVol=vol[b]; found=b;} } // highest volume else { found=b; break; } // last opposite } if(found<0) return; if((high[found]-low[found])<0.15*g_atr) return; g_obs[n].top=high[found]; g_obs[n].bot=low[found]; ... } // mitigation (FilterAndDrawOBs): close[b]top (bear) -> mit ``` Observations: LEGACY definition — OB recorded ONLY at a STRUCTURE BREAK (BOS/CHoCH), the OB candle = last (or highest-volume) opposite candle between the last opposite pivot and the break bar; full range; min 0.15 x ATR; close-through mitigation. This is the A-2 second definition. v4.5 MTF OB = same rule per-TF. ### D.4 Entry consumption (v4.4) ```mql5 int FindEntryOB(bool bull,double price) // unmitigated OB, mid within +-0.2 ATR of price ... if(bull && mid>price+0.2*g_atr) continue; ... buyOBTap = (obB>=0 && price<=g_obs[obB].top+tap && price>=g_obs[obB].bot-tap); // tap=1 ATR buy += 15 (OB tap); signal "Sweep->CHoCH->Bullish OB (discount)"; pending: "wait pullback to bullish OB" at zone top. ``` Observations: legacy entry consumes ALL unmitigated OBs within tap (S-14/A-5); the Engine-2 C/E agents consume only the NEWEST OB without a mitigation check. --- ## E. CONFORMANCE MATRIX (Phase C) Verdicts: CONFORMING / PARTIALLY CONFORMING / NON-CONFORMING / UNVERIFIABLE / SPECIFICATION AMBIGUOUS. | # | Requirement | Specification | Code (Function/Line) | Actual Behavior | Verdict | |---|-------------|--------------|----------------------|-----------------|---------| | E-1 | Formation | opposite candle B before strong move M (body >= 1.5 x avg) (S-1) | AF_FindOrderBlock:309-318; AF_CollectOBs:210-220 | matches; legacy uses structure-break rule instead (A-2) | **CONFORMING** (current) / A-2 legacy divergence | | E-2 | Candle selection | full opposite candle; doji excluded; FULL RANGE (S-2) | AF_FindOrderBlock:313,318; AF_CollectOBs:215-223; v4.4 RecordOB:544-555 | full range [Low,High]; doji excluded | **CONFORMING** | | E-3 | Zone boundaries | top=High(B), bot=Low(B); no padding (S-3) | all: top/bot = High/Low of OB candle | exact boundaries; 0.15 ATR min filter differs by consumer (A-1) | **CONFORMING** (+ AMBIGUOUS A-1) | | E-4 | Direction | +1 bullish / -1 bearish / 0 none (S-4) | AF_FindOrderBlock:313-318; AF_CollectOBs:218-220 | direction = move direction; symmetric | **CONFORMING** | | E-5 | Structural precondition | NONE (canonical) (S-5) | AF_FindOrderBlock: no break/BOS/CHoCH check | current detector = opposite+strong-body only | **CONFORMING** (current); legacy = structure-break (A-2, PARTIALLY CONFORMING at project level) | | E-6 | Formation timing | observable at M close; newest pair (t-1, t); NO 1-bar lag (S-6) | AF_FindOrderBlock: i=1 (move=idx0) | newest closed bar IS the move candle; OB candle = idx 1 | **CONFORMING** | | E-7 | Closed-bar / no future | all inputs <= t (S-7) | Engine-1 lock; v4.4 tc=total-1 | no future visibility; deterministic | **CONFORMING** | | E-8 | Lifecycle | ZONE + FORMATION EVENT; one zone per pair; no event stream (S-8) | zone arrays (g_obs / dd.ob); newest-query | one zone per pair; no duplication (OB-T09) | **CONFORMING** | | E-9 | Mitigation | close-through full fill (S-9) | AF_CollectOBs:227-231; v4.4 FilterAndDrawOBs:563-566; AF_FindOrderBlock: NONE | display/legacy apply close-through mit; Engine-2 detector NONE | **NON-CONFORMING** (Engine 2, BUG-P3S5-001) | | E-10 | Invalidation | NOT MODELED (S-10) | no invalidation code | none exists | **CONFORMING** | | E-11 | Overlap / multiple | separate zones per pair; dedupe only in display (S-11/A-3) | AF_CollectOBs:234-239 dedupe 0.5 ATR; AF_FindOrderBlock newest-only; v4.4 keep-all | keep-all vs dedupe intent not adjudicated | **PARTIALLY CONFORMING** (A-3) | | E-12 | Breaker | NOT IMPLEMENTED (S-12) | grep breaker = 0 project code matches | no Breaker/flipped-OB code | **CONFORMING** (no claim) | | E-13 | Timeframe | Engine 2 per-TF; canonical AMBIGUOUS (S-13) | AF_FindOrderBlock per slot (H4/M30/M15/M3); v4.5 MTF cache | per-TF independent; HTF role not defined | **SPECIFICATION AMBIGUOUS** (A-4) | | E-14 | Consumer behavior | C/E zone membership (newest OB); legacy entry all-unmitigated (S-14/A-5) | C:AF_Engine2_Agents:511-512,539-541; E:607-608,621-623; legacy FindEntryOB | Engine-2 consumes newest-ANY (no mit/age); legacy all-unmitigated within tap | **PARTIALLY CONFORMING** (BUG-P3S5-001, A-5) | | E-15 | Runtime/training parity | OB NOT an ML feature; PARITY = N/A (S-15) | FEATURE_CONTRACT/EA/ml: no OB | no training-side OB; no parity target | **CONFORMING** (N/A by absence) | --- ## F. CONFIRMED BUGS (Phase D — DOCUMENT ONLY, no code changes) ```text BUG-P3S5-001 SEVERITY : MEDIUM SOURCE : AF_FindOrderBlock — AF_Engine2_Agents.mqh:293-322 (Engine 2 C/E agents) SPEC REQ : S-9 — mitigation is part of the OB zone lifecycle; the canonical consumer query should use unmitigated zones (display/legacy do) ACTUAL CODE : AF_FindOrderBlock returns the newest OB with NO mitigation check and NO age/freshness bound; it returns ONLY the newest zone (older unmitigated OBs invisible to the agents) IMPACT : C agent "price in OB zone" (weight 0.30) and E agent "zone tap" can fire on a FULLY-FILLED (mitigated) OB, and on an OB that may be hundreds of bars old (no freshness). The legacy entry path (FindEntryOB) filters mitigation; the current Engine-2 path does not. Same bug class as BUG-P3S4-001 (FVG side). NOT the f7/f9/f18 duplication class — OB is a zone, not an event stream (verified OB-T09). PROPOSED FIX : apply the close-through mitigation filter (S-9) to AF_FindOrderBlock (or let the agents filter mitigated zones) and add a zone-age bound if consumers require freshness; document the zone-selection rule (newest vs newest-unmitigated). BUG-P3S5-002 SEVERITY : LOW SOURCE : two OB definitions in one project — AF_FindOrderBlock (opposite + strong move) vs v4.3/v4.4/v4.5 RecordOB (opposite before STRUCTURE BREAK) SPEC REQ : S-5/A-2 — the canonical definition must be explicit ACTUAL CODE : the current Algo Forge detector (DESIGN.md rule) and the legacy indicator (BOS/CHoCH rule) can select DIFFERENT candles as "the OB" for the same price sequence IMPACT : runtime Engine-2 outputs are NOT directly comparable with the legacy v4.4/v4.5 OB displays; the legacy volume-weighted mode (InpVolumeOB / InpOBStyle=OB_HIGHEST_VOLUME) selects a different candle again (A-6) PROPOSED FIX : document the current rule as canonical and mark the legacy structure-break/volume rule as historical (no code change to the legacy indicators this session). BUG-P3S5-003 SEVERITY : INFO (specification ambiguity) SOURCE : minimum zone size — AF_Defines.mqh:59 (0.15 ATR) vs AF_FindOrderBlock (none) vs v4.4:549 (0.15 ATR) SPEC REQ : S-3/A-1 — a canonical project minimum zone size ACTUAL CODE : Engine-2 detector has no filter; display/legacy use 0.15 x ATR IMPACT : the same candle can be "OB" in Engine 2 but filtered by display/legacy PROPOSED FIX : adjudicate a single threshold (NOT optimized here) or explicitly scope the filters to their consumers. BUG-P3S5-004 SEVERITY : INFO (documentation) SOURCE : display dedupe — AF_Engine2_Display.mqh:234-239 (0.5 x ATR) vs Engine-2 newest-only vs legacy keep-all SPEC REQ : S-11/A-3 — overlap handling intent ACTUAL CODE : three different zone-selection/overlap policies IMPACT : display may hide an OB the Engine-2 agents still use PROPOSED FIX : adjudicate keep-all vs dedupe (documented; not fixed here). ``` --- ## G. SEMANTIC AMBIGUITIES (Phase F — consistency) ```text G-1 MINIMUM ZONE SIZE (A-1) Engine 2 none / display 0.15 x ATR / legacy 0.15 x ATR. No canonical value. G-2 TWO OB DEFINITIONS (A-2) current = opposite candle before strong move (DESIGN.md, Algo Forge); legacy = opposite candle before structure break (v4.3/v4.4/v4.5, BOS/CHoCH, volume mode). Different candles can be selected. G-3 OVERLAP / DEDUPE (A-3) display dedupes zones within 0.5 x ATR; Engine 2 and legacy keep all. G-4 CANONICAL TIMEFRAME (A-4) Engine-2 M15 slot explicit; HTF OB as M15 context / M3 execution not defined. Same class as CHoCH G-4 / sweep G-3 / FVG A-3. G-5 CONSUMER ZONE SCOPE (A-5) Engine 2 newest-ANY (no mit/age) vs legacy all-unmitigated within tap vs display newest-N-unmitigated. BUG-P3S5-001. G-6 VOLUME-WEIGHTED OB (A-6) legacy-only (InpVolumeOB / OB_HIGHEST_VOLUME); current = last candle only. ``` --- ## H. SEMANTIC RELATIONSHIP WITH THE SMC CHAIN (Phase C) ```text Detection : OB detection is independent (canonical current: opposite + strong body; no sweep/CHoCH/FVG required) — CONFORMING S-1/S-5. Legacy chain : Sweep -> CHoCH -> OB/FVG within InpSeqWindow (v4.4) — OB is the final ENTRY ZONE of the chain; ordering/freshness handled by the sweep/CHoCH gates (P3-S.2/P3-S.3 audits); the OB zone itself has no age rule (mitigation is its only termination). Engine 2 : C agent = OB as CONTEXT (price-in-zone, weight 0.30); E agent = OB as ENTRY ZONE with ZONE + CONFIRMATION = setup (DESIGN.md). Consistent with the design intent. ML : OB ABSENT from f0-f18 — the chain is runtime/display only. NO production dependency between OB and f7/f8/f9/f10/f11/FVG/CHoCH was changed. ``` --- ## I. RUNTIME/TRAINING PARITY (Phase C — diagnostic, not a retrain) ```text OB is not a Feature Contract feature (f0-f18) and has no Python training representation (verified: no OB in FEATURE_CONTRACT.md, EA runtime, ml/**/*.py). -> PARITY = N/A BY ABSENCE (S-15). No mismatch exists; the absence itself is a documented fact, not a defect. If OB is later promoted to an ML feature, a Feature Contract entry and a parity harness are required first (out of scope). ``` --- ## J. VERDICT ```text PARTIALLY CONFORMING Formation (E-1, E-2, E-4, E-6, E-7) : CONFORMING (current definition) Zone boundaries (E-3) : CONFORMING (+ AMBIGUOUS A-1 min size) Structural precondition (E-5) : CONFORMING (current = none); legacy BOS/CHoCH rule = A-2 Lifecycle (E-8) : CONFORMING (zone; no event duplication) Mitigation (E-9) : NON-CONFORMING (Engine 2, BUG-P3S5-001) Invalidation (E-10) : CONFORMING (not modeled) Overlap (E-11) : PARTIALLY CONFORMING (A-3) Breaker (E-12) : NOT IMPLEMENTED (no claim) Timeframe (E-13) : SPECIFICATION AMBIGUOUS (A-4) Consumer semantics (E-14) : PARTIALLY CONFORMING (BUG-P3S5-001, A-5) Runtime/training parity (E-15) : CONFORMING (N/A by absence) Verdict = conformance to the PROJECT SEMANTIC SPECIFICATION, NOT profitability/edge. The DETECTOR core (formation, candle selection, direction, closed-bar, zone lifecycle) is conforming; the gaps are consumer-side (Engine-2 mitigation/age filter missing, zone selection scope, canonical threshold/timeframe) plus the legacy structure-break second definition. ``` --- ## K. NEXT GATE ```text After the Order Block verdict (PARTIALLY CONFORMING): Displacement -> MTF Alignment -> Candidate Setup. DO NOT return to ML; DO NOT build a meta-label; DO NOT create new event labels; DO NOT fix production bugs before the audit chain completes (BUG-P3S5-00x stay documented until the semantic audit chain is finished). ``` --- ## L. CHECKPOINT & PROVENANCE (P3-S.5) ```text Forge HEAD (session start) : 176880f (P3-S.4) — VERIFIED P3-S.4 spec (immutable) : docs/SMC_FVG_SPEC_v1.md P3-S.3 spec (immutable) : docs/SMC_CHOCH_MSS_SPEC_v1.md P3-S.2 spec (immutable) : docs/SMC_LIQUIDITY_SWEEP_SPEC_v1.md FEATURE_CONTRACT : C44CC6F2... (P2-era) / 7b908b12... (committed) symbol/tf : XAUUSD / M15 (2017-01-01 .. 2026-08-20) Human verification : CANCELLED No production change : AF_FindOrderBlock / AF_CollectOBs / v4.3/v4.4/v4.5 / Engine 2 / Engine 3 / f7-f18 / FVG / CHoCH / Displacement / ML : NOT touched ```