From 7e5c95d786995d9960501bf7e91af71602ba1290 Mon Sep 17 00:00:00 2001 From: Lior Date: Tue, 26 May 2026 02:22:02 -0400 Subject: [PATCH 1/5] claim: task-b0786-feature-flags-doc-slice-20260526 - feature flags doc slice Co-Authored-By: Codex --- .../task-b0786-feature-flags-doc-slice-20260526.md | 13 +++++++++++++ 1 file changed, 13 insertions(+) create mode 100644 docs/claims/task-b0786-feature-flags-doc-slice-20260526.md diff --git a/docs/claims/task-b0786-feature-flags-doc-slice-20260526.md b/docs/claims/task-b0786-feature-flags-doc-slice-20260526.md new file mode 100644 index 0000000000..f8ffe5259b --- /dev/null +++ b/docs/claims/task-b0786-feature-flags-doc-slice-20260526.md @@ -0,0 +1,13 @@ +# Claim - task-b0786-feature-flags-doc-slice-20260526 + +- **Session ID:** cx-20260526T0620Z-b0786 +- **Harness:** codex +- **Claimed at:** 2026-05-26T06:20:00Z +- **ETA:** 2026-05-26T07:20:00Z +- **Scope:** B-0786 smallest doc slice: add a feature-flags substrate decision doc and wire the backlog row to it; no implementation. +- **Durable target:** `docs/DECISIONS/2026-05-26-feature-flags-substrate-openfeature-flipt.md`; `docs/backlog/P2/B-0786-feature-flags-substrate-openfeature-as-operator-contract-flipt-as-simplest-first-backend-aaron-mika-2026-05-25.md` +- **Platform mirror:** none + +## Notes + +Selected after live Codex/Vera health, open PR lane, and remote claim ownership checks. Path set is docs-only and outside parked remote claim refs and known dirty worktrees. From c904d7af119a3615e986ef39d3f014b799295997 Mon Sep 17 00:00:00 2001 From: Lior Date: Tue, 26 May 2026 02:26:53 -0400 Subject: [PATCH 2/5] docs: record feature flags substrate decision Co-Authored-By: Codex --- ...ature-flags-substrate-openfeature-flipt.md | 69 +++++++++++++++++++ ...est-first-backend-aaron-mika-2026-05-25.md | 11 ++- 2 files changed, 79 insertions(+), 1 deletion(-) create mode 100644 docs/DECISIONS/2026-05-26-feature-flags-substrate-openfeature-flipt.md diff --git a/docs/DECISIONS/2026-05-26-feature-flags-substrate-openfeature-flipt.md b/docs/DECISIONS/2026-05-26-feature-flags-substrate-openfeature-flipt.md new file mode 100644 index 0000000000..d8da2adaa1 --- /dev/null +++ b/docs/DECISIONS/2026-05-26-feature-flags-substrate-openfeature-flipt.md @@ -0,0 +1,69 @@ +# ADR: Feature flags substrate uses OpenFeature as contract and Flipt first + +**Status:** Proposed +**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. diff --git a/docs/backlog/P2/B-0786-feature-flags-substrate-openfeature-as-operator-contract-flipt-as-simplest-first-backend-aaron-mika-2026-05-25.md b/docs/backlog/P2/B-0786-feature-flags-substrate-openfeature-as-operator-contract-flipt-as-simplest-first-backend-aaron-mika-2026-05-25.md index 10004ec462..410d545746 100644 --- a/docs/backlog/P2/B-0786-feature-flags-substrate-openfeature-as-operator-contract-flipt-as-simplest-first-backend-aaron-mika-2026-05-25.md +++ b/docs/backlog/P2/B-0786-feature-flags-substrate-openfeature-as-operator-contract-flipt-as-simplest-first-backend-aaron-mika-2026-05-25.md @@ -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 @@ -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 @@ -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. - [ ] `Zeta.Feature.Flags` F# project per B-0776 plugin pattern: - `IFeatureFlagProvider` interface (mirrors OpenFeature Provider contract; F# native) From 6f15725c1a71242951bbbebb0e2170aa9db2073b Mon Sep 17 00:00:00 2001 From: Lior Date: Tue, 26 May 2026 02:27:10 -0400 Subject: [PATCH 3/5] release: task-b0786-feature-flags-doc-slice-20260526 - docs slice ready Co-Authored-By: Codex --- .../task-b0786-feature-flags-doc-slice-20260526.md | 13 ------------- 1 file changed, 13 deletions(-) delete mode 100644 docs/claims/task-b0786-feature-flags-doc-slice-20260526.md diff --git a/docs/claims/task-b0786-feature-flags-doc-slice-20260526.md b/docs/claims/task-b0786-feature-flags-doc-slice-20260526.md deleted file mode 100644 index f8ffe5259b..0000000000 --- a/docs/claims/task-b0786-feature-flags-doc-slice-20260526.md +++ /dev/null @@ -1,13 +0,0 @@ -# Claim - task-b0786-feature-flags-doc-slice-20260526 - -- **Session ID:** cx-20260526T0620Z-b0786 -- **Harness:** codex -- **Claimed at:** 2026-05-26T06:20:00Z -- **ETA:** 2026-05-26T07:20:00Z -- **Scope:** B-0786 smallest doc slice: add a feature-flags substrate decision doc and wire the backlog row to it; no implementation. -- **Durable target:** `docs/DECISIONS/2026-05-26-feature-flags-substrate-openfeature-flipt.md`; `docs/backlog/P2/B-0786-feature-flags-substrate-openfeature-as-operator-contract-flipt-as-simplest-first-backend-aaron-mika-2026-05-25.md` -- **Platform mirror:** none - -## Notes - -Selected after live Codex/Vera health, open PR lane, and remote claim ownership checks. Path set is docs-only and outside parked remote claim refs and known dirty worktrees. From a0bf8bf634e0eb3b33dcfface2efebfae8875149 Mon Sep 17 00:00:00 2001 From: Lior Date: Tue, 26 May 2026 02:27:35 -0400 Subject: [PATCH 4/5] docs: trim feature flags ADR whitespace Co-Authored-By: Codex --- .../2026-05-26-feature-flags-substrate-openfeature-flipt.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/docs/DECISIONS/2026-05-26-feature-flags-substrate-openfeature-flipt.md b/docs/DECISIONS/2026-05-26-feature-flags-substrate-openfeature-flipt.md index d8da2adaa1..e312c0e18e 100644 --- a/docs/DECISIONS/2026-05-26-feature-flags-substrate-openfeature-flipt.md +++ b/docs/DECISIONS/2026-05-26-feature-flags-substrate-openfeature-flipt.md @@ -1,8 +1,8 @@ # ADR: Feature flags substrate uses OpenFeature as contract and Flipt first -**Status:** Proposed -**Date:** 2026-05-26 -**Backlog:** B-0786 +**Status:** Proposed +**Date:** 2026-05-26 +**Backlog:** B-0786 **Scope:** Decision substrate only; no implementation in this slice. ## Context From 06de71864842b790fd4167e0b65f823d67eeaa34 Mon Sep 17 00:00:00 2001 From: Lior Date: Tue, 26 May 2026 02:32:38 -0400 Subject: [PATCH 5/5] docs: accept feature flags ADR Align the ADR status with the B-0786 decision-substrate acceptance row so the PR artifacts do not contradict each other. Co-Authored-By: Codex --- .../2026-05-26-feature-flags-substrate-openfeature-flipt.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/DECISIONS/2026-05-26-feature-flags-substrate-openfeature-flipt.md b/docs/DECISIONS/2026-05-26-feature-flags-substrate-openfeature-flipt.md index e312c0e18e..933f825004 100644 --- a/docs/DECISIONS/2026-05-26-feature-flags-substrate-openfeature-flipt.md +++ b/docs/DECISIONS/2026-05-26-feature-flags-substrate-openfeature-flipt.md @@ -1,6 +1,6 @@ # ADR: Feature flags substrate uses OpenFeature as contract and Flipt first -**Status:** Proposed +**Status:** Accepted **Date:** 2026-05-26 **Backlog:** B-0786 **Scope:** Decision substrate only; no implementation in this slice.