feat: Implement PackRunApprovalDecisionService for handling approval decisions
Some checks failed
Docs CI / lint-and-preview (push) Has been cancelled

- Added PackRunApprovalDecisionService to manage approval workflows for pack runs.
- Introduced PackRunApprovalDecisionRequest and PackRunApprovalDecisionResult records.
- Implemented logic to apply approval decisions and schedule run resumes based on approvals.
- Updated related tests to validate approval decision functionality.

test: Enhance tests for PackRunApprovalDecisionService

- Created PackRunApprovalDecisionServiceTests to cover various approval scenarios.
- Added in-memory stores for approvals and states to facilitate testing.
- Validated behavior for applying approvals, including handling missing states.

test: Add FilesystemPackRunArtifactUploaderTests for artifact uploads

- Implemented tests for FilesystemPackRunArtifactUploader to ensure correct file handling.
- Verified that missing files are recorded without exceptions and outputs are written as expected.

fix: Update PackRunState creation to include plan reference

- Modified PackRunState creation logic to include the plan in the state.

chore: Refactor service registration in Program.cs

- Updated service registrations in Program.cs to include new approval store and dispatcher services.
- Ensured proper dependency injection for PackRunApprovalDecisionService.

chore: Enhance TaskRunnerServiceOptions for approval store paths

- Added ApprovalStorePath and other paths to TaskRunnerServiceOptions for better configuration.

chore: Update PackRunWorkerService to handle artifact uploads

- Integrated artifact uploading into PackRunWorkerService upon successful run completion.

docs: Update TASKS.md for sprint progress

- Documented progress on approvals workflow and related tasks in TASKS.md.
This commit is contained in:
master
2025-11-06 11:08:52 +02:00
157 changed files with 6386 additions and 3296 deletions

View File

@@ -1,6 +1,6 @@
namespace StellaOps.Scheduler.WebService.GraphJobs;
internal readonly record struct GraphJobUpdateResult<TJob>(bool Updated, TJob Job) where TJob : class
public readonly record struct GraphJobUpdateResult<TJob>(bool Updated, TJob Job) where TJob : class
{
public static GraphJobUpdateResult<TJob> UpdatedResult(TJob job) => new(true, job);

View File

@@ -43,6 +43,7 @@ internal sealed class PolicySimulationMetricsProvider : IPolicySimulationMetrics
private readonly Histogram<double> _latencyHistogram;
private readonly object _snapshotLock = new();
private IReadOnlyDictionary<string, long> _latestQueueSnapshot = new Dictionary<string, long>(StringComparer.Ordinal);
private string _latestTenantId = string.Empty;
private bool _disposed;
public PolicySimulationMetricsProvider(IPolicyRunJobRepository repository, TimeProvider? timeProvider = null)
@@ -83,9 +84,12 @@ internal sealed class PolicySimulationMetricsProvider : IPolicySimulationMetrics
totalQueueDepth += count;
}
var snapshot = new Dictionary<string, long>(queueCounts, StringComparer.Ordinal);
lock (_snapshotLock)
{
_latestQueueSnapshot = queueCounts;
_latestQueueSnapshot = snapshot;
_latestTenantId = tenantId;
}
var sampleSize = 200;
@@ -113,7 +117,7 @@ internal sealed class PolicySimulationMetricsProvider : IPolicySimulationMetrics
Average(durations));
return new PolicySimulationMetricsResponse(
new PolicySimulationQueueDepth(totalQueueDepth, queueCounts),
new PolicySimulationQueueDepth(totalQueueDepth, snapshot),
latencyMetrics);
}
@@ -134,16 +138,21 @@ internal sealed class PolicySimulationMetricsProvider : IPolicySimulationMetrics
private IEnumerable<Measurement<long>> ObserveQueueDepth()
{
IReadOnlyDictionary<string, long> snapshot;
string tenantId;
lock (_snapshotLock)
{
snapshot = _latestQueueSnapshot;
tenantId = _latestTenantId;
}
tenantId = string.IsNullOrWhiteSpace(tenantId) ? "unknown" : tenantId;
foreach (var pair in snapshot)
{
yield return new Measurement<long>(
pair.Value,
new KeyValuePair<string, object?>("status", pair.Key));
new KeyValuePair<string, object?>("status", pair.Key),
new KeyValuePair<string, object?>("tenantId", tenantId));
}
}

