Skip to main content

Rule Engine Runtime Packages

This page documents the runtime execution packages that make up the Muonroi Rule Engine stack. These packages handle rule storage, approval workflow, canary deployment, hot-reload, CEP windowing, decision table execution, NRules bridging, AI-driven scenario proliferation, and EF Core persistence.


Muonroi.RuleEngine.Runtime

NuGet: Muonroi.RuleEngine.Runtime | Tier: Commercial (Licensed+) | Distribution: GitHub Packages

Purpose

Core runtime layer. Provides RulesEngineService — the primary façade for loading, executing, validating, and dry-running workflow rulesets. Supports three ruleset shapes: legacy Microsoft RulesEngine JSON, code-based (rule codes that resolve to DI-registered IRule<TContext>), and flow-graph (BPMN-style node/edge JSON parsed by RuleGraphParser). Includes runtime caching, Redis pub/sub hot-reload, FEEL and Liquid rule adapters, audit signing, and canary rollout support.

Key Types

TypeKindPurpose
RulesEngineServiceService (scoped)Main façade — ExecuteAsync, ExecuteWithResultAsync, DryRunAsync, SaveRuleSetAsync, SetActiveVersionAsync, GetVersionDetailsAsync
RuleEngine<T>ServiceCode-first engine for registering and executing IRule<T> instances with dependency ordering
IRuleSetStoreInterfaceRuleset persistence contract (SaveAsync, GetAsync, GetVersionsAsync, SetActiveVersionAsync)
IRuleSetAuditStoreInterfaceAudit trail persistence (AppendAsync, QueryAsync)
IRuleSetApprovalServiceInterfaceMaker-checker approval workflow
ICanaryRolloutServiceInterfaceCanary version targeting per tenant
IRuleActivationStrategy<T>InterfacePluggable rule activation filter
IRuleSetSignerInterfaceHMAC/RSA ruleset signing
FileRuleSetStoreImplementationFile-system ruleset store (all tiers)
FileRuleSetAuditStoreImplementationFile-system audit store
RuleSetRuntimeCacheImplementationIMemoryCache-backed per-tenant ruleset cache with invalidation
WorkflowCacheTelemetryServiceOTel metrics: hit/miss counters, eviction counter, cache size gauge, hot-reload lag histogram
RuleSetStatusEnumRuleset lifecycle states
RuleControlPlaneOptionsOptionsRequireApproval, NotifyOnStateChange, EnableCanary, audit signing keys
RuleStoreConfigsOptionsRootPath, EnableRuntimeCache, RuleChangeChannel
FeelRuleAdapter<T>AdapterFEEL expression → FactBag output
LiquidRuleAdapter<T>AdapterLiquid/Scriban template rules
GraphRuleDispatchAdapter<T>AdapterFlow-graph node dispatch with branching
DecisionTableRuleAdapter<T>AdapterInline decision table node in a flow graph
SubFlowRuleAdapter<T>AdapterRecursive sub-flow calls within a flow graph
ConnectorRuleAdapter<T>AdapterExternal service connector nodes
JavaScriptRuleAdapter<T>AdapterJint-based JavaScript condition nodes
RuleGraphParserServiceParses flow-graph JSON using Kahn's topological sort
HmacSha256RuleSetSignerImplementationHMAC-SHA256 ruleset signing
RsaRuleSetAuditSignerImplementationRSA audit trail signing
InMemoryRuleSetChangeNotifierImplementationIn-process hot-reload notifications
RedisRuleSetChangeNotifierImplementationRedis pub/sub cross-node hot-reload
ExternalJsonRuleImplementationJSON-serialized rule definition
MRuleContextJsonRegistryServiceType-safe context deserialization registry
RuleSetDefinitionValidatorServiceValidates ruleset JSON structure before persistence

RuleSetStatus Lifecycle

Draft → PendingApproval → Active → Archived
↓ (rejected)
Rejected
  • Draft — ruleset saved but not yet submitted for review.
  • PendingApproval — submitted; awaiting maker-checker approval.
  • Active — current live version served to all rule executions.
  • Archived — superseded version retained for audit history.
  • Rejected — approval was denied; returned to Draft or discarded.

When RuleControlPlaneOptions.RequireApproval = true, a ruleset must pass through IRuleSetApprovalService.ApproveAsync() before SetActiveVersionAsync will serve it to callers.

Canary Deployment

ICanaryRolloutService assigns a specific ruleset version to a named tenant cohort. When RulesEngineService resolves a workflow, it calls GetCanaryVersionForTenantAsync(workflowName, tenantId) first; if a canary version is assigned the canary version is loaded, bypassing the default active version. All other tenants continue using the active version.

Enable with:

services.Configure<RuleControlPlaneOptions>(o => o.EnableCanary = true);
services.TryAddScoped<ICanaryRolloutService, CanaryRolloutService>(); // provided by EFCore package

DI Registration

// File-backed store (all tiers — Free, Licensed, Enterprise)
services.AddRuleEngineStore(configuration, configure: o =>
{
o.RootPath = "rules";
o.EnableRuntimeCache = true;
o.RuleChangeChannel = "rule-change";
});

// Optional: Redis cross-node hot-reload
services.AddMRuleEngineWithRedisHotReload(
configuration.GetConnectionString("Redis")!);

// Optional: CloudEvents bridge for ruleset lifecycle events
services.AddRuleEventBridge();

Usage Example

// Inject RulesEngineService (scoped)
public class OrderHandler(RulesEngineService rulesEngine)
{
public async Task ProcessAsync(OrderContext ctx, CancellationToken ct)
{
// Dry-run to validate before committing
FactBag preview = await rulesEngine.DryRunAsync(
"order-workflow",
json: await rulesEngine.GetRuleSetAsync("order-workflow") ?? "",
context: JsonSerializer.SerializeToElement(ctx),
contextType: typeof(OrderContext).FullName,
ct);

// Full execution (Phase 1 + Phase 2)
OrchestratorResult result = await rulesEngine.ExecuteWithResultAsync(
"order-workflow", ctx, ct);

if (!result.IsSuccess)
throw new InvalidOperationException(string.Join("; ", result.Errors));

string? orderId = result.Facts.Get<string>("order.id");
}
}

Muonroi.RuleEngine.Runtime.Web

NuGet: Muonroi.RuleEngine.Runtime.Web | Tier: Commercial (Licensed+) | Distribution: GitHub Packages

Purpose

ASP.NET web layer for the runtime engine. Exposes REST endpoints for ruleset lifecycle management (CRUD, activate, validate, dry-run, audit), a SignalR hub for real-time hot-reload notifications, and the rule flow contract discovery endpoint. Requires LicenseTier.Licensed or above.

Key Types

TypeKindPurpose
RuntimeRuleSetControllerControllerREST endpoints for ruleset management
MRuleFlowContractControllerControllerRule flow schema discovery
MRuleFlowExecuteControllerControllerDirect flow-graph execution
RuleSetChangeHubSignalR hubReal-time ruleset change notifications to clients
RuleSetHubNotifierHosted serviceSubscribes to IRuleSetChangeNotifier and pushes to SignalR hub
RuleDryRunServiceServiceDry-run execution without side effects
IMRuleFlowContractProviderInterfaceRule flow JSON schema provider
RuleSetHotReloadClientClientSubscribes to a remote RuleSetChangeHub

Key REST Endpoints

