audit work, fixed StellaOps.sln warnings/errors, fixed tests, sprints work, new advisories

This commit is contained in:
master
2026-01-07 18:49:59 +02:00
parent 04ec098046
commit 608a7f85c0
866 changed files with 56323 additions and 6231 deletions

View File

@@ -4,7 +4,7 @@ namespace StellaOps.Policy.Determinization.Models;
/// <summary>
/// Context for determinization evaluation.
/// Contains environment, criticality, and policy settings.
/// Contains environment, criticality, policy settings, and computed evidence data.
/// </summary>
public sealed record DeterminizationContext
{
@@ -18,56 +18,116 @@ public sealed record DeterminizationContext
/// Asset criticality level.
/// </summary>
[JsonPropertyName("criticality")]
public required AssetCriticality Criticality { get; init; }
public AssetCriticality Criticality { get; init; } = AssetCriticality.Medium;
/// <summary>
/// Entropy threshold for this context.
/// Observations above this trigger guardrails.
/// </summary>
[JsonPropertyName("entropy_threshold")]
public required double EntropyThreshold { get; init; }
public double EntropyThreshold { get; init; } = 0.5;
/// <summary>
/// Decay threshold for this context.
/// Observations below this are considered stale.
/// </summary>
[JsonPropertyName("decay_threshold")]
public required double DecayThreshold { get; init; }
public double DecayThreshold { get; init; } = 0.5;
/// <summary>
/// Creates context with default production settings.
/// Signal snapshot containing evidence from various sources.
/// </summary>
public static DeterminizationContext Production() => new()
{
Environment = DeploymentEnvironment.Production,
Criticality = AssetCriticality.High,
EntropyThreshold = 0.4,
DecayThreshold = 0.50
};
[JsonPropertyName("signal_snapshot")]
public required SignalSnapshot SignalSnapshot { get; init; }
/// <summary>
/// Creates context with relaxed development settings.
/// Calculated uncertainty score for this context.
/// </summary>
public static DeterminizationContext Development() => new()
{
Environment = DeploymentEnvironment.Development,
Criticality = AssetCriticality.Low,
EntropyThreshold = 0.6,
DecayThreshold = 0.35
};
[JsonPropertyName("uncertainty_score")]
public required UncertaintyScore UncertaintyScore { get; init; }
/// <summary>
/// Creates context with custom thresholds.
/// Observation decay information.
/// </summary>
[JsonPropertyName("decay")]
public required ObservationDecay Decay { get; init; }
/// <summary>
/// Aggregated trust score (0.0-1.0).
/// </summary>
[JsonPropertyName("trust_score")]
public required double TrustScore { get; init; }
/// <summary>
/// Creates context with default production settings and placeholder signal data.
/// </summary>
public static DeterminizationContext Production(
SignalSnapshot? snapshot = null,
UncertaintyScore? uncertaintyScore = null,
ObservationDecay? decay = null,
double trustScore = 0.5)
{
var now = DateTimeOffset.UtcNow;
return new()
{
Environment = DeploymentEnvironment.Production,
Criticality = AssetCriticality.High,
EntropyThreshold = 0.4,
DecayThreshold = 0.50,
SignalSnapshot = snapshot ?? SignalSnapshot.Empty("CVE-0000-0000", "pkg:unknown/unknown@0.0.0", now),
UncertaintyScore = uncertaintyScore ?? UncertaintyScore.Zero(1.0, now),
Decay = decay ?? ObservationDecay.Fresh(now),
TrustScore = trustScore
};
}
/// <summary>
/// Creates context with relaxed development settings and placeholder signal data.
/// </summary>
public static DeterminizationContext Development(
SignalSnapshot? snapshot = null,
UncertaintyScore? uncertaintyScore = null,
ObservationDecay? decay = null,
double trustScore = 0.5)
{
var now = DateTimeOffset.UtcNow;
return new()
{
Environment = DeploymentEnvironment.Development,
Criticality = AssetCriticality.Low,
EntropyThreshold = 0.6,
DecayThreshold = 0.35,
SignalSnapshot = snapshot ?? SignalSnapshot.Empty("CVE-0000-0000", "pkg:unknown/unknown@0.0.0", now),
UncertaintyScore = uncertaintyScore ?? UncertaintyScore.Zero(1.0, now),
Decay = decay ?? ObservationDecay.Fresh(now),
TrustScore = trustScore
};
}
/// <summary>
/// Creates context with custom thresholds and placeholder signal data.
/// </summary>
public static DeterminizationContext Create(
DeploymentEnvironment environment,
AssetCriticality criticality,
double entropyThreshold,
double decayThreshold) => new()
double decayThreshold,
SignalSnapshot? snapshot = null,
UncertaintyScore? uncertaintyScore = null,
ObservationDecay? decay = null,
double trustScore = 0.5)
{
Environment = environment,
Criticality = criticality,
EntropyThreshold = entropyThreshold,
DecayThreshold = decayThreshold
};
var now = DateTimeOffset.UtcNow;
return new()
{
Environment = environment,
Criticality = criticality,
EntropyThreshold = entropyThreshold,
DecayThreshold = decayThreshold,
SignalSnapshot = snapshot ?? SignalSnapshot.Empty("CVE-0000-0000", "pkg:unknown/unknown@0.0.0", now),
UncertaintyScore = uncertaintyScore ?? UncertaintyScore.Zero(1.0, now),
Decay = decay ?? ObservationDecay.Fresh(now),
TrustScore = trustScore
};
}
}

