Skip to content

feat(core): pass bound domain to provider initialize and enforce domain-scoped binding#1433

Open
jonathannorris wants to merge 5 commits into
mainfrom
feat/ofrep-domain-cache-key
Open

feat(core): pass bound domain to provider initialize and enforce domain-scoped binding#1433
jonathannorris wants to merge 5 commits into
mainfrom
feat/ofrep-domain-cache-key

Conversation

@jonathannorris

@jonathannorris jonathannorris commented Jun 26, 2026

Copy link
Copy Markdown
Member

Summary

  • Add optional domain parameter to provider initialize and pass the bound domain from the provider mutator (spec 1.1.2.2, 2.4.1)
  • Add domainScoped provider declaration and reject binding a domain-scoped instance to more than one domain (spec 2.4.3, 1.1.8.1)
  • Forward domain through web and server MultiProvider initialize
  • Add conformance tests in web and server SDK test suites, including legacy single-argument initialize backward compatibility

Motivation

Unblocks OFREP static-context providers that need the bound domain at init time to scope persisted cache keys per open-feature/spec#393 and protocol ADR 0009.

Notes

  • Non-breaking: domain is an optional second parameter to initialize
  • Non-domain-scoped providers retain existing behavior (single instance can back multiple domains; initialize runs once)
  • Legacy providers that only implement initialize(context) remain compatible; the extra domain argument is ignored if unused

Related Issues

Relates to: open-feature/spec#393

Test plan

  • npx jest --selectProjects=shared --selectProjects=web --selectProjects=server

@coderabbitai

coderabbitai Bot commented Jun 26, 2026

Copy link
Copy Markdown

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 91546b08-8211-43e1-9249-2c0f774fa800

📥 Commits

Reviewing files that changed from the base of the PR and between 62e2e99 and 199f03b.

📒 Files selected for processing (2)
  • packages/server/test/multi-provider.spec.ts
  • packages/web/test/multi-provider-web.spec.ts
🚧 Files skipped from review as they are similar to previous changes (1)
  • packages/web/test/multi-provider-web.spec.ts

📝 Walkthrough

Walkthrough

Provider initialization now carries an optional domain through shared contracts, OpenFeature binding, and server/web MultiProvider paths. Tests were added for legacy single-argument providers and domain-scoped binding rules.

Changes

Provider domain handling

Layer / File(s) Summary
Contract and legacy helper
packages/shared/src/provider/provider.ts, packages/shared/test/legacy-initialize-provider.ts
CommonProvider adds domainScoped and a second initialize argument, and the shared legacy test helper tracks initialization calls and resolver stubs.
Domain-aware initialization forwarding
packages/shared/src/open-feature.ts, packages/server/test/open-feature.spec.ts, packages/web/test/open-feature.spec.ts, packages/web/test/evaluation-context.spec.ts
setAwaitableProvider passes domain into provider initialization, and tests cover default/domain initialization plus legacy single-argument providers.
MultiProvider domain forwarding
packages/server/src/provider/multi-provider/multi-provider.ts, packages/web/src/provider/multi-provider/multi-provider-web.ts, packages/server/test/multi-provider.spec.ts, packages/web/test/multi-provider-web.spec.ts
Both MultiProvider implementations forward (context, domain) to child providers, and the matching tests check legacy and regular child providers.
Domain-scoped binding guard
packages/shared/src/open-feature.ts, packages/server/test/open-feature.spec.ts, packages/web/test/open-feature.spec.ts
setAwaitableProvider now rejects reusing a domainScoped provider across domains, and tests cover the thrown error and shared-provider reuse cases.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 66.67% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly summarizes the main change: passing domain into provider initialization and enforcing domain-scoped binding.
Description check ✅ Passed The description is directly related to the changeset and accurately describes the new behavior, compatibility, and tests.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch

Comment @coderabbitai help to get the list of available commands.

…in-scoped binding

Signed-off-by: Jonathan Norris <jonathan.norris@dynatrace.com>
@jonathannorris jonathannorris force-pushed the feat/ofrep-domain-cache-key branch from 0614414 to ad42990 Compare June 26, 2026 14:24
Signed-off-by: Jonathan Norris <jonathan.norris@dynatrace.com>
Signed-off-by: Jonathan Norris <jonathan.norris@dynatrace.com>
Signed-off-by: Jonathan Norris <jonathan.norris@dynatrace.com>

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

This PR updates the SDK provider lifecycle to support domain-aware initialization by adding an optional domain argument to Provider.initialize, forwarding it through MultiProvider, and enforcing that domainScoped provider instances cannot be bound to multiple domains. It also adds conformance tests (web + server) and introduces a shared legacy-provider test helper to validate backwards compatibility with single-argument initialize implementations.

Changes:

  • Extend Provider.initialize to accept (context?, domain?) and pass the bound domain during provider registration/initialization.
  • Add domainScoped provider declaration and reject binding the same domain-scoped instance to more than one domain.
  • Forward domain through web/server MultiProvider.initialize and add conformance + legacy compatibility tests.