MethodRouteDescription
GET/api/v1/rule-engine/rulesetsList all workflows with version summaries
GET/api/v1/rule-engine/rulesets/{workflow}/versionsPaginated version details (limit, offset)
GET/api/v1/rule-engine/rulesets/{workflow}/exportExport ruleset JSON for a workflow/version
POST/api/v1/rule-engine/rulesets/{workflow}Save a new ruleset version
POST/api/v1/rule-engine/rulesets/{workflow}/activate/{version}Activate a specific version
POST/api/v1/rule-engine/rulesets/{workflow}/validateValidate a ruleset definition (no save)
POST/api/v1/rule-engine/rulesets/{workflow}/dry-runDry-run a ruleset against a context payload
GET/api/v1/rule-engine/rulesets/{workflow}/auditPaginated audit history for a workflow
GET/api/v1/rule-flow/contractRule flow JSON schema for the UI designer

SignalR Hub

wss://{host}/hubs/rule-set-change

Clients subscribe to receive RuleSetChangeEvent messages when a ruleset is saved, activated, or invalidated. Used by the UI engine for hot-reload without page refresh.

DI Registration

builder.Services.AddRuleEngineRuntimeWeb(builder.Configuration);

// Map SignalR hub (in app.MapHub calls)
app.MapHub<RuleSetChangeHub>("/hubs/rule-set-change");

Usage Example

// POST /api/v1/rule-engine/rulesets/order-workflow
{
"ruleSet": { /* workflow JSON */ },
"activateAfterSave": true,
"actor": "[email protected]"
}

// POST /api/v1/rule-engine/rulesets/order-workflow/dry-run
{
"ruleSet": { /* workflow JSON */ },
"context": { "amount": 500, "customerId": "c-123" },
"contextType": "MyApp.OrderContext"
}

Muonroi.RuleEngine.CEP

NuGet: Muonroi.RuleEngine.CEP | Tier: Commercial (Licensed+) | Distribution: GitHub Packages

Purpose

Complex Event Processing (CEP) engine for stateful, time-windowed rule evaluation. Evaluates decisions that depend on event sequences, time correlation keys (user ID, session ID, device ID), or burst thresholds. Ships with in-memory window state, durable config storage via EF Core, and a REST/simulation controller.

Key Types

TypeKindPurpose
CepEngine<T>ServiceCore windowing engine — AddEvent(key, value, timestamp) returns the active window
CepEvent<T>RecordEvent container: Key, Timestamp, Value
WindowTypeEnumSliding, Tumbling
CepWindowBuilderStatic builderFluent DSL for CepConfig and CepWindow<T> creation
CepWindow<T>Runtime wrapperBinds CepConfig to a typed payload with key selector
CepConfigModelPersisted config: WindowType, WindowSize, TimeToLive, CorrelationKey, TenantId
ICepConfigRepositoryInterfaceConfig CRUD contract
InMemoryCepConfigRepositoryImplementationProcess-local config storage
EfCoreCepConfigRepositoryImplementationPostgres/SQL Server config storage
CepConfigDatabaseMigratorHosted serviceAuto-migrates CEP config table at startup
CepControllerControllerREST CRUD + simulation for CEP configs
CepMetricsServiceOTel: cep.events.processed, cep.window.evaluations, cep.window.event.count, cep.config.reads/writes

Window Types

Sliding — answers "what happened in the last X time units relative to this event?" Events from now - windowSize to now are included. Use for burst detection, rate limits, fraud spikes.

Tumbling — answers "which fixed bucket does this event belong to?" The window boundary is computed as floor(event.Ticks / windowSize.Ticks) * windowSize.Ticks. Use for fixed reporting buckets, billing summaries, non-overlapping aggregations.

Session — grouping by inactivity gap (host-defined; not built-in to the package — implement as a key-expiry wrapper around CepEngine<T>).

Key REST Endpoints

MethodRouteDescription
GET/api/v1/rule-engine/cepList all CEP configs ordered by name
GET/api/v1/rule-engine/cep/{id}Get one config by ID
PUT/api/v1/rule-engine/cep/{id}Save or update a config
DELETE/api/v1/rule-engine/cep/{id}Delete a config
POST/api/v1/rule-engine/cep/{id}/simulateSimulate event batches against a config

DI Registration

