# Pine ↔ Python Parity Audit — S2 Bonds (Pine RX07 ↔ Python RX10)

Audit date: 2026-05-15
Pine source: `Q7_AEGIS_AI_S2_RX07_SPRD_MR_Bonds_5LEG.pine` (1094 lines)
Whitepaper: `Q7_AEGIS_AI_S2_Bonds_Architecture_Whitepaper.docx` → `_s2_whitepaper_v_2026_05_15.txt`
Python: `q7_s2bonds_5leg_engine.py` + producer `parity_s2bonds_rx10_aegis.py`
Auditor: parity-only — no Python or Pine files were modified.

---

## §1 Summary table

| Category | EXACT | DRIFT | MISSING | EXTRA (layered) |
|---|---:|---:|---:|---:|
| **Global / Z-engine** | 5 | 2 | 0 | 0 |
| **Risk + halts** | 7 | 1 | 0 | 1 |
| **DV01 sizing** | 2 | 0 | 0 | 4 (`dv01_wt_{ZF,ZN,ZB,UB}`) |
| **Slippage filter** | 2 | 0 | 0 | 0 |
| **Cointegration** | 2 | 0 | 0 | 0 |
| **Fed blackout** | 4 | 0 | 0 | 0 |
| **HAI + sentiment** | 4 | 0 | 0 | 1 (`i_useHAIInBacktest` calibratable) |
| **Curve regime gate** | 2 | 0 | 0 | 0 |
| **Λ-Vol classifier** | 5 | 0 | 0 | 0 |
| **Confluence weights** | 6 | 0 | 0 | 1 (`wt_zeta`) |
| **Confluence gate** | 3 | 0 | 0 | 0 |
| **Regime router (P3)** | 9 | 0 | 0 | 0 |
| **5-leg allocations** | 5 | 0 | 0 | 0 (now calibratable, defaults match Pine) |
| **5-leg fractions** | 5 | 0 | 0 | 0 |
| **5-leg protection** | 3 | 0 | 0 | 0 |
| **Per-config (G10, 16×8 + cm)** | n/a | 16 | 0 | 0 — Pine carries 16 explicit cm seeds; Python has no `conf_min_base` per-config table — covered indirectly by Optuna calibration of `conf_min_base` |
| **ζ-Field (layered)** | n/a | 0 | 0 | 5 (`zeta_window`, `zeta_w_v`, `zeta_w_j`, `zeta_w_c`, `wt_zeta`) |
| **TOTALS (excl. per-config)** | **59** | **3** | **0** | **12** |

EXACT here means: name/semantic mapped 1:1, Python default == Pine default OR ParamSpec range centred on Pine default within ±5 %.

---

## §2 Input inventory table

Notation: ✓ EXACT · ⚠ DRIFT · ✗ MISSING · ➕ EXTRA. Python defaults are read from engine `_resolve_param(..., default=…)` calls; Python ParamSpec midpoints are read from producer HAND_CODED_BASE.

### G01 — Strategy mode

| Pine | type | default | Python equivalent | status | notes |
|---|---|---|---|---|---|
| `i_execMode` | str | "BACKTEST" | (no peer — execution mode is harness concern) | n/a | benign — non-numeric |
| `i_useHAI` | bool | true | `use_hai` derived from `i_useHAIInBacktest` | ✓ | |
| `i_useHAIInBacktest` | bool | true | `i_useHAIInBacktest` (ParamSpec, choices `[True, False]`) | ➕ | calibratable per 2026-05-15 HAI rule, supersedes CLAUDE.md #7 |
| `i_enableWebhook` | bool | false | (n/a — Python is backtest-only) | n/a | |
| `i_brokerName` | str | "paper" | (n/a) | n/a | |

### G02 — Spread

| Pine | type | default | Python equivalent | status |
|---|---|---|---|---|
| `i_spread` | str | "SPRD_30_UB" | enumerated via `eng.SPREADS` (4 spreads × 4 TFs = 16 configs) | ✓ |
| `long_sym`/`short_sym` mapping | — | per Pine L59-60 | `SPREADS` dict L88-93 | ✓ — symbol pairs match |
| `dv01_wt` per-spread | float | 0.55/0.45/0.25/0.80 | `DEFAULT_DV01_WT` L72-77 | ✓ — defaults identical |

### G03 — Z-engine (Pine globals)

