feat: add PolicyPackSelectorComponent with tests and integration

- Implemented PolicyPackSelectorComponent for selecting policy packs.
- Added unit tests for component behavior, including API success and error handling.
- Introduced monaco-workers type declarations for editor workers.
- Created acceptance tests for guardrails with stubs for AT1–AT10.
- Established SCA Failure Catalogue Fixtures for regression testing.
- Developed plugin determinism harness with stubs for PL1–PL10.
- Added scripts for evidence upload and verification processes.
This commit is contained in:
StellaOps Bot
2025-12-05 21:24:34 +02:00
parent 347c88342c
commit 18d87c64c5
220 changed files with 7700 additions and 518 deletions

View File

@@ -6,4 +6,5 @@ public interface ITimelineQueryService
{
Task<IReadOnlyList<TimelineEventView>> QueryAsync(string tenantId, TimelineQueryOptions options, CancellationToken cancellationToken = default);
Task<TimelineEventView?> GetAsync(string tenantId, string eventId, CancellationToken cancellationToken = default);
Task<TimelineEvidenceView?> GetEvidenceAsync(string tenantId, string eventId, CancellationToken cancellationToken = default);
}

View File

@@ -6,4 +6,5 @@ public interface ITimelineQueryStore
{
Task<IReadOnlyList<TimelineEventView>> QueryAsync(string tenantId, TimelineQueryOptions options, CancellationToken cancellationToken);
Task<TimelineEventView?> GetAsync(string tenantId, string eventId, CancellationToken cancellationToken);
Task<TimelineEvidenceView?> GetEvidenceAsync(string tenantId, string eventId, CancellationToken cancellationToken);
}

View File

@@ -0,0 +1,16 @@
namespace StellaOps.TimelineIndexer.Core.Models;
/// <summary>
/// Evidence linkage for a timeline event, pointing to sealed bundle/attestation artifacts.
/// </summary>
public sealed class TimelineEvidenceView
{
public required string EventId { get; init; }
public required string TenantId { get; init; }
public Guid? BundleId { get; init; }
public string? BundleDigest { get; init; }
public string? AttestationSubject { get; init; }
public string? AttestationDigest { get; init; }
public string? ManifestUri { get; init; }
public DateTimeOffset CreatedAt { get; init; }
}

View File

@@ -19,6 +19,37 @@ public sealed class TimelineQueryService(ITimelineQueryStore store) : ITimelineQ
return store.GetAsync(tenantId, eventId, cancellationToken);
}
public async Task<TimelineEvidenceView?> GetEvidenceAsync(string tenantId, string eventId, CancellationToken cancellationToken = default)
{
ArgumentException.ThrowIfNullOrWhiteSpace(tenantId);
ArgumentException.ThrowIfNullOrWhiteSpace(eventId);
var evidence = await store.GetEvidenceAsync(tenantId, eventId, cancellationToken).ConfigureAwait(false);
if (evidence is null)
{
return null;
}
var manifest = evidence.ManifestUri;
if (manifest is null && evidence.BundleId is not null)
{
manifest = $"bundles/{evidence.BundleId:N}/manifest.dsse.json";
}
var subject = evidence.AttestationSubject ?? evidence.BundleDigest;
return new TimelineEvidenceView
{
EventId = evidence.EventId,
TenantId = evidence.TenantId,
BundleId = evidence.BundleId,
BundleDigest = evidence.BundleDigest,
AttestationSubject = subject,
AttestationDigest = evidence.AttestationDigest,
ManifestUri = manifest,
CreatedAt = evidence.CreatedAt
};
}
private static TimelineQueryOptions Normalize(TimelineQueryOptions options)
{
var limit = options.Limit;