Reviewed changes

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

Show a summary per file
File Description
packages/shared/src/provider/provider.ts Adds domainScoped to provider interface and updates initialize signature/docs.
packages/shared/src/open-feature.ts Enforces domain-scoped single-domain binding and forwards (context, domain) into provider initialization.
packages/web/src/provider/multi-provider/multi-provider-web.ts Forwards domain through MultiProvider.initialize to child providers.
packages/server/src/provider/multi-provider/multi-provider.ts Forwards domain through MultiProvider.initialize to child providers.
packages/shared/test/legacy-initialize-provider.ts Adds reusable legacy single-arg initialize test provider helper for web/server suites.
packages/web/test/open-feature.spec.ts Adds conformance tests for passing domain to initialize, enforcing domainScoped, and legacy init compatibility.
packages/web/test/multi-provider-web.spec.ts Adds test asserting MultiProvider forwards domain without breaking legacy child providers.
packages/web/test/evaluation-context.spec.ts Updates expectations to include (context, domain) in initialize calls.
packages/server/test/open-feature.spec.ts Mirrors web conformance tests for server SDK behavior + legacy init compatibility.
packages/server/test/multi-provider.spec.ts Mirrors web MultiProvider legacy-domain-forwarding test for server SDK.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread packages/shared/src/open-feature.ts
Comment thread packages/shared/src/provider/provider.ts

@coderabbitai coderabbitai Bot 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.

🧹 Nitpick comments (1)
packages/shared/test/legacy-initialize-provider.ts (1)

47-50: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Add JSDoc @param/@returns to satisfy format-lint.

The format-lint check warns that the JSDoc blocks on legacyInitializeProvider (Line 47) and legacyInitTestProvider (Line 78) are missing @param and @returns declarations.

📝 Proposed JSDoc additions
 /**
  * Provider with a single-argument initialize that ignores any extra arguments passed by the SDK.
+ * `@param` options provider configuration (paradigm, name, resolver mode)
+ * `@returns` a legacy single-argument initialize provider
  */
 export function legacyInitializeProvider(options: LegacyInitializeProviderOptions): LegacyInitializeProvider {
 /**
  * Legacy initialize provider with the stubs MultiProvider expects on child providers.
+ * `@param` options provider configuration (paradigm, name, resolver mode)
+ * `@param` extras MultiProvider child stubs (events, hooks, track)
+ * `@returns` a legacy provider augmented with MultiProvider child stubs
  */
 export function legacyInitTestProvider(
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@packages/shared/test/legacy-initialize-provider.ts` around lines 47 - 50, Add
the missing JSDoc tags on legacyInitializeProvider and legacyInitTestProvider so
format-lint passes: update each function’s docblock to include an `@param` entry
for the options argument and an `@returns` entry describing the provider returned.
Keep the existing function names and doc comments intact, and apply the same
JSDoc pattern to both legacyInitializeProvider and legacyInitTestProvider.

Source: Linters/SAST tools

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Nitpick comments:
In `@packages/shared/test/legacy-initialize-provider.ts`:
- Around line 47-50: Add the missing JSDoc tags on legacyInitializeProvider and
legacyInitTestProvider so format-lint passes: update each function’s docblock to
include an `@param` entry for the options argument and an `@returns` entry
describing the provider returned. Keep the existing function names and doc
comments intact, and apply the same JSDoc pattern to both
legacyInitializeProvider and legacyInitTestProvider.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: b35fb910-9cfc-4133-b796-ea1f346e78c5

📥 Commits

Reviewing files that changed from the base of the PR and between 3c01041 and 62e2e99.

📒 Files selected for processing (10)
  • packages/server/src/provider/multi-provider/multi-provider.ts
  • packages/server/test/multi-provider.spec.ts
  • packages/server/test/open-feature.spec.ts
  • packages/shared/src/open-feature.ts
  • packages/shared/src/provider/provider.ts
  • packages/shared/test/legacy-initialize-provider.ts
  • packages/web/src/provider/multi-provider/multi-provider-web.ts
  • packages/web/test/evaluation-context.spec.ts
  • packages/web/test/multi-provider-web.spec.ts
  • packages/web/test/open-feature.spec.ts

@jonathannorris jonathannorris marked this pull request as ready for review June 26, 2026 15:01
@jonathannorris jonathannorris requested review from a team as code owners June 26, 2026 15:01

@MattIPv4 MattIPv4 left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

How does the MultiProvider handle domain-scoped providers? Or is wrapping a provider in MultiProvider essentially a way to bypass that restriction?

expect(initializations).toBe(2);
});

it('forwards domain to legacy single-argument child providers without error', async () => {

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Should there also be coverage for forwarding the domain?

expect(initializations).toBe(2);
});

it('forwards domain to legacy single-argument child providers without error', async () => {

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Ditto, coverage for forwarding the domain?

Signed-off-by: Jonathan Norris <jonathan.norris@dynatrace.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.

3 participants