DORA Incident Classification Contract v1
Contract ID: CONTRACT-DORA-INCIDENT-CLASSIFICATION-V1-020 Schema version: stella.ops/doraIncidentClassification@v1 Status: Published Owner: Notify engineering owner with regulatory schema owner review Initial legal basis: Commission Delegated Regulation (EU) 2024/1772 Last updated: 2026-04-30
Part of the Stella Ops Contracts index. Audience: implementers who produce or consume DORA incident-classification facts (Notify, Telemetry, Export Center, and the CLI), and reviewers verifying the transport shape against
src/.
Purpose
This contract defines the structured DORA major ICT-related incident classification facts carried on IncidentResponse.doraClassification. It adds the seven DORA classification criteria without replacing the existing IncidentResponse.metadata dictionary. Tenant-specific notes and ad-hoc operator fields remain in metadata; regulatory classification facts belong in doraClassification.
The contract does not hardcode customer-specific legal conclusions. Classifier and operator workflows may set nullable thresholdMet values and override audit records, but default incident responses omit doraClassification until DORA facts are available.
Schema Pinning Policy
stella.ops/doraIncidentClassification@v1 is pinned per Stella minor release. The v1 contract is pinned to classification criteria from EU 2024/1772 (DoraClassification.CurrentSchemaVersion / CurrentLegalBasis in src/Notify/StellaOps.Notify.WebService/Contracts/IncidentContracts.cs).
The downstream DORA RTS/template encoder work is implemented and pins its legal sources by explicit package version rather than following latest upstream schema changes automatically. See DoraMajorIncidentReportConstants in src/Notify/__Libraries/StellaOps.Notify.Connectors.Dora/:
- reporting content legal basis
EU 2025/301(ReportingContentLegalBasis), - reporting template legal basis
EU 2025/302(ReportingTemplateLegalBasis), - legal template version
dora-major-incident-report-eu-2025-302(LegalTemplateVersion), - local taxonomy package
dora-major-incident-report-eu-2025-302-local-contract-v1(LocalTaxonomyPackageVersion).
The official EBA DPM/XBRL taxonomy package is not yet vendored. Until it is pinned and licensed, EbaPublishedSchemaValidationStatus is blocked and the encoder validates against the local rule set dora-major-incident-report-local-validation-v1 (LocalValidationRuleSetVersion). External schema fetches are disabled per the offline-first posture.
Placement
IncidentResponse gains an optional nullable property:
{
"incidentId": "incident-dora-1",
"tenantId": "tenant-dora",
"eventKind": "dora.incident.opened",
"status": "open",
"severity": "critical",
"title": "Core payment outage",
"eventCount": 9,
"firstOccurrence": "2026-04-30T07:00:00Z",
"lastOccurrence": "2026-04-30T09:30:00Z",
"metadata": {
"operatorNote": "free-form metadata stays available"
},
"doraClassification": {
"schemaVersion": "stella.ops/doraIncidentClassification@v1",
"legalBasis": "EU 2024/1772",
"classifiedAt": "2026-04-30T09:45:00Z",
"classifiedBy": "dora-classifier",
"evidenceRefs": [
"ledger://notify/dora/opened/incident-dora-1",
"evidence://telemetry/snapshot/payments-20260430"
],
"clientsAndTransactionsAffected": {
"thresholdMet": true,
"affectedClientsCount": 12500,
"affectedFinancialCounterpartiesCount": 8,
"affectedTransactionsCount": 42000,
"affectedTransactionsAmount": 1250000.75,
"currencyCode": "EUR",
"rationale": "Payment authorization failures exceeded tenant threshold."
},
"reputationalImpact": {
"thresholdMet": true,
"publicMediaCoverage": true,
"recurringClientComplaints": true,
"regulatorOrPublicAuthorityNotification": false,
"impactSummary": "Press coverage and client complaints observed.",
"rationale": "Multiple external signals indicate reputational impact."
},
"duration": {
"thresholdMet": true,
"startedAt": "2026-04-30T07:00:00Z",
"endedAt": "2026-04-30T09:30:00Z",
"incidentDurationMinutes": 150,
"serviceDowntimeMinutes": 120,
"rationale": "Downtime exceeded the DORA classification threshold."
},
"geographicalSpread": {
"thresholdMet": true,
"affectedJurisdictionCodes": ["DE", "FR"],
"affectedMemberStateCount": 2,
"crossBorderImpact": true,
"rationale": "The same service degradation affected two member states."
},
"dataLosses": {
"thresholdMet": false,
"availabilityLoss": true,
"authenticityLoss": false,
"integrityLoss": false,
"confidentialityLoss": false,
"recordsAffected": 0,
"dataCategories": "none",
"rationale": "No customer data loss was detected."
},
"criticalityOfServices": {
"thresholdMet": true,
"supportsCriticalOrImportantFunction": true,
"affectedCriticalServiceIds": ["svc-payments", "svc-auth"],
"affectedCriticalServiceNames": [
"Payment authorization",
"Strong customer authentication"
],
"rationale": "The affected services support critical payment functions."
},
"economicImpact": {
"thresholdMet": true,
"directCostsAmount": 250000,
"indirectCostsAmount": 95000.5,
"grossLossAmount": 345000.5,
"currencyCode": "EUR",
"rationale": "Estimated losses exceeded configured reporting threshold."
},
"overrides": [
{
"criterion": "economicImpact",
"field": "grossLossAmount",
"previousValue": "300000.50",
"newValue": "345000.50",
"reason": "Finance supplied corrected estimate.",
"actor": "incident-commander@example.test",
"overriddenAt": "2026-04-30T10:00:00Z",
"evidenceRef": "ledger://authority/audit/dora-override-1"
}
]
}
}
Field Requirements
| Field | Required | Description |
|---|---|---|
schemaVersion | yes | Always stella.ops/doraIncidentClassification@v1. |
legalBasis | yes | Initial value EU 2024/1772; bump only through release schema governance. |
classifiedAt | no | UTC time the facts were produced or last refreshed. |
classifiedBy | no | Classifier, service, or operator identifier. |
evidenceRefs | no | Immutable ledger/evidence references needed for offline replay. |
clientsAndTransactionsAffected | no | Criterion facts for clients, financial counterparts, and transactions affected. |
reputationalImpact | no | Criterion facts for public, client, authority, or market reputation impact. |
duration | no | Criterion facts for incident duration and service downtime. |
geographicalSpread | no | Criterion facts for affected jurisdictions and cross-border spread. |
dataLosses | no | Criterion facts for availability, authenticity, integrity, or confidentiality loss. |
criticalityOfServices | no | Criterion facts for critical or important functions and affected services. |
economicImpact | no | Criterion facts for direct, indirect, and gross economic loss. |
overrides | no | Operator override audit entries with before/after values, reason, actor, time, and evidence reference. |
Criterion objects use nullable thresholdMet values. null means the criterion has not yet been assessed or the operator has not supplied enough facts.
Each overrides[] entry records a criterion and field name (free-form strings in the transport contract), the before/after values, the reason, actor, overriddenAt UTC timestamp, and an optional evidenceRef. The deterministic classifier that produces overrides (DoraIncidentClassificationOverrideRequest) supports thresholdMet changes only in v1 (its Field defaults to thresholdMet); the embedded overrides[] shape itself remains generic so later override fields can be recorded without a schema bump.
Implementation Surface (Producers & Consumers)
This contract is the transport projection carried on IncidentResponse. The facts it carries are produced and consumed across several modules:
Producer — deterministic classifier.
StellaOps.Telemetry.Core.DoraIncidentClassifier(seesrc/Telemetry/StellaOps.Telemetry.Core/StellaOps.Telemetry.Core/DoraIncidentClassifier.csandDoraIncidentClassifierModels.cs) turns immutable incident facts (DoraIncidentFacts), a tenant compliance profile (DoraTenantComplianceProfileSnapshotwith explicitDoraIncidentClassificationThresholds), and an optional frozen telemetry snapshot (DoraIncidentTelemetrySnapshot) into aDoraIncidentClassificationResult. Each of the seven criteria carries a three-state assessment,DoraCriterionAssessmentStatus(NotMet/Met/InsufficientData), plus aMissingInputslist. The classifier shares the sameCurrentSchemaVersion/CurrentLegalBasisconstants as the transport contract. Operator overrides also emit a separate audit event, event kindtelemetry.dora.classification.override(DoraClassificationOverrideAuditEvent.EventKindValue).Transport — Notify incident response.
DoraClassificationand its criterion records live insrc/Notify/StellaOps.Notify.WebService/Contracts/IncidentContracts.cs. The property is[JsonIgnore(Condition = WhenWritingNull)]so it is omitted when absent (see Backward Compatibility below).Consumer — DORA major-incident report encoder.
StellaOps.Notify.Connectors.Doraconsumes classification facts into the signed EU 2025/302 XBRL / inline-XBRL major-incident report (see Schema Pinning Policy). The report is wrapped in a DSSE envelope and a filesystem handoff manifest for offline transfer.Consumer — Export Center assurance profile. The
dora.major-incident-reportassurance export profile (AssuranceExportProfileRegistry.DoraMajorIncidentReportProfileId, schema iddora-major-incident-report.v1) declaresnotify.dora-incident.classificationas a required source input. Signed export readiness is blocked until the official schema mapping (dora-major-incident-report-eu-2025-302) is pinned.CLI surface.
src/Cli/StellaOps.Cli/Commands/DoraIncidentCommandGroup.csexposes:stella incident classify <id> --input <file> [--output <file>] [--json]— runs the deterministic classifier over a frozendoraIncidentClassificationinput and prints the classification hash plus counts of criteria met / insufficient.stella export dora-incident-report <id> --variant <initial|intermediate|final> --input <file> --output <dir> --signing-key-file <file> [...]— produces the signed filesystem handoff.stella verify dora-incident-report <path> --signing-key-file <file> [...]— verifies a handoff offline.
Backward Compatibility
doraClassificationis nullable and omitted from JSON when absent.- Existing
metadatabehavior is unchanged and remains available for ad-hoc tenant/operator fields. - Consumers that do not understand DORA fields can ignore the new property.
- Producers must not move legacy metadata keys into DORA criteria unless they can preserve the original metadata value or record an explicit migration.
Replay And Offline Expectations
All values must be derivable from in-repo code, tenant configuration, immutable ledger events, or frozen telemetry/evidence snapshots. Classification replay must not fetch live regulator endpoints, live EBA taxonomy data, or SaaS services.
Deterministic coverage lives in:
- Transport round-trip (legacy payload + seven criteria + override audit):
src/Notify/__Tests/StellaOps.Notify.WebService.Tests/IncidentContractsDoraClassificationTests.cs - Classifier determinism and three-state assessment:
src/Telemetry/StellaOps.Telemetry.Core/StellaOps.Telemetry.Core.Tests/DoraIncidentClassifierTests.cs - Report encoder determinism / signing:
src/Notify/__Tests/StellaOps.Notify.Connectors.Dora.Tests/DoraMajorIncidentReportEncoderTests.cs - CLI classify / export / verify:
src/Cli/__Tests/StellaOps.Cli.Tests/Commands/DoraIncidentCommandGroupTests.cs
Downstream work must keep frozen evidence fixtures beside its own test project and keep fixture hashes stable for repeated replay.
