Skip to content

docs: update remote feature flag threshold API - #176

Closed
asalsys wants to merge 1 commit into
mainfrom
docs/remote-feature-flag-threshold-api
Closed

docs: update remote feature flag threshold API#176
asalsys wants to merge 1 commit into
mainfrom
docs/remote-feature-flag-threshold-api

Conversation

@asalsys

@asalsys asalsys commented Jul 2, 2026

Copy link
Copy Markdown

Summary

Updates remote feature flags documentation to reflect the RemoteFeatureFlagController API changes in MetaMask/core#9325, MetaMask/core#9289:

  • Threshold flags return the selected value directly from remoteFeatureFlags (no { name, value } wrapper).
  • Selected group names are exposed via featureFlagThresholdGroups when the winning threshold entry includes name.
  • Documents optional idType on threshold entries (canonical by default, metametrics for legacy MetaMetrics segmentation).
  • Updates the local override example to use a direct flag value.

Test plan

  • Reviewed markdown for accuracy against RemoteFeatureFlagController behavior in core PR #9325

Made with Cursor

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>
@asalsys
asalsys requested review from DDDDDanica and removed request for DDDDDanica July 2, 2026 14:08
@asalsys asalsys closed this Jul 2, 2026
@asalsys
asalsys deleted the docs/remote-feature-flag-threshold-api branch July 2, 2026 14:10
@asalsys
asalsys restored the docs/remote-feature-flag-threshold-api branch July 2, 2026 14:41
@asalsys asalsys reopened this Jul 2, 2026
@asalsys asalsys closed this Jul 2, 2026
@asalsys
asalsys deleted the docs/remote-feature-flag-threshold-api branch July 2, 2026 14:46
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>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant