feat: Add initial implementation of Vulnerability Resolver Jobs
Some checks failed
Docs CI / lint-and-preview (push) Has been cancelled

- Created project for StellaOps.Scanner.Analyzers.Native.Tests with necessary dependencies.
- Documented roles and guidelines in AGENTS.md for Scheduler module.
- Implemented IResolverJobService interface and InMemoryResolverJobService for handling resolver jobs.
- Added ResolverBacklogNotifier and ResolverBacklogService for monitoring job metrics.
- Developed API endpoints for managing resolver jobs and retrieving metrics.
- Defined models for resolver job requests and responses.
- Integrated dependency injection for resolver job services.
- Implemented ImpactIndexSnapshot for persisting impact index data.
- Introduced SignalsScoringOptions for configurable scoring weights in reachability scoring.
- Added unit tests for ReachabilityScoringService and RuntimeFactsIngestionService.
- Created dotnet-filter.sh script to handle command-line arguments for dotnet.
- Established nuget-prime project for managing package downloads.
This commit is contained in:
master
2025-11-18 07:52:15 +02:00
parent e69b57d467
commit 8355e2ff75
299 changed files with 13293 additions and 2444 deletions

View File

@@ -0,0 +1,81 @@
using System.Diagnostics;
using System.Text.Json.Nodes;
using FluentAssertions;
using StellaOps.Findings.Ledger.Domain;
using StellaOps.Findings.Ledger.Observability;
using Xunit;
namespace StellaOps.Findings.Ledger.Tests.Observability;
public class LedgerTimelineTests
{
[Fact]
public void EmitLedgerAppended_writes_structured_log_with_event_id()
{
var logger = new TestLogger<LedgerTimelineTests>();
using var activity = new Activity("test").Start();
var record = CreateRecord();
LedgerTimeline.EmitLedgerAppended(logger, record, "evidence-123");
logger.Entries.Should().HaveCount(1);
var entry = logger.Entries.First();
entry.EventId.Name.Should().Be("ledger.event.appended");
entry.EventId.Id.Should().Be(6101);
var state = AsDictionary(entry.State);
state["Tenant"].Should().Be(record.TenantId);
state["EvidenceRef"].Should().Be("evidence-123");
}
[Fact]
public void EmitProjectionUpdated_writes_structured_log_with_status()
{
var logger = new TestLogger<LedgerTimelineTests>();
using var activity = new Activity("test").Start();
var record = CreateRecord();
LedgerTimeline.EmitProjectionUpdated(logger, record, "affected");
var entry = logger.Entries.Single();
entry.EventId.Name.Should().Be("ledger.projection.updated");
entry.EventId.Id.Should().Be(6201);
var state = AsDictionary(entry.State);
state["Status"].Should().Be("affected");
}
private static LedgerEventRecord CreateRecord()
{
var payload = new JsonObject { ["status"] = "affected" };
return new LedgerEventRecord(
"tenant-a",
Guid.NewGuid(),
1,
Guid.NewGuid(),
"finding.status.changed",
"v1",
"finding-1",
"artifact-1",
null,
"actor-1",
"operator",
DateTimeOffset.UtcNow,
DateTimeOffset.UtcNow,
payload,
"hash-event",
"hash-prev",
"hash-leaf",
"canonical-json");
}
private static IDictionary<string, object?> AsDictionary(object state)
{
if (state is not IEnumerable<KeyValuePair<string, object?>> pairs)
{
return new Dictionary<string, object?>();
}
return pairs.ToDictionary(k => k.Key, v => v.Value);
}
}