Skip to content

Conversation

@JerrettDavis
Copy link
Owner

Add 8 new packages for advanced experimentation scenarios:

  • ExperimentFramework.Rollout: Percentage-based and staged rollout support
  • ExperimentFramework.Targeting: Rule-based user targeting and segmentation
  • ExperimentFramework.Distributed: Shared state for multi-instance deployments
  • ExperimentFramework.Distributed.Redis: Redis implementation for distributed state
  • ExperimentFramework.Audit: Audit trail and compliance logging
  • ExperimentFramework.Admin: REST API endpoints for experiment management
  • ExperimentFramework.Bandit: Multi-armed bandit algorithms (Thompson Sampling, UCB, Epsilon-Greedy)
  • ExperimentFramework.AutoStop: Automatic stopping rules with statistical significance detection

Also includes:

  • Configuration extensibility with IConfigurationSelectionModeHandler and IConfigurationDecoratorHandler
  • Comprehensive BDD-style tests achieving 95%+ code coverage
  • Full documentation integrated into docfx structure

…g and documentation

Add 8 new packages for advanced experimentation scenarios:

- ExperimentFramework.Rollout: Percentage-based and staged rollout support
- ExperimentFramework.Targeting: Rule-based user targeting and segmentation
- ExperimentFramework.Distributed: Shared state for multi-instance deployments
- ExperimentFramework.Distributed.Redis: Redis implementation for distributed state
- ExperimentFramework.Audit: Audit trail and compliance logging
- ExperimentFramework.Admin: REST API endpoints for experiment management
- ExperimentFramework.Bandit: Multi-armed bandit algorithms (Thompson Sampling, UCB, Epsilon-Greedy)
- ExperimentFramework.AutoStop: Automatic stopping rules with statistical significance detection

Also includes:
- Configuration extensibility with IConfigurationSelectionModeHandler and IConfigurationDecoratorHandler
- Comprehensive BDD-style tests achieving 95%+ code coverage
- Full documentation integrated into docfx structure
@JerrettDavis JerrettDavis requested a review from Copilot December 28, 2025 16:45
@JerrettDavis JerrettDavis self-assigned this Dec 28, 2025
@JerrettDavis JerrettDavis added the enhancement New feature or request label Dec 28, 2025
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR introduces 8 new packages for advanced experimentation scenarios including rollout management, targeting, distributed state, audit logging, REST API administration, multi-armed bandit algorithms, and automatic stopping rules. The changes add comprehensive BDD-style tests achieving 95%+ code coverage and full documentation integrated into the docfx structure.

Key Changes

  • Added rollout packages (ExperimentFramework.Rollout) for percentage-based and time-staged deployments
  • Implemented targeting system (ExperimentFramework.Targeting) with rule-based user segmentation
  • Created distributed state management with Redis backend support
  • Added audit, admin API, bandit algorithms, and auto-stop functionality
  • Integrated configuration extensibility through handler interfaces
  • Added comprehensive test coverage using TinyBDD framework

Reviewed changes

Copilot reviewed 134 out of 139 changed files in this pull request and generated no comments.

Show a summary per file
File Description
ExperimentFramework.Tests.csproj Added project references for 8 new packages and Testcontainers.Redis dependency
Targeting test files Tests for rule-based targeting with context providers and configuration
Rollout test files Tests for percentage-based and staged rollout with time-based progression
Resilience test files Tests for circuit breaker functionality with Polly integration
OpenFeature test files Tests for OpenFeature SDK integration for feature flag management
FeatureManagement test files Tests for Microsoft.FeatureManagement variant flag provider
Distributed test files Tests for in-memory and Redis-backed distributed state and locking
Data test files Tests for outcome recording, querying, aggregation and storage

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

@codecov-commenter
Copy link

codecov-commenter commented Dec 28, 2025

Codecov Report

❌ Patch coverage is 97.91895% with 19 lines in your changes missing coverage. Please review.
⚠️ Please upload report for BASE (main@3de7602). Learn more about missing BASE report.

