finish 9th jan sprints
This commit is contained in:
@@ -12,7 +12,7 @@ namespace StellaOps.OpsMemory.Similarity;
|
||||
/// Generates similarity vectors for finding related security decisions.
|
||||
/// Sprint: SPRINT_20260107_006_004 Task OM-004
|
||||
/// </summary>
|
||||
public sealed class SimilarityVectorGenerator
|
||||
public sealed class SimilarityVectorGenerator : ISimilarityVectorGenerator
|
||||
{
|
||||
// Vector dimensions:
|
||||
// [0-9] : CVE category one-hot (10 categories)
|
||||
|
||||
@@ -8,6 +8,7 @@ using Microsoft.Extensions.Logging.Abstractions;
|
||||
using Npgsql;
|
||||
using StellaOps.OpsMemory.Integration;
|
||||
using StellaOps.OpsMemory.Models;
|
||||
using StellaOps.OpsMemory.Playbook;
|
||||
using StellaOps.OpsMemory.Similarity;
|
||||
using StellaOps.OpsMemory.Storage;
|
||||
using Xunit;
|
||||
@@ -38,12 +39,12 @@ public sealed class OpsMemoryChatProviderIntegrationTests : IAsyncLifetime
|
||||
|
||||
_vectorGenerator = new SimilarityVectorGenerator();
|
||||
|
||||
// Create chat provider with mock stores for known issues and tactics
|
||||
// Create chat provider with required dependencies
|
||||
_chatProvider = new OpsMemoryChatProvider(
|
||||
_store,
|
||||
new NullKnownIssueStore(),
|
||||
new NullTacticStore(),
|
||||
_vectorGenerator,
|
||||
new NullPlaybookSuggestionService(),
|
||||
TimeProvider.System,
|
||||
NullLogger<OpsMemoryChatProvider>.Instance);
|
||||
|
||||
_testTenantId = $"test-{Guid.NewGuid()}";
|
||||
@@ -321,58 +322,23 @@ public sealed class OpsMemoryChatProviderIntegrationTests : IAsyncLifetime
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Null implementation of IKnownIssueStore for testing.
|
||||
/// Null implementation of IPlaybookSuggestionService for testing.
|
||||
/// </summary>
|
||||
private sealed class NullKnownIssueStore : IKnownIssueStore
|
||||
private sealed class NullPlaybookSuggestionService : IPlaybookSuggestionService
|
||||
{
|
||||
public Task<KnownIssue> CreateAsync(KnownIssue issue, CancellationToken ct) =>
|
||||
Task.FromResult(issue);
|
||||
public Task<PlaybookSuggestionResult> GetSuggestionsAsync(
|
||||
PlaybookSuggestionRequest request,
|
||||
CancellationToken cancellationToken = default) =>
|
||||
Task.FromResult(new PlaybookSuggestionResult
|
||||
{
|
||||
Suggestions = ImmutableArray<PlaybookSuggestion>.Empty
|
||||
});
|
||||
|
||||
public Task<KnownIssue?> UpdateAsync(KnownIssue issue, CancellationToken ct) =>
|
||||
Task.FromResult<KnownIssue?>(issue);
|
||||
|
||||
public Task<KnownIssue?> GetByIdAsync(string issueId, string tenantId, CancellationToken ct) =>
|
||||
Task.FromResult<KnownIssue?>(null);
|
||||
|
||||
public Task<ImmutableArray<KnownIssue>> FindByContextAsync(
|
||||
string tenantId, string? cveId, string? component, CancellationToken ct) =>
|
||||
Task.FromResult(ImmutableArray<KnownIssue>.Empty);
|
||||
|
||||
public Task<ImmutableArray<KnownIssue>> ListAsync(
|
||||
string tenantId, int limit, int offset, CancellationToken ct) =>
|
||||
Task.FromResult(ImmutableArray<KnownIssue>.Empty);
|
||||
|
||||
public Task<bool> DeleteAsync(string issueId, string tenantId, CancellationToken ct) =>
|
||||
Task.FromResult(false);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Null implementation of ITacticStore for testing.
|
||||
/// </summary>
|
||||
private sealed class NullTacticStore : ITacticStore
|
||||
{
|
||||
public Task<Tactic> CreateAsync(Tactic tactic, string tenantId, CancellationToken ct) =>
|
||||
Task.FromResult(tactic);
|
||||
|
||||
public Task<Tactic?> UpdateAsync(Tactic tactic, string tenantId, CancellationToken ct) =>
|
||||
Task.FromResult<Tactic?>(tactic);
|
||||
|
||||
public Task<Tactic?> GetByIdAsync(string tacticId, string tenantId, CancellationToken ct) =>
|
||||
Task.FromResult<Tactic?>(null);
|
||||
|
||||
public Task<ImmutableArray<Tactic>> FindByTriggerAsync(
|
||||
string tenantId, TacticTrigger trigger, CancellationToken ct) =>
|
||||
Task.FromResult(ImmutableArray<Tactic>.Empty);
|
||||
|
||||
public Task<ImmutableArray<Tactic>> ListAsync(
|
||||
string tenantId, int limit, int offset, CancellationToken ct) =>
|
||||
Task.FromResult(ImmutableArray<Tactic>.Empty);
|
||||
|
||||
public Task<Tactic?> RecordUsageAsync(
|
||||
string tacticId, string tenantId, bool wasSuccessful, CancellationToken ct) =>
|
||||
Task.FromResult<Tactic?>(null);
|
||||
|
||||
public Task<bool> DeleteAsync(string tacticId, string tenantId, CancellationToken ct) =>
|
||||
Task.FromResult(false);
|
||||
public Task<IReadOnlyList<PlaybookSuggestion>> GetSuggestionsAsync(
|
||||
SituationContext situation,
|
||||
int maxSuggestions,
|
||||
CancellationToken cancellationToken = default) =>
|
||||
Task.FromResult<IReadOnlyList<PlaybookSuggestion>>(
|
||||
ImmutableArray<PlaybookSuggestion>.Empty);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -163,7 +163,7 @@ public sealed class OpsMemoryChatProviderTests
|
||||
// Arrange
|
||||
var action = new ActionExecutionResult
|
||||
{
|
||||
Action = DecisionAction.AcceptRisk,
|
||||
Action = DecisionAction.Accept,
|
||||
CveId = "CVE-2021-44228",
|
||||
Component = "pkg:maven/org.apache.logging.log4j/log4j-core@2.14.0",
|
||||
Success = true,
|
||||
@@ -195,7 +195,7 @@ public sealed class OpsMemoryChatProviderTests
|
||||
Assert.NotNull(result);
|
||||
Assert.StartsWith("om-chat-", result.MemoryId);
|
||||
Assert.Equal("tenant-1", result.TenantId);
|
||||
Assert.Equal(DecisionAction.AcceptRisk, result.Decision.Action);
|
||||
Assert.Equal(DecisionAction.Accept, result.Decision.Action);
|
||||
Assert.Equal("user-123", result.Decision.DecidedBy);
|
||||
Assert.Contains("Risk accepted", result.Decision.Rationale);
|
||||
}
|
||||
@@ -211,7 +211,7 @@ public sealed class OpsMemoryChatProviderTests
|
||||
CreateTestRecord("om-002", "CVE-2021-44229", OutcomeStatus.Failure)
|
||||
),
|
||||
TotalCount = 2,
|
||||
HasMore = false
|
||||
NextCursor = null
|
||||
};
|
||||
|
||||
_storeMock.Setup(s => s.QueryAsync(It.IsAny<OpsMemoryQuery>(), It.IsAny<CancellationToken>()))
|
||||
@@ -277,7 +277,7 @@ public sealed class OpsMemoryChatProviderTests
|
||||
},
|
||||
Decision = new DecisionRecord
|
||||
{
|
||||
Action = DecisionAction.AcceptRisk,
|
||||
Action = DecisionAction.Accept,
|
||||
Rationale = "Test rationale",
|
||||
DecidedBy = "test-user",
|
||||
DecidedAt = DateTimeOffset.UtcNow
|
||||
@@ -286,6 +286,7 @@ public sealed class OpsMemoryChatProviderTests
|
||||
? new OutcomeRecord
|
||||
{
|
||||
Status = outcomeStatus.Value,
|
||||
RecordedBy = "test-user",
|
||||
RecordedAt = DateTimeOffset.UtcNow
|
||||
}
|
||||
: null
|
||||
|
||||
@@ -46,7 +46,7 @@ public sealed class OpsMemoryContextEnricherTests
|
||||
{
|
||||
MemoryId = "om-001",
|
||||
CveId = "CVE-2021-44227",
|
||||
Action = DecisionAction.AcceptRisk,
|
||||
Action = DecisionAction.Accept,
|
||||
OutcomeStatus = OutcomeStatus.Success,
|
||||
SimilarityScore = 0.85,
|
||||
DecidedAt = DateTimeOffset.UtcNow,
|
||||
@@ -65,7 +65,7 @@ public sealed class OpsMemoryContextEnricherTests
|
||||
Assert.True(result.HasEnrichment);
|
||||
Assert.Contains("Institutional Memory", result.EnrichedPrompt);
|
||||
Assert.Contains("CVE-2021-44227", result.EnrichedPrompt);
|
||||
Assert.Contains("AcceptRisk", result.EnrichedPrompt);
|
||||
Assert.Contains("Accept", result.EnrichedPrompt);
|
||||
Assert.Contains("[SUCCESS]", result.EnrichedPrompt);
|
||||
}
|
||||
|
||||
@@ -157,7 +157,7 @@ public sealed class OpsMemoryContextEnricherTests
|
||||
Assert.True(result.HasEnrichment);
|
||||
Assert.Contains("Playbook Tactics", result.EnrichedPrompt);
|
||||
Assert.Contains("Immediate Patch", result.EnrichedPrompt);
|
||||
Assert.Contains("95%", result.EnrichedPrompt); // Success rate formatted as percentage
|
||||
Assert.Contains("95", result.EnrichedPrompt); // Success rate formatted as percentage
|
||||
}
|
||||
|
||||
[Fact]
|
||||
@@ -171,7 +171,7 @@ public sealed class OpsMemoryContextEnricherTests
|
||||
{
|
||||
MemoryId = "om-001",
|
||||
CveId = "CVE-2021-44228",
|
||||
Action = DecisionAction.AcceptRisk,
|
||||
Action = DecisionAction.Accept,
|
||||
SimilarityScore = 0.85,
|
||||
DecidedAt = DateTimeOffset.UtcNow
|
||||
}
|
||||
@@ -208,7 +208,7 @@ public sealed class OpsMemoryContextEnricherTests
|
||||
{
|
||||
MemoryId = "om-001",
|
||||
CveId = "CVE-2021-44228",
|
||||
Action = DecisionAction.AcceptRisk,
|
||||
Action = DecisionAction.Accept,
|
||||
OutcomeStatus = OutcomeStatus.Failure,
|
||||
SimilarityScore = 0.85,
|
||||
DecidedAt = DateTimeOffset.UtcNow,
|
||||
@@ -239,7 +239,7 @@ public sealed class OpsMemoryContextEnricherTests
|
||||
{
|
||||
MemoryId = "om-001",
|
||||
CveId = "CVE-1",
|
||||
Action = DecisionAction.AcceptRisk,
|
||||
Action = DecisionAction.Accept,
|
||||
SimilarityScore = 0.9,
|
||||
DecidedAt = DateTimeOffset.UtcNow
|
||||
},
|
||||
|
||||
Reference in New Issue
Block a user