FFL-2837: dynamic (rules-based) offline init plan - #1345
Conversation
There was a problem hiding this comment.
Pull request overview
Adds planning documentation for FFL-2837 (“dynamic/rules-based offline init”) in the React Native SDK, outlining intended behavior, dependency needs in @datadog/flagging-core, risks, and a proposed RN implementation + test plan.
Changes:
- Add a detailed technical plan covering architecture, upstream gaps, risk analysis, and step-by-step implementation/testing.
- Add a Simplified Technical English version of the plan for broader review/accessibility.
Reviewed changes
Copilot reviewed 2 out of 2 changed files in this pull request and generated 3 comments.
| File | Description |
|---|---|
| dynamic_offline.plan.md | Detailed implementation plan, upstream dependency analysis, and risks/test plan for rules-based offline evaluation. |
| dynamic_offline_simplified.plan.md | Simplified Technical English version of the same plan for clearer cross-team review. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| Use this existing flow: | ||
|
|
||
| ```text | ||
| configurationFromString -> setConfiguration -> evaluate |
| @@ -0,0 +1,772 @@ | |||
| # FFL-2837 — Dynamic (rules-based) offline init in dd-sdk-reactnative | |||
|
|
|||
| **Jira:** [FFL-2837 — Building Blocks API for dynamic offline init in ReactNative SDK](https://datadoghq.atlassian.net/browse/FFL-2837) | |||
| - [Portable Flag Configuration RFC](https://docs.google.com/document/d/1OWNBtXtSk535VXqf-9fqsAmU9W8kpFLAwxYi2y1qyQQ/edit?pli=1&tab=t.0#heading=h.n52036mkzewg) (local snapshot: `./Portable-Flag-Configuration-RFC.md`, repo root, untracked) — defines the building blocks: `ConfigurationWire`, `configurationFromString/ToString`, `CoreProvider`, fetch fns, hooks. | ||
| - [Offline Initialization for Feature Flagging RFC](https://docs.google.com/document/d/1q1GlEbAgCGuO1OWfGbmKQkk5Oo-rE7YQwq29kMJJ4II/edit?pli=1&tab=t.0#heading=h.rnd972k0hiyer) (local snapshot: `./Offline-Initialization-for-Feature-Flagging.md`, repo root, untracked) — offline recipes built from those blocks; the operation is always `configurationFromString(wire) → provider.setConfiguration(config) → evaluate(...)`. | ||
| - [ConfigurationWire (Confluence)](https://datadoghq.atlassian.net/wiki/spaces/PANA/pages/5141725646/ConfigurationWire) — the published wire spec. Its **protobuf/base64** rules encoding is the intended target (see §2.5), even though the current code still uses JSON. | ||
| - **RFC: Obfuscation for rules-based client configs** (local: `./RFC_Obfuscation_for_rules-based_client configs.md`, 2026-07-10, first draft, one approval) — defines the obfuscation design for client rules: per-flag opt-in switch, salted `ONE_OF_SHA256`/`NOT_ONE_OF_SHA256` operators (server-compatible, engine-evaluated), binary structure format, and "document what's exposed". Answers most of our obfuscation open question — see G6/D7. |
| # FFL-2837 — Dynamic Offline PR Stack | ||
|
|
||
| This document uses Simplified Technical English. |
|
|
||
| FFL-2837 adds the **rules-based** (dynamic) offline flow: | ||
|
|
||
| - Customer loads a **rules-based** configuration (Universal Flag Configuration) via `setConfiguration` |
There was a problem hiding this comment.
So setConfiguration can be used both to set a precomputed flag config and also the rules used to evaluate and compute it against a context?
Is there any particular reason for this and not have a specific and more clearly named function to set the rules?
I fear the API might end up being too broad for customers to clearly understand what does what and which precise calls they need to make to achieve the setup they want.
|
|
||
| --- | ||
|
|
||
| ## 2. Current state of `@datadog/flagging-core` |
There was a problem hiding this comment.
What's the expected size footprint of this package?, also, is this module stable?, we need to keep in mind that we don't do major releases that often so if any functionality of this module is to be exposed on the public SDK API we need to be sure that this does not introduce breaking changes often.
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 2 out of 2 changed files in this pull request and generated no new comments.
Comments suppressed due to low confidence (1)
dynamic_offline_pr_stack.plan.md:3
- The PR description says this PR adds
dynamic_offline.plan.md(detailed plan), but the branch currently addsdynamic_offline_pr_stack.plan.mdinstead. This mismatch makes it hard for reviewers to find the detailed plan document; either add/rename the detailed plan file as described, or update the PR description to match the actual files in the PR.
# FFL-2837 — Dynamic Offline PR Stack
This document uses Simplified Technical English.
Planning doc for rules-based (dynamic) offline feature-flag init in the React Native SDK: gaps to bridge in @datadog/flagging-core, explicit implementation steps, test plan, and risks/unknowns. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Resolve five of the plan's open questions: gate rules exposure on doLog (D3), keep two evaluation paths (D4), accept static-import bundle cost and reject dynamic import (D5), no offline opt-in gate for rules (D6), treat obfuscation/hashing as upstream (D7). Punt the flagging-core version/protobuf questions (Q1-Q2) to coordinate with upstream owners. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Point the Portable Flag Configuration and Offline Initialization references at their source Google Docs, keeping the local snapshot filenames noted alongside. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Fold in the Obfuscation RFC (salted ONE_OF_SHA256 operators + binary structure) and the round-5/6 review findings. Obfuscation operators are absent from 2.0.1 and today silently fall back to DEFAULT, so unknown operators must be rejected as GENERAL, derived from the pinned OperatorType rather than an RN-maintained set. Sync SHA-256 is new bundle mass (Hermes+JSC). The hash protocol is unspecified and needs cross-SDK vectors plus malformed-condition load validation. Unsupported operators invalidate the rules branch only, keeping a valid precomputed sibling. Corrected the threat model and the full "what stays visible" UFC list. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
4878144 to
7b00adc
Compare
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 2 out of 2 changed files in this pull request and generated no new comments.
Comments suppressed due to low confidence (3)
dynamic_offline_simplified.plan.md:19
- This “Upstream PR #344” reference is ambiguous without an explicit repo/link (it can be read as a PR in this repo). Consider fully qualifying it like other cross-repo references.
Upstream PR #344 now defines the expected implementation contract.
dynamic_offline_simplified.plan.md:9
- The PR references are written as plain “#NNN”, which is ambiguous inside this repository (e.g., “#344” could be interpreted as a dd-sdk-reactnative PR). Using explicit links here will keep the plan unambiguous over time.
This issue also appears on line 19 of the same file.
**Upstream references:** DataDog/openfeature-js-client PRs #343, #344, and #336
dynamic_offline_pr_stack.plan.md:26
- These references to “Upstream PR #344” / “PR #336” are ambiguous without a repo name/link (they can be interpreted as PRs in this repo). Using explicit links will make the stack plan clearer for readers.
Upstream PR #344 adds the generated Protobuf-ES rules parser, SHA-256 evaluation, validation, safe flag lookup, and React Native compatibility.
It adds `@bufbuild/protobuf` as a runtime dependency.
Its packed-package smoke test uses the Metro export conditions from this repository.
Upstream PR #336 uses that parser in the browser `CoreProvider`.
PR #336 also uses the safe upstream lookup for precomputed flags.
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 2 out of 2 changed files in this pull request and generated no new comments.
Comments suppressed due to low confidence (4)
dynamic_offline_simplified.plan.md:21
- “Upstream PR #344” is ambiguous; qualify it with the upstream repository name to avoid confusion with PR numbers in this repo.
The RFC documents are drafts.
Upstream PR #344 now defines the expected implementation contract.
Names and versions can still change before publication.
dynamic_offline_pr_stack.plan.md:35
- Similarly, qualify “PR #336” with the upstream repository name to make it clear this is referring to DataDog/openfeature-js-client, not this repo.
Upstream PR #336 uses that parser in the browser `CoreProvider`.
PR #336 also uses the safe upstream lookup for precomputed flags.
dynamic_offline_simplified.plan.md:9
- References like “PR #344” are ambiguous in this repo (there is also a PR #344 here). Use an explicit repo-qualified reference so readers know this is DataDog/openfeature-js-client.
This issue also appears on line 19 of the same file.
**Upstream references:** DataDog/openfeature-js-client PRs #343, #344, and #336; ddoghq/dd-source PR #34959
dynamic_offline_pr_stack.plan.md:26
- Upstream PR numbers are ambiguous in this repo. Qualify “PR #344” with the upstream repository name (DataDog/openfeature-js-client) so it can’t be confused with dd-sdk-reactnative PR numbers.
This issue also appears on line 34 of the same file.
Published flagging-core version 2.0.2 does not contain the new rules wire contract.
Upstream PR #344 adds the generated Protobuf-ES rules parser, SHA-256 evaluation, validation, safe flag lookup, and React Native compatibility.
It adds `@bufbuild/protobuf` as a runtime dependency.
Its packed-package smoke test uses the Metro export conditions from this repository.
It moves wire parsing and `FlagsConfigurationWire` to `@datadog/flagging-core/configuration`.
The default flagging-core entry point keeps the evaluator and shared types.
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 2 out of 2 changed files in this pull request and generated no new comments.
Comments suppressed due to low confidence (2)
dynamic_offline_simplified.plan.md:21
- The references like “Upstream PR #344” are ambiguous in this repo because PR numbers also exist locally (e.g., this repository has its own PR #344). Qualify upstream PR references with the repository name (or a full link) at the point of use to avoid confusion for readers.
The RFC documents are drafts.
Upstream PR #344 now defines the expected implementation contract.
Names and versions can still change before publication.
dynamic_offline_pr_stack.plan.md:22
- This document refers to “Upstream PR #344” / “PR #336” by number only. Since this repository also has its own PR numbers, please qualify these references with the upstream repo (e.g., DataDog/openfeature-js-client#344) so the stack plan is unambiguous.
Published flagging-core version 2.0.2 does not contain the new rules wire contract.
Upstream PR #344 adds the generated Protobuf-ES rules parser, SHA-256 evaluation, evaluation-time validation, safe flag lookup, and React Native compatibility.
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 2 out of 2 changed files in this pull request and generated no new comments.
Suppressed comments (2)
dynamic_offline_pr_stack.plan.md:21
- This plan uses unqualified references like "PR #344" and "PR #336" throughout. Since the repository also has PR numbers, add a short note defining that unqualified "PR #NNN" references are upstream PRs (unless repo-qualified) to prevent ambiguity.
## Temporary upstream code
Published flagging-core version 2.0.2 does not contain the new rules wire contract.
dynamic_offline_simplified.plan.md:10
- The document references many items as "PR #NNN". Because this repo also has PR numbers (and this PR metadata includes an unrelated "#344"), unqualified PR references are ambiguous for readers. Add a short note defining what an unqualified "PR #NNN" refers to in this plan, and prefer repo-qualified references in the upstream list.
**Upstream references:** DataDog/openfeature-js-client PRs #343, #344, and #336; ddoghq/dd-source PR #34959
Pull request stack
This description uses Simplified Technical English. Technical names and API names do not change.
Summary
This PR adds the implementation plans for FFL-2837. FFL-2837 adds dynamic rules-based offline feature flags to the React Native SDK. This PR does not change product code.
This branch starts from
develop. The existing SDK already supports precomputed offline configurations,OfflineProvider, andsetConfiguration.This PR adds these documents:
dynamic_offline_simplified.plan.mddefines the complete feature plan.dynamic_offline_pr_stack.plan.mddivides the implementation into three reviewable PRs.Feature behavior
setConfiguration.setContextchanges the active context.One provider supports precomputed data, rules data, and mixed data. The SDK selects the path for each resolution:
Upstream state
The latest published
@datadog/flagging-coreversion is 2.0.2. Version 2.0.2 does not contain the required rules wire contract.configuration.rules.response, protobuf and base64 decoding, independent branch parsing, per-flag validation, SHA-256 operators, safe flag lookup, rules serialization rejection, and a React Native Metro smoke test.CoreProviderand the combined coreevaluatefunction. React Native uses this work as an integration reference.The React Native implementation does not import unpublished package code. It uses a temporary legacy JSON compatibility wire with explicit
TODO(FFL-2837)markers.Implementation stack
FlagsClient.The temporary compatibility code must use the final
rules.responsecontract after PR #344 is published. The SDK must keep the original rules wire becauseconfigurationToStringcannot recreate the protobuf payload.Remaining gates
The implementation PRs remain drafts until these gates are complete.