- Added IIssuerDirectory interface for managing VEX document issuers, including methods for registration, revocation, and trust validation. - Created InMemoryIssuerDirectory class as an in-memory implementation of IIssuerDirectory for testing and single-instance deployments. - Introduced ISignatureVerifier interface for verifying signatures on VEX documents, with support for multiple signature formats. - Developed SignatureVerifier class as the default implementation of ISignatureVerifier, allowing extensibility for different signature formats. - Implemented handlers for DSSE and JWS signature formats, including methods for verification and signature extraction. - Defined various records and enums for issuer and signature metadata, enhancing the structure and clarity of the verification process.
5.7 KiB
Policy AOC Linting Rules
Document ID: DESIGN-POLICY-AOC-LINTING-001
Version: 1.0
Status: Published
Last Updated: 2025-12-06
Overview
This document defines the linting and static analysis rules for Policy Engine and related library projects. These rules enforce determinism, nullability, async consistency, and JSON property ordering to ensure reproducible policy evaluation.
Target Projects
| Project | Path | Notes |
|---|---|---|
| StellaOps.Policy.Engine | src/Policy/StellaOps.Policy.Engine/ |
Primary target |
| StellaOps.Policy | src/Policy/__Libraries/StellaOps.Policy/ |
Core library |
| StellaOps.PolicyDsl | src/Policy/StellaOps.PolicyDsl/ |
DSL compiler |
| StellaOps.Policy.RiskProfile | src/Policy/StellaOps.Policy.RiskProfile/ |
Risk scoring |
| StellaOps.Policy.Storage.Postgres | src/Policy/__Libraries/StellaOps.Policy.Storage.Postgres/ |
Storage layer |
Excluded
**/obj/**- Build artifacts**/bin/**- Build outputs**/*.Tests/**- Test projects (separate rules)**/Migrations/**- Generated EF migrations
Rule Categories
1. Determinism Rules (Error Severity)
Enforced by ProhibitedPatternAnalyzer at src/Policy/StellaOps.Policy.Engine/DeterminismGuard/.
| Rule ID | Pattern | Severity | Remediation |
|---|---|---|---|
| DET-001 | DateTime.Now |
Error | Use TimeProvider.GetUtcNow() |
| DET-002 | DateTime.UtcNow |
Error | Use TimeProvider.GetUtcNow() |
| DET-003 | DateTimeOffset.Now |
Error | Use TimeProvider.GetUtcNow() |
| DET-004 | DateTimeOffset.UtcNow |
Error | Use TimeProvider.GetUtcNow() |
| DET-005 | Guid.NewGuid() |
Error | Use StableIdGenerator or content hash |
| DET-006 | new Random() |
Error | Use seeded random or remove |
| DET-007 | RandomNumberGenerator |
Error | Remove from evaluation path |
| DET-008 | HttpClient in eval |
Critical | Remove network from eval path |
| DET-009 | File.Read* in eval |
Critical | Remove filesystem from eval path |
| DET-010 | Dictionary iteration | Warning | Use OrderBy or SortedDictionary |
| DET-011 | HashSet iteration | Warning | Use OrderBy or SortedSet |
2. Nullability Rules (Error Severity)
| Rule ID | Description | EditorConfig |
|---|---|---|
| NUL-001 | Enable nullable reference types | nullable = enable |
| NUL-002 | Nullable warnings as errors | dotnet_diagnostic.CS8600-CS8609.severity = error |
| NUL-003 | Null parameter checks | ArgumentNullException.ThrowIfNull() |
3. Async/Sync Consistency Rules (Warning Severity)
| Rule ID | Description | EditorConfig |
|---|---|---|
| ASY-001 | Async void methods | dotnet_diagnostic.CA2012.severity = error |
| ASY-002 | Missing ConfigureAwait | dotnet_diagnostic.CA2007.severity = warning |
| ASY-003 | Sync over async | dotnet_diagnostic.MA0045.severity = warning |
| ASY-004 | Task.Result in async | dotnet_diagnostic.MA0042.severity = error |
4. JSON Property Ordering Rules
For deterministic JSON output, all DTOs must use explicit [JsonPropertyOrder] attributes.
| Rule ID | Description | Enforcement |
|---|---|---|
| JSN-001 | Explicit property order | Code review + analyzer |
| JSN-002 | Stable serialization | JsonSerializerOptions.WriteIndented = false |
| JSN-003 | Key ordering | JsonSerializerOptions.PropertyNamingPolicy with stable order |
5. Code Style Rules
| Rule ID | Description | EditorConfig |
|---|---|---|
| STY-001 | File-scoped namespaces | csharp_style_namespace_declarations = file_scoped |
| STY-002 | Primary constructors | csharp_style_prefer_primary_constructors = true |
| STY-003 | Collection expressions | csharp_style_prefer_collection_expression = true |
| STY-004 | Implicit usings | ImplicitUsings = enable |
Severity Levels
| Level | Behavior | CI Impact |
|---|---|---|
| Error | Build fails | Blocks merge |
| Warning | Build succeeds, logged | Review required |
| Info | Logged only | No action required |
CI Integration
Build-time Enforcement
Policy projects use TreatWarningsAsErrors=true in .csproj:
<PropertyGroup>
<TreatWarningsAsErrors>true</TreatWarningsAsErrors>
<Nullable>enable</Nullable>
</PropertyGroup>
Static Analysis Pipeline
The .gitea/workflows/policy-lint.yml workflow runs:
- dotnet build with analyzer packages
- DeterminismGuard analysis via CLI
- Format check via
dotnet format --verify-no-changes
Required Analyzer Packages
<ItemGroup>
<PackageReference Include="Microsoft.CodeAnalysis.NetAnalyzers" Version="10.0.0-*" />
<PackageReference Include="Meziantou.Analyzer" Version="2.0.*" />
</ItemGroup>
Baseline Suppressions
Create .globalconfig for legacy code that cannot be immediately fixed:
# Legacy suppressions - track issue for remediation
[src/Policy/**/LegacyCode.cs]
dotnet_diagnostic.DET-010.severity = suggestion
Runtime Enforcement
The DeterminismGuardService provides runtime monitoring:
using var scope = _determinismGuard.CreateScope(scopeId, timestamp);
var result = await evaluation(scope);
var analysis = scope.Complete();
if (!analysis.Passed) { /* log/reject */ }
Acceptance Criteria
- All Policy projects build with zero errors
dotnet formatreports no changes needed- DeterminismGuard analysis passes
- New code has no nullable warnings
- Async methods use
ConfigureAwait(false)