| Pine | type | default | Python ParamSpec | midpoint | status |
|---|---|---|---|---|---|
| `i_z_window` | int | 60 | `z_window` 20–200 | 110 | ⚠ DRIFT (midpoint +83 %); Pine baseline 60 is reachable but search starts wider; CALIB:BEGIN per-config seeds 30–175 also reachable |
| `i_entry_z` | float | 2.0 | `entry_z` 1.0–3.5 | 2.25 | ✓ within 12.5 % of default; Pine per-config defaults span 1.50–2.85 so range is appropriate |
| `i_exit_z` | float | 0.3 | `exit_z` 0.0–1.5 | 0.75 | ⚠ Python upper bound 1.5 exceeds Pine maxval 0.8 — Pine cap not enforced |
| `i_stop_z` | float | 3.5 | `stop_z` 1.8–4.5 | 3.15 | ✓ |
| `i_ts_bars` | int | 24 | `ts_bars` 20–200 | 110 | ⚠ Python upper bound 200 far exceeds Pine maxval 60 |

### G04 — Risk

| Pine | type | default | Python | midpoint | status |
|---|---|---|---|---|---|
| `i_risk_pct` | float | 0.40 | `risk_pct` 0.25–2.5 | 1.375 | ⚠ midpoint +243 % vs Pine default; Pine maxval 2.0, Python 2.5 |
| `i_max_units` | int | 5 | `max_units` 1–8 | 4–5 | ✓ |
| `i_useDailyCap` | bool | true | hard-coded True (no spec) | ✓ | |
| `i_dailyLossCap` | float | 3.0 | `daily_loss_pct` 3.0–15.0 | 9 | ⚠ midpoint 3× Pine default |
| `i_useRollingDD` | bool | true | hard-coded | ✓ | |
| `i_rollingDDPct` | float | 8.0 | `rolling_dd_pct` 3.0–18.0 | 10.5 | ✓ |
| `i_useKillSwitch` | bool | true | hard-coded | ✓ | |
| `i_killDDPct` | float | 15.0 | `kill_dd_pct` 10.0–25.0 | 17.5 | ✓ |

### G04b — DV01 sizing

| Pine | type | default | Python | status |
|---|---|---|---|---|
| `i_useDV01Tight` | bool | true | `use_dv01_tight` hard-coded True | ✓ |
| `i_dv01_target_pct` | float | 0.50 | `dv01_target_pct` 0.10–2.00 | ✓ |
| `i_dv01_short_cap` | float | 0.95 | `dv01_short_cap` 0.50–1.50 | ✓ |
| — | — | — | `dv01_wt_ZF` 0.30–0.85 | ➕ (Pine default 0.55; in 2026-05-15 spec) |
| — | — | — | `dv01_wt_ZN` 0.25–0.75 | ➕ (0.45) |
| — | — | — | `dv01_wt_ZB` 0.10–0.50 | ➕ (0.25) |
| — | — | — | `dv01_wt_UB` 0.50–1.10 | ➕ (0.80) |

### G04c — Slippage filter

| Pine | type | default | Python | status |
|---|---|---|---|---|
| `i_useSlippageModel` | bool | true | hard-coded True | ✓ |
| `i_slip_budget_bps` | float | 4.0 | `slip_budget_bps` 1.0–15.0 | ✓ |
| `i_slip_vol_mult` | float | 0.15 | `slip_vol_mult` 0.0–0.50 | ✓ |

### G04d — Cointegration

| Pine | type | default | Python | status |
|---|---|---|---|---|
| `i_useCointegCheck` | bool | true | hard-coded True | ✓ |
| `i_cointeg_window` | int | 120 | `cointeg_window` 60–400 | ✓ |
| `i_cointeg_max_drift` | float | 0.80 | `cointeg_max_drift` 0.3–2.0 | ✓ |

### G04e — Fed blackout

| Pine | type | default | Python | status |
|---|---|---|---|---|
| `i_useEventBlackout` | bool | true | `use_blackout` hard-coded True | ✓ |
| `i_blackout_minutes` | int | 60 | `blackout_minutes` 15–240 | ✓ |
| `i_blackout_hour_FOMC` | int | 18 | `blackout_hour_fomc` 0–23 | ✓ |
| `i_blackout_hour_CPI` | int | 13 | `blackout_hour_cpi` 0–23 | ✓ |
| `i_blackout_NFP_friday` | bool | true | `blackout_nfp_friday` `[True, False]` | ✓ |

### G04f — Hard stop + cooldown

