Release v0.51.541 — Release SZ (model picker recovers a stale disk cache on catalog timeout)
Ships #4555 (starship-s) with maintainer hardening applied from the ship-gate. Cherry-picked with author attribution preserved.
Fixed
- The model picker now falls back to a stale disk cache instead of a thin "Default" group when the live catalog rebuild times out (#3928 follow-up). The strict cache loader rejects
models_cache.jsonwhen its metadata/fingerprint stamps are out of date, which previously forced the over-budget rebuild path all the way back to the minimal static catalog — losing the user's real provider/model groups whenever a rebuild ran long with only a stale cache on disk. A new shape-validated loader reads that stale payload (read before acquiring the cache lock, so it doesn't extend the lock hold) and serves it as the over-budget fallback. Strict cold-path cache hits and the static fallback for a truly empty cache are unchanged. Thanks @starship-s.
Hardening applied at ship-gate (Codex + Opus)
- Schema guard: the stale loader rejects a cross-schema cache (
_schema_versionmismatch) so an incompatible groups/badge shape can't reach the picker. /api/modelsaliases contract preserved: the disk save path never persistedaliases, so BOTH disk loaders (strict cold-path AND the new stale fallback) were dropping them — silently breaking/model <alias>slash-command resolution on any disk-cache hit. A shared_model_aliases_from_config()helper now reconstructs aliases from current config in both loaders (preserving a present dict, reconstructing only when absent). This also fixes a pre-existing gap in the strict loader.- Test hermeticity: the autouse fixture isolates the cache path so the static-fallback test can't read a real
models_cache.jsonand become an order-dependent flake.
Gate
- Full pytest suite: 9746 passed, 0 failed
- Codex regression gate: SAFE TO SHIP
- Opus advisor: SAFE — SHIP (alias reconstruction symmetric in both loaders, no cross-profile leak, schema guard sound)
Closes #3928.