fix(mobile): stop unrenewed-grace rotation churn and close gate cadence gaps - #12426
Conversation
- skip proactive rotation when the resume confirmation reports renewed=false (a re-resume provably returns the same unchanged deadline; rotating churned one session replacement per clamp floor, ~60/hour, until a fresh credential) - armCredentialReprobe under a held gate mints the tick's pass token so the effective reprobe cadence stays 60s..15min instead of doubling to ~30min - registerFailure honors scheduleRetry=false in gate branches: no reprobe timer is armed while backgrounded/stopped; foreground resume re-arms - extract RelayRetryDelays and supervisor test fakes into their own modules (max-lines)
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: Repository UI Review profile: CHILL Plan: Pro Plus Run ID: 📒 Files selected for processing (6)
📝 WalkthroughWalkthroughThe change centralizes relay retry-delay calculations in 🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✨ Finishing Touches📝 Generate docstrings
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
|
Merging on green CI + red-before/green-after tests + a line-by-line self-review of the final diff. Note for the record: an external adversarial review pass was spawned but did not return; the three behavior changes here implement remedies that were themselves specified during PR #12374's review rounds (grace-path rotation skip, gate-token minting, scheduleRetry honoring), so the design has had adversarial eyes even though this diff has not. |
Follow-ups documented on #12374 (all three were review-round residuals deliberately left out of the incident PR so the phone-verified binary matched the merge commit):
Unrenewed-grace rotation churn. When the cell answers a resume with
renewed: false(return-unchanged-grace), the returned deadline never advances, so the phone force-rotated once per clamp floor — ~60 session replacements/hour, each killing any in-flight RPC — until a fresh credential arrived. A re-resume with the same grace credential provably returns the same decision, so rotation is now skipped entirely whenconfirmation?.renewed === false. Fresh credentials still arrive via direct rotation or durable bundle reads, exactly as before.Gate cadence doubling under external-signal gates. An E2EE (
external-signal) gate never records rejected credential versions, soarmCredentialReprobewith no dialable bundle took the plain-cooldown branch and its tick carried no gate pass token — every second wakeup bounced offshouldDefer, settling the effective attempt interval at ~30min instead of the intended 15min ceiling. Under a held gate the reprobe now mints the token.Gate timers armed against
scheduleRetry=false.registerFailure's gate branches armed a reprobe tick even when the supervisor was backgrounded/stopped. Measured-benign but wrong lifecycle; the gate branches now honorscheduleRetry, and a test proves foreground resume restores the cadence (no permanent stall).Also extracts
RelayRetryDelays(all jittered retry delay policy) and the supervisor test fakes into their own modules to satisfy max-lines without weakening the cap.Tests
Three new red-before/green-after tests (verified failing on pre-fix sources):
skips forced rotation for a session resumed without renewal(red: 2nd dial at the 60s clamp floor)mints the gate pass when arming a no-bundle reprobe under a held gate(red:shouldDefertrue after the 120s tick)does not arm a gate reprobe timer when the supervisor declined retries(red: timer armed after each gated failure)Full mobile suite: 2969 passed (1 pre-existing unrelated local failure: missing
mermaid-webview-engine.generatedcodegen artifact).