| Pine | type | default | Python | status |
|---|---|---|---|---|
| `i_useHardStop` | bool | true | hard-coded True | ✓ |
| `i_hardStopPct` | float | 1.5 | `hard_stop_pct` 0.5–4.0 | ✓ |
| `i_useLossCooldown` | bool | true | hard-coded True | ✓ |
| `i_lossCooldownBars` | int | 4 | `loss_cooldown_bars` 0–30 | ✓ |
| `i_stopCooldownMult` | int | 2 | `stop_cooldown_mult` 1–5 | ✓ |

### G05 — HAI + sentiment

| Pine | type | default | Python | status |
|---|---|---|---|---|
| `i_haiMinScore` | float | 0.55 | `i_mlMinScore` via `pp.hai_calibration_space` | ✓ |
| `i_mlPrediction` | float | 0.5 | `ml_prediction` runtime injection | ✓ |
| `i_sentimentScore` | float | 0.0 | `sentiment_score` | ✓ |
| `i_useSentimentGate` | bool | true | `use_sentiment` hard-coded True | ✓ |
| `i_finbert_block` | float | −0.70 | `hai_sentiment_threshold` via hai_calibration_space | ✓ |
| `i_curveRegime` | str | "AUTO" | hard-coded AUTO | ✓ |
| `i_useRegimeGate` | bool | true | `use_curve_regime` via `hai_regime_enforce` (choices) | ✓ |
| `i_regimeLookback` | int | 60 | `regime_lookback` 20–300 | ✓ |

### G05b — Λ-Vol

| Pine | type | default | Python | status |
|---|---|---|---|---|
| `i_useLambdaVol` | bool | true | `use_lvol` hard-coded True | ✓ |
| `i_lvol_window` | int | 40 | `lvol_window` 20–200 | ✓ |
| `i_lvol_calm_thresh` | float | 0.40 | `lvol_calm_thresh` 0.20–0.80 | ✓ |
| `i_lvol_high_thresh` | float | 1.80 | `lvol_high_thresh` 1.40–3.00 | ✓ |
| `i_lvol_trend_thresh` | float | 1.30 | `lvol_trend_thresh` 1.10–2.00 | ✓ |
| `i_lvol_block_stress` | bool | true | `lvol_block_stress` choices | ✓ |

### G06 — Confluence weights + gate

| Pine | type | default | Python | status |
|---|---|---|---|---|
| `i_useConfluence` | bool | true | `use_confluence` hard-coded | ✓ |
| `i_confMinGlobal` | int | 75 | `conf_min_base` 50–95 | ✓ |
| `i_wt_zscore` | float | 0.30 | `wt_zscore` 0.10–0.60 | ✓ |
| `i_wt_hai` | float | 0.20 | `wt_hai` 0.05–0.40 | ✓ |
| `i_wt_regime` | float | 0.15 | `wt_regime` 0.05–0.30 | ✓ |
| `i_wt_cointeg` | float | 0.15 | `wt_cointeg` 0.05–0.30 | ✓ |
| `i_wt_slippage` | float | 0.10 | `wt_slippage` 0.02–0.25 | ✓ |
| `i_wt_lvol` | float | 0.10 | `wt_lvol` 0.05–0.30 | ✓ |
| — | — | — | `wt_zeta` 0.02–0.30 | ➕ layered (2026-05-15 ζ-Field rule) |
| `i_dirAdj_long` | float | 1.00 | `dir_adj_long` 0.70–1.30 | ✓ |
| `i_dirAdj_short` | float | 1.05 | `dir_adj_short` 0.70–1.30 | ✓ |

### G07 — Regime router

| Pine | type | default | Python | status |
|---|---|---|---|---|
| `i_useRegimeRouter` | bool | true | `use_router` hard-coded | ✓ |
| `i_modeOverride` | str | "AUTO" | `mode_override` "AUTO" | ✓ |
| `i_mode_over_ez` | float | 1.20 | `mode_over_ez` 1.00–1.50 | ✓ |
| `i_mode_over_xz` | float | 1.30 | `mode_over_xz` 1.00–2.00 | ✓ |
| `i_mode_over_sz` | float | 1.15 | `mode_over_sz` 1.00–1.40 | ✓ |
| `i_mode_over_ts` | float | 1.40 | `mode_over_ts` 1.00–2.00 | ✓ |
| `i_mode_tight_ez` | float | 0.85 | `mode_tight_ez` 0.60–1.00 | ✓ |
| `i_mode_tight_xz` | float | 0.75 | `mode_tight_xz` 0.50–1.00 | ✓ |
| `i_mode_tight_sz` | float | 0.90 | `mode_tight_sz` 0.70–1.10 | ✓ |
| `i_mode_tight_ts` | float | 0.70 | `mode_tight_ts` 0.50–1.00 | ✓ |
| `i_mode_def_tsmult` | float | 0.50 | `mode_def_tsmult` 0.30–0.80 | ✓ |

