v2.2.1 — Security Hardening & Bug Fixes
Bug Fixes
Weekly-zero exhausted display (High)
When an account's weekly limit reaches 0%, it was incorrectly shown as Safe if the 5-hour window still showed 100%. The weekly budget gates the 5-hour budget — no requests can succeed once weekly is exhausted. Both the risk label and the health dot now correctly show Exhausted / red in this state.
Auth permission hardening (Medium)
The re-login flow (reloginAuthChanged) was not applying 0o600 permissions to the updated profile auth file, leaving it potentially world-readable under a permissive umask. Now consistent with captureCurrentAuth and activate.
Seamless verification flow restored (High)
attemptSeamlessSwitch was unconditionally restarting Codex after every account switch, contradicting the "restart-free by default, restart fallback" design and making the .verifying state machine unreachable. The flow now enters the verifying state and only restarts Codex if a rate-limit signal is detected within 45 seconds — matching the original intent.
Auth watcher first-run safety (Medium)
watchAuthFileForNewLogin silently dropped the file watcher on machines where ~/.codex/auth.json didn't exist yet (open(O_EVTONLY) returns -1). Now creates the parent directory and an empty placeholder file before opening so the watcher always attaches on first run.
Switch history attribution (Medium)
A failed switch attempt could write a history entry before knowing whether activation succeeded, corrupting analytics attribution. History is now only written from finalizeActivation after verification passes.
Tests
- 10 new unit tests for
ProfileManagerJWT claim extraction - 6 new unit tests for
RateLimitForecastercovering the weekly-zero gate and surrounding cases