docs: update remote feature flag threshold API - #176
Closed
asalsys wants to merge 1 commit into
Closed
Conversation
Document featureFlagThresholdGroups, canonical ID as the default threshold
segmentation identifier, and removal of the legacy { name, value } wrapper.
Co-authored-by: Cursor <cursoragent@cursor.com>
basgys
pushed a commit
to basgys/metamask-core
that referenced
this pull request
Aug 20, 2026
…MetricsFlags with canonical ID default (MetaMask#9325) ## Summary - Add required `getCanonicalProfileId` constructor callback and `metaMetricsFlags` map for threshold flag segmentation. - Threshold flags use canonical profile ID by default; flags whose names are present in `metaMetricsFlags` use MetaMetrics ID instead. - Generalize threshold calculation to hash the selected segmentation ID while preserving the existing deterministic bucketing behavior. - Pass the new segmentation options through `@metamask/wallet` remote feature flag controller initialization. ## Segmentation Behavior | Flag configuration | Identifier used | Constructor callback | | --- | --- | --- | | Flag name absent from `metaMetricsFlags` | Canonical profile ID | `getCanonicalProfileId()` | | Flag name present in `metaMetricsFlags` | MetaMetrics ID | `getMetaMetricsId()` | If the selected identifier is empty, threshold arrays are preserved as-is and not processed. Example threshold config using canonical segmentation by default: ```json { "myCanonicalFlag": [ { "name": "groupA", "scope": { "type": "threshold", "value": 0.5 }, "value": "valueA" }, { "name": "groupB", "scope": { "type": "threshold", "value": 1.0 }, "value": "valueB" } ] } ``` Example controller setup for a flag that should keep MetaMetrics segmentation: ```ts new RemoteFeatureFlagController({ // ... getMetaMetricsId, getCanonicalProfileId, metaMetricsFlags: { legacyMetaMetricsFlag: true, }, }); ``` ## Migration Consumers must pass `getCanonicalProfileId` for threshold flags that should use canonical profile segmentation, which is now the default for flags absent from `metaMetricsFlags`. Existing threshold flags that must keep MetaMetrics-based bucketing should be listed in `metaMetricsFlags` and continue to provide `getMetaMetricsId`. ## Test plan - [x] `yarn workspace @metamask/remote-feature-flag-controller run jest --no-coverage src/utils/user-segmentation-utils.test.ts src/remote-feature-flag-controller.test.ts` - [x] Threshold flags absent from `metaMetricsFlags` use `getCanonicalProfileId` for segmentation - [x] Threshold flags present in `metaMetricsFlags` use `getMetaMetricsId` for segmentation - [x] Threshold arrays are preserved when the selected identifier is empty - [x] Threshold cache entries use the selected segmentation ID and stale entries are cleaned up when flags are removed from the server response ## Related - Documentation: [MetaMask/contributor-docs#176](MetaMask/contributor-docs#176) - Ticket - https://consensyssoftware.atlassian.net/browse/MCWP-662 <!-- CURSOR_SUMMARY --> --- > [!NOTE] > **Medium Risk** > Breaking constructor and experiment-assignment change: existing threshold flags will re-bucket unless listed in `metaMetricsFlags`. Not auth or payment logic, but it can change live A/B group membership. > > **Overview** > **Breaking:** threshold flags now bucket by **canonical profile ID** by default instead of MetaMetrics ID. `RemoteFeatureFlagController` requires `getCanonicalProfileId`; flags listed in optional `metaMetricsFlags` still use `getMetaMetricsId`. > > Hash-based assignment hashes the chosen segmentation ID. If that ID is empty, the threshold array is left unprocessed. Explicit MetaMetrics ID targeting is unchanged. Threshold cache keys and stale-entry cleanup cover both identifiers. > > `@metamask/wallet` forwards the new options (optional; empty-string default for canonical ID). Consumers that need the old MetaMetrics bucketing must list those flag names in `metaMetricsFlags`. > > <sup>Reviewed by [Cursor Bugbot](https://cursor.com/bugbot) for commit 09b141f. Bugbot is set up for automated code reviews on this repo. Configure [here](https://www.cursor.com/dashboard/bugbot).</sup> <!-- /CURSOR_SUMMARY --> --------- Co-authored-by: Cursor <cursoragent@cursor.com> Co-authored-by: Cal-L <cal.leung@consensys.net> Co-authored-by: Cal Leung <cleun007@gmail.com> Co-authored-by: Elliot Winkler <elliot.winkler@gmail.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Updates remote feature flags documentation to reflect the
RemoteFeatureFlagControllerAPI changes in MetaMask/core#9325, MetaMask/core#9289:valuedirectly fromremoteFeatureFlags(no{ name, value }wrapper).featureFlagThresholdGroupswhen the winning threshold entry includesname.idTypeon threshold entries (canonicalby default,metametricsfor legacy MetaMetrics segmentation).Test plan
RemoteFeatureFlagControllerbehavior in core PR #9325Made with Cursor