Files with missing lines Patch % Lines
...uration/Building/ConfigurationExperimentBuilder.cs 86.48% 5 Missing ⚠️
...Configuration/Validation/ConfigurationValidator.cs 93.61% 3 Missing ⚠️
...ion/Extensions/Handlers/LoggingDecoratorHandler.cs 91.66% 2 Missing ⚠️
...ork.Distributed/InMemoryDistributedLockProvider.cs 92.59% 2 Missing ⚠️
...entFramework.Bandit/Algorithms/ThompsonSampling.cs 97.36% 1 Missing ⚠️
...tion/Extensions/Handlers/CustomDecoratorHandler.cs 93.75% 1 Missing ⚠️
.../Extensions/Handlers/CustomSelectionModeHandler.cs 83.33% 1 Missing ⚠️
...tFramework.Distributed/InMemoryDistributedState.cs 95.45% 1 Missing ⚠️
...esilience/ResilienceServiceCollectionExtensions.cs 85.71% 1 Missing ⚠️
...Configuration/StagedRolloutSelectionModeHandler.cs 97.95% 1 Missing ⚠️
... and 1 more
Additional details and impacted files
@@           Coverage Diff           @@
##             main      #10   +/-   ##
=======================================
  Coverage        ?   91.82%           
=======================================
  Files           ?      157           
  Lines           ?     5379           
  Branches        ?      970           
=======================================
  Hits            ?     4939           
  Misses          ?      440           
  Partials        ?        0           
Flag Coverage Δ
unittests 91.82% <97.91%> (?)

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

Add tests for:
- BanditServiceCollectionExtensions (8 lines previously uncovered)
- ConfigurationExtensionRegistry (7 lines previously uncovered)
- ConfigurationExtensionServiceCollectionExtensions (8 lines previously uncovered)
- TargetingSelectionModeHandler Apply method (4 lines previously uncovered)

Improves overall patch coverage toward 95%+ target.
Add /p:BuildInParallel=false to both build commands in the CI workflow
to prevent race conditions when building ExperimentFramework.Generators.
The source generator's deps.json file was being accessed simultaneously
by multiple build nodes, causing intermittent build failures.
- Add AddTrial<StableService> to tests that use ExperimentFrameworkBuilder.Define()
  since Define() calls Build() internally which requires at least one trial
- Fix Apply_uses_targeting_modes_constant test to correctly compare ModeType
  (lowercase "targeting" for YAML) with TargetingModes.Targeting (capitalized)
  using case-insensitive comparison
Add tests for:
- Built-in configuration handlers (timeout, custom, logging) via registry
- Data package AddExperimentDataConfiguration method
- CircuitBreakerDecoratorHandler edge cases (unsupported types)
- OutcomeCollectionDecoratorHandler edge cases (unsupported types)

These tests exercise internal handlers indirectly through the
ConfigurationExtensionRegistry, covering previously untested
code paths like type resolution failures and unsupported option types.
@github-actions
Copy link

Code Coverage

Summary
  Generated on: 12/28/2025 - 21:24:12
  Coverage date: 12/28/2025 - 21:23:46 - 12/28/2025 - 21:24:01
  Parser: MultiReport (2x Cobertura)
  Assemblies: 17
  Classes: 176
  Files: 156
  Line coverage: 90.4%
  Covered lines: 4865
  Uncovered lines: 513
  Coverable lines: 5378
  Total lines: 20414
  Branch coverage: 80.8% (2004 of 2479)
  Covered branches: 2004
  Total branches: 2479
  Method coverage: 96.6% (796 of 824)
  Full method coverage: 84.4% (696 of 824)
  Covered methods: 796
  Fully covered methods: 696
  Total methods: 824