View File

@@ -29,12 +29,13 @@
## Policy Studio (Sprint 27)
| ID | Status | Owner(s) | Depends on | Description | Exit Criteria |
|----|--------|----------|------------|-------------|---------------|
| SCHED-CONSOLE-27-001 | DONE (2025-11-03) | Scheduler WebService Guild, Policy Registry Guild | SCHED-WEB-16-103, REGISTRY-API-27-005 | Provide policy batch simulation orchestration endpoints (`/policies/simulations` POST/GET) exposing run creation, shard status, SSE progress, cancellation, and retries with RBAC enforcement. | API handles shard lifecycle with SSE heartbeats + retry headers; unauthorized requests rejected; integration tests cover submit/cancel/resume flows. |
| SCHED-CONSOLE-27-002 | DONE (2025-11-05) | Scheduler WebService Guild, Observability Guild | SCHED-CONSOLE-27-001 | Emit telemetry endpoints/metrics (`policy_simulation_queue_depth`, `policy_simulation_latency_seconds`) and webhook callbacks for completion/failure consumed by Registry. | Metrics exposed via gateway, dashboards seeded, webhook contract documented, integration tests validate metrics emission. |
> 2025-11-05: Resuming to align instrumentation naming with architecture spec, exercise latency recording in SSE flows, and ensure registry webhook contract (samples/docs) reflects terminal result behaviour.
> 2025-11-05: Histogram renamed to `policy_simulation_latency_seconds`, queue gauge kept stable, new unit tests cover metrics capture/latency recording, and docs updated. Local `dotnet test` build currently blocked by existing GraphJobs visibility errors (see `StellaOps.Scheduler.WebService/GraphJobs/IGraphJobStore.cs`).
## Vulnerability Explorer (Sprint 29)
| SCHED-CONSOLE-27-001 | DONE (2025-11-03) | Scheduler WebService Guild, Policy Registry Guild | SCHED-WEB-16-103, REGISTRY-API-27-005 | Provide policy batch simulation orchestration endpoints (`/policies/simulations` POST/GET) exposing run creation, shard status, SSE progress, cancellation, and retries with RBAC enforcement. | API handles shard lifecycle with SSE heartbeats + retry headers; unauthorized requests rejected; integration tests cover submit/cancel/resume flows. |
| SCHED-CONSOLE-27-002 | DONE (2025-11-05) | Scheduler WebService Guild, Observability Guild | SCHED-CONSOLE-27-001 | Emit telemetry endpoints/metrics (`policy_simulation_queue_depth`, `policy_simulation_latency_seconds`) and webhook callbacks for completion/failure consumed by Registry. | Metrics exposed via gateway, dashboards seeded, webhook contract documented, integration tests validate metrics emission. |
> 2025-11-05: Resuming to align instrumentation naming with architecture spec, exercise latency recording in SSE flows, and ensure registry webhook contract (samples/docs) reflects terminal result behaviour.
> 2025-11-05: Histogram renamed to `policy_simulation_latency_seconds`, queue gauge kept stable, new unit tests cover metrics capture/latency recording, and docs updated. Local `dotnet test` build currently blocked by existing GraphJobs visibility errors (see `StellaOps.Scheduler.WebService/GraphJobs/IGraphJobStore.cs`).
> 2025-11-06: Added tenant-aware tagging to `policy_simulation_queue_depth` gauge samples and refreshed metrics provider snapshot coverage.
## Vulnerability Explorer (Sprint 29)
| ID | Status | Owner(s) | Depends on | Description | Exit Criteria |
|----|--------|----------|------------|-------------|---------------|
| SCHED-VULN-29-001 | TODO | Scheduler WebService Guild, Findings Ledger Guild | SCHED-WEB-16-103, SBOM-VULN-29-001 | Expose resolver job APIs (`POST /vuln/resolver/jobs`, `GET /vuln/resolver/jobs/{id}`) to trigger candidate recomputation per artifact/policy change with RBAC and rate limits. | Resolver APIs documented; integration tests cover submit/status/cancel; unauthorized requests rejected. |