### G08 — 5-leg adaptive exit

| Pine | type | default | Python | status |
|---|---|---|---|---|
| `i_use5Leg` | bool | true | `use_5leg` hard-coded True | ✓ |
| `i_leg1_pct..i_leg5_pct` | float | 30/25/20/15/10 | `leg_alloc_p1..p5` matching ranges | ✓ defaults identical |
| `i_leg1_frac..i_leg4_frac` | float | 0.30/0.55/0.80/1.00 | `leg1_frac..leg4_frac` matching ranges | ✓ |
| `i_leg5_runner_z` | float | 0.30 | `leg5_runner_z` 0.10–0.80 | ✓ |
| `i_useBE` | bool | true | `use_be` hard-coded True | ✓ |
| `i_useRatchet` | bool | true | `use_ratchet` hard-coded True | ✓ |
| `i_ratchet_frac` | float | 0.50 | `ratchet_frac` 0.20–0.80 | ✓ |

### G10 — Per-config CALIB:BEGIN (16 configs × 8 fields)

The 4 spreads × 4 TFs Pine warm-start table (entry_z / exit_z / stop_z / ts_bars / z_win / risk_pct / max_u / confMin) is **not** mirrored as discrete Python knobs. Python relies on Optuna per-config search over the same names within the producer's ParamSpec ranges plus `matrix_coverage.build_param_space` overrides keyed by `S2`. This is the correct architecture — but it means **per-config Pine seeds are not used as warm-starts** when `_load_warmstart` finds no prior RX results. Recommend feeding Pine CALIB:BEGIN values into `warm_start_loader` for trial-0 boost.

### Layered enhancements (NOT in Pine — must remain)

| Python | type | range | source |
|---|---|---|---|
| `zeta_window` | int | from `pp.zeta_calibration_space` | 2026-05-15 ζ-Field rule |
| `zeta_w_v` | float | 〃 | 〃 |
| `zeta_w_j` | float | 〃 | 〃 |
| `zeta_w_c` | float | 〃 | 〃 |
| `wt_zeta` | float | 0.02–0.30 (HAND_CODED_BASE) | 〃 |
| `i_useHAIInBacktest` | bool | calibratable choice | HAI Option B tandem |
| `pre_hai_trial_pct` | float | 0.30 (cfg) | HAI Option B Phase-1/2 split |
| `gate_profile="SPRD_MR"` | str | producer cfg | single-engine MR gate (locked 2026-05-15) |

---

## §3 Formula parity notes (12 spot-checks)

