feat(flags): feature-flag system with sdk.flags and operation gating#59
Merged
Conversation
Platform instances enable features per environment, exposed at GET /ide-service/flags (categories internal/preview/features, each with available+enabled lists). This adds: - sdk.flags (FlagsResource): get()/refresh()/is_available()/is_enabled()/ require(), category-scoped or union lookups, categories_with() for collision insight. Snapshot models are frozen pydantic classes - Gating infrastructure: APIOperation gains required_flag: FlagRequirement | None (mirrors the input_model pattern); enforced as the first step of execute_operation, so a gated call raises BEFORE any request when the flag is not enabled. _require_flag() escape hatch on ResourceBase/BoundModel for non-operation paths (streams, shell features). No existing endpoint is gated - FlagsStore engine in new top-level feature_flags.py (cycle-free wrt core<->http_client), hosted per-connection on APIHttpClient; lazy fetch under an asyncio.Lock (one fetch across concurrent gated calls), cached for client lifetime, refresh() re-fetches. Fail closed on legacy instances: flags-endpoint 404 caches an empty snapshot and gated calls raise with a legacy-platform hint; transient errors propagate uncached - New exceptions: FeatureFlagError base (flag/category attrs) with FeatureNotAvailableError (wrong instance/platform version) and FeatureNotEnabledError (available but off), exported top-level along with FlagCategory/FlagsSnapshot/CategoryFlags - Tests: snapshot model matrix, sdk.flags caching/refresh/404/transient behavior, operation gating incl. pre-request fail-fast proof (gated route never called), single flag fetch across concurrent gated calls, _require_flag on ResourceBase and bound/detached BoundModel; exception matrix extended; live integration test - Docs: CONTRIBUTING 'Gating an Endpoint Behind a Feature Flag' recipe (explicit category required in SDK declarations, async-generator guidance, test pattern), README 'Feature flags' section
🛡️ Bandit Security Scan Results✅ No security issues found by Bandit. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Platform instances enable features per environment, exposed at GET /ide-service/flags (categories internal/preview/features, each with available+enabled lists). This adds: