SniperGold_ML/docs/P3_S22_1_DISCREPANCY_REPORT.md

126 lines
5.7 KiB
Markdown

# P3-S22.1 DISCREPANCY REPORT
```text
Date : 2026-08-25
Session : P3-S22.1 — Verification Debt Closure
Status : DISCREPANCIES DOCUMENTED — NOT REPAIRED (verification-only phase)
Policy : docs/CODE_VERIFICATION_AND_SILENT_BUG_POLICY_v1.md
Repair : NONE performed in this phase (frozen source, contracts, results
untouched). No historical ML conclusion was re-run as a result.
```
Two contract-level departures were discovered by independent oracle parity
checks in the debt-closure phase. Both are represented by deliberate evidence
fixtures and a minimal reproducer. Neither is a production-change in this
phase; each is documented for owner investigation.
---
## DISCREPANCY-ADJ-1 — F2 `mit_state` label for PARTIALLY_FILLED zones
### Observed behavior
The MQL5 production functions `AF_FVGZoneState` / `AF_OBZoneState`
(`MQL5/Include/AlgoForge/AF_Engine2_Agents.mqh`) never assign
`mit_state = AF_ZONE_PARTIALLY_FILLED (1)`. For a zone that price has
entered but not fully filled, they leave `mit_state = AF_ZONE_UNMITIGATED (0)`
and set the auxiliary `partial_filled = true` flag. Source-verified: the token
`AF_ZONE_PARTIALLY_FILLED` occurs in that file only in the enum definition and
in `IsActive()` — never in the state functions.
### Expected behavior
The frozen F2 contract (`docs/P3_S12_ZONE_CONTRACT_REPAIR.md` §F) and the
committed research chain (reference transcription + vectorized OB/FVG kernels;
the same encoding used by `spec_tests_zone_contract.py`) require a
partially-filled zone to be labelled `mit_state = PARTIALLY_FILLED (1)`
(ACTIVE, consumable).
### Minimal reproducer
`ml/p3/p3_s2211_debt_closure/s2211_s1_f2_boundary.py`
cases `F2B-02`, `F2B-05` (FVG), `F2B-09` (OB):
- runtime: `{"mit": 0, "partial": true, "invalidated": false}`
- oracle : `{"mit": 1, "partial": true, "invalidated": false}`
Real-feed cross-check: 570 of 1085 zone-state checks in the 600-bar slice are
`exact_label_departures` (all of the partial-fill kind); 0 aligned mismatches.
### Affected scope
- `AF_FVGZoneState`, `AF_OBZoneState` state label; the finders
(`AF_FindFVG`/`AF_FindOrderBlock`) and all consumers use `IsActive()`, which
treats `UNMITIGATED` and `PARTIALLY_FILLED` identically.
- F3 Candidate Setup is NOT affected: it consumes the research-encoded inputs
and was verified EXACT 25/25 in P3-S22.
- ML features do not consume `mit_state` (zone features are geometry-based).
### Likely cause
The MQL5 implementation models PARTIALLY_FILLED with the separate
`partial_filled` flag instead of the contract's enumerated mit_state value;
the two encodings are functionally equivalent at the consumer level but not
label-identical.
### Severity
LOW. Representation-level state label; no consumer-visible or
historical-result effect found (IsActive identical; F3 exact; ML untouched).
### Could historical results be affected?
Not demonstrated. The research chain (source of all historical counts,
labels and features) uses the contract encoding (mit=1), consistent with the
verified reference/kernels. The MQL5 F2 label difference does not enter the
feature/label/F3 path.
---
## DISCREPANCY-ADJ-2 — Research M30 gate alignment vs runtime UTC-clock M30
### Observed behavior
The committed M30 gate series (`p3_s17r1_gate_series_cache.npz`) changes ONLY
at odd M15 indices (28,395 change points, 100% at odd index). It is constant
within each index-pair M15 segment but NOT within fixed-UTC 30-minute buckets
(best wall-clock grid violations: 7,040 of 197,032 bars), and the pair phase
drifts across session/data gaps (weekends, holidays). H4, by contrast, is
constant within the frozen as-of buckets (0 violations).
### Expected behavior
The frozen as-of contract (`contract §L`, GR-T11) and the comment in
`spec_tests_engine2_gates.py` (`m30_from_m15` "identical to the runtime M30
OHLC") imply M30_asof(t) = newest CLOSED M30 bar with close_time <= t+900 on
the UTC 30-min grid → constant within each UTC 30-min bucket, including
across the two M15 bars of the underlying feed.
### Minimal reproducer
`ml/p3/p3_s2211_debt_closure/s2211_s2_mtf_boundary.py`
(M30 diagnostics block): `changes_at_odd_index_only = True`,
`best_wallclock_grid_violations = 7040`,
`index_pair_asof_internal_violations = 0`. Plus `_debug_s2c.py` (deleted
after use) showing distribution of change-point gaps.
### Affected scope
The research M30 gate series only. It is derived by index-pair resampling of
M15 rather than from UTC 30-min bars, so at feed gaps the M30 bar identity
differs from the runtime CopyRates M30. The H4 gate and the M15 gate are not
affected.
### Likely cause
`m30_from_m15` groups consecutive M15 indices in pairs to synthesize M30 bars;
when the feed contains gaps (missing bars), the pairing phase drifts and the
synthesized M30 bucket boundaries no longer align to wall-clock 30-min marks.
### Severity
LOW-MODERATE. Research-vs-runtime MTF alignment divergence at data gaps; the
setup-level structural identity `h4 == m30 == direction` still holds on all
571 binary rows; F3 exactness was independently established (P3-S22 25/25);
ML features do not consume M30 bar timestamps.
### Could historical results be affected?
Not demonstrated. No setup-level or feature-level inconsistency was found.
The divergence affects only the M30 bar-identity TIMING used to derive the
M30 gate; the downstream F3 chain remained internally consistent and is
immune to the gate-value differences it validated.
---
## DECISION
Both discrepancies are recorded for owner investigation. They are NOT
repaired in this phase (verification-only). No historical report, handover,
contract, dataset, model, or production MQL5 file was modified. No historical
ML conclusion was re-run as a consequence of these findings.
*End of discrepancy report.*