fix(keyring): cache availability probe with OnceLock to prevent repeated keychain dialogs#2651
fix(keyring): cache availability probe with OnceLock to prevent repeated keychain dialogs#2651M3gA-Mind wants to merge 3 commits into
Conversation
…ted keychain dialogs AuthProfilesStore::new() is called on every CoreStateProvider poll (every 2s), which triggered the keyring availability probe repeatedly. On macOS this caused the system keychain access dialog to appear in a loop, blocking users on the loading screen. Probe result is now cached in a process-lifetime OnceLock<bool> so macOS only shows the permission dialog once per app launch.
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: Organization UI Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (1)
📝 WalkthroughWalkthroughSimplify BootCheckGate's success handling, add a Tauri-specific core-mode fallback in OAuth readiness, move auth-profile loading into a blocking task, and make the keyring availability probe idempotent by caching results and deleting stale probe keys; add regression tests for probe idempotence. ChangesOAuth Initialization Flow
Keyring Availability Probe Idempotence
Estimated code review effort🎯 4 (Complex) | ⏱️ ~45 minutes Possibly related PRs
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. Warning There were issues while running some tools. Please review the errors and either fix the tool's configuration or disable the tool if it's a critical failure. 🔧 ESLint
ESLint skipped: no ESLint configuration detected in root package.json. To enable, add Comment |
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@src/openhuman/keyring/tests.rs`:
- Around line 514-532: The test is meant to validate repeated calls but only
invokes super::ops::is_available() once; update the test function
is_available_returns_true_on_repeated_calls_os_backend to call
super::ops::is_available() twice (or more) after seeding the OS keyring via
backend::OsBackend and probe_key, asserting true on each call to exercise the
cached/second-call path.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
Run ID: 27ec4a5e-9f0c-4d98-a329-16749c6f2d4a
📒 Files selected for processing (6)
app/src/components/BootCheckGate/BootCheckGate.tsxapp/src/components/oauth/oauthAuthReadiness.tssrc/openhuman/app_state/ops.rssrc/openhuman/keyring/mod.rssrc/openhuman/keyring/ops.rssrc/openhuman/keyring/tests.rs
CodeRabbit flagged that the repeated-calls test only invoked is_available() once, leaving the OnceLock cache path untested. Add a second assertion.
…_mode_unset scenario storeCoreMode was missing from the vi.mock factory, causing vitest to throw on the Tauri branch. The core_mode_unset test also needed isTauri=false: in Tauri mode the function defaults to 'local' and never returns that reason.
Summary
AuthProfilesStore::new()is called on everyCoreStateProviderpoll (~every 2s), which triggered the OS keyring availability probe on each callstatic AVAILABILITY_CACHE: OnceLock<bool>; the macOS keychain dialog appears at most once per app launchprobe_availability()fn;is_available()callsget_or_init— semantics unchanged, cost reduced from O(poll rate) to O(1)Problem
is_available()was called on every snapshot poll; each call attempted a keychain write/read/delete cycle which triggered the system dialogSolution
static AVAILABILITY_CACHE: OnceLock<bool>at module scope insrc/openhuman/keyring/ops.rsis_available()now delegates toget_or_init(probe_availability)— the probe runs exactly once per process, result is shared for all subsequent callerskeyring/tests.rscovering the cached probe and verifying the underlying backend operations (file backend used in CI to avoid keychain permission requirements)Submission Checklist
keyring/tests.rswith probe caching and backend operation testsprobe_availability()andis_available()paths covered bykeyring/tests.rs; coverage CI gate will validatedocs/TEST-COVERAGE-MATRIX.mdOnceLockis from Rust std; file backend used in testsCloses #NNN— no linked issue (user-reported prod repro, not tracked in GitHub issues)Impact
OPENHUMAN_KEYRING_BACKEND=fileis setis_available()return value is identical; only the call frequency to the OS keychain is reducedRelated
AI Authored PR Metadata (required for Codex/Linear PRs)
Linear Issue
Commit & Branch
fix/keyring-probe-onclockdbd77b9b228a568ccd6a75b8fd7f1103ac2f6bfaValidation Run
pnpm --filter openhuman-app format:check— ran via pre-push hook; auto-fixed import line wrap inoauthAuthReadiness.ts, committedpnpm typecheck— passedpnpm test:rust(keyring unit tests)cargo check --manifest-path Cargo.toml— exit 0Validation Blocked
command:N/Aerror:N/Aimpact:N/ABehavior Changes
Parity Contract
is_available()returns the same boolean; callers unchangedOnceLockresult is consistent across all callers in the same processDuplicate / Superseded PR Handling
Summary by CodeRabbit
Bug Fixes
Performance
Tests