Skip to content

Commit 19a1446

Browse files
committed
feat(governance-runtime): propagate request metadata into governed mutations
1 parent 3742e99 commit 19a1446

1 file changed

Lines changed: 45 additions & 13 deletions

File tree

‎src/Governance/Runtime/Execution/Mutation/GovernedMutation.cs‎

Lines changed: 45 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -2,19 +2,26 @@
22
using ModularityKit.Mutator.Abstractions.Engine;
33
using ModularityKit.Mutator.Abstractions.Intent;
44
using ModularityKit.Mutator.Abstractions.Results;
5+
using ModularityKit.Mutator.Governance.Abstractions.Requests.Model;
56

67
namespace ModularityKit.Mutator.Governance.Runtime.Execution.Mutation;
78

89
/// <summary>
9-
/// Wraps a mutation so governance request identifiers flow into core execution audit and history metadata.
10+
/// Wraps mutation so governance request identifiers flow into core execution audit and history metadata.
1011
/// </summary>
1112
internal sealed class GovernedMutation<TState> : IMutation<TState>
1213
{
14+
private const string GovernanceRequestIdMetadataKey = "GovernanceRequestId";
15+
private const string GovernanceRequestMetadataKey = "GovernanceRequestMetadata";
16+
private const string GovernanceIntentMetadataKey = "GovernanceIntentMetadata";
17+
private const string GovernanceEstimatedBlastRadiusMetadataKey = "GovernanceEstimatedBlastRadius";
18+
1319
private readonly IMutation<TState> _inner;
1420

15-
public GovernedMutation(IMutation<TState> inner, string requestId, string stateId)
21+
public GovernedMutation(IMutation<TState> inner, MutationRequest request)
1622
{
1723
_inner = inner ?? throw new ArgumentNullException(nameof(inner));
24+
ArgumentNullException.ThrowIfNull(request);
1825

1926
Intent = new MutationIntent
2027
{
@@ -23,17 +30,17 @@ public GovernedMutation(IMutation<TState> inner, string requestId, string stateI
2330
Description = _inner.Intent.Description,
2431
RiskLevel = _inner.Intent.RiskLevel,
2532
IsReversible = _inner.Intent.IsReversible,
26-
EstimatedBlastRadius = _inner.Intent.EstimatedBlastRadius,
27-
Tags = _inner.Intent.Tags,
33+
EstimatedBlastRadius = request.Intent.EstimatedBlastRadius ?? _inner.Intent.EstimatedBlastRadius,
34+
Tags = MergeTags(request.Intent.Tags, _inner.Intent.Tags),
2835
CreatedAt = _inner.Intent.CreatedAt,
29-
Metadata = MergeMetadata(_inner.Intent.Metadata, requestId)
36+
Metadata = MergeIntentMetadata(request)
3037
};
3138

3239
Context = _inner.Context with
3340
{
34-
StateId = string.IsNullOrWhiteSpace(_inner.Context.StateId) ? stateId : _inner.Context.StateId,
35-
CorrelationId = string.IsNullOrWhiteSpace(_inner.Context.CorrelationId) ? requestId : _inner.Context.CorrelationId,
36-
Metadata = MergeMetadata(_inner.Context.Metadata, requestId)
41+
StateId = string.IsNullOrWhiteSpace(_inner.Context.StateId) ? request.StateId : _inner.Context.StateId,
42+
CorrelationId = string.IsNullOrWhiteSpace(_inner.Context.CorrelationId) ? request.RequestId : _inner.Context.CorrelationId,
43+
Metadata = MergeContextMetadata(request)
3744
};
3845
}
3946

@@ -47,15 +54,40 @@ public GovernedMutation(IMutation<TState> inner, string requestId, string stateI
4754

4855
public MutationResult<TState> Simulate(TState state) => _inner.Simulate(state);
4956

50-
private static IReadOnlyDictionary<string, object> MergeMetadata(
51-
IReadOnlyDictionary<string, object> source,
52-
string requestId)
57+
private IReadOnlyDictionary<string, object> MergeContextMetadata(MutationRequest request)
5358
{
54-
var metadata = new Dictionary<string, object>(source)
59+
var metadata = new Dictionary<string, object>(_inner.Context.Metadata)
5560
{
56-
["GovernanceRequestId"] = requestId
61+
[GovernanceRequestIdMetadataKey] = request.RequestId
5762
};
5863

64+
if (request.Metadata.Count > 0)
65+
metadata[GovernanceRequestMetadataKey] = request.Metadata;
66+
67+
if (request.Intent.Metadata.Count > 0)
68+
metadata[GovernanceIntentMetadataKey] = request.Intent.Metadata;
69+
70+
if (request.Intent.EstimatedBlastRadius is not null)
71+
metadata[GovernanceEstimatedBlastRadiusMetadataKey] = request.Intent.EstimatedBlastRadius;
72+
5973
return metadata;
6074
}
75+
76+
private IReadOnlyDictionary<string, object> MergeIntentMetadata(MutationRequest request)
77+
{
78+
var metadata = new Dictionary<string, object>(request.Intent.Metadata)
79+
{
80+
[GovernanceRequestIdMetadataKey] = request.RequestId
81+
};
82+
83+
if (_inner.Intent.Metadata.Count > 0)
84+
metadata["ExecutionIntentMetadata"] = _inner.Intent.Metadata;
85+
86+
return metadata;
87+
}
88+
89+
private static IReadOnlySet<string> MergeTags(
90+
IReadOnlySet<string> requestTags,
91+
IReadOnlySet<string> executionTags)
92+
=> new HashSet<string>(requestTags.Concat(executionTags), StringComparer.Ordinal);
6193
}

0 commit comments

Comments
 (0)