Repository navigation
FFLSDK-258: Add experimentation opt-out modes - #4024
leoromanovsky wants to merge 12 commits into
Conversation
Add native and OpenFeature opt-out configuration with timestamp validation. Require server acknowledgment and isolate cached assignments and pending contexts.
🎉 All green!🧪 All tests passed 🔄 Datadog retried 1 test - 1 passed on retry 🎯 Code Coverage (details) 🔗 Commit SHA: 0a4f91e | Docs | View more details | Give us feedback! |
Bind assignment acknowledgements and persisted caches to the selected mode and exact subject cutoff. Cover request, restart, and stale-response behavior.
Deliver committed state changes and callbacks outside the policy lock. Read one assignment snapshot and retain the attempted subject for error telemetry.
Codex Review SummaryThis comment shows the latest Codex review activity on this pull request.
ℹ️ About Codex in GitHubYour team has set up Codex to review pull requests in this repo. Reviews are triggered when you
Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings. |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: f335b48a3d
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
There was a problem hiding this comment.
The most critical concern is that EvaluationContextCallback completion callbacks can be delivered on the UI thread — both via drain() executing on whichever thread calls it and via the direct onFailure call in the invalid-context path — violating the background-thread contract. A separate issue in DatadogFlagsClient.kt causes the React Native snapshot path to block for up to 200 ms (two sequential 100 ms waits) when persistence is loading and the opt-out policy is disabled.
🤖 Bits Code Review · Commit f335b48
|
Created DOCS-16087 for the editorial review. |
Use Gregorian dates and explicit UTC bounds for opt-out timestamps. Derive request options from the effective policy and validate acknowledgements.
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 7b7ab71778
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| Invalid timestamps return application defaults with `INVALID_CONTEXT` and do not send an assignment request. | ||
|
|
||
| The backend skips experiment allocations and continues through ordinary feature allocations. | ||
| The SDK requires the backend to acknowledge exclusion before using the response. |
There was a problem hiding this comment.
🤖 Comment from Codex working with Leo:
Recorded the precompute acknowledgement and activation-metadata prerequisites in 9c18ede. Local checks confirm that Android rejects missing or mismatched acknowledgements and recovers after a valid response. These checks use supplied responses and do not confirm backend deployment. Release enablement still requires verified site coverage for the acknowledgement, fallback, and activation changes linked here.
This release gate remains open until site deployment is verified. No backend deployment was performed in this SDK work.
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 9c18edeca8
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: cda7955b63
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 347884bca8
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 6e5fe6cf62
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
Recreate the develop merge without the unrelated master ancestry. Preserve the complete file tree from d95597b. Ref: FFLSDK-258
d95597b to
0a4f91e
Compare
What does this PR do?
Add immediate and future-experiments-only opt-out to
FlagsClient.Builder. The OpenFeature provider uses the same configuration.DISABLED, the defaultIMMEDIATEFUTURE_EXPERIMENTS_ONLYOmit the timestamp for eligible subjects. Invalid enabled input returns
INVALID_CONTEXTwithout an assignment request. Future timestamps take effect immediately.Require acknowledgement of the effective policy and, for future mode, the exact cutoff. Bind caches to the mode and context. Enabled modes withhold older contexts during refresh, including when the timestamp is absent. Flag resolution waits for persistence once before acquiring the policy lock. Request cleanup uses a nonblocking snapshot.
A client-owned queue delivers callbacks on background workers. Each worker shuts down after its drain task is submitted. A blocked fetch cannot delay initialization timeout callbacks. Callback exceptions cannot prevent later delivery. Recoverable errors remain recoverable through OpenFeature.
Motivation
Applications need to exclude subjects from experimentation while retaining ordinary feature delivery. Experimentation and evaluation telemetry controls remain independent. Future mode uses allocation activation, not prior subject enrollment. Retained allocations still perform normal targeting and exposure logging.
The three granular tracking bridge methods reject snapshots from superseded contexts. Timestamp documentation describes the supported RFC3339 subset. Tests cover both modes, mode-only acknowledgement rejection, invalid-context mapping, and worker-start recovery.
Additional Notes
Both mobile implementations pass the 187-case shared precompute profile. The catalog still marks D006 as unresolved and fleet reuse as proposed. Backend acknowledgement, ordinary fallback, and activation delivery remain release prerequisites. The deployment-verification thread remains open.
Validation
DataDog/dd-sdk-android@d95597bc31e78c280547cb33e6c10f242df21e06Review checklist (to be filled by reviewers)
FFE reviewer selection
Reviewers: @typotter, @sameerank
Why: android — Adds Android Flags SDK experimentation opt-out modes (DISABLED/IMMEDIATE/FUTURE_EXPERIMENTS_ONLY) driven by a dd_experimentation_opt_out_at context attribute. Reviewers come from the matched pod.
🤖 Automated selection.
Selection details
Initiative: fallback / android
Why this match: Adds Android Flags SDK experimentation opt-out modes (DISABLED/IMMEDIATE/FUTURE_EXPERIMENTS_ONLY) driven by a dd_experimentation_opt_out_at context attribute. The modes exclude experiment allocations from assignment and bind caches to the mode and context, with OpenFeature provider support and callback dispatch changes. This removes subjects from experiment assignment. It does not suppress evaluation/exposure event egress (the PR keeps telemetry controls independent, so ufc-compliance does not fit), and it does not implement layers, holdouts, bandits or any other registered project. The Android fallback for Kotlin flags/OpenFeature code applies.
The PR author was excluded. Existing reviewers and teams were preserved.
Debug or fix a problem
Workflow run · Bits Code session
dry_run=false. Unchanged completed runs are skipped. If the receipt saysneeds_reconciliationor a write outcome is uncertain, ask the workflow owner to reconcile GitHub and the receipt before retrying; do not delete the lock blindly.Evidence and run details
✅ Complete — reviewer coverage verified. The workflow checked pending requests or submitted reviews on the evaluated head.
Generated asynchronously by the FFE reviewer-routing workflow.
Changed paths:
features/dd-sdk-android-flags/src/main/kotlin/com/datadog/android/flags/ExperimentationOptOutMode.kt,features/dd-sdk-android-flags/src/main/kotlin/com/datadog/android/flags/internal/evaluation/ExperimentationOptOut.kt,features/dd-sdk-android-flags/src/main/kotlin/com/datadog/android/flags/FlagsClient.kt,features/dd-sdk-android-flags/src/main/kotlin/com/datadog/android/flags/internal/DatadogFlagsClient.kt,features/dd-sdk-android-flags/src/main/kotlin/com/datadog/android/flags/internal/repository/net/PrecomputeMapper.kt,features/dd-sdk-android-flags/src/main/kotlin/com/datadog/android/flags/internal/evaluation/EvaluationsManager.kt,features/dd-sdk-android-flags-openfeature/src/main/kotlin/com/datadog/android/flags/openfeature/DatadogFlagsProvider.ktEvaluated head:
0a4f91eed3bdd0f1b2f8800e30dd72776e6d6e71Registry revision:
revision:1946aa2a-530e-487a-84a7-83aff44a1089Pinned skill source:
d214cfc65ae154b97d39af5cf32caf48aaec9bf0Instructions: workflow-injected snapshot (no plugin loaded)
Instruction snapshot SHA-256:
f23b2a88c13c0da90e2dd58246a14f257af91e2195c555039bd555b52e6f3516