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:
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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; }
|
||||
}
|
||||
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user