ExperimentFramework                                                                                93.9%
  ExperimentFramework.Activation.ActivationEvaluator                                               93.1%
  ExperimentFramework.Activation.SystemTimeProvider                                                 100%
  ExperimentFramework.Decorators.BenchmarkDecoratorFactory                                          100%
  ExperimentFramework.Decorators.DecoratorPipeline                                                  100%
  ExperimentFramework.Decorators.ErrorLoggingDecoratorFactory                                       100%
  ExperimentFramework.Decorators.TimeoutDecoratorFactory                                            100%
  ExperimentFramework.ExperimentBuilder                                                            74.3%
  ExperimentFramework.ExperimentBuilderExtensions                                                   100%
  ExperimentFramework.ExperimentFrameworkBuilder                                                    100%
  ExperimentFramework.ExperimentLoggingBuilder                                                      100%
  ExperimentFramework.ExperimentRegistry                                                            100%
  ExperimentFramework.KillSwitch.ExperimentDisabledException                                        100%
  ExperimentFramework.KillSwitch.InMemoryKillSwitchProvider                                         100%
  ExperimentFramework.KillSwitch.KillSwitchDecoratorFactory                                         100%
  ExperimentFramework.KillSwitch.NoopKillSwitchProvider                                             100%
  ExperimentFramework.KillSwitch.TrialDisabledException                                             100%
  ExperimentFramework.Metrics.MetricsDecoratorFactory                                               100%
  ExperimentFramework.Metrics.NoopExperimentMetrics                                                 100%
  ExperimentFramework.Models.BehaviorRule                                                           100%
  ExperimentFramework.Models.Experiment                                                             100%
  ExperimentFramework.Models.ExperimentRegistration                                                  75%
  ExperimentFramework.Models.SelectionModeExtensions                                                100%
  ExperimentFramework.Models.SelectionRule                                                          100%
  ExperimentFramework.Models.ServiceExperimentDefinition<T>                                         100%
  ExperimentFramework.Models.Trial                                                                  100%
  ExperimentFramework.Naming.DefaultExperimentNamingConvention                                      100%
  ExperimentFramework.Naming.ExperimentSelectorName                                                 100%
  ExperimentFramework.RuntimeExperimentProxy<T>                                                    81.8%
  ExperimentFramework.Selection.Providers.BooleanFeatureFlagProvider                                100%
  ExperimentFramework.Selection.Providers.BooleanFeatureFlagProviderFactory                         100%
  ExperimentFramework.Selection.Providers.ConfigurationValueProvider                                 80%
  ExperimentFramework.Selection.Providers.ConfigurationValueProviderFactory                         100%
  ExperimentFramework.Selection.SelectionModeAttribute                                              100%
  ExperimentFramework.Selection.SelectionModeProviderBase                                           100%
  ExperimentFramework.Selection.SelectionModeProviderFactory<T>                                     100%
  ExperimentFramework.Selection.SelectionModeRegistry                                               100%
  ExperimentFramework.ServiceCollectionExtensions                                                  99.1%
  ExperimentFramework.ServiceExperimentBuilder<T>                                                  93.8%
  ExperimentFramework.Telemetry.NoopExperimentTelemetry                                             100%
  ExperimentFramework.Telemetry.OpenTelemetryExperimentTelemetry                                    100%
  ExperimentFramework.Validation.TrialConflictDetector                                             98.7%
  ExperimentFramework.Validation.TrialConflictException                                             100%
  ExperimentFramework.Variants.VariantFeatureManagerAdapter                                         100%

ExperimentFramework.Admin                                                                           100%
  ExperimentFramework.Admin.ExperimentAdminEndpoints                                                100%

ExperimentFramework.AutoStop                                                                        100%
  ExperimentFramework.AutoStop.AutoStopOptions                                                      100%
  ExperimentFramework.AutoStop.Rules.MinimumSampleSizeRule                                          100%
  ExperimentFramework.AutoStop.Rules.StatisticalSignificanceRule                                    100%
  ExperimentFramework.AutoStop.ServiceCollectionExtensions                                          100%
  ExperimentFramework.AutoStop.VariantData                                                          100%

ExperimentFramework.Bandit                                                                         98.8%
  ExperimentFramework.Bandit.Algorithms.EpsilonGreedy                                               100%
  ExperimentFramework.Bandit.Algorithms.ThompsonSampling                                           97.3%
  ExperimentFramework.Bandit.Algorithms.UpperConfidenceBound                                        100%
  ExperimentFramework.Bandit.ArmStatistics                                                          100%
  ExperimentFramework.Bandit.ServiceCollectionExtensions                                            100%

ExperimentFramework.Configuration                                                                  83.7%
  ExperimentFramework.Configuration.Building.ConfigurationExperimentBuilder                        85.3%
  ExperimentFramework.Configuration.Building.TypeResolver                                            69%
  ExperimentFramework.Configuration.ConfigurationFileWatcher                                       90.1%
  ExperimentFramework.Configuration.Exceptions.ConfigurationLoadException                           100%
  ExperimentFramework.Configuration.Exceptions.ExperimentConfigurationException                     100%
  ExperimentFramework.Configuration.Exceptions.TypeResolutionException                              100%
  ExperimentFramework.Configuration.Extensions.ConfigurationExtensionRegistry                       100%
  ExperimentFramework.Configuration.Extensions.ConfigurationExtensionServiceCollectionExtensions    100%
  ExperimentFramework.Configuration.Extensions.Handlers.ConfigurationKeySelectionModeHandler        100%
  ExperimentFramework.Configuration.Extensions.Handlers.CustomDecoratorHandler                     93.7%
  ExperimentFramework.Configuration.Extensions.Handlers.CustomSelectionModeHandler                 66.6%
  ExperimentFramework.Configuration.Extensions.Handlers.FeatureFlagSelectionModeHandler             100%
  ExperimentFramework.Configuration.Extensions.Handlers.LoggingDecoratorHandler                    91.6%
  ExperimentFramework.Configuration.Extensions.Handlers.TimeoutDecoratorHandler                     100%
  ExperimentFramework.Configuration.Loading.ConfigurationFileDiscovery                              100%
  ExperimentFramework.Configuration.Loading.ExperimentConfigurationLoader                          84.6%
  ExperimentFramework.Configuration.Models.CircuitBreakerDecoratorOptions                           100%
  ExperimentFramework.Configuration.Models.OutcomeCollectionDecoratorOptions                        100%
  ExperimentFramework.Configuration.Models.TimeoutDecoratorOptions                                  100%
  ExperimentFramework.Configuration.ServiceCollectionExtensions                                    90.1%
  ExperimentFramework.Configuration.Validation.ConfigurationValidationError                         100%
  ExperimentFramework.Configuration.Validation.ConfigurationValidationResult                        100%
  ExperimentFramework.Configuration.Validation.ConfigurationValidator                              69.5%

ExperimentFramework.Data                                                                           98.1%
  ExperimentFramework.Data.Configuration.OutcomeCollectionDecoratorHandler                          100%
  ExperimentFramework.Data.Decorators.OutcomeCollectionDecoratorFactory                             100%
  ExperimentFramework.Data.ExperimentBuilderExtensions                                              100%
  ExperimentFramework.Data.Models.ExperimentOutcome                                                 100%
  ExperimentFramework.Data.Models.OutcomeAggregation                                                100%
  ExperimentFramework.Data.Models.OutcomeQuery                                                      100%
  ExperimentFramework.Data.Recording.OutcomeRecorder                                                100%
  ExperimentFramework.Data.Recording.OutcomeRecorderOptions                                         100%
  ExperimentFramework.Data.ServiceCollectionExtensions                                              100%
  ExperimentFramework.Data.Storage.InMemoryOutcomeStore                                            93.6%
  ExperimentFramework.Data.Storage.NoopOutcomeStore                                                 100%

ExperimentFramework.Distributed                                                                    94.6%
  ExperimentFramework.Distributed.InMemoryDistributedLockProvider                                  92.5%
  ExperimentFramework.Distributed.InMemoryDistributedState                                         95.4%
  ExperimentFramework.Distributed.ServiceCollectionExtensions                                       100%

ExperimentFramework.Distributed.Redis                                                               100%
  ExperimentFramework.Distributed.Redis.RedisDistributedLockProvider                                100%
  ExperimentFramework.Distributed.Redis.RedisDistributedState                                       100%
  ExperimentFramework.Distributed.Redis.ServiceCollectionExtensions                                 100%

ExperimentFramework.FeatureManagement                                                               100%
  ExperimentFramework.FeatureManagement.ExperimentBuilderExtensions                                 100%
  ExperimentFramework.FeatureManagement.ServiceCollectionExtensions                                 100%
  ExperimentFramework.FeatureManagement.VariantFeatureFlagProvider                                  100%

ExperimentFramework.Metrics.Exporters                                                              99.3%
  ExperimentFramework.Metrics.Exporters.OpenTelemetryExperimentMetrics                              100%
  ExperimentFramework.Metrics.Exporters.PrometheusExperimentMetrics                                99.2%

ExperimentFramework.OpenFeature                                                                     100%
  ExperimentFramework.OpenFeature.ExperimentBuilderExtensions                                       100%
  ExperimentFramework.OpenFeature.OpenFeatureProvider                                               100%
  ExperimentFramework.OpenFeature.ServiceCollectionExtensions                                       100%

ExperimentFramework.Plugins                                                                        86.8%
  ExperimentFramework.Plugins.Abstractions.PluginEventArgs                                          100%
  ExperimentFramework.Plugins.Abstractions.PluginLoadFailedEventArgs                                100%
  ExperimentFramework.Plugins.Configuration.PluginConfigurationValidator                            100%
  ExperimentFramework.Plugins.Configuration.PluginDiscoveryService                                  100%
  ExperimentFramework.Plugins.Configuration.PluginsConfig                                           100%
  ExperimentFramework.Plugins.HotReload.PluginReloadEventArgs                                       100%
  ExperimentFramework.Plugins.HotReload.PluginReloadFailedEventArgs                                 100%
  ExperimentFramework.Plugins.HotReload.PluginReloadService                                         100%
  ExperimentFramework.Plugins.HotReload.PluginWatcher                                              85.8%
  ExperimentFramework.Plugins.Integration.PluginBuilderExtensions                                   100%
  ExperimentFramework.Plugins.Integration.PluginManager                                            83.3%
  ExperimentFramework.Plugins.Integration.PluginTypeResolver                                        100%
  ExperimentFramework.Plugins.Loading.PluginContext                                                55.4%
  ExperimentFramework.Plugins.Loading.PluginLoadContext                                              72%
  ExperimentFramework.Plugins.Loading.PluginLoader                                                 91.9%
  ExperimentFramework.Plugins.Loading.SharedTypeRegistry                                           89.1%
  ExperimentFramework.Plugins.Manifest.ManifestLoader                                                92%
  ExperimentFramework.Plugins.Manifest.ManifestValidationResult                                      50%
  ExperimentFramework.Plugins.Manifest.ManifestValidator                                           97.7%
  ExperimentFramework.Plugins.Manifest.PluginManifest                                               100%
  ExperimentFramework.Plugins.Manifest.PluginManifestAttribute                                      100%
  ExperimentFramework.Plugins.Manifest.PluginManifestJson                                           100%
  ExperimentFramework.Plugins.Security.PluginSecurityValidator                                       73%
  ExperimentFramework.Plugins.ServiceCollectionDecoratorExtensions                                 70.5%
  ExperimentFramework.Plugins.ServiceCollectionExtensions                                           100%

ExperimentFramework.Resilience                                                                       99%
  ExperimentFramework.Resilience.CircuitBreakerDecoratorFactory                                     100%
  ExperimentFramework.Resilience.CircuitBreakerOpenException                                        100%
  ExperimentFramework.Resilience.CircuitBreakerOptions                                              100%
  ExperimentFramework.Resilience.Configuration.CircuitBreakerDecoratorHandler                       100%
  ExperimentFramework.Resilience.ResilienceBuilderExtensions                                        100%
  ExperimentFramework.Resilience.ResilienceServiceCollectionExtensions                             85.7%

ExperimentFramework.Rollout                                                                        98.7%
  ExperimentFramework.Rollout.Configuration.RolloutSelectionModeHandler                             100%
  ExperimentFramework.Rollout.Configuration.StagedRolloutSelectionModeHandler                      97.9%
  ExperimentFramework.Rollout.ExperimentBuilderExtensions                                           100%
  ExperimentFramework.Rollout.RolloutAllocator                                                       95%
  ExperimentFramework.Rollout.RolloutProvider                                                       100%
  ExperimentFramework.Rollout.ServiceCollectionExtensions                                           100%
  ExperimentFramework.Rollout.StagedRolloutOptions                                                  100%
  ExperimentFramework.Rollout.StagedRolloutProvider                                                 100%

ExperimentFramework.Science                                                                        88.8%
  ExperimentFramework.Science.Analysis.ExperimentAnalyzer                                          88.3%
  ExperimentFramework.Science.Builders.EndpointBuilder                                              100%
  ExperimentFramework.Science.Builders.HypothesisBuilder                                            100%
  ExperimentFramework.Science.Builders.SuccessCriteriaBuilder                                       100%
  ExperimentFramework.Science.Corrections.BenjaminiHochbergCorrection                               100%
  ExperimentFramework.Science.Corrections.BonferroniCorrection                                      100%
  ExperimentFramework.Science.Corrections.HolmBonferroniCorrection                                  100%
  ExperimentFramework.Science.EffectSize.CohensD                                                    100%
  ExperimentFramework.Science.EffectSize.EffectSizeExtensions                                       100%
  ExperimentFramework.Science.EffectSize.OddsRatio                                                  100%
  ExperimentFramework.Science.EffectSize.RelativeRisk                                               100%
  ExperimentFramework.Science.Models.Hypothesis.Endpoint                                              0%
  ExperimentFramework.Science.Models.Hypothesis.HypothesisDefinition                                  0%
  ExperimentFramework.Science.Models.Results.StatisticalTestResult                                 66.6%
  ExperimentFramework.Science.Models.Snapshots.EnvironmentInfo                                        0%
  ExperimentFramework.Science.Power.PowerAnalyzer                                                  78.7%
  ExperimentFramework.Science.Reporting.JsonReporter                                               88.8%
  ExperimentFramework.Science.Reporting.MarkdownReporter                                           72.8%
  ExperimentFramework.Science.ServiceCollectionExtensions                                           100%
  ExperimentFramework.Science.Snapshots.InMemorySnapshotStore                                      90.1%
  ExperimentFramework.Science.Statistics.ChiSquareTest                                             79.1%
  ExperimentFramework.Science.Statistics.MannWhitneyUTest                                          97.3%
  ExperimentFramework.Science.Statistics.OneWayAnova                                               98.4%
  ExperimentFramework.Science.Statistics.PairedTTest                                               81.5%
  ExperimentFramework.Science.Statistics.TwoSampleTTest                                            88.4%

ExperimentFramework.StickyRouting                                                                  92.5%
  ExperimentFramework.StickyRouting.ExperimentBuilderExtensions                                     100%
  ExperimentFramework.StickyRouting.ServiceCollectionExtensions                                     100%
  ExperimentFramework.StickyRouting.StickyRoutingProvider                                          86.6%
  ExperimentFramework.StickyRouting.StickyTrialRouter                                               100%

ExperimentFramework.Targeting                                                                       100%
  ExperimentFramework.Targeting.Configuration.TargetingSelectionModeHandler                         100%
  ExperimentFramework.Targeting.InMemoryTargetingConfiguration                                      100%
  ExperimentFramework.Targeting.ServiceCollectionExtensions                                         100%
  ExperimentFramework.Targeting.SimpleTargetingContext                                              100%
  ExperimentFramework.Targeting.TargetingProvider                                                   100%
  ExperimentFramework.Targeting.TargetingRules                                                      100%

@JerrettDavis JerrettDavis requested a review from Copilot December 28, 2025 21:27
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 136 out of 145 changed files in this pull request and generated no new comments.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

@JerrettDavis JerrettDavis merged commit d61346a into main Dec 28, 2025
4 checks passed
@JerrettDavis JerrettDavis deleted the feat/advanced-experimentation-packages branch December 28, 2025 21:33
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants