EU Regulatory Artifact Ledger v1

Version: eu-regulatory-artifact-ledger.v1 Owner: EvidenceLocker Status: implemented Sprint: SPRINT_20260430_200

Part of the Stella Ops Contracts index. Audience: implementers and reviewers of the EvidenceLocker regulatory replay index and any downstream module (Graph, CLIs) that reads it through the HTTP API.

Companion contract: eu-regulatory-audit-events-v1.md— the audit events referenced by the ledger.

Source of truth (code):

Purpose

The regulatory artifact ledger is the EvidenceLocker-owned replay index for CRA reports, NIS2 incident packets, DORA reports, RoI snapshots, TLPT evidence packs, and standards-mapping exports. Downstream modules write or call this contract rather than inventing local persistence for regulatory artifact identity, schema pins, signatures, approvals, or retention.

Artifact Type Enum

ValueUse
cra-advisory-reportCRA vulnerability/advisory report evidence.
cra-technical-fileCRA Annex VII technical-file bundle.
cra-conformity-dossierCRA conformity/self-assessment dossier.
nis2-incident-packetNIS2/customer CSIRT reporting packet.
nis2-control-register-controlHash-only projection of a Policy NIS2 control lifecycle event.
nis2-control-register-snapshotPolicy NIS2 control-register snapshot pinned by content hash and source refs.
nis2-statement-of-applicabilityNIS2 SoA export hash pinned to the source control-register snapshot.
dora-incident-reportDORA major-incident report artifact.
dora-roi-snapshotAnnual DORA Register of Information snapshot.
tlpt-evidence-packDORA TLPT signed evidence pack capsule.
standards-mapping-exportISO/IEC/ETSI/JRC mapping export.
public-product-metadataCRA support/security public metadata.

Regime Enum

regime is one of (RegulatoryRegimes consts; DB CHECK (regime IN (...))):

ValueUse
craEU Cyber Resilience Act artifacts.
nis2NIS2 directive artifacts.
doraDORA (Digital Operational Resilience Act) artifacts.
standardsISO/IEC/ETSI/JRC standards-mapping artifacts.

Values are normalized to lower case before persistence (RegulatoryValueNormalizer.NormalizeRequired).

Ledger Fields

Each record (RegulatoryArtifactLedgerRecord) stores:

Retention Metadata

Retention records (RegulatoryRetentionRecord) live in evidence_locker.regulatory_retention_records and carry:

Retention rules (RegulatoryRetentionRules): default DORA RoI retention is 7 years (DefaultDoraRoiRetentionYears). Tenant RoI overrides are bounded to 5-10 years (Minimum/MaximumDoraRoiRetentionYears). TLPT evidence-pack retention has a 10-year minimum (MinimumTlptRetentionYears); stricter tenant policies can extend it. Shortening an existing retain-until date fails closed (InvalidOperationException) unless shorteningApprovalRef is present. The approval never permits a record below its own declared created-at horizon, and legal hold is extension-only. Core validation rejects default/overflowing creation timestamps. Database migration 019_regulatory_retention_horizon.sql enforces the relationship against the persisted original created_at on every new or updated row. Its initial NOT VALID state leaves historical-row audit as an explicit operator action before VALIDATE CONSTRAINT.

Determinism

RegulatoryArtifactLedgerIds.Create(...) computes the ledger id from normalized tenant id, regime, artifact type, and content hash. sourceEvidenceRefs[] are deduplicated and ordinal sorted before persistence. Replay lookup is by (tenantId, regime, artifactType, contentHash), enforced as a unique constraint (uq_regulatory_artifact_lookup); upserts collapse to that key.

HTTP Read API

EvidenceLocker exposes a single source-owned read endpoint. Downstream services (Graph, CLIs, etc.) must call this API or a typed client over it rather than reading the tables directly.

Each items[] entry (RegulatoryArtifactLedgerItem) is JSON with: artifactId (the ledgerRecordId), regime, artifactType, reportingYear (year of createdAt), artifactHash (the contentHash), evidenceRefs[], auditEventIds[] (non-null approval / generation / signing ids), schemaPinId, taxonomyPinId, signatureRef, signerKeyId, retentionRecordId, and createdAt.

Results are ordered by reporting year descending, then artifactType ascending, contentHash ascending, and ledgerRecordId ascending. reportingYear filtering matches EXTRACT(YEAR FROM created_at AT TIME ZONE 'UTC').

There is currently no CLI command bound to this contract.

Persistence And Migration

Migration 007_regulatory_audit_retention_ledger.sql adds:

Tenancy and integrity:

The migration is embedded in the EvidenceLocker infrastructure assembly and is applied by the startup migration hosted service (EvidenceLockerMigrationHostedService) when EvidenceLocker:Database:ApplyMigrationsAtStartup=true (the default; EvidenceLockerOptions.Database.ApplyMigrationsAtStartup).

Offline Replay

Replay requires only the ledger rows, audit event rows, source evidence refs, schema/taxonomy assets already pinned in-repo or runtime assets, and signature material. The ledger must not store mutable report payloads, live regulator responses, credentials, or expanded human PII.

NIS2 Control Register Projection

Policy remains the source of truth for nis2-control-register-v1 entries, lifecycle events, and snapshot JSON in policy.control_register_*. When Policy is configured with the EvidenceLocker regulatory repository, control lifecycle events are projected as evidence.eu.control.lifecycle_recorded audit events using the Policy event id as the audit event id. Published snapshots create hash-only artifact ledger rows for nis2-control-register-snapshot and nis2-statement-of-applicability; their sourceEvidenceRefs[] point back to the Policy snapshot/event refs and the EvidenceLocker bundle ref instead of copying control state into the ledger.