// In-memory config store (default)
builder.Services.AddControllers();
builder.Services.AddCepWeb();

// Postgres config persistence
builder.Services.AddCepWeb(options =>
{
options.PostgresConnectionString = builder.Configuration
.GetConnectionString("RuleEngineDb");
options.Schema = "ruleengine";
});

Usage Example

// Low-level engine (no ASP.NET required)
var engine = new CepEngine<TransactionEvent>(
TimeSpan.FromSeconds(30),
WindowType.Sliding,
ttl: TimeSpan.FromMinutes(2));

IReadOnlyList<CepEvent<TransactionEvent>> window = engine.AddEvent(
key: "customer-42",
value: new TransactionEvent(250m, "card"),
timestamp: DateTime.UtcNow);

if (window.Count >= 3)
{
// threshold crossed — trigger rule engine evaluation
}

// Fluent builder approach
CepConfig config = CepWindowBuilder
.Named("fraud-window")
.ForTenant("tenant-a")
.Sliding(TimeSpan.FromSeconds(30))
.KeepEventsFor(TimeSpan.FromMinutes(2))
.CorrelateBy("customerId")
.Build();

CepWindow<TransactionEvent> window2 = CepWindowBuilder
.For<TransactionEvent>(config)
.CorrelateBy(evt => evt.CustomerId)
.Build();

IReadOnlyList<CepEvent<TransactionEvent>> events = window2.Add(txEvent, DateTime.UtcNow);

Muonroi.RuleEngine.NRules

NuGet: Muonroi.RuleEngine.NRules | Tier: Commercial | Distribution: GitHub Packages

Status: Frozen. This package is no longer actively developed. New implementations should use Muonroi.RuleEngine.Runtime instead. The package is preserved for projects that already depend on NRules.

Purpose

Thin integration bridge between the Muonroi ecosystem and NRules — a .NET production rules engine with Rete algorithm. Loads rule definitions from assemblies, compiles them into a session factory, and fires rules against inserted facts. Supports per-rule enable/disable toggles and version pinning via RuleOptions.

Key Types

TypeKindPurpose
NRulesEngineService (singleton)Loads assemblies, compiles NRules session factory, executes Fire(facts[])
RuleAttributeAttribute[Rule(Name, Version)] — names and versions a rule class for toggle support
RuleOptionsOptionsPer-rule enable/disable flags and version pinning

NRules Integration Pattern

NRules rules are declared using the standard NRules Rule base class. The [RuleAttribute] metadata integrates with RuleOptions to allow runtime toggling without code changes.

[Rule(Name = "HighValueOrder", Version = "1.0")]
public class HighValueOrderRule : Rule
{
public override void Define()
{
OrderContext order = default!;

When()
.Match<OrderContext>(() => order, o => o.Amount > 1000);

Then()
.Do(_ => order.ApplyDiscount(0.10m));
}
}

DI Registration

// Register NRulesEngine (frozen API — prefer RuleEngine.Runtime for new work)
#pragma warning disable CS0618
builder.Services.AddNRulesEngine(
configure: options =>
{
options.Rules["HighValueOrder"] = new RuleConfig { Enabled = true, Version = "1.0" };
},
typeof(HighValueOrderRule).Assembly);
#pragma warning restore CS0618

Usage Example

public class OrderService(NRulesEngine engine)
{
public void Apply(OrderContext order)
{
engine.Fire(order); // inserts facts, fires matching rules
}
}

Muonroi.RuleEngine.DecisionTable

NuGet: Muonroi.RuleEngine.DecisionTable | Tier: Commercial (Licensed+) | Distribution: GitHub Packages

Purpose

DMN-style decision table engine. Tables are organized as a grid of input conditions (FEEL unary tests) and output expressions, evaluated according to a hit policy. Supports import from Excel and DMN 1.3 XML, export to JSON/XML/CSV, version snapshots, overlap/gap detection, and integration into flow graph nodes via DecisionTableRuleAdapter.

