Initial Commit

This commit is contained in:
2026-05-27 23:29:53 +01:00
commit fbc70f96e6
10000 changed files with 1102152 additions and 0 deletions

View File

@@ -0,0 +1,33 @@
# Capability Spec: feature-flags
**Package**: `@suaveplan/feature-flags`
**Version**: 0.0.0 (genesis)
**Status**: ADDED
---
## ADDED Requirements
### FF-01 — Provider contract
`BaseFlagProvider` MUST implement `getFlag(key): FlagDefinition | undefined`, `listFlags(): FlagDefinitionMap`, `subscribe(listener): () => void`, and `close(): void`. Concrete providers (`MemoryProvider`, `JsonProvider`) MUST satisfy the same contract test suite.
### FF-02 — Evaluator contract
`Evaluator.evaluate(key, context)` MUST resolve the flag definition, run its strategy chain in declared order, short-circuit on the first non-`none` `StrategyResult`, and return a `FlagEvaluationResult` carrying `{ value, reason, flag, context, duration_ms }`. Unknown flag keys MUST throw or return a fallback per `EvaluatorOptions.fallbackMode`.
### FF-03 — Deterministic bucketing
`PercentageStrategy` MUST use `hashToPercentage(combineKeys(flagKey, userKey))` and bucket `[0, rolloutPercentage)`. For fixed inputs it MUST return the same result across processes and platforms; the implementation MUST NOT depend on `Math.random`.
### FF-04 — Composite strategy semantics
`CompositeStrategy` MUST evaluate children left-to-right. `AND` MUST short-circuit on the first `none`/`no-match`. `OR` MUST short-circuit on the first `match`. Errors in a child strategy MUST surface as `FEATURE_FLAGS.STRATEGY_ERROR` with the child's index in context.
### FF-05 — Attribute targeting
`AttributeStrategy` MUST support `AttributeOperator` values `eq`, `neq`, `in`, `nin`, `gt`, `gte`, `lt`, `lte`, `contains`, `startsWith`, `endsWith`, `regex`. `getNestedValue(ctx, path)` MUST walk dot-notation paths safely, returning `undefined` for missing segments rather than throwing.
### FF-06 — Change notification
Any change pushed through a provider (`updateFlag`, remote poll) MUST emit a `FlagChangeEvent` on the shared `EventBus`. `FlagManager` MUST expose `subscribe(listener)` that forwards these events to consumers.
### FF-07 — Observability
Every `Evaluator.evaluate` call MUST record a histogram `ff.evaluate.duration_ms` and increment `ff.evaluate.total` with labels `flag` and `result` (`match | no-match | fallback | error`).
### FF-08 — Definition validation
All flag definitions registered via `FlagRegistry` MUST pass `FlagDefinitionSchema.parse`. Invalid shapes MUST surface as `FEATURE_FLAGS.INVALID_DEFINITION`.