using Microsoft.Extensions.DependencyInjection;
using ModularityKit.Mutator.Abstractions;
using ModularityKit.Mutator.Abstractions.Changes;
using ModularityKit.Mutator.Abstractions.Context;
using ModularityKit.Mutator.Abstractions.Engine;
using ModularityKit.Mutator.Abstractions.Intent;
using ModularityKit.Mutator.Abstractions.Policies;
using ModularityKit.Mutator.Abstractions.Results;
using ModularityKit.Mutator.Runtime;
var services = new ServiceCollection();
services.AddMutators(MutationEngineOptions.Strict);
var provider = services.BuildServiceProvider();
var engine = provider.GetRequiredService<IMutationEngine>();
engine.RegisterPolicy(new PreventNegativeQuotaPolicy());
var state = new QuotaState("tenant-42", 10);
var mutation = new IncreaseQuotaMutation("tenant-42", 5);
var result = await engine.ExecuteAsync(mutation, state);
Console.WriteLine(result.NewState!.Quota);
public sealed record QuotaState(string StateId, int Quota);
public sealed class IncreaseQuotaMutation : IMutation<QuotaState>
{
public IncreaseQuotaMutation(string stateId, int amount)
{
Amount = amount;
Intent = new MutationIntent
{
OperationName = "IncreaseQuota",
Category = "Quota",
Description = "Increase tenant quota"
};
Context = MutationContext.System("Initial quota setup") with { StateId = stateId };
}
public int Amount { get; }
public MutationIntent Intent { get; }
public MutationContext Context { get; }
public MutationResult<QuotaState> Apply(QuotaState state)
=> MutationResult<QuotaState>.Success(
state with { Quota = state.Quota + Amount },
ChangeSet.Single(StateChange.Modified("Quota", state.Quota, state.Quota + Amount)));
public ValidationResult Validate(QuotaState state)
=> Amount > 0
? ValidationResult.Success()
: ValidationResult.WithError("Amount", "Amount must be positive.");
public MutationResult<QuotaState> Simulate(QuotaState state) => Apply(state);
}
public sealed class PreventNegativeQuotaPolicy : IMutationPolicy<QuotaState>
{
public string Name => "PreventNegativeQuota";
public int Priority => 100;
public string? Description => "Rejects quota changes that would go negative.";
public PolicyDecision Evaluate(IMutation<QuotaState> mutation, QuotaState state)
=> PolicyDecision.Allow();
}IMutationEngine runs a consistent pipeline around every mutation:
- evaluate registered policies
- validate the mutation against current state
- run interceptors
- apply the mutation
- record audit/history data
- update runtime metrics
Core runtime concurrency is controlled by MutationEngineOptions.MaxConcurrentMutations.
- mutations targeting the same
MutationContext.StateIdare serialized - batch execution remains ordered and sequential
- this is separate from request-storage concurrency in
ModularityKit.Mutator.Governance
IMutation<TState>IMutationEngineIMutationExecutorMutationEngineOptions
IMutationPolicy<TState>IPolicyRegistryPolicyDecisionPolicyRequirement
MutationResult<TState>BatchMutationResult<TState>ValidationResultChangeSetStateChange
MutationContextMutationIntentBlastRadius
IMutationAuditorIMutationHistoryStoreMutationHistoryIMetricsCollectorMutationStatisticsIMutationInterceptor
Runnable examples for the core engine live under Examples/Core:
ModularityKit.Mutator is the direct execution runtime.
If your workflow needs deferred execution, request approval, pending states, or stale-version resolution before the mutation can run, use ModularityKit.Mutator.Governance on top of the core package.
Included today:
- direct mutation execution
- batch execution
- policy evaluation
- validation and failure modeling
- audit/history capture
- metrics and interception
- in-memory runtime components for local and test scenarios
Not included in the core package:
- request lifecycle management
- approval workflow orchestration
- versioned request resolution
- governed request persistence contracts