Key Types

TypeKindPurpose
IDecisionTableExecutorInterfaceExecuteAsync(table, inputFacts, ct) → DecisionTableExecutionResult
DecisionTableExecutorImplementationHit policy dispatch: Unique, Any, First, All, Collect, RuleOrder, Priority, CollectSum, CollectMin, CollectMax, CollectCount
DecisionTableModelTable definition: Id, Name, HitPolicy, InputColumns, OutputColumns, Rows, Version, TenantId
HitPolicyEnum9 hit policies matching DMN 1.3
DecisionTableExecutionResultRecordMatched rows + computed output values
IDecisionTableStoreInterfaceCreateAsync, ReadAsync, UpdateAsync, DeleteAsync, ListAsync, UpsertAsync
InMemoryDecisionTableStoreImplementationVolatile in-process store
EfCoreDecisionTableStoreImplementationPostgres/SQL Server persistent store
DecisionTableDbContextEF contextSchema for table and row persistence
DecisionTableDatabaseMigratorHosted serviceAuto-migrates at startup
IFeelCellEvaluatorInterfaceEvaluate(expr, actual, dataType) → bool
FullFeelCellEvaluatorImplementationComplete FEEL support (> 100, [1..10], "Gold","Silver", -, arithmetic)
SimplifiedFeelCellEvaluatorImplementationSubset dialect for simple unary tests
DecisionTableValidatorServiceStructural validation
OverlapDetectorServiceSingle-column condition overlaps
MultiColumnOverlapDetectorServiceMulti-column conflict detection
GapDetectorServiceInput coverage gap detection
RedundancyDetectorServiceRedundant row detection
ExcelToDecisionTableConverterUtilityExcel → DecisionTable model
DmnImporter / DmnExporterUtilitiesDMN 1.3 XML import/export
DecisionTableDifferServiceVersion diff with row/cell-level change tracking

DI Registration

// In-memory store
services.AddDecisionTableEngine();

// Postgres store
services.AddDecisionTableEngine(options =>
{
options.PostgresConnectionString = configuration.GetConnectionString("RuleEngineDb");
});

// SQL Server store
services.AddDecisionTableEngine(options =>
{
options.SqlServerConnectionString = configuration.GetConnectionString("RuleEngineDb");
});

Usage Example

// Execute a decision table
var executor = services.GetRequiredService<IDecisionTableExecutor>();
var store = services.GetRequiredService<IDecisionTableStore>();

DecisionTable table = await store.ReadAsync("discount-table-001", ct);

DecisionTableExecutionResult result = await executor.ExecuteAsync(
table,
inputFacts: new Dictionary<string, object?>
{
["CustomerType"] = "Gold",
["OrderAmount"] = 750m
},
ct);

// result.MatchedRows — rows that matched
// result.OutputValues — computed output key/value pairs
decimal discount = (decimal)(result.OutputValues["Discount"] ?? 0);

Muonroi.RuleEngine.DecisionTable.Web

NuGet: Muonroi.RuleEngine.DecisionTable.Web | Tier: Commercial (Licensed+) | Distribution: GitHub Packages

Purpose

ASP.NET web layer for decision table management. Exposes REST endpoints for CRUD, FEEL evaluation, validation, export/import, and DMN compatibility. Requires LicenseTier.Licensed or above. Contributes a UI manifest entry to the Muonroi UI engine catalog.

Key Types

TypeKindPurpose
DecisionTableControllerControllerMain CRUD + execution endpoints
DecisionTableFeelControllerControllerEvaluate a FEEL expression against sample data
DecisionTableValidationControllerControllerValidate table structure and FEEL syntax
DecisionTableExportControllerControllerExport as JSON, DMN XML, or CSV
DecisionTableCompatControllerBaseBaseShared response shaping

Key REST Endpoints

