Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
# ADR: Feature flags substrate uses OpenFeature as contract and Flipt first

**Status:** Accepted
**Date:** 2026-05-26
**Backlog:** B-0786
**Scope:** Decision substrate only; no implementation in this slice.

## Context

B-0786 records the feature-flags substrate shape for the B-0776
plugin sequence. The operator requirement is deliberately small:
open-source tooling, lowest operational overhead first, and a path
to add heavier backends only after the simple backend fails an
observed requirement.

The row also composes with namespace and experiment routing work:
operator-specific namespaces need flag values that do not perturb the
common namespace, and Argo Rollouts needs a stable way to ask whether
a rollout should proceed for a given operator context.

## Decision

Use **OpenFeature** as the operator-facing feature-flag contract and
ship **Flipt** as the first backend.

The intended layering is:

| Layer | Choice | Reason |
|---|---|---|
| Operator API | OpenFeature SDK shape | Backend-agnostic contract; keeps application code stable when providers change |
| First backend | Flipt | Smallest open-source operating surface for the first implementation |
| Later backends | Unleash, Flagd, in-memory providers | Add only when a concrete requirement exceeds the Flipt shape |
| Routing composition | Namespace context plus experiment header | Lets operator branches vary flags without changing common namespace defaults |

The F# surface should expose a native provider interface and wrap the
OpenFeature provider model rather than binding callers directly to one
backend. Flipt is an implementation choice, not the operator contract.

## Consequences

Positive:

- Operators get a standard feature-flag API while Zeta keeps backend
choice replaceable.
- The first implementation stays small enough for a P2 plugin slice.
- Namespace routing and progressive delivery can share one decision
surface instead of inventing separate toggle semantics.

Costs:

- Flipt-specific operational details still need an implementation row
before the plugin can ship.
- OpenFeature conformance tests become part of the eventual provider
contract, even though this slice does not add code.

## Out Of Scope

- Implementing `Zeta.Feature.Flags`.
- Adding Flipt deployment manifests.
- Adding Argo Rollouts AnalysisTemplate examples.
- Choosing a second backend before Flipt fails an observed requirement.

## Follow-Up

- Add `docs/plugins/zeta-feature-flags.md` with persona ontology maps
and rollout examples.
- Implement the F# provider interface and OpenFeature adapter in the
B-0776 plugin sequence.
- Add conformance tests that every future backend must pass.
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ title: Feature flags substrate — OpenFeature as operator contract; Flipt as si
effort: M
ask: aaron-mika-grok 2026-05-25
created: 2026-05-25
last_updated: 2026-05-25
last_updated: 2026-05-26
depends_on:
- B-0776
- B-0777
Expand Down Expand Up @@ -60,6 +60,12 @@ Per Aaron's "simplest first" — ship Flipt-backed only in v1;
add Unleash / Flagd / etc. backends as v2 sub-rows when the
simple shape demonstrably doesn't fit.

Decision substrate:
`docs/DECISIONS/2026-05-26-feature-flags-substrate-openfeature-flipt.md`
records OpenFeature as the operator contract and Flipt as the
first backend. This keeps B-0786 implementation work anchored to a
reviewable ADR before any project or provider code lands.

## OpenFeature is the load-bearing operator contract

[OpenFeature](https://openfeature.dev/) is the **CNCF Sandbox
Expand Down Expand Up @@ -100,6 +106,9 @@ will never need beyond Flipt.

## Acceptance

- [x] Decision substrate:
`docs/DECISIONS/2026-05-26-feature-flags-substrate-openfeature-flipt.md`
records OpenFeature-as-contract and Flipt-first backend choice.
Comment thread
AceHack marked this conversation as resolved.
- [ ] `Zeta.Feature.Flags` F# project per B-0776 plugin pattern:
- `IFeatureFlagProvider` interface (mirrors OpenFeature
Provider contract; F# native)
Expand Down
Loading