1. **Spread construction** (Pine L59-61, L526; Python L141-152) — long − dv01_wt × short. ✓ EXACT. DV01 weights match (0.55/0.45/0.25/0.80) and Python adds them as calibratable ParamSpecs without breaking the Pine path.
2. **z-score window + std** (Pine L527-529, ta.sma/ta.stdev; Python L162-164, pandas rolling). ✓ EXACT; both use SMA mean + sample std. Python uses `pd.rolling().std()` which is ddof=1 by default; Pine `ta.stdev` is also ddof=1 — match.
3. **6-component confluence aggregation** (Pine L711-714; Python `_confluence` L268-301). ✓ EXACT on 6 components. Python adds a 7th `wt_zeta` component INSIDE the same weighted-sum / wt_norm formula, so the original 6 remain byte-equivalent when `wt_zeta=0`. ⚠ Behavioral note: when ζ-Field weight is non-zero, confluence numbers diverge from Pine — this is intentional under the 2026-05-15 rule but must be flagged in TV parity comparisons.
4. **Λ-Vol classifier** (Pine L546-556; Python `_classify_lvol` L171-204). ✓ EXACT — priority order STRESS_HIGH → TREND_ACTIVE → TREND_CALM → TRANSITION → MEAN_REVERT, threshold defaults all match (0.40 / 1.30 / 1.80 / 0.8 drift / 0.3 drift / 1.10 transition lower).
5. **5-leg z-target geometry** (Pine `f_compute_leg_targets` L792-803; Python L734-744). ✓ EXACT — `ez_signed + sign*span_to_exit*leg_k_frac` for legs 1-3, `span_to_exit + xz_abs` for leg 4, runner at `±leg5_runner_z`. Allocations 30/25/20/15/10 default match.
6. **Regime router** (Pine L669-693; Python `_select_mode` L307-319). ✓ EXACT — STRESS_HIGH OR unhealthy coint → MR_DEFENSIVE; TREND_ACTIVE → MR_OVERSHOOT; TREND_CALM + healthy → MR_TIGHT; else MR_NORMAL.
7. **Sub-mode router (S6 has these labels; S2 uses MR_NORMAL/OVERSHOOT/TIGHT/DEFENSIVE — S2's are correct).** ✓
8. **FLIP semantics** — not applicable to S2 (whitepaper §3.1: "TRND on a spread is anti-edge"). Python correctly does not implement FLIP. ✓
9. **BE + ratchet** (Pine L944-959; Python L842-852). ✓ EXACT — BE arms after L1 fires (`stop_spread := entry_spread`); ratchet after L2 toward mean at `(1 - ratchet_frac)` of the gap (Pine 50 %, Python 50 %).
10. **Fed event blackout** (Pine L606-624; Python `_event_blackout_mask` L241-262). ✓ EXACT semantics — FOMC ±60min at 18 UTC, CPI ±60min at 13 UTC, NFP first-Friday using CPI hour. Both treat blackout as an entry filter only (existing positions continue). ⚠ Pine uses minute-resolution `hour(time, "UTC") * 60 + minute(time, "UTC")`; Python uses `dt.hour * 60 + dt.minute`. Same. **Audit fully aligns with whitepaper §5.3.**
11. **DV01-tight sizing** (Pine `f_dv01_tight_units` L783-787; Python L700-704). ✓ EXACT — `min(risk_target, hard_cap) / stop_dist_dollars`, with `risk_target = equity × dv01_target_pct / 100` and `hard_cap = equity × hardStopPct / 100`. Short-leg uses `n_short = round(n_long × dv01_wt × dv01_short_cap)` (Pine L828, Python L556).
12. **Slippage filter** (Pine L626-642; Python L506-512). ✓ EXACT — `ba_proxy = (high - low) / close * 10000` and `est_slip = ba_proxy + spread_vol_pct * slip_vol_mult` with budget gate.

**Net**: all 12 formulas align. The only behavioral divergence is the additive 7th confluence component (`wt_zeta`), and it's intentional and locked by the 2026-05-15 standing rule.

---

## §4 Defaults drift report

Drift = |Python midpoint − Pine default| / Pine default × 100 %. Flagged when > 5 %.

| Param | Pine default | Python ParamSpec | midpoint | drift % | severity |
|---|---:|---|---:|---:|---|
| `z_window` | 60 | 20–200 | 110 | +83 % | HIGH — Pine maxval 300 but per-config seeds 30–175 |
| `exit_z` | 0.30 | 0.0–1.5 | 0.75 | +150 % | HIGH — Pine maxval 0.80, Python upper bound 1.5 exceeds |
| `ts_bars` | 24 | 20–200 | 110 | +358 % | HIGH — Pine maxval 60, Python upper bound 200 far exceeds |
| `risk_pct` | 0.40 | 0.25–2.5 | 1.375 | +243 % | HIGH — Pine maxval 2.0, Python upper bound 2.5 exceeds |
| `daily_loss_pct` | 3.0 | 3.0–15.0 | 9 | +200 % | MEDIUM — could over-allocate daily loss budget |
| `entry_z` | 2.0 | 1.0–3.5 | 2.25 | +12.5 % | LOW |
| `stop_z` | 3.5 | 1.8–4.5 | 3.15 | −10 % | LOW |
| `risk_pct` upper | 2.0 | 2.5 | — | bound | LOW |

All others within ±5 %.

The 4 HIGH-severity drifts are not random — they're **legitimate widenings** of the search space relative to the Pine warm-start defaults: per-config Pine CALIB:BEGIN values span `z_win=30..175`, `ts_bars=15..60`, `risk_pct=0.40..1.50`, `exit_z=0.05..0.80`. Python ranges are wider to permit Optuna to discover non-warm-start optima, which is correct under whitepaper §7.2 ("TPE with 600–800 trials warm-started from RX06-FINAL"). However the Python upper bounds for `ts_bars` (200) and `exit_z` (1.5) **exceed Pine's enforced maxvals** (60, 0.8). This will not produce a TV crash (Pine's maxval is a chart-UI clamp, not a runtime gate), but it can produce Optuna-best trials whose values are **un-loadable in TradingView** — a deployment blocker. See §6 PROPOSED EDITS.

---

## §5 FX-RX tag coverage report

Pine declares `// Fix tag format: FX-RX07-[SPREAD]-[TF]-[LEVEL]-[SEQ]` at L247. A scan of the Pine file for `FX-RX07-` shows the format is **declared but currently empty** — no surgical fixes have been applied in the CALIB:BEGIN block. This is expected because Pine RX07 is itself a fresh layer-in of the four PRISM patterns onto RX06; FX-RX07 tags would appear in the next surgical fix cycle. Python producer's `CYCLE = "RX10"` and no FX-RX10 surgical tags exist in either file.

**Coverage: 0/0 — trivially satisfied.** When RX08 surgical patches appear in Pine they will need corresponding Python tags.

---

## §6 PROPOSED EDITS (prioritized)

### P1 — calibration correctness (would change Optuna outputs)

1. **Cap `ts_bars` upper bound at 60** in `parity_s2bonds_rx10_aegis.py:103` to honor Pine `minval=8, maxval=60`. Current Python `ts_bars 20–200, is_integer=True` can produce values un-loadable in TV. Change to `gp_search.ParamSpec("ts_bars", 8, 60, is_integer=True)`.
2. **Cap `exit_z` upper bound at 0.8** in `parity_s2bonds_rx10_aegis.py:101`. Pine `minval=0.0, maxval=0.8`. Change to `gp_search.ParamSpec("exit_z", 0.0, 0.8)`.
3. **Cap `risk_pct` upper bound at 2.0** in `parity_s2bonds_rx10_aegis.py:105` (Pine maxval 2.0). Change to `gp_search.ParamSpec("risk_pct", 0.10, 2.0)` and align lower bound to Pine minval 0.10.
4. **Reduce `z_window` upper bound to 200** — already correct (Python 20–200, Pine maxval 300). Pine per-config seeds top out at 175 so 200 is appropriate.
5. **Reduce `daily_loss_pct` upper bound to 10.0** to match Pine maxval. Currently 3.0–15.0; change to 0.5–10.0.

### P2 — formula / behavioral

6. **Wire Pine CALIB:BEGIN per-config warm-starts into `_load_warmstart`** so trial 0 of each (spread, tf) uses Pine's hand-tuned defaults rather than uninitialized GP-BO. The 16-row table in Pine L253-398 covers: entry_z / exit_z / stop_z / ts_bars / z_win / risk_pct / max_u / confMin per (spread, tf). When no `s2_bonds_rx10_results_final.json` exists, fall through to a dict built from Pine. Concrete: replace the bare `[]` return at parity_s2bonds_rx10_aegis.py:63 with a Pine-derived seed for the matching (spread, tf) tuple.
7. **Curve regime threshold** Pine L583 uses `> 1.0` / `< -1.0` for BULL_STEEPENER / BEAR_FLATTENER — Python `_classify_curve_regime` L227-234 also uses 1.0 / −1.0. ✓ already aligned; no edit needed.

### P3 — naming / cosmetic

8. **Rename `i_mlMinScore` ↔ `i_haiMinScore`** alignment: Python producer uses `i_mlMinScore` while Pine input is `i_haiMinScore`. The engine consumes `i_mlMinScore` (see q7_s2bonds_5leg_engine.py:385). Either rename Python to `hai_min_score` or document the alias explicitly inside `pp.hai_calibration_space`. Cosmetic, but it will save UI Integration churn when wiring config UIs.
9. **Document `wt_zeta` extension** in Pine — add a comment under G06 noting the 7th confluence component now exists Python-side. No Pine code change required.
10. **Add an FX-RX10 tag block** to Pine CALIB:BEGIN with a single placeholder fix tag declaring the 2026-05-15 layered enhancements (ζ-Field, HAI Option B). Pure documentation aid.

---

## §7 Verdict

S2 RX07 Pine ↔ Python RX10 parity is **HIGH**. All 12 spot-check formulas align. Λ-Vol classifier, regime router, confluence aggregation (on the 6 original components), 5-leg geometry, BE/ratchet, Fed blackout, DV01 sizing, and slippage filter all match Pine exactly. The three layered enhancements (HAI Option B, ζ-Field 7th component, MDD floor at −100 %) are additive and gated by their own switches. The five HIGH-severity range drifts above are **all in the upper-bound direction** of search space and can be reproduced in TV only if Optuna picks a value above Pine's maxval, which is a deployment-time blocker — fix by clamping ParamSpec upper bounds as listed in P1.
