AOC (Aggregation-Only Contracts)
Status: Implemented Source: src/Aoc/ Owner: Platform Team
Purpose
Audience: developers building or maintaining ingestion connectors (Concelier, Excititor, and similar), plus reviewers verifying that raw upstream data is never silently enriched with computed fields.
AOC enforces aggregation-only contract rules during data ingestion: connectors may persist raw upstream data with provenance, but must not write fields that are computed by downstream merge/decisioning pipelines. Enforcement is two-layered — a runtime write-guard and Roslyn analyzers. AOC is a shared library; it has no HTTP service of its own. (Some source comments still say “Append-Only Contract”; same concept.)
Components
Libraries:
StellaOps.Aoc- Runtime guardIAocGuard/AocWriteGuard(Validate(JsonElement document, AocGuardOptions? options = null)→AocGuardResult),ValidateOrThrow(...)extension that raisesAocGuardException, violation codesERR_AOC_001..010(AocViolationCodeenum +ToErrorCode()), DI viaAddAocGuard()(registersAocWriteGuardas singletonIAocGuard)StellaOps.Aoc.AspNetCore- Minimal-API endpoint filter (RequireAocGuard<TRequest>(...)over two payload-selector overloads) + RFC 7807 problem responses (AocHttpResults.Problem)
Analyzers:
StellaOps.Aoc.Analyzers- One Roslyn analyzer (AocForbiddenFieldAnalyzer) with diagnostics AOC0001 (forbidden field, Error), AOC0002 (derivedeffective_*field, Error), AOC0003 (unguarded DB write, Warning). The analyzer only fires inside ingestion contexts (assemblies/namespaces matching.Connector/.Ingestion, types/members marked[AocIngestion]/[AocIngestionContext], or via MSBuild opt-inStellaOpsAocIngestion/StellaOpsAocIngestionAssemblies/StellaOpsAocIngestionNamespacePrefixes);.Tests/.Analyzersassemblies are excluded. Note: the analyzer’s forbidden-field set additionally treatseffective_statusandeffective_rangeas AOC0001 forbidden fields (the runtime guard treats alleffective_*fields uniformly as derived →ERR_AOC_006).
CLI:
- No project in
src/Aoc/.stella aoc verifyis a CLI plugin atsrc/Cli/__Libraries/StellaOps.Cli.Plugins.Aoc/. Required options:--since/-s(ISO-8601),--postgres/-p(connection string); optional:--tenant/-t,--output/-o(JSON report),--ndjson/-n(one violation per line),--dry-run. Exit codes:0clean,2violations found,1configuration/runtime error.
Key Concepts
Forbidden fields (runtime guard, top-level → ERR_AOC_001):
severity,cvss,cvss_vector- computed from CVSS + contextmerged_from,consensus_provider- merge/VEX provenance & provider selectionrisk_score,reachability,asset_criticality- runtime/policy analysis
Derived fields (→ ERR_AOC_006):
- Any field prefixed with
effective_*(handled separately from the forbidden set above)
Document shape: the guard also enforces required/allowed top-level fields, a non-empty tenant, and upstream/content/linkset/signature provenance. Default required top-level fields are tenant, source, upstream, content, linkset (see AocGuardOptions). Codes emitted: ERR_AOC_004 (missing provenance — upstream.content_hash / upstream.signature / content.raw), ERR_AOC_005 (signature payload invalid), ERR_AOC_007 (unknown top-level field), ERR_AOC_008 (missing required field, incl. missing upstream/content/linkset), ERR_AOC_009 (invalid tenant), ERR_AOC_010 (invalid signature metadata). The enum also reserves ERR_AOC_002 (MergeAttempt) and ERR_AOC_003 (IdempotencyViolation), but AocWriteGuard.Validate does not currently emit them. See ./architecture.md §2–§3.
Configuration (AocGuardOptions): RequireTenant (default true), RequireSignatureMetadata (default true, requires upstream.signature), AllowedSignatureFormats (empty = accept any), RequiredTopLevelFields, AllowedTopLevelFields. The ASP.NET Core filter resolves options from an explicit guardOptions argument, else IOptions<AocGuardOptions>, else AocGuardOptions.Default.
HTTP mapping (AocHttpResults.Problem): RFC 7807 with problem type https://stella-ops.org/problems/aoc-violation; status by first violation code — ERR_AOC_003 → 409, ERR_AOC_004/ERR_AOC_005 → 422, ERR_AOC_006 → 403, all others → 400.
Related Documentation
- Architecture:
./architecture.md - Concelier:
../concelier/(consumes the guard; hostsPOST /aoc/verify—StellaOps.Concelier.WebService/Program.cs) - Excititor:
../excititor/(consumes the guard; pre-normalize lineage gate; also hostsPOST /aoc/verify—StellaOps.Excititor.WebService/Program.cs) - Authority scope:
aoc:verify(StellaOpsScopes.AocVerify); the/aoc/verifyendpoints are guarded by a require-ALL policy ofadvisory:read+aoc:verify.