View File

@@ -38,10 +38,22 @@ public sealed record GuardRails
[JsonPropertyName("notes")]
public string? Notes { get; init; }
/// <summary>
/// Default guardrails instance with safe settings.
/// </summary>
public static GuardRails Default { get; } = new()
{
EnableMonitoring = true,
RestrictToNonProd = false,
RequireApproval = false,
ReevalAfter = TimeSpan.FromDays(7),
Notes = null
};
/// <summary>
/// Creates GuardRails with default safe settings.
/// </summary>
public static GuardRails Default() => new()
public static GuardRails CreateDefault() => new()
{
EnableMonitoring = true,
RestrictToNonProd = false,

View File

@@ -3,7 +3,7 @@ using System.Text.Json.Serialization;
namespace StellaOps.Policy.Determinization.Models;
/// <summary>
/// Per-observation decay configuration.
/// Per-observation decay configuration and computed state.
/// Tracks evidence staleness with configurable half-life.
/// Formula: decayed = max(floor, exp(-ln(2) * age_days / half_life_days))
/// </summary>
@@ -13,27 +13,27 @@ public sealed record ObservationDecay
/// When the observation was first recorded (UTC).
/// </summary>
[JsonPropertyName("observed_at")]
public required DateTimeOffset ObservedAt { get; init; }
public DateTimeOffset ObservedAt { get; init; } = DateTimeOffset.UtcNow;
/// <summary>
/// When the observation was last refreshed (UTC).
/// </summary>
[JsonPropertyName("refreshed_at")]
public required DateTimeOffset RefreshedAt { get; init; }
public DateTimeOffset RefreshedAt { get; init; } = DateTimeOffset.UtcNow;
/// <summary>
/// Half-life in days.
/// Default: 14 days.
/// </summary>
[JsonPropertyName("half_life_days")]
public required double HalfLifeDays { get; init; }
public double HalfLifeDays { get; init; } = 14.0;
/// <summary>
/// Minimum confidence floor.
/// Default: 0.35 (consistent with FreshnessCalculator).
/// </summary>
[JsonPropertyName("floor")]
public required double Floor { get; init; }
public double Floor { get; init; } = 0.35;
/// <summary>
/// Staleness threshold (0.0-1.0).
@@ -41,7 +41,31 @@ public sealed record ObservationDecay
/// Default: 0.50
/// </summary>
[JsonPropertyName("staleness_threshold")]
public required double StalenessThreshold { get; init; }
public double StalenessThreshold { get; init; } = 0.50;
/// <summary>
/// Last signal update time (alias for RefreshedAt for convenience).
/// </summary>
[JsonPropertyName("last_signal_update")]
public DateTimeOffset LastSignalUpdate { get; init; } = DateTimeOffset.UtcNow;
/// <summary>
/// Age in days since last refresh.
/// </summary>
[JsonPropertyName("age_days")]
public double AgeDays { get; init; }
/// <summary>
/// Pre-computed decay multiplier (0.0-1.0).
/// </summary>
[JsonPropertyName("decayed_multiplier")]
public double DecayedMultiplier { get; init; } = 1.0;
/// <summary>
/// Whether the observation is considered stale.
/// </summary>
[JsonPropertyName("is_stale")]
public bool IsStale { get; init; }
/// <summary>
/// Calculates the current decay multiplier.
@@ -59,7 +83,7 @@ public sealed record ObservationDecay
/// <summary>
/// Returns true if the observation is stale (decay below threshold).
/// </summary>
public bool IsStale(DateTimeOffset now) =>
public bool CheckIsStale(DateTimeOffset now) =>
CalculateDecay(now) < StalenessThreshold;
/// <summary>

View File

@@ -82,6 +82,12 @@ public sealed record UncertaintyScore
[JsonPropertyName("calculated_at")]
public required DateTimeOffset CalculatedAt { get; init; }
/// <summary>
/// Completeness ratio (present_weight / max_weight).
/// </summary>
[JsonIgnore]
public double Completeness => MaxWeight > 0 ? PresentWeight / MaxWeight : 0.0;
/// <summary>
/// Creates an UncertaintyScore with calculated tier.
/// </summary>