Skip to content

FFL-2837: dynamic (rules-based) offline init plan - #1345

Open
btthomas wants to merge 20 commits into
developfrom
blake.thomas/FFL-2837
Open

FFL-2837: dynamic (rules-based) offline init plan#1345
btthomas wants to merge 20 commits into
developfrom
blake.thomas/FFL-2837

Conversation

@btthomas

@btthomas btthomas commented Jul 22, 2026

Copy link
Copy Markdown
Collaborator

Pull request stack

  1. Plan PR (FFL-2837: dynamic (rules-based) offline init plan #1345) <- you are here
  2. PR1: Rules engine boundary (#1346)
  3. PR2: Dynamic offline evaluation (#1347)
  4. PR3: Provider API and documentation (#1348)

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 supports precomputed offline configurations, DatadogOfflineOpenFeatureProvider, and setConfiguration.

This PR adds these documents:

  • dynamic_offline_simplified.plan.md defines the complete feature plan.
  • dynamic_offline_pr_stack.plan.md divides the implementation into three reviewable PRs.

Feature behavior

  • The customer supplies a configuration with setConfiguration.
  • The provider does not fetch data from the network.
  • setContext changes the active context.
  • The SDK evaluates rules on the device for each flag request.
  • The SDK uses the flagging-core evaluator.
  • An empty context ({}) is a real OpenFeature context.
  • A precomputed customer can use getPrecomputedContext(configuration) and explicitly set that context.

One provider supports precomputed data, rules data, and mixed data. The SDK selects the path for each resolution:

  1. Use matching precomputed data or its flag error.
  2. Otherwise, use valid rules data.
  3. Otherwise, return the applicable configuration error.

Upstream state

The latest published @datadog/flagging-core version is 2.0.2. Version 2.0.2 does not contain the required rules wire contract.

  • openfeature-js-client#344 is open at 939da97. It adds configuration.rules.response, protobuf decoding, independent branch parsing, evaluation validation, SHA-256 operators, safe lookup, rules serialization, and React Native package tests.
  • Commits ab22ad0 and 939da97 only refresh generated Node-server declarations and isolate browser provider tests. They do not change the React Native parser, evaluator, wire, or lifecycle contract.
  • openfeature-js-client#336 is open at 6d3d6a4. It is stacked on PR Add Support for RN 0.71 #344 at 939da97. Its latest change only restacks the branch. It adds the browser offline provider, combined evaluation, valid-sibling fallback, optional initial configuration, and provider error events.
  • openfeature-js-client#353 is open. It adds the shared getPrecomputedContext helper. React Native uses a temporary local helper until a published package exports it.
  • openfeature-js-client#343 produced version 2.0.2. It did not add a required feature.

The React Native implementation does not import unpublished package code. It uses temporary compatibility code with explicit TODO(FFL-2837) markers.

Implementation stack

  • PR1 adds the rules-engine boundary. It also fixes empty-context semantics and adds the temporary getPrecomputedContext helper.
  • PR2 adds rules-only and mixed evaluation to FlagsClient.
  • PR3 connects the offline provider and adds integration tests, documentation, and examples.

The complete stack contains 19 TODO(FFL-2837) markers. Each marker names the upstream replacement or the required decision.

Remaining gates

The implementation PRs remain drafts until these gates are complete.

Base automatically changed from blake.thomas/FFL-2666 to develop July 23, 2026 12:37
@btthomas
btthomas marked this pull request as ready for review July 23, 2026 14:42
@btthomas
btthomas requested a review from a team as a code owner July 23, 2026 14:42
Copilot AI lite review requested due to automatic review settings July 23, 2026 14:42

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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
Comment thread dynamic_offline.plan.md Outdated
@@ -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)
Comment thread dynamic_offline.plan.md Outdated
Comment on lines +9 to +12
- [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.
Copilot AI review requested due to automatic review settings July 24, 2026 00:38

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 3 out of 3 changed files in this pull request and generated 1 comment.

Comment on lines +1 to +3
# FFL-2837 — Dynamic Offline PR Stack

This document uses Simplified Technical English.
@sbarrio
sbarrio requested review from barboraplasovska and sbarrio and removed request for barboraplasovska July 24, 2026 07:06
Comment thread dynamic_offline.plan.md Outdated

FFL-2837 adds the **rules-based** (dynamic) offline flow:

- Customer loads a **rules-based** configuration (Universal Flag Configuration) via `setConfiguration`

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

Comment thread dynamic_offline.plan.md Outdated

---

## 2. Current state of `@datadog/flagging-core`

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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 adds dynamic_offline_pr_stack.plan.md instead. 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.

btthomas and others added 8 commits July 28, 2026 11:43
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>
Copilot AI review requested due to automatic review settings July 28, 2026 16:51
@btthomas
btthomas force-pushed the blake.thomas/FFL-2837 branch from 4878144 to 7b00adc Compare July 28, 2026 16:51

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

Copilot AI review requested due to automatic review settings July 30, 2026 13:37

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

Copilot AI review requested due to automatic review settings July 31, 2026 13:57

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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

Copilot AI review requested due to automatic review settings August 3, 2026 15:45

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 2 out of 2 changed files in this pull request and generated no new comments.

Suppressed comments (3)

dynamic_offline_simplified.plan.md:9

  • This upstream reference list uses unqualified "PRs #..." which GitHub will often auto-link to pull requests in this repository, not the upstream repos. Use fully-qualified cross-repo references (e.g. DataDog/openfeature-js-client#344, ddoghq/dd-source#34959) to avoid incorrect links; apply this convention consistently throughout the document.
**Upstream references:** DataDog/openfeature-js-client PRs #343, #344, and #336; ddoghq/dd-source PRs #34959 and #40304

dynamic_offline_pr_stack.plan.md:23

  • "Upstream PR #344" is ambiguous in Markdown because #344 can auto-link to a PR in this repository. Prefer fully-qualified references like DataDog/openfeature-js-client#344 (and similarly for #336, #343, etc.) so readers land on the correct upstream pull request; apply this convention throughout the document.
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.
Its code head is `9f794c7` as of 2026-08-03.

dynamic_offline_simplified.plan.md:1342

  • The review-history timeline is hard to follow because it says PR #336 "was restacked on the latest PR #344 head" and then later says it "required a new restack". Clarify which PR #344 head it was restacked onto and why another restack was needed (e.g., PR #344 advanced afterward).
The plan was updated on 2026-07-30 after PR #336 was restacked on the latest PR #344 head.
The plan was updated on 2026-07-31 after live verification found no new code heads but found new PR-description details and an uncovered no-`BigInt` evaluator path.
The plan was updated on 2026-08-03 after PR #344 added the canonical feature-level wording and capability-specific entry points.
PR #336 had no new commit and required a new restack.

Copilot AI review requested due to automatic review settings August 7, 2026 12:23

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 2 out of 2 changed files in this pull request and generated no new comments.

Suppressed comments (1)

dynamic_offline_simplified.plan.md:828

  • This section mixes OpenFeature ProviderEvents names (e.g. Ready, ConfigurationChanged, Error) with uppercase status-like tokens (READY, CONFIGURATION_CHANGED, PROVIDER_ERROR). In this repo’s OpenFeature provider implementation/tests, the emitted events are ProviderEvents.Ready, ProviderEvents.ConfigurationChanged, and ProviderEvents.Error (see packages/react-native-openfeature/src/__tests__/offlineProvider.test.ts:215-218). Using uppercase here makes it look like different event names and can mislead implementers.
Keep the existing provider event mapping.
PR #336 now confirms the same mapping in the browser provider.
On recovery, emit `READY` before `CONFIGURATION_CHANGED`.
Emit `CONFIGURATION_CHANGED` for each valid replacement.
Emit `PROVIDER_ERROR` for an invalid replacement.

Copilot AI review requested due to automatic review settings August 10, 2026 18:54

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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_simplified.plan.md:20

  • This references "PR #344" without a repo qualifier, which is ambiguous in this repo context (it can be mistaken for an in-repo PR). Consider using a fully qualified reference (e.g., DataDog/openfeature-js-client#344) consistently for upstream PRs.
Upstream PR #344 now defines the expected implementation contract.

dynamic_offline_pr_stack.plan.md:22

  • "Upstream PR #344" is ambiguous without the repository name. Using a fully qualified reference (e.g., DataDog/openfeature-js-client#344) makes it clear this is not a dd-sdk-reactnative PR number.
Upstream PR #344 adds the generated Protobuf-ES rules parser, SHA-256 evaluation, evaluation-time validation, safe flag lookup, and React Native compatibility.

Copilot AI review requested due to automatic review settings August 11, 2026 20:09

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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_simplified.plan.md:9

  • PR references are written as plain #NNN without links; in this repo that can be ambiguous (this repository also has PR numbers). Using fully qualified PR references (and ideally links) makes the plan easier to follow and reduces confusion when the document is read outside the PR description context.
**Upstream references:** DataDog/openfeature-js-client PRs #343, #344, and #336; ddoghq/dd-source PRs #34959 and #40304

dynamic_offline_pr_stack.plan.md:22

  • This file also references upstream PRs by number only. Consider using a fully qualified reference here (and consistently throughout) to avoid confusion with PR numbers in this repository.
Upstream PR #344 adds the generated Protobuf-ES rules parser, SHA-256 evaluation, evaluation-time validation, safe flag lookup, and React Native compatibility.

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.

3 participants