MethodRouteDescription
GET/api/v1/decision-tablesList tables (paged, filterable by tenant)
POST/api/v1/decision-tablesCreate a new decision table
GET/api/v1/decision-tables/{id}Get a table by ID
PUT/api/v1/decision-tables/{id}Update a table
DELETE/api/v1/decision-tables/{id}Delete a table
POST/api/v1/decision-tables/{id}/executeExecute a table against input facts
POST/api/v1/decision-tables/{id}/feelEvaluate a FEEL expression with sample input
POST/api/v1/decision-tables/validateValidate table structure
GET/api/v1/decision-tables/{id}/exportExport (?format=json|dmn|csv)
POST/api/v1/decision-tables/importImport from Excel or DMN XML (multipart/form-data)
GET/api/v1/decision-tables/{id}/versionsVersion history
GET/api/v1/decision-tables/{id}/versions/{v1}/diff/{v2}Column/row diff between two versions

DI Registration

builder.Services.AddDecisionTableWeb(options =>
{
options.PostgresConnectionString = builder.Configuration
.GetConnectionString("RuleEngineDb");
});

Usage Example

POST /api/v1/decision-tables/discount-table-001/execute
Content-Type: application/json

{
"customerType": "Gold",
"orderAmount": 750
}

Response:

{
"matchedRows": [1],
"outputs": { "Discount": 15, "FreeShipping": true }
}

Muonroi.RuleEngine.EntityFrameworkCore

NuGet: Muonroi.RuleEngine.EntityFrameworkCore | Tier: Commercial (Licensed+) | Distribution: GitHub Packages

Purpose

EF Core persistence layer for the rule engine runtime. Replaces the file-backed FileRuleSetStore with PostgresRuleSetStore, provides approval workflow via RuleSetApprovalService, canary deployment via CanaryRolloutService, and Postgres row-level security (RLS) via TenantRlsConnectionInterceptor. Manages the RuleEngineDbContext with versioned migrations.

Key Types

TypeKindPurpose
PostgresRuleSetStoreImplementationPostgres-backed IRuleSetStore
PostgresRuleSetAuditStoreImplementationPostgres-backed IRuleSetAuditStore
RuleSetApprovalServiceImplementationIRuleSetApprovalService — maker-checker approval workflow
CanaryRolloutServiceImplementationICanaryRolloutService — version targeting per tenant
RuleEngineDbContextEF contextTables: RuleSetRecords, RuleSetAuditRecords, TenantRuleAssignments, TenantQuotaOverrides
TenantRlsConnectionInterceptorInterceptorSets app.current_tenant_id session variable for Postgres RLS policies
TenantQuotaOverrideRecordEntityPer-tenant quota overrides for concurrency and evaluation limits
TenantRuleAssignmentRecordEntityCanary version assignments keyed by (TenantId, WorkflowName)

Migrations

MigrationDescription
20260306055106_InitialRuleControlPlaneInitial schema: rulesets, audit, assignments
20260325000000_AddRowLevelSecurityPoliciesPostgres RLS policies for tenant isolation

DI Registration

// Replaces FileRuleSetStore with Postgres; registers approval + canary services
builder.Services.AddMRuleEngineWithPostgres(
connectionString: builder.Configuration.GetConnectionString("RuleEngineDb")!,
configureOptions: options =>
{
options.RequireApproval = true;
options.NotifyOnStateChange = true;
options.EnableCanary = true;
// Optional: inline PEM for audit signing
// options.AuditPrivateKeyPemPath = "/run/secrets/audit-rsa.pem";
});

// Optional: enable Redis cross-node hot-reload
builder.Services.AddMRuleEngineWithRedisHotReload(
builder.Configuration.GetConnectionString("Redis")!);

// Optional: enable approval workflow explicitly
builder.Services.AddMRuleEngineApprovalWorkflow();

// Optional: enable canary rollout explicitly
builder.Services.AddMCanaryRollout();

Muonroi.RuleEngine.Proliferation

