Skip to content

Design/guidance: first-class support for 'local AND remote' (AND) feature gating, or recommended approach? #296

Description

@kirich1409

Context

Featured's resolution is OR-priority by design: local override ?: remote ?: default
(ValueResolutionStrategy.Default). A flag's effective value is the first non-null candidate.

We have a recurring scenario this model does not cover directly: "client-readiness AND
server-rollout" gating
. A feature must be enabled only when both sides explicitly enable it:

  • a client/local gate — this app build has shipped and turned the feature on, and
  • a remote gate — the backend has rolled the feature out.

The key safety property: a remote flag is global across all clients and all backends, so the
remote side must not be able to enable a feature on a client that has not locally enabled it
(kill-switch / fail-closed). i.e. enabled = local AND remote, not local OR remote.

This is an analogue of the classic "bundled local_feature_toggle.json AND server config" pattern.

Why the current options don't fit cleanly

  1. Custom ValueResolutionStrategy doing default && remote — works, but it's a global
    resolution override applied to every flag, it reuses default to mean "local gate" (a
    conflation: default normally means "value when no remote"), and it has a footgun — a flag
    with default = false can never be enabled by the server (false && remote == false). It also
    feels like working against the library's intended model.
  2. Two separate flags (localFlags + remoteFlags) AND-ed at the call site — the natural
    expression, but it is blocked by the runtime-isolation gap and the debug-panel UX problem
    described in Local and remote flags with the same key are not isolated (shared snapshot + shared provider chain) #294 (same-key collision; local/remote not isolated; two required toggles per
    feature is confusing for QA).

Question for the maintainer

Is "local AND remote" (client-readiness AND server-rollout) gating a scenario Featured should
support first-class — e.g. a per-feature resolution policy, or a declared hybrid feature
(local + remote) that is resolved as AND and presented in the debug panel as a single logical
feature — ?

Or is there a recommended standard approach we are missing, and is expressing AND a sign we are
deviating too far from the library's intended design? Honest guidance either way would help us
decide whether to keep a project-side interim or wait for first-class support.

Related: #294 (the technical isolation + panel-UX prerequisite for the two-flag form).

Version: 1.2.0

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions