Skip to content

Conversation

@JerrettDavis
Copy link
Owner

No description provided.

… governance and rollout features

- Create standalone dashboard NuGet packages (Dashboard, Dashboard.UI, Dashboard.Api, Dashboard.Abstractions, Dashboard.Analytics)
- Implement full governance UI with lifecycle management, approvals, policies, versions, and audit trail
- Add experiment-specific rollout management with staged deployment and progress tracking
- Implement multi-tenancy support with pluggable ITenantResolver (HttpHeader, Claim, Subdomain, Composite)
- Add authorization delegation via IAuthorizationProvider with claims-based permissions
- Create comprehensive API endpoints for experiments, governance, analytics, rollout, and targeting
- Migrate dashboard pages from AspireDemo.Web to reusable Dashboard.UI components
- Implement real-time killswitch synchronization across dashboard and downstream apps
- Add informational messages to governance pages when persistence is not configured
- Add XML documentation to resolve all CS1591 warnings
- Update blog plugin endpoints to respect killswitch state for proper experiment control
- Implement polling mechanism for killswitch state updates every 3 seconds
- Add DashboardHost sample application demonstrating dashboard integration
- Configure AspireDemo.Web to use embedded dashboard via /dashboard route
…ce and experiment integration

- Add IRolloutPersistenceBackplane interface for rollout configuration storage
- Implement InMemoryRolloutPersistence for development/testing
- Integrate rollout endpoints with IMutableExperimentRegistry for real-time experiment percentage updates
- Update rollout advancement to modify actual experiment rollout percentages
- Add rollout completion logic that sets experiments to 100% when rollout completes
- Add rollout rollback functionality that resets experiments to 0%
- Validate target variants exist before creating rollouts
- Update RolloutConfiguration and RolloutStageDto models in Dashboard.Abstractions
- Migrate ExperimentApiClient to use shared rollout DTOs from Abstractions
- Update Rollout.razor UI to use new RolloutConfiguration model
- Register InMemoryRolloutPersistence as default implementation in DI
- Add tenant-aware rollout configuration storage
- Implement pause, resume, restart rollout operations
- Add user-facing error messages when persistence not configured
…ations

- Remove required constraint from RolloutConfiguration.ExperimentName to allow JSON deserialization
- Add Rollout property to Dashboard.Abstractions.ExperimentInfo
- Update DefaultDashboardDataProvider to fetch and populate rollout configurations from IRolloutPersistenceBackplane
- Inject IRolloutPersistenceBackplane into DefaultDashboardDataProvider constructor
- Make GetExperimentsAsync and GetExperimentAsync async to support rollout data loading
- Ensure ExperimentName is populated when returning rollout configurations
- Fix "JSON deserialization for type 'RolloutConfiguration' was missing required properties" error
- Add ASP.NET Core Identity with Entity Framework Core and SQLite
- Create ApplicationUser model with custom properties (FullName, Department, permissions)
- Implement ApplicationDbContext for Identity data storage
- Add IdentitySeeder to create default roles (Admin, Experimenter, Viewer, Analyst)
- Seed 4 test users with different roles and permission levels
- Create Login page with quick-login buttons for demo users
- Create Logout and AccessDenied pages
- Configure authentication and authorization middleware in Program.cs
- Add authorization policies (CanAccessExperiments, CanModifyExperiments, CanManageRollouts, AdminOnly)
- Enable database migration and seeding on application startup

Test Users:
- admin@experimentdemo.com / Admin123! - Full access
- experimenter@experimentdemo.com / Experimenter123! - Can modify experiments
- viewer@experimentdemo.com / Viewer123! - Read-only access
- analyst@experimentdemo.com / Analyst123! - Analytics focus

fix(rollout): improve UI responsiveness and error handling

- Add StateHasChanged() calls to ensure UI updates after rollout actions
- Add detailed error logging for failed rollout operations
- Fix rollout stage initialization when switching between experiments
- Improve rollout wizard state management
- Wrap MainLayout in AuthorizeView to require authentication
- Add user profile section to sidebar showing authenticated user
- Display user avatar, name, and role badge in sidebar
- Add color-coded role badges (Admin=red, Experimenter=blue, Analyst=green, Viewer=gray)
- Add logout button to sidebar user section
- Show "Authentication Required" page for unauthorized users
- Enable RequireAuthorization in dashboard options with "CanAccessExperiments" policy
- Add CSS styling for sidebar-user section and unauthorized page
- Ignore SQLite database files in gitignore

The dashboard now requires authentication and displays the current user's information in the sidebar. Unauthorized users see a friendly prompt to sign in.
- Create initial Identity migration with all AspNet* tables
- Add ApplicationUser custom properties to schema
- Generate migration files for Identity database schema
- Fix "SQLite Error 1: no such table: AspNetRoles" error

The migrations will now automatically create the Identity tables (AspNetUsers, AspNetRoles, AspNetUserRoles, AspNetUserClaims, etc.) when the application starts.
- Update DashboardMiddleware to redirect unauthenticated users to login page
- Add returnUrl query parameter support to preserve original destination
- Redirect authenticated users without proper permissions to AccessDenied page
- Update Login page to accept and use returnUrl parameter after successful login
- Remove full-page AuthorizeView from MainLayout (middleware handles auth now)
- Keep AuthorizeView only for sidebar user section display
- Wrap MainLayout in CascadingAuthenticationState for proper auth context

Authentication Flow:
1. Unauthenticated user visits /dashboard → Redirected to /Account/Login?returnUrl=/dashboard
2. User logs in successfully → Redirected back to /dashboard (or original returnUrl)
3. Authenticated user without permissions → Redirected to /Account/AccessDenied
4. Dashboard pages are now only accessible to authenticated users with proper roles

This ensures users cannot see any dashboard content without authentication, and they're automatically redirected back to their intended destination after login.
…uthentication

- Added UseExperimentDashboard() method to register middleware before endpoint mapping
- Register DashboardOptions as singleton (in addition to IOptions pattern)
- Update Program.cs to call UseExperimentDashboard() after UseAuthentication/UseAuthorization
- Fixes issue where RequireAuthorization was not being enforced
…ributes

- Add MinimalLayout for unauthenticated pages (landing, login, access denied)
- Set all Dashboard.UI pages to use Dashboard MainLayout with [Authorize] attribute
- Landing page (/) now uses MinimalLayout with no sidebar
- Dashboard pages require authentication at component level AND middleware level
…mode

- Added [SupplyParameterFromForm] attribute to login model for .NET 8+ form handling
- Added @rendermode InteractiveServer to Login and Home pages
- Added null checks for model in login methods
- Fixed form submission issue requiring FormName attribute
…ve mode

- InteractiveServer render mode doesn't use FormName/SupplyParameterFromForm
- Reverted to simple two-way binding with EditForm
- Removed null checks since model is no longer nullable
- Set prerender: false on Login and Home pages
- Prevents static SSR phase that requires FormName attribute
- Pages now render only in interactive mode
- Added FormName='LoginForm' to EditForm
- .NET 8+ requires FormName on all forms for identification
- Keep simple model binding without SupplyParameterFromForm for interactive mode
…r demo cards

- Added Enhance attribute to EditForm for enhanced navigation
- Added AntiforgeryToken component for CSRF protection
- Changed demo user cards from div to button type='button' to prevent form submission
- Ensures click handlers don't accidentally trigger form post
…nteractive mode

- Removed FormName - not needed in fully interactive mode
- Removed Enhance - only for static SSR forms
- Removed AntiforgeryToken - not needed for SignalR-based forms
- Pure interactive Blazor forms work through event handlers, not form posts
- Removed EditForm completely to avoid FormName requirement
- Using plain HTML inputs with @Bind for two-way binding
- Changed submit button to type='button' with @OnClick handler
- No form POST - pure event-driven interactive Blazor
…ractive components

- Created AccountEndpoints with /api/account/login and /api/account/logout
- Login uses traditional HTML form POST to avoid 'headers already started' error
- Demo user cards now use individual forms with hidden fields
- Logout auto-submits form to logout endpoint
- Fixes issue where SignInManager can't set cookies in interactive Blazor components
…iddleware auth

- Removed [Authorize] attribute from Dashboard.UI _Imports.razor
- Middleware already enforces authentication via DashboardMiddleware
- Component-level auth after form POST redirect was causing blank screen
- Middleware auth is sufficient and works correctly with form-based login
- Move DefaultLayout parameter from Router to AuthorizeRouteView component
- Add comprehensive CSS reset to eliminate browser default margins/padding
- Implement dark mode support with media queries and .theme-dark classes
- Fix navigation link styling with !important flags for proper rendering
- Add cache-busting version parameters to CSS files
- Correct DSL editor route from /dashboard/dsl-editor to /dashboard/dsl
- Fix @media query syntax in Razor files (use @@media)
- Auto-load current configuration on DSL editor page initialization
- Add change detection logic to only show modified experiments in preview
- Implement HasChanges() method to compare experiment configurations
- Skip unchanged experiments in validation preview panel
- Fall back to sample YAML if auto-load fails
- Auto-discover plugins during application initialization
- Remove manual 'Discover Plugins' button from UI
- Log plugin discovery events to audit trail
- Update empty state message to reflect automatic discovery
- Plugins are now available immediately upon dashboard access
- Automate termination of running Aspire processes
- Clean and rebuild solution
- Start AppHost and test endpoints
- Provide detailed test results and application URLs
- Add Plugin source type to ExperimentSource enum
- Plugin services now appear as experiments in Experiments page
- Add visual distinction with purple border and Plugin badge
- Support variant activation for plugin implementations
- Add Plugins category filter
- Convert Source property to string for JSON serialization compatibility
- Add SourceEnum internal property for code use with JsonIgnore attribute
- Configure experiment governance in ApiService with in-memory persistence
- Set up approval gates for lifecycle state transitions
- Initialize governance system with 8 demo experiments on startup
- Fix API endpoint paths to include /lifecycle/ segment for governance calls
- Add JSON property name attributes to DTOs for correct camelCase deserialization
- Create LifecycleHistoryResponse wrapper class to match API response structure
- Add StateHasChanged() calls in Lifecycle.razor to trigger UI updates
- Implement loading states and error handling in governance UI
- Add diagnostic endpoints for troubleshooting governance system
- Add debug logging to trace API calls and responses
@JerrettDavis JerrettDavis requested a review from Copilot January 7, 2026 05:49
@JerrettDavis JerrettDavis self-assigned this Jan 7, 2026
@JerrettDavis JerrettDavis added the enhancement New feature or request label Jan 7, 2026
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 a comprehensive pluggable dashboard framework for managing A/B tests and experiments. The dashboard provides a Hangfire-style embeddable web UI with features including experiment management, analytics, governance workflows, rollout management, targeting rules, and plugin support. The framework supports multi-tenancy through pluggable tenant resolvers and delegates authorization to ASP.NET Core.

Key Changes

  • Added complete dashboard infrastructure with middleware, options, and dependency injection setup
  • Implemented multi-tenancy support with four tenant resolver strategies (HTTP header, subdomain, claims, composite)
  • Created comprehensive test suite including integration tests with WebApplicationFactory
  • Built Blazor-based UI components with Monaco editor integration and theme support

Reviewed changes

Copilot reviewed 133 out of 135 changed files in this pull request and generated 10 comments.

