Skip to content

Vesper Delivery — fix/flag-051-regime-drift

What This Fixes

S53 entered ANCHOR_IDLE at tick ~5 and never exited. Root cause: the EMA baseline persisted from prior sessions (S49/S50/S52) where structural was +10 bps cap-locked. S53 opened with structural at −5 bps. Residual = −5 − (+10) = −15 bps, which exceeds the 7.0 bps ANCHOR_IDLE entry threshold. The engine correctly fired ANCHOR_IDLE, but had no way to exit because the residual stayed large until the 150-tick EMA caught up — which would take ~10+ minutes in a 30-minute session, and during warmup (first 50 ticks) it was using the legacy window where abs(−5.08) > 4.0 bps exit threshold anyway.

The time-based staleness check (24h) didn't help because S52 ended within minutes of S53 starting.

The Fix

One new field in AnchorDualSignalConfig: baseline_regime_drift_threshold_bps (default 10.0 bps).

One new flag in AnchorDualSignalCalculator: _pending_regime_drift_check, set on seed_baseline(), cleared and evaluated on the first call to observe() after a persistence restore.

Logic: On the first structural observation after loading a persisted baseline, if abs(structural − persisted_baseline) > threshold, the baseline is discarded and warm-up restarts from the current structural value. Normal cross-session resume if drift is within threshold.

At 10.0 bps threshold: - S52→S53 scenario (structural −5, persisted baseline ~+10, drift ~15): triggers cold start ✓ - Normal inter-session jitter (structural +4, persisted +2, drift ~2): baseline preserved ✓ - Legitimate regime shift of 10+ bps: cold start (correct — EMA would be wrong) ✓

Effect in S54 (Next Session)

Session starts. Persisted EMA from prior sessions ~+8–10 bps. First structural at −5 bps (drift ~13–15 bps > 10.0 threshold).

[ANCHOR_DS] FLAG-051 — regime drift on first post-seed tick; discarding persisted baseline and cold-starting warm-up

Calculator cold-starts at −5 bps. After 50 ticks (~3 min): - EMA baseline ≈ −5 bps (tracking structural) - Residual ≈ 0 bps - Legacy window also shows −5 bps → abs(−5) < 7.0 → anchor entry guard does NOT fire - Engine stays in MODE_OK and quotes normally

If structural is −5 bps, the engine quotes. If structural spikes to −9 bps (abs > 7.0 + 40% prevalence > 5 bps), the anchor guard fires correctly. This is correct behavior.

Files Changed

File Change
neo_engine/config.py Add baseline_regime_drift_threshold_bps: float = 10.0 to AnchorDualSignalConfig, parse in load_config, validate in _validate_anchor_dual_signal
neo_engine/dual_signal_calculator.py Add _pending_regime_drift_check flag to __init__ and seed_baseline; add drift check to top of observe(); clear flag in reset()
config/config_live_stage1.yaml Add baseline_regime_drift_threshold_bps: 10.0 to anchor_dual_signal block
tests/test_flag_051_regime_drift.py 11 new tests (all passing)

Test Coverage (11 tests, all passing)

Test Confirms
test_large_drift_discards_persisted_baseline 15 bps drift > 10 threshold → cold start
test_cold_start_after_drift_warms_up_correctly Post-cold-start warm-up is normal
test_drift_check_clears_pending_flag Check fires exactly once
test_no_cold_start_if_no_seed No seed = no check (cold start from scratch unaffected)
test_small_drift_preserves_baseline 2 bps drift < 10 → baseline preserved
test_drift_exactly_at_threshold_does_not_trigger Strictly-greater-than boundary
test_drift_one_bps_above_threshold_triggers Boundary epsilon
test_none_threshold_preserves_baseline_regardless_of_drift None disables check
test_reset_after_seed_clears_drift_check reset() clears pending flag
test_zero_threshold_raises_config_error Config validation
test_none_threshold_passes_validation Config validation

S53 scenario regression (T11): Seed at +10 bps (500 samples), first observe at −5 bps → cold start → 3 ticks → warm, residual = 0.0000 bps. ✓

Apply Instructions (PowerShell)

Important: the working tree in the Linux sandbox has SMB corruption. Run git status first on your machine to confirm the working tree is clean.

cd "C:\Users\Katja\Documents\NEO GitHub\neo-2026"

# Confirm working tree is clean
git status

# Create branch
git checkout main
git pull
git branch -D fix/flag-051-regime-drift 2>$null
git checkout -b fix/flag-051-regime-drift

# Copy the 3 source files from workspace into repo
Copy-Item "C:\Users\Katja\Documents\Claude Homebase Neo\02 Projects\NEO Trading Engine\03 Branches\fix-flag-051-regime-drift\files\config.py" neo_engine\config.py
Copy-Item "C:\Users\Katja\Documents\Claude Homebase Neo\02 Projects\NEO Trading Engine\03 Branches\fix-flag-051-regime-drift\files\dual_signal_calculator.py" neo_engine\dual_signal_calculator.py
Copy-Item "C:\Users\Katja\Documents\Claude Homebase Neo\02 Projects\NEO Trading Engine\03 Branches\fix-flag-051-regime-drift\files\config_live_stage1.yaml" config\config_live_stage1.yaml
Copy-Item "C:\Users\Katja\Documents\Claude Homebase Neo\02 Projects\NEO Trading Engine\03 Branches\fix-flag-051-regime-drift\files\test_flag_051_regime_drift.py" tests\test_flag_051_regime_drift.py

# Verify, run tests, then commit
git diff --stat
pytest tests/test_flag_051_regime_drift.py -v

Expected: 11 passed.

Then commit:

git add neo_engine/config.py neo_engine/dual_signal_calculator.py config/config_live_stage1.yaml tests/test_flag_051_regime_drift.py
git commit -m "fix(calc,config): FLAG-051 — regime-drift cold-start check for persisted EMA baseline

On the first structural observation after a cross-session EMA restore,
if abs(structural - persisted_baseline) > baseline_regime_drift_threshold_bps
(default 10.0 bps), the persisted baseline is discarded and warm-up
restarts from the current structural value.

Fixes S53 lockout: EMA persisted from +10 bps cap-locked sessions
produced residual of -15 bps on session open with structural at -5 bps,
triggering ANCHOR_IDLE immediately with no viable exit path.

After this fix: S54 opens, drift check fires, cold start from -5 bps,
50-tick warmup completes, residual near 0 bps, engine quotes normally."

git log --oneline main..HEAD
git push origin fix/flag-051-regime-drift

Then merge:

git checkout main
git merge --ff-only fix/flag-051-regime-drift
git push origin main
git branch -d fix/flag-051-regime-drift

Post-Merge: Run Adjacent Suite

pytest tests/test_flag_051_regime_drift.py tests/test_anchor_dual_signal.py tests/test_anchor_idle_state.py tests/test_anchor_saturation_guard.py -v

— Vesper 2026-04-22