Vesper Review — feat/flag-044-recovery-cooldown¶
Verdict: APPROVED — ready to merge
Spec Compliance¶
All Atlas constraints from the 2026-04-21 ruling are met:
- Cool-down armed on re-entry only — first DEGRADED episode can recover immediately (no cool-down), matching FLAG-042 first-episode semantics. Only a second entry from the same source within the same session arms the countdown. ✅
- Episode cap
>=semantics — Nth entry halts. Third entry from the same source in one session →degraded_episode_limit_halt. ✅ - Per-source independence — anchor episode count never affects drift or corridor, and vice versa. Tested explicitly in
test_episode_cap_is_per_source. ✅ - DEGRADED is the only state during cool-down — no quoting, no order placement, truth checks continue. The suppression in Step 8.4 is a genuine no-op for the recovery evaluator. ✅
- Wallet-truth / reconciler explicitly excluded from
RECOVERY_CAPPED_SOURCES— uncapped path preserved exactly as FLAG-042 left it. ✅ - Startup reset extended — both
cooldown_ticks_remainingandepisode_countcleared to "0" on fresh session start. ✅ - DEGRADED semantics, hysteresis, stability windows, drift condition C exclusion — all untouched. ✅
recovery_enabled=Falsegate — still short-circuits before the cool-down path. Backward compatibility confirmed. ✅
Deviations¶
Deviation 1 — Countdown vs. absolute-tick storage¶
cooldown_ticks_remaining (countdown) instead of cooldown_until_tick (absolute). Accepted. I ruled Option B mid-implementation. The "not sliding" invariant is tested (test_cooldown_not_extended_while_degraded_persists). Decrement-then-check semantics mean armed-to-120 gives 119 suppressed ticks then the 120th proceeds — intentional, documented, tested in Parts D and E.
Deviation 2 — 4 commits vs. 5 planned¶
C2 folded the taxonomy removal and episode-count addition. Both touch the same taxonomy block and entry-side escalation site in _enter_degraded_mode. Splitting would have produced a temporarily incoherent intermediate state. Accepted — sound engineering judgment, not a spec deviation.
Test Coverage¶
26 new tests in tests/test_flag_044_recovery_cooldown.py, all required cases covered:
| Required test | Where covered |
|---|---|
| Cool-down activation | Part C — re-entry arms cooldown |
| Cool-down suppression during active cooldown | Part D |
| Cool-down expiry (re-enables evaluator) | Part D — tick that reads 0 proceeds |
| Successful recovery after cool-down | Part E end-to-end lifecycle |
| Episode cap triggers HALT | Part C + Part E (3rd entry) |
| Episode cap is per-source | Part C test_episode_cap_is_per_source |
| Startup reset | Part B / Part C |
| Cool-down timer not sliding | test_cooldown_not_extended_while_degraded_persists |
18 additional tests across Parts A/B/D (fail-safe I/O, counter helpers, per-source suppression) add meaningful coverage beyond the minimum.
Test delta +37/−11 explained: +26 new FLAG-044 tests + +11 FLAG-042 tests unblocked by the C4 mock-stub refresh (_decrement_recovery_cooldown auto-stubbed as MagicMock(return_value=0) on the three helper fixtures). Net improvement. Zero regressions.
Apply Instructions — Confirmed¶
Apply instructions are correct. Run in Katja's VS Code terminal:
cd C:\Users\Katja\Documents\NEO GitHub\neo-2026
git checkout main
git pull
git branch -D feat/flag-044-recovery-cooldown 2>$null
git checkout -b feat/flag-044-recovery-cooldown
Get-ChildItem "C:\Users\Katja\Documents\Claude Homebase Neo\02 Projects\NEO Trading Engine\08 Patches\patches-flag-044-recovery-cooldown" -Filter "*.patch" |
Sort-Object Name |
ForEach-Object { git am $_.FullName }
# Verify — expect 4 commits
git log --oneline main..HEAD
# Test — expect 42 passed + 2 subtests
python -m pytest tests/test_flag_044_recovery_cooldown.py tests/test_flag_042_degraded_recovery.py -q
# Merge
git checkout main
git merge --no-ff feat/flag-044-recovery-cooldown
git push
git branch -D feat/flag-044-recovery-cooldown 2>$null
Expected commit log (topmost 4):
c926cb7 test(recovery): FLAG-044 C4 — 26 tests for cool-down + session cap
f0a6d79 feat(main_loop): FLAG-044 C3 — cool-down suppression at Step 8.4
b557f23 feat(engine): FLAG-044 C2 — cool-down taxonomy, state keys, entry-side logic
4e6d681 feat(config): FLAG-044 C1 — cool-down + session episode cap (Atlas 2026-04-21)
Prerequisite: FLAG-042 (9639b18) must be on main. Per CLAUDE.md it merged Apr 21 — confirmed.
Post-Merge¶
Once merged:
- Run pre-session realignment as usual: python tools/realign_inventory_to_onchain.py --config config/config_live_stage1.yaml --db neo_live_stage1.db --dry-run then --confirm
- Use --duration-seconds 7200 (2-hour sessions) per Atlas's ruling — the cool-down needs room to work
- S46 is the first live test of the new model
— Vesper