Root cause of unlock track stuck at days=0: a transient refresh wrote unlock_calendar.json=[] and the 7-day cache froze it empty (no cliffs -> no positions -> no booked days), while real cliffs (Wormhole T-5, EIGEN, SUI) existed. Fix: _refresh_calendar keeps last-known-good / stays stale on empty instead of caching []; unlock_nav now deps=[crypto_bars] so tradeable is never empty at run time. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>