NuGet: Muonroi.RuleEngine.Proliferation | Tier: Commercial (Enterprise) | Distribution: GitHub Packages

Purpose

AI-powered scenario proliferation engine. Analyzes a ruleset definition and uses a language model (Ollama, OpenAI, or Claude) to autonomously generate test scenarios, execute them against the rule engine, analyze failures, deduplicate scenarios (hash and vector-semantic), and produce coverage reports. Designed for CI/CD pipeline gates and continuous rule quality assurance. Ships with in-memory store; replace with Muonroi.RuleEngine.Proliferation.Persistence for Postgres durability.

Key Types

TypeKindPurpose
IRuleProliferationBrainInterfaceAnalyzeAsync(seedRuleCode, ruleSetJson, executionResult, factBagSnapshot, context, ct) → ProliferationPlan
OllamaProliferationBrainImplementationOllama local LLM backend
OpenAiProliferationBrainImplementationOpenAI API backend
ClaudeProliferationBrainImplementationAnthropic Claude API backend
CompositeProliferationBrainImplementationSequential or parallel multi-brain fallback chain
IScenarioExecutorInterfaceExecutes generated scenarios against the runtime
ScenarioExecutorImplementationInternal rule engine executor
ExternalScenarioExecutorImplementationHTTP-based executor for external project rulesets
RoutingScenarioExecutorImplementationRoutes between internal and external execution
IProliferationStoreInterfaceScenario and result persistence
InMemoryProliferationStoreImplementationVolatile in-process store
ProliferationWorkerHosted serviceBackground worker that drains the proliferation queue
NeuronScenarioRecordGenerated scenario: Id, SeedRuleCode, ScenarioName, Type, Scope, InputFacts, ExpectedBehavior, Status
ScenarioResultRecordExecution result: IsSuccess, MatchesExpectation, OutputFacts, Errors, Duration
ProliferationPlanRecordBrain output: SeedRuleCode, Scope, Scenarios, AiModelUsed, GenerationDuration
ProliferationStatsRecordAggregate pass/fail/coverage statistics
CiRunResultRecordCI/CD gate result with coverage thresholds
ScenarioStatusEnumPending, Running, Passed, Failed, Error, Skipped
ProliferationScopeEnumRule, Workflow, CrossRule
IScenarioDeduplicatorInterfaceHash-based or vector-semantic deduplication
InputHashDeduplicatorImplementationSHA-256 hash deduplication
VectorSemanticDeduplicatorImplementationOllama embedding + cosine similarity deduplication
IBudgetAllocatorInterfaceCoverage-weighted scenario budget allocation
CoverageWeightedBudgetAllocatorImplementationAllocates more budget to low-coverage branches
ICoverageTrackerInterfaceTracks field, node, and edge coverage across runs
IFailureAnalyzerInterfaceClassifies failures and proposes follow-up scenarios
ChaosScenarioGeneratorServiceGenerates edge-case and chaos scenarios
NaturalLanguageRuleConverterServiceTranslates natural language descriptions into ruleset JSON
TestReportExporterServiceExports reports as TRX, xUnit XML, or custom formats
ProliferationOptionsOptionsBrainProvider, CompositeBrains, CompositeMode, AiTimeoutSeconds, EnableSemanticDedup, EnableInfraAwareBudget

DI Registration

builder.Services.AddMProliferationEngine(builder.Configuration);

// appsettings.json
{
"Proliferation": {
"BrainProvider": "ollama",
"OllamaBaseUrl": "http://localhost:11434",
"OllamaModel": "llama3",
"AiTimeoutSeconds": 120,
"EnableSemanticDedup": true,
"EnableInfraAwareBudget": false,
"CompositeBrains": "",
"CompositeMode": "sequential"
}
}

Usage Example

// Trigger a proliferation run
var brain = services.GetRequiredService<IRuleProliferationBrain>();
var executor = services.GetRequiredService<IScenarioExecutor>();
var store = services.GetRequiredService<IProliferationStore>();

