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

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions