ADE-72: Chat/AI runtime: Keychain key in argv + SDK pool ref-count race, plus chat/AI/ade-action god-file & typed-dispatch decomposition#494
Conversation
|
The latest updates on your projects. Learn more about Vercel for GitHub. |
|
Warning Review limit reached
More reviews will be available in 31 minutes and 9 seconds. Learn how PR review limits work. Your organization has run out of usage credits. Purchase more in the billing tab. ⌛ How to resolve this issue?After more reviews become available, a review can be triggered using the We recommend that you space out your commits to avoid hitting the rate limit. 🚦 How do rate limits work?CodeRabbit enforces hourly rate limits for each developer per organization. Our paid plans include higher PR review limits than trial, open-source, and free plans. In all cases, reviews become available again over time. During sustained high-volume PR review activity, CodeRabbit may temporarily slow when the next review becomes available. Please see our Fair Usage Limits Policy for further information. ℹ️ Review info⚙️ Run configurationConfiguration used: Path: .coderabbit.yaml Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (6)
✨ Finishing Touches🧪 Generate unit tests (beta)
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 |
|
Capy auto-review is paused for this organization because the monthly auto-review limit has been reached. Increase the limit or turn it off in billing settings to resume automatic reviews. |
|
@copilot review but do not make fixes |
Refs ADE-72
Summary
Describe the change.
What Changed
Key files and behaviors.
Validation
How you tested.
Risks
Anything to watch.
Linked Linear issues
Greptile Summary
This PR fixes two distinct runtime bugs: (1) API keys were being passed as clear-text CLI arguments to
/usr/bin/security(visible inpsoutput), replaced now by writing exclusively to ElectronsafeStorage; (2) concurrentacquireSdkConnectioncallers shared a single init promise but only the non-initOwnercaller incremented the ref-count — a race that could produce a premature dispose. The migration direction is also inverted (Keychain → encrypted store instead of encrypted store → Keychain), and the provider-index write path is removed entirely.writeMacosKeychainSecretand its provider-index helpers are deleted;storeApiKeyanddeleteApiKeynow always targetsafeStorage; a newmigrateLegacyMacosKeychainIntoEncryptedStoreruns on first cold start to absorb any pre-existing Keychain entries into the encrypted store, with encrypted-store values taking precedence over Keychain values in the merge.forloop (STALE_INIT_RETRY_LIMIT = 2); bothinitOwnerand non-initOwnercallers check process liveness afterawait init;initOwnerthrows immediately on post-init worker exit; non-initOwnerretries up to the limit before throwing.forkcall and each hold an independent ref that must be released before dispose fires;apiKeyStoretests updated to assert zeroadd-generic-passwordcalls and verify the new merge semantics.Confidence Score: 5/5
Safe to merge; the security fix and ref-count corrections are sound, and the two noted observations are edge-case quality improvements.
All three core changes (removing Keychain argv writes, inverting migration direction, bounding SDK pool retries) are implemented correctly and are covered by new tests. The two flagged items are resilience and cleanup concerns that surface only under unusual conditions — a transient disk-write failure during startup migration, and repeated but idempotent migration writes for users who upgrade without changing their keys. Neither represents incorrect behaviour under normal operating conditions.
apps/desktop/src/main/services/ai/apiKeyStore.ts — the migration path in ensureStore deserves a second look for error-handling resilience.
Important Files Changed
writeMacosKeychainSecret(which passed keys as-w keyCLI args visible in process list); rewrites migration direction (Keychain to encrypted store);migrateLegacyMacosKeychainIntoEncryptedStorelacks the try/catch that guarded the old migration path.Sequence Diagram
sequenceDiagram participant App participant ensureStore participant loadEncryptedStore participant migrateLegacyKeychain participant Keychain participant safeStorage App->>ensureStore: "first call (cache=null)" ensureStore->>loadEncryptedStore: read encrypted store loadEncryptedStore->>safeStorage: decryptString(blob) safeStorage-->>loadEncryptedStore: stored keys map loadEncryptedStore-->>ensureStore: encryptedStore alt canPersistEncryptedStore() and isMacosKeychainAvailable() ensureStore->>migrateLegacyKeychain: encryptedStore migrateLegacyKeychain->>Keychain: readProviderIndex and readStore Keychain-->>migrateLegacyKeychain: legacy entries Note over migrateLegacyKeychain: merge keychainStore then encryptedStore encrypted store wins on conflict migrateLegacyKeychain->>safeStorage: persistEncryptedStore(merged) migrateLegacyKeychain-->>ensureStore: mergedStore becomes cache else safeStorage unavailable and Keychain available ensureStore->>Keychain: readProviderIndex and readStore read-only Keychain-->>ensureStore: cached keys end App->>storeApiKey: provider and new value storeApiKey->>safeStorage: persistEncryptedStore storeApiKey->>Keychain: deleteMacosKeychainSecretBestEffort Note over storeApiKey: mark provider in missingMacosKeychainProviders App->>releaseSdkConnection: poolKey and generation Note over releaseSdkConnection: ref minus 1 if zero then dispose and cleanupPrompt To Fix All With AI
Reviews (2): Last reviewed commit: "fix: address chat runtime review finding..." | Re-trigger Greptile