string ruleSetJson = await rulesEngine.GetRuleSetAsync("fraud-detection") ?? "";

ProliferationPlan plan = await brain.AnalyzeAsync(
seedRuleCode: "detect-fraud",
ruleSetJson: ruleSetJson,
executionResult: null,
factBagSnapshot: null,
context: new ProliferationContext
{
Scope = ProliferationScope.Workflow,
RemainingBudget = 20,
TenantId = "tenant-a"
});

foreach (NeuronScenario scenario in plan.Scenarios)
{
ScenarioResult result = await executor.ExecuteAsync(scenario);
await store.SaveResultAsync(result);
}

ProliferationStats stats = await store.GetStatsAsync("detect-fraud");
Console.WriteLine($"Pass rate: {stats.Passed}/{stats.TotalScenarios}");

Muonroi.RuleEngine.Proliferation.Persistence

NuGet: Muonroi.RuleEngine.Proliferation.Persistence | Tier: Commercial (Enterprise) | Distribution: GitHub Packages

Purpose

Postgres persistence layer for the proliferation engine. Replaces the in-memory InMemoryProliferationStore with PostgresProliferationStore backed by ProliferationDbContext. Persists generated scenarios (NeuronScenarioEntity), execution results (ScenarioResultEntity), and rule lineage (RuleLineageEntity) across application restarts. Required in production when CI runs must retain history and coverage data across deployments.

Key Types

TypeKindPurpose
PostgresProliferationStoreImplementationPostgres-backed IProliferationStore
ProliferationDbContextEF contextTables: NeuronScenarios, ScenarioResults, RuleLineage
NeuronScenarioEntityEntityPersisted scenario: id, seed rule code, input facts (JSONB), status
ScenarioResultEntityEntityExecution result: success, match, output facts (JSONB), errors, duration
RuleLineageEntityEntityScenario lineage: parent ID, depth, reason

DI Registration

// Call after AddMProliferationEngine — replaces the in-memory store
builder.Services.AddMProliferationEngine(builder.Configuration);
builder.Services.AddMProliferationPostgres(
builder.Configuration.GetConnectionString("RuleEngineDb")!);

Usage Example

After registering AddMProliferationPostgres, the IProliferationStore resolved from DI is the Postgres-backed implementation. No application code changes are needed — usage is identical to the in-memory store.

// Postgres store is injected automatically
var store = services.GetRequiredService<IProliferationStore>();

await store.SaveScenarioAsync(scenario);
await store.SaveResultAsync(result);
ProliferationStats stats = await store.GetStatsAsync(seedRuleCode: "detect-fraud");

The ProliferationDbContext uses Npgsql and stores InputFacts/OutputFacts as jsonb columns for efficient querying. Apply EF Core migrations using dotnet ef database update or DbContext.Database.MigrateAsync() at startup.


Package Dependency Map

Muonroi.RuleEngine.Runtime
└─ Muonroi.RuleEngine.Core (orchestrator, quota, tracing)
└─ Muonroi.RuleEngine.Abstractions (IRule, FactBag, RuleResult)

Muonroi.RuleEngine.Runtime.Web
└─ Muonroi.RuleEngine.Runtime

Muonroi.RuleEngine.EntityFrameworkCore
└─ Muonroi.RuleEngine.Runtime (stores approval, canary)

Muonroi.RuleEngine.DecisionTable
└─ Muonroi.RuleEngine.Abstractions

Muonroi.RuleEngine.DecisionTable.Web
└─ Muonroi.RuleEngine.DecisionTable

Muonroi.RuleEngine.CEP
└─ Muonroi.Core.Abstractions

Muonroi.RuleEngine.NRules [frozen]
└─ NRules (external)

Muonroi.RuleEngine.Proliferation
└─ Muonroi.RuleEngine.Runtime

Muonroi.RuleEngine.Proliferation.Persistence
└─ Muonroi.RuleEngine.Proliferation

See Also