|
| 1 | +# CLAUDE.md |
| 2 | + |
| 3 | +This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository. |
| 4 | + |
| 5 | +## Project Overview |
| 6 | + |
| 7 | +OpenFeature Ruby SDK — implements the [OpenFeature specification](https://openfeature.dev) (v0.8.0) for vendor-agnostic feature flag management. Published as the `openfeature-sdk` gem. Pure Ruby, no runtime dependencies. Requires Ruby >= 3.1. |
| 8 | + |
| 9 | +## Commands |
| 10 | + |
| 11 | +```bash |
| 12 | +# Install dependencies |
| 13 | +bundle install |
| 14 | + |
| 15 | +# Run full test suite + linting (default rake task) |
| 16 | +bundle exec rake |
| 17 | + |
| 18 | +# Run tests only |
| 19 | +bundle exec rspec |
| 20 | + |
| 21 | +# Run a single test file |
| 22 | +bundle exec rspec spec/open_feature/sdk/client_spec.rb |
| 23 | + |
| 24 | +# Run a specific test by line number |
| 25 | +bundle exec rspec spec/open_feature/sdk/client_spec.rb:40 |
| 26 | + |
| 27 | +# Lint (StandardRB with performance plugin) |
| 28 | +bundle exec rake standard |
| 29 | + |
| 30 | +# Auto-fix lint issues |
| 31 | +bundle exec standardrb --fix |
| 32 | +``` |
| 33 | + |
| 34 | +## Architecture |
| 35 | + |
| 36 | +Entry point: `require 'open_feature/sdk'` — the `OpenFeature::SDK` module delegates all method calls to `API.instance` (Singleton) via `method_missing`. |
| 37 | + |
| 38 | +### Core Components |
| 39 | + |
| 40 | +- **API** (`lib/open_feature/sdk/api.rb`) — Singleton orchestrator. Manages providers (global or domain-scoped), builds clients, stores API-level evaluation context, and registers event handlers. |
| 41 | +- **Configuration** (`lib/open_feature/sdk/configuration.rb`) — Thread-safe provider storage. Handles provider lifecycle (init/shutdown), domain-scoped provider mapping, and event dispatching. Uses Mutex for all shared state. |
| 42 | +- **Client** (`lib/open_feature/sdk/client.rb`) — Flag evaluation interface. Uses `class_eval` metaprogramming to generate 12 typed methods: `fetch_{boolean,string,number,integer,float,object}_value` and `fetch_*_details` variants. Merges evaluation contexts (API + client + invocation). |
| 43 | +- **EvaluationContext** (`lib/open_feature/sdk/evaluation_context.rb`) — Key-value targeting data with a special `targeting_key`. Supports merging with precedence: invocation > client > API. |
| 44 | + |
| 45 | +### Provider System |
| 46 | + |
| 47 | +- **Provider interface** — Must implement 6 `fetch_*_value` methods, optional `init(evaluation_context)` and `shutdown`. Returns `ResolutionDetails`. |
| 48 | +- **EventEmitter** (`lib/open_feature/sdk/provider/event_emitter.rb`) — Mixin that providers include to emit lifecycle events. |
| 49 | +- **Built-in providers**: `NoOpProvider` (default), `InMemoryProvider` (testing/examples). |
| 50 | +- **Provider states**: `NOT_READY → READY`, with `ERROR`, `FATAL`, `STALE` transitions. Tracked per-instance via `ProviderStateRegistry` using `object_id`. |
| 51 | +- **Initialization modes**: `set_provider` (async, background thread) or `set_provider_and_wait` (sync, raises `ProviderInitializationError` on failure). |
| 52 | + |
| 53 | +### Event System |
| 54 | + |
| 55 | +- **EventDispatcher** (`lib/open_feature/sdk/event_dispatcher.rb`) — Thread-safe pub-sub. Handlers called outside mutex to prevent deadlocks. Supports API-level and client-level handlers. |
| 56 | +- **ProviderEvent** constants: `PROVIDER_READY`, `PROVIDER_ERROR`, `PROVIDER_STALE`, `PROVIDER_CONFIGURATION_CHANGED`. |
| 57 | + |
| 58 | +## Test Structure |
| 59 | + |
| 60 | +Tests in `spec/` split into two categories: |
| 61 | +- `spec/specification/` — OpenFeature spec compliance tests, organized by requirement number (e.g., "Requirement 1.1.1") |
| 62 | +- `spec/open_feature/` — Unit tests for individual components |
| 63 | + |
| 64 | +Uses Timecop for time-sensitive tests (auto-reset after each test), SimpleCov for coverage. |
| 65 | + |
| 66 | +## Conventions |
| 67 | + |
| 68 | +- **Linter**: StandardRB (Ruby Standard Style) with `standard-performance` plugin, targeting Ruby 3.1 |
| 69 | +- **Commits**: Conventional Commits required for PR titles (enforced by CI) |
| 70 | +- **Releases**: Automated via release-please; changelog auto-generated |
| 71 | +- **Threading**: All shared mutable state must be Mutex-protected. Provider storage uses immutable reassignment (`@providers = @providers.dup.merge(...)`) |
| 72 | +- **Structs for DTOs**: `EvaluationDetails`, `ResolutionDetails`, `ClientMetadata`, `ProviderMetadata` are `Struct`-based |
0 commit comments