Feat: Seed remote feature flag controller with default flags - #9747
Feat: Seed remote feature flag controller with default flags#9747Cal-L wants to merge 18 commits into
Conversation
…ts-remote-feature-flag-controller
| includeInDebugSnapshot: true, | ||
| usedInUi: false, | ||
| }, | ||
| processedRemoteFeatureFlags: { |
There was a problem hiding this comment.
This persisted state is the processed version of REMOTE feature flags, excluding defaults and overrides. Used for flag reconstruction on controller creation, preventing the need for a deconstruction.
…to current effective flags
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes and found 1 potential issue.
❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, have a team admin enable autofix in the Cursor dashboard.
Reviewed by Cursor Bugbot for commit 8576196. Configure here.
| getMetaMetricsId, | ||
| clientVersion, | ||
| prevClientVersion, | ||
| defaultFeatureFlags = {}, |
There was a problem hiding this comment.
Ability for platforms to provide feature flag defaults
|
|
||
| // Force a refetch when processed remote has never been persisted so the | ||
| // new field is populated (from the API). | ||
| const shouldForceRefetch = |
There was a problem hiding this comment.
Force refetch if processed remote feature flags do not exist
| !hasPersistedProcessedRemote || hasClientVersionChanged; | ||
|
|
||
| // Derive effective flags from defaults + processed + overrides. | ||
| const remoteFeatureFlags = { |
There was a problem hiding this comment.
Prioritize feature flags in this order

Explanation
This is part of an effort to keep the RemoteFeatureFlagController as the source of truth for feature flags. As part of that effort, we've added a new optional constructor arg named
defaultFeatureFlags, which will be provided by the platform apps. Under the hood, the controller will account for these flags when processing the effective flags that the consumers will use. The order of priority for the flags are - default flags > remote flags > override flags.References
Checklist
Note
Medium Risk
Changes how effective flags are computed and persisted across upgrades and offline fetch failures; behavior is heavily tested but affects a widely used controller path.
Overview
Remote feature flag layering — Apps can pass optional
defaultFeatureFlags(not persisted) intoRemoteFeatureFlagController; Wallet exposes the same viainstanceOptions.remoteFeatureFlagController.defaultFeatureFlags.Persisted processed remote — State gains
processedRemoteFeatureFlags(persisted) as the remote layer after threshold/version processing. EffectiveremoteFeatureFlagsare always derived via#getEffectiveFeatureFlags: defaults < processed remote < local overrides. Overrides and cache updates write through that helper instead of mutatingremoteFeatureFlagsdirectly.Upgrade and fetch behavior — If
processedRemoteFeatureFlagswas never saved, cache is invalidated to force a refetch; pre-upgrade installs still use the old persistedremoteFeatureFlagsfor first paint while defaults apply underneath. When a fetch fails in that state, the controller can hydrateprocessedRemoteFeatureFlagsfrom persistedrawRemoteFeatureFlagswithout advancingcacheTimestampso retries still happen.Tests cover defaults, precedence, migration, failed-fetch hydration, and threshold edge cases (no matching group, nameless threshold entries).
Reviewed by Cursor Bugbot for commit 2b81ab9. Bugbot is set up for automated code reviews on this repo. Configure here.