Show a summary per file
File Description
tests/ExperimentFramework.Dashboard.Tests/*.cs Integration test suite with factory pattern for dashboard endpoints and configuration
src/ExperimentFramework.Dashboard/DashboardOptions.cs Configuration options class with tenant resolver and authorization settings
src/ExperimentFramework.Dashboard/DashboardMiddleware.cs ASP.NET Core middleware handling tenant resolution and authorization
src/ExperimentFramework.Dashboard/ServiceCollectionExtensions.cs DI registration for dashboard services with default implementations
src/ExperimentFramework.Dashboard/EndpointRouteBuilderExtensions.cs Endpoint mapping extensions for dashboard API routes
src/ExperimentFramework.Dashboard/TenantResolvers/*.cs Four tenant resolver implementations for multi-tenancy scenarios
src/ExperimentFramework.Dashboard/Theming/DefaultThemeProvider.cs Default theme provider with customizable colors
src/ExperimentFramework.Dashboard/Persistence/InMemoryRolloutPersistence.cs In-memory rollout configuration storage
src/ExperimentFramework.Dashboard/Data/DefaultDashboardDataProvider.cs Default data provider bridging experiment registry to dashboard
src/ExperimentFramework.Dashboard/Authorization/ClaimsPrincipalAuthProvider.cs Claims-based authorization provider
src/ExperimentFramework.Dashboard.UI/Services/*.cs UI service layer including API client, state management, code generation, and theming
src/ExperimentFramework.Dashboard.UI/Components/**/*.razor Blazor pages and shared components for the dashboard UI
src/ExperimentFramework.Dashboard.UI/wwwroot/*.js JavaScript interop for Monaco editor and theme management
src/ExperimentFramework.Dashboard/DASHBOARD_README.md Comprehensive documentation with usage examples
Files not reviewed (1)
  • samples/ExperimentFramework.AspireDemo/AspireDemo.Web/Data/Migrations/20260105033931_InitialIdentity.Designer.cs: Language not supported

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

Replace fixed 1-second delay with polling approach that waits up to 5 seconds
for the file watcher callback to be invoked. This makes the test more reliable
in CI environments where file system watchers can be slower.

- Add WaitForConditionAsync helper method for polling with timeout
- Update Hot_reload_callback_invoked_on_file_change to use polling
- Add clearer assertion message when callback is not received
Security fixes:
- Add SanitizeForLog helper to prevent log-forging vulnerabilities in Login.cshtml.cs
- Sanitize HttpContext.Request.Path and QueryString before logging

Code quality improvements:
- Replace empty catch blocks with proper error logging in LiveDemo.razor
- Remove unused variables: tenantContext (AnalyticsEndpoints.cs), isPending (Rollout.razor), effectiveTheme (theme.js)
- Replace foreach loops with LINQ: RuntimeExperimentManager.cs, IdentitySeeder.cs, RolloutEndpoints.cs
- Use ternary operator for conditional assignment in Rollout.razor

These changes address all issues raised in PR review #30
@codecov-commenter
Copy link

codecov-commenter commented Jan 7, 2026

Codecov Report

✅ All modified and coverable lines are covered by tests.
⚠️ Please upload report for BASE (main@ace0352). Learn more about missing BASE report.

Additional details and impacted files
@@           Coverage Diff           @@
##             main      #30   +/-   ##
=======================================
  Coverage        ?   83.20%           
=======================================
  Files           ?      184           
  Lines           ?     6860           
  Branches        ?      962           
=======================================
  Hits            ?     5708           
  Misses          ?     1152           
  Partials        ?        0           
Flag Coverage Δ
unittests 83.20% <ø> (?)

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.

JerrettDavis and others added 2 commits January 7, 2026 08:45
… user input

Co-authored-by: Copilot Autofix powered by AI <62310815+github-advanced-security[bot]@users.noreply.github.com>
… user input

Co-authored-by: Copilot Autofix powered by AI <62310815+github-advanced-security[bot]@users.noreply.github.com>
Repository owner deleted a comment from github-actions bot Jan 7, 2026
@github-actions
Copy link

github-actions bot commented Jan 7, 2026

Code Coverage

Summary
  Generated on: 01/07/2026 - 14:51:31
  Coverage date: 01/07/2026 - 14:50:23 - 01/07/2026 - 14:51:09
  Parser: MultiReport (2x Cobertura)
  Assemblies: 19
  Classes: 215
  Files: 185
  Line coverage: 80.2%
  Covered lines: 5537
  Uncovered lines: 1361
  Coverable lines: 6898
  Total lines: 26071
  Branch coverage: 72% (2179 of 3026)
  Covered branches: 2179
  Total branches: 3026
  Method coverage: 88.4% (881 of 996)
  Full method coverage: 76.8% (765 of 996)
  Covered methods: 881
  Fully covered methods: 765
  Total methods: 996

ExperimentFramework                                                                                  90.4%
  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                                                              81.1%
  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                                                    77.6%
  ExperimentFramework.ServiceExperimentBuilder<T>                                                    94.5%
  ExperimentFramework.ServiceRegistration.OperationMetadata                                           100%
  ExperimentFramework.ServiceRegistration.OperationResult                                             100%
  ExperimentFramework.ServiceRegistration.PlanExecutionResult                                        83.3%
  ExperimentFramework.ServiceRegistration.RegistrationPlan                                            100%
  ExperimentFramework.ServiceRegistration.RegistrationPlanBuilder                                    97.2%
  ExperimentFramework.ServiceRegistration.RegistrationPlanExecutor                                   62.7%
  ExperimentFramework.ServiceRegistration.RegistrationPlanReport                                     98.1%
  ExperimentFramework.ServiceRegistration.ServiceGraphPatchOperation                                   77%
  ExperimentFramework.ServiceRegistration.ServiceGraphSnapshot                                        100%
  ExperimentFramework.ServiceRegistration.ValidationFinding                                           100%
  ExperimentFramework.ServiceRegistration.Validators.LifetimeSafetyValidator                          100%
  ExperimentFramework.Telemetry.NoopExperimentTelemetry                                               100%
  ExperimentFramework.Telemetry.OpenTelemetryExperimentTelemetry                                      100%
  ExperimentFramework.Validation.TrialConflictDetector                                               98.7%
  ExperimentFramework.Validation.TrialConflictException                                               100%
  ExperimentFramework.Variants.VariantFeatureManagerAdapter                                           100%

ExperimentFramework.Admin                                                                            33.4%
  ExperimentFramework.Admin.ExperimentAdminEndpoints                                                  100%
  ExperimentFramework.Admin.GovernanceAdminEndpoints                                                    0%

ExperimentFramework.Audit                                                                               0%
  ExperimentFramework.Audit.CompositeAuditSink                                                          0%
  ExperimentFramework.Audit.LoggingAuditSink                                                            0%
  ExperimentFramework.Audit.ServiceCollectionExtensions                                                 0%

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                                                                    68.6%
  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                        79.1%
  ExperimentFramework.Configuration.Extensions.ConfigurationExtensionServiceCollectionExtensions     92.8%
  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.GovernanceConfigurationHandler                 44%
  ExperimentFramework.Configuration.Extensions.Handlers.InMemoryBackplaneConfigurationHandler        11.1%
  ExperimentFramework.Configuration.Extensions.Handlers.LoggingBackplaneConfigurationHandler         11.1%
  ExperimentFramework.Configuration.Extensions.Handlers.LoggingDecoratorHandler                      91.6%
  ExperimentFramework.Configuration.Extensions.Handlers.OpenTelemetryBackplaneConfigurationHandler   11.1%
  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.Schema.Generated.ConfigurationSchema                                0%
  ExperimentFramework.Configuration.Schema.Generated.SchemaRegistry                                     0%
  ExperimentFramework.Configuration.Schema.SchemaExporter                                               0%
  ExperimentFramework.Configuration.Schema.SchemaHasher                                               100%
  ExperimentFramework.Configuration.Schema.SchemaVersionTracker                                      94.5%
  ExperimentFramework.Configuration.ServiceCollectionExtensions                                      48.2%
  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                                                                  80%
  ExperimentFramework.FeatureManagement.ExperimentBuilderExtensions                                    50%
  ExperimentFramework.FeatureManagement.ServiceCollectionExtensions                                   100%
  ExperimentFramework.FeatureManagement.VariantFeatureFlagProvider                                    100%

ExperimentFramework.Governance                                                                       33.4%
  ExperimentFramework.Governance.Approval.AutomaticApprovalGate                                         0%
  ExperimentFramework.Governance.Approval.ManualApprovalGate                                            0%
  ExperimentFramework.Governance.Approval.RoleBasedApprovalGate                                        23%
  ExperimentFramework.Governance.ApprovalManager                                                     11.1%
  ExperimentFramework.Governance.ApprovalResult                                                         0%
  ExperimentFramework.Governance.GovernanceBuilder                                                   65.9%
  ExperimentFramework.Governance.GovernanceConfiguration                                                0%
  ExperimentFramework.Governance.LifecycleManager                                                    79.1%
  ExperimentFramework.Governance.Policy.ConflictPreventionPolicy                                        0%
  ExperimentFramework.Governance.Policy.ErrorRatePolicy                                              11.7%
  ExperimentFramework.Governance.Policy.PolicyEvaluator                                              30.7%
  ExperimentFramework.Governance.Policy.TimeWindowPolicy                                                0%
  ExperimentFramework.Governance.Policy.TrafficLimitPolicy                                           10.8%
  ExperimentFramework.Governance.ServiceCollectionExtensions                                          100%
  ExperimentFramework.Governance.Versioning.VersionManager                                              0%

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

ExperimentFramework.OpenFeature                                                                        80%
  ExperimentFramework.OpenFeature.ExperimentBuilderExtensions                                          50%
  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 merged commit 672f0e5 into main Jan 7, 2026
4 checks passed
@JerrettDavis JerrettDavis deleted the feature/extend-dashboard branch January 7, 2026 16:19
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