2026-04-22·15 min read·

EU AI Act Art.12: Logging Obligations as an Operational Compliance System — Event Classification, Retention Architecture, and Python LoggingEventRegistry (2026)

Article 12 of the EU AI Act is the audit trail backbone of high-risk AI compliance. But most implementation guides stop at "enable logs." Art.12 requires something more precise: a classification system that distinguishes which events are legally mandatory, a retention architecture that separates operational logs from archival records, and a retrieval mechanism that can produce MSA-ready evidence packages under a market surveillance investigation timeline.

The August 2, 2026 deadline applies to all high-risk AI systems placed on the EU market or put into service on or after that date. Systems placed on the market before 2026 that receive substantial modifications under Art.11(4) must also comply. Every provider that has not built Art.12-compliant logging before market placement is deploying a non-compliant system.

This guide covers the full Art.12 operational system: what paragraphs 1–3 actually require, the Event Classification Matrix distinguishing mandatory from recommended logging, how to build a Python LoggingEventRegistry that operationalises compliance, SIEM integration patterns for Art.12 audit trails, the six-month vs. ten-year retention split, and the cross-reference map connecting Art.12 to Art.9, Art.11, Art.13, and Art.14.


What Art.12 Actually Requires: The Three-Paragraph Architecture

Art.12 contains three paragraphs, each creating a distinct obligation layer:

Art.12(1) — Automatic logging capability: High-risk AI systems must be designed and developed with capabilities enabling the automatic recording of events ("logs") throughout the system's lifetime. The word "automatic" eliminates discretionary logging — events within scope must be captured without human decision at the time of capture.

Art.12(2) — Specific event categories: The logging capabilities must ensure, to the degree appropriate to the intended purpose, the ability to: (a) record the period of each use; (b) reference the input data for which the search, detection, recommendation, or decision was made, wherever feasible with regard to data protection; (c) identify persons involved in the verification of results where human oversight is mandated under Art.14; (d) identify major changes in the system functionality and version.

Art.12(3) — Retention obligations: For high-risk AI systems used by public authorities or financial institutions, the logs are kept by those entities for at least six months, or for any other period established in applicable EU or national law. Providers deploying systems to operators must contractually ensure log retention — the legal obligation falls on the operator, but the provider must ensure the technical capability exists.

The critical insight: Art.12(1) is a design obligation (build the capability), Art.12(2) is a content obligation (capture specific event types), and Art.12(3) is a retention obligation (preserve specific logs for specific actors). A system that logs everything but doesn't retain it for the right parties fails Art.12(3). A system that retains logs but doesn't capture Art.12(2)(a)–(d) events fails Art.12(2).


Not every log event has the same compliance status under Art.12. The matrix below distinguishes mandatory events (required by Art.12(2) text), structurally required events (implied by Art.9/Art.14 obligations that feed Art.12), and recommended events (operational best practice that survives MSA scrutiny).

Event CategoryArt.12 StatusSource ParagraphEvidence Function
Session start / end timestampsMandatoryArt.12(2)(a)Proves "period of each use"
Input data reference (hash/ID, not content)Mandatory where feasibleArt.12(2)(b)Links decision to input set
Human oversight verification (Art.14 decisions)MandatoryArt.12(2)(c)Documents human-in-the-loop events
Major version/functionality changesMandatoryArt.12(2)(d)Ties to Art.11(4) substantial modification
Risk score changes (Art.9 RMS outputs)Structurally requiredArt.9 + Art.12(1)Demonstrates Art.9 runtime execution
Model inference outputs (decision type, confidence)Structurally requiredArt.13 + Art.12(1)Supports transparency obligation
Data quality flags (Art.10 triggers)Structurally requiredArt.10 + Art.12(1)Links data governance to decisions
Configuration changes (thresholds, parameters)RecommendedArt.12(2)(d) scopeMSA audit evidence
Access events (who queried the system)RecommendedArt.14 scopeOperator accountability chain
Error and exception eventsRecommendedArt.9(6) scopeDemonstrates incident detection capability
Model update events (minor, below substantial modification threshold)RecommendedArt.11 scopeVersion tracking for non-substantial changes
Monitoring alert eventsRecommendedArt.9(8) scopePost-market monitoring evidence

The distinction between mandatory and recommended matters for system design. Mandatory events must be captured even when the system is under load, even when storage is constrained, and even when the input data itself cannot be retained due to GDPR. The feasibility qualifier in Art.12(2)(b) applies only to the input data content — the input reference (a hash, an ID, a timestamp) must always be logged.


Python LoggingEventRegistry Implementation

The LoggingEventRegistry is the operational core of Art.12 compliance. It classifies incoming events, applies retention tagging, and provides MSA package generation:

from dataclasses import dataclass, field
from datetime import datetime, timezone
from enum import Enum
from typing import Optional, Dict, Any, List
import hashlib
import json
import uuid


class EventMandatoryStatus(Enum):
    MANDATORY = "mandatory"          # Art.12(2) explicit text
    STRUCTURAL = "structural"        # Art.9/Art.14/Art.13 implied
    RECOMMENDED = "recommended"      # Best practice, not legally mandated


class RetentionTier(Enum):
    OPERATIONAL = "operational"      # 6 months (Art.12(3) minimum)
    ARCHIVAL = "archival"            # 10 years (Art.11(3) technical documentation)
    EPHEMERAL = "ephemeral"          # Session-only, GDPR-driven deletion


@dataclass
class Art12Event:
    event_id: str
    event_type: str
    mandatory_status: EventMandatoryStatus
    retention_tier: RetentionTier
    timestamp: datetime
    session_id: str
    input_reference: Optional[str]   # Hash, not content (Art.12(2)(b))
    human_oversight_actor: Optional[str]  # Art.12(2)(c)
    version_reference: Optional[str]     # Art.12(2)(d)
    payload: Dict[str, Any] = field(default_factory=dict)
    art12_paragraph: str = ""


class LoggingEventRegistry:
    """Art.12-compliant event logging registry for high-risk AI systems."""

    # Event type → (mandatory_status, retention_tier, art12_paragraph)
    EVENT_CLASSIFICATION: Dict[str, tuple] = {
        "session.start": (EventMandatoryStatus.MANDATORY, RetentionTier.OPERATIONAL, "Art.12(2)(a)"),
        "session.end": (EventMandatoryStatus.MANDATORY, RetentionTier.OPERATIONAL, "Art.12(2)(a)"),
        "input.reference": (EventMandatoryStatus.MANDATORY, RetentionTier.OPERATIONAL, "Art.12(2)(b)"),
        "human_oversight.decision": (EventMandatoryStatus.MANDATORY, RetentionTier.OPERATIONAL, "Art.12(2)(c)"),
        "human_oversight.override": (EventMandatoryStatus.MANDATORY, RetentionTier.ARCHIVAL, "Art.12(2)(c)"),
        "system.version_change": (EventMandatoryStatus.MANDATORY, RetentionTier.ARCHIVAL, "Art.12(2)(d)"),
        "system.major_functionality_change": (EventMandatoryStatus.MANDATORY, RetentionTier.ARCHIVAL, "Art.12(2)(d)"),
        "risk_score.change": (EventMandatoryStatus.STRUCTURAL, RetentionTier.OPERATIONAL, "Art.9+Art.12(1)"),
        "model.inference": (EventMandatoryStatus.STRUCTURAL, RetentionTier.OPERATIONAL, "Art.13+Art.12(1)"),
        "data_quality.flag": (EventMandatoryStatus.STRUCTURAL, RetentionTier.OPERATIONAL, "Art.10+Art.12(1)"),
        "config.change": (EventMandatoryStatus.RECOMMENDED, RetentionTier.OPERATIONAL, "Art.12(2)(d) scope"),
        "access.query": (EventMandatoryStatus.RECOMMENDED, RetentionTier.OPERATIONAL, "Art.14 scope"),
        "system.error": (EventMandatoryStatus.RECOMMENDED, RetentionTier.OPERATIONAL, "Art.9(6) scope"),
        "model.minor_update": (EventMandatoryStatus.RECOMMENDED, RetentionTier.OPERATIONAL, "Art.11 scope"),
        "monitoring.alert": (EventMandatoryStatus.RECOMMENDED, RetentionTier.OPERATIONAL, "Art.9(8) scope"),
    }

    def __init__(self, system_id: str, system_version: str):
        self.system_id = system_id
        self.system_version = system_version
        self.events: List[Art12Event] = []
        self._current_session_id: Optional[str] = None

    def start_session(self) -> str:
        """Art.12(2)(a): Record period of each use — session start."""
        self._current_session_id = str(uuid.uuid4())
        self.log_event(
            event_type="session.start",
            payload={"system_id": self.system_id, "version": self.system_version}
        )
        return self._current_session_id

    def end_session(self) -> None:
        """Art.12(2)(a): Record period of each use — session end."""
        self.log_event(event_type="session.end", payload={})
        self._current_session_id = None

    def log_input_reference(self, input_data: Any) -> str:
        """Art.12(2)(b): Log input reference (hash, not content) where feasible."""
        input_bytes = json.dumps(input_data, sort_keys=True, default=str).encode()
        input_hash = hashlib.sha256(input_bytes).hexdigest()
        self.log_event(
            event_type="input.reference",
            input_reference=input_hash,
            payload={"input_hash": input_hash, "input_type": type(input_data).__name__}
        )
        return input_hash

    def log_human_oversight(
        self,
        actor_id: str,
        decision: str,
        override: bool = False,
        rationale: str = ""
    ) -> None:
        """Art.12(2)(c): Record persons involved in human oversight verification."""
        event_type = "human_oversight.override" if override else "human_oversight.decision"
        self.log_event(
            event_type=event_type,
            human_oversight_actor=actor_id,
            payload={
                "decision": decision,
                "override": override,
                "rationale": rationale,
                "art14_triggered": True
            }
        )

    def log_version_change(
        self,
        new_version: str,
        change_type: str,
        is_substantial_modification: bool
    ) -> None:
        """Art.12(2)(d): Record major changes in system functionality and version."""
        event_type = (
            "system.major_functionality_change"
            if is_substantial_modification
            else "system.version_change"
        )
        self.log_event(
            event_type=event_type,
            version_reference=new_version,
            payload={
                "previous_version": self.system_version,
                "new_version": new_version,
                "change_type": change_type,
                "substantial_modification": is_substantial_modification,
                "art11_4_triggered": is_substantial_modification
            }
        )
        if is_substantial_modification:
            self.system_version = new_version

    def log_event(
        self,
        event_type: str,
        input_reference: Optional[str] = None,
        human_oversight_actor: Optional[str] = None,
        version_reference: Optional[str] = None,
        payload: Optional[Dict] = None
    ) -> Art12Event:
        classification = self.EVENT_CLASSIFICATION.get(event_type)
        if classification is None:
            mandatory_status = EventMandatoryStatus.RECOMMENDED
            retention_tier = RetentionTier.OPERATIONAL
            art12_paragraph = "unclassified"
        else:
            mandatory_status, retention_tier, art12_paragraph = classification

        event = Art12Event(
            event_id=str(uuid.uuid4()),
            event_type=event_type,
            mandatory_status=mandatory_status,
            retention_tier=retention_tier,
            timestamp=datetime.now(timezone.utc),
            session_id=self._current_session_id or "no-session",
            input_reference=input_reference,
            human_oversight_actor=human_oversight_actor,
            version_reference=version_reference,
            payload=payload or {},
            art12_paragraph=art12_paragraph
        )
        self.events.append(event)
        return event

    def get_mandatory_events(self) -> List[Art12Event]:
        """Return only Art.12(2)-mandatory events for MSA audit package."""
        return [e for e in self.events if e.mandatory_status == EventMandatoryStatus.MANDATORY]

    def generate_msa_evidence_package(self, investigation_period: tuple) -> Dict:
        """Generate MSA-ready evidence package for a specific investigation period."""
        start_dt, end_dt = investigation_period
        period_events = [
            e for e in self.events
            if start_dt <= e.timestamp <= end_dt
        ]
        mandatory_in_period = [
            e for e in period_events
            if e.mandatory_status == EventMandatoryStatus.MANDATORY
        ]
        return {
            "package_id": str(uuid.uuid4()),
            "system_id": self.system_id,
            "investigation_period": {
                "start": start_dt.isoformat(),
                "end": end_dt.isoformat()
            },
            "art12_compliance_summary": {
                "total_events": len(period_events),
                "mandatory_events": len(mandatory_in_period),
                "session_coverage": self._verify_session_coverage(period_events),
                "human_oversight_events": len([
                    e for e in mandatory_in_period
                    if "human_oversight" in e.event_type
                ]),
                "version_change_events": len([
                    e for e in mandatory_in_period
                    if "version_change" in e.event_type or "functionality_change" in e.event_type
                ])
            },
            "events": [
                {
                    "event_id": e.event_id,
                    "event_type": e.event_type,
                    "timestamp": e.timestamp.isoformat(),
                    "art12_paragraph": e.art12_paragraph,
                    "mandatory_status": e.mandatory_status.value,
                    "session_id": e.session_id,
                    "input_reference": e.input_reference,
                    "human_oversight_actor": e.human_oversight_actor,
                    "version_reference": e.version_reference
                }
                for e in mandatory_in_period
            ]
        }

    def _verify_session_coverage(self, events: List[Art12Event]) -> bool:
        """Verify every session.start has a corresponding session.end."""
        sessions_started = {e.session_id for e in events if e.event_type == "session.start"}
        sessions_ended = {e.session_id for e in events if e.event_type == "session.end"}
        return sessions_started == sessions_ended

The generate_msa_evidence_package method is the operational payoff: when a market surveillance authority initiates an investigation, your legal team can extract the Art.12(2) mandatory events for the investigation period in a structured JSON package that maps each event to its Art.12 paragraph source.


SIEM Integration Architecture for Art.12 Compliance

Most production high-risk AI deployments already have a SIEM. Art.12 compliance does not require a separate logging stack — but it requires that your SIEM configuration captures Art.12(2) event categories as structured data, not raw application logs.

The integration pattern uses three layers:

Layer 1 — Structured log emission: The LoggingEventRegistry emits events in a structured format (JSON) with Art.12 classification metadata. Each event includes mandatory_status and art12_paragraph fields that SIEM parsing rules can use for filtering and alerting.

Layer 2 — SIEM ingestion with Art.12 tagging: Configure your SIEM (Elastic SIEM, Splunk, Wazuh, Graylog) to parse the art12_paragraph field and apply a retention policy tag. Art.12 mandatory events get a retention=6m tag; Art.11(3) archival events (version changes, substantial modifications) get a retention=10y tag.

import structlog
import json
from typing import Dict, Any


class Art12SIEMEmitter:
    """Emits Art.12-tagged log events in structured format for SIEM ingestion."""

    def __init__(self, registry: LoggingEventRegistry, siem_destination: str = "stdout"):
        self.registry = registry
        self.siem_destination = siem_destination
        self.logger = structlog.get_logger().bind(
            system_id=registry.system_id,
            log_schema="art12_v1"
        )

    def emit(self, event: Art12Event) -> None:
        """Emit event as structured log entry with Art.12 compliance metadata."""
        log_entry = {
            "event_id": event.event_id,
            "event_type": event.event_type,
            "timestamp": event.timestamp.isoformat(),
            "session_id": event.session_id,
            "system_id": self.registry.system_id,
            "system_version": self.registry.system_version,
            # Art.12 classification fields — used by SIEM retention policy engine
            "art12_paragraph": event.art12_paragraph,
            "art12_mandatory_status": event.mandatory_status.value,
            "art12_retention_tier": event.retention_tier.value,
            # Art.12(2)(b): input reference
            "input_reference": event.input_reference,
            # Art.12(2)(c): human oversight
            "human_oversight_actor": event.human_oversight_actor,
            # Art.12(2)(d): version reference
            "version_reference": event.version_reference,
            # Event payload (non-PII, MSA-visible)
            "payload": event.payload
        }
        self.logger.info("art12_event", **log_entry)

    def emit_all_pending(self) -> int:
        """Emit all unemitted events from registry. Returns count emitted."""
        emitted = 0
        for event in self.registry.events:
            self.emit(event)
            emitted += 1
        return emitted

Layer 3 — Retention policy enforcement: Configure SIEM retention policies per tag:

Retention TagSIEM PolicyLegal SourceVerification
art12_retention_tier: operational6 months minimumArt.12(3)MSA audit readiness
art12_retention_tier: archival10 yearsArt.11(3) + Art.12(2)(d)Substantial modification record
art12_retention_tier: ephemeralGDPR-driven deletionGDPR Art.5(1)(e)Data minimisation compliance

The key architectural decision is where the 6-month vs. 10-year boundary falls. Version change events (system.version_change, system.major_functionality_change) are archival-tier by default in the LoggingEventRegistry because they feed Art.11(3) technical documentation retention. All other Art.12(2) mandatory events are operational-tier (6-month minimum).


The Six-Month vs. Ten-Year Retention Split

The retention architecture creates two separate storage tiers with different performance and cost profiles:

Tier 1 — Operational logs (6-month minimum):

Tier 2 — Archival records (10-year):

from datetime import timedelta
from typing import List, Tuple


class Art12RetentionManager:
    """Manages Art.12 log retention enforcement and GDPR-compliant deletion."""

    OPERATIONAL_RETENTION = timedelta(days=183)   # 6 months (conservative)
    ARCHIVAL_RETENTION = timedelta(days=3650)      # 10 years (Art.11(3))

    def __init__(self, registry: LoggingEventRegistry):
        self.registry = registry

    def get_retention_deadline(self, event: Art12Event) -> datetime:
        """Return the earliest deletion-safe date for an event."""
        if event.retention_tier == RetentionTier.ARCHIVAL:
            return event.timestamp + self.ARCHIVAL_RETENTION
        elif event.retention_tier == RetentionTier.OPERATIONAL:
            return event.timestamp + self.OPERATIONAL_RETENTION
        else:  # EPHEMERAL — GDPR-driven, no fixed Art.12 minimum
            return event.timestamp  # Delete at GDPR-defined boundary

    def identify_expired_events(self, reference_date: datetime) -> Tuple[List[Art12Event], List[Art12Event]]:
        """
        Returns (safe_to_delete, must_retain) based on Art.12 retention requirements.
        Note: safe_to_delete still requires GDPR legal basis check before deletion.
        """
        safe_to_delete = []
        must_retain = []
        for event in self.registry.events:
            deadline = self.get_retention_deadline(event)
            if reference_date > deadline:
                safe_to_delete.append(event)
            else:
                must_retain.append(event)
        return safe_to_delete, must_retain

    def generate_retention_compliance_report(self) -> Dict:
        """Generate Art.12 retention compliance report for MSA evidence."""
        now = datetime.now(timezone.utc)
        operational_events = [e for e in self.registry.events if e.retention_tier == RetentionTier.OPERATIONAL]
        archival_events = [e for e in self.registry.events if e.retention_tier == RetentionTier.ARCHIVAL]
        return {
            "report_date": now.isoformat(),
            "system_id": self.registry.system_id,
            "retention_tiers": {
                "operational": {
                    "count": len(operational_events),
                    "minimum_retention_days": self.OPERATIONAL_RETENTION.days,
                    "legal_source": "Art.12(3)"
                },
                "archival": {
                    "count": len(archival_events),
                    "minimum_retention_days": self.ARCHIVAL_RETENTION.days,
                    "legal_source": "Art.11(3) + Art.12(2)(d)"
                }
            }
        }

The identify_expired_events method returns events that have passed their Art.12 retention deadline — but deletion still requires a separate GDPR legal basis check. Art.12 retention and GDPR data minimisation create a compliance window: you must not delete before the Art.12 deadline, and you should delete after the GDPR retention period ends. For personal data embedded in logs (user IDs, input references linked to natural persons), this window may be narrower than the Art.12 six-month minimum.


The GDPR × Art.12 Retention Conflict: Operational Resolution

Art.12 requires retention; GDPR Art.5(1)(e) requires storage limitation. The conflict resolves through three design patterns:

Pattern 1 — Reference logging, not content logging: Log the SHA-256 hash of input data (Art.12(2)(b) compliant) rather than the data itself. The hash is not personal data under GDPR Recital 26 if the original data cannot be reconstructed from it. The log_input_reference method in the LoggingEventRegistry implements this pattern by default.

Pattern 2 — Pseudonymisation of actor IDs: Art.12(2)(c) requires identifying persons involved in human oversight. Pseudonymise actor IDs (store actor_hash rather than actor_name) and maintain the pseudonymisation key separately under GDPR Art.25 data protection by design. The MSA can request de-pseudonymisation under Art.58 GDPR supervisory authority cooperation mechanisms.

Pattern 3 — Tiered deletion by data category: Design your log schema so that PII-adjacent fields (actor IDs, input references linked to natural persons) can be selectively deleted at the GDPR retention boundary without invalidating the structural Art.12 log record. A log record with a null actor_id field (post-GDPR deletion) still proves the human oversight event occurred at a specific timestamp — the Art.12(2)(c) obligation is met even without the PII content.


Art.12 × Art.11 × Art.9 × Art.13 × Art.14 Cross-Reference System

Art.12 does not operate in isolation. The logging obligation is the evidence layer that makes other Art.9–15 obligations verifiable:

Art.12 Event TypeFeedsCompliance Function
session.start/end (Art.12(2)(a))Art.9(6) testing recordsProves operational use period in post-market monitoring
input.reference (Art.12(2)(b))Art.10 data governanceLinks production inputs to training data distribution analysis
human_oversight.decision (Art.12(2)(c))Art.14 human oversightDocuments human-in-the-loop compliance at decision point
system.version_change (Art.12(2)(d))Art.11(4) substantial modificationFeeds technical documentation update obligation
risk_score.changeArt.9 RMS runtimeProves risk management system executed during operational use
model.inferenceArt.13 transparencySupports output traceability for transparency obligation
data_quality.flagArt.10(3) bias monitoringEvidence for bias detection and correction measures
monitoring.alertArt.9(8) post-marketPost-market monitoring system activation evidence

The cross-reference table reveals why Art.12 logging is not just a standalone obligation: it is the audit evidence layer for the entire Art.9–15 compliance stack. An MSA investigating a high-risk AI incident will look at Art.12 logs first — they are the primary evidence source for whether Art.9 (risk management), Art.14 (human oversight), and Art.13 (transparency) obligations were actually implemented in the operational system.


MSA Investigation Readiness: The Six-Point Evidence Checklist

When a market surveillance authority initiates an investigation under Art.74–80 of the EU AI Act, Art.12 logs become the primary evidence set. Your investigation readiness depends on six operational capabilities:

Checklist Point 1 — Session coverage completeness: Can you produce a complete list of all sessions (start/end pairs) for the investigation period? Gaps in session coverage suggest logging system failures that may constitute Art.12(1) violations.

Checklist Point 2 — Input reference retrievability: Can you retrieve input references (hashes) for every inference decision in the investigation period? Missing input references for Art.12(2)(b) mandatory events indicate structural non-compliance.

Checklist Point 3 — Human oversight chain: For every Art.14-mandated human review in the investigation period, can you produce the human_oversight.decision event with actor ID, decision outcome, and timestamp? Gaps here directly evidence Art.12(2)(c) non-compliance.

Checklist Point 4 — Version history completeness: Can you produce a complete version change log for the investigation period? If a substantial modification occurred and the system.major_functionality_change event is missing, this constitutes both Art.12(2)(d) and Art.11(4) non-compliance.

Checklist Point 5 — Retention verification: Can you demonstrate that all Art.12(3) mandatory retention periods were met? The MSA will check whether logs were deleted before the six-month minimum.

Checklist Point 6 — Package generation time: The MSA investigation timeline is tight. Can you generate a structured evidence package within 24 hours of an investigation notice? The generate_msa_evidence_package method is the technical implementation of this requirement.


SME Logging Considerations

Micro and small enterprises operating high-risk AI systems benefit from the Art.11(2) documentation simplification but have no equivalent simplification under Art.12. The logging obligation in Art.12(2) applies in full regardless of operator size.

The practical SME minimum viable Art.12 implementation:

Event CategorySME MinimumStorage Estimate
Session start/endJSON log per session~200 bytes/session
Input referenceSHA-256 hash~64 bytes/inference
Human oversightDecision record + actor ID~500 bytes/decision
Version changeStructured change record~1 KB/change

For a system processing 1,000 inferences per day with 50 human oversight decisions, the six-month operational log volume is approximately 15 MB — trivially storable on any infrastructure. The cost barrier to Art.12 compliance is architectural (building the classification system), not storage (the data volumes are small).


Implementation Checklist — 20 Points

Art.12(1) — Capability design:

Art.12(2) — Event coverage:

Art.12(3) — Retention architecture:

SIEM integration:

MSA readiness:


Common Failure Modes

Failure 1 — Logging the wrong events as mandatory: Treating all log events as Art.12(2) mandatory creates an unmanageable MSA evidence set. Use the Event Classification Matrix to separate mandatory from recommended events from system design time.

Failure 2 — Content logging instead of reference logging: Logging input data content (not hashes) creates a GDPR retention conflict that cannot be resolved. The log_input_reference pattern (hash, not content) satisfies Art.12(2)(b) without creating personal data retention obligations.

Failure 3 — Missing version change logging for minor updates: Art.12(2)(d) requires logging "major changes in system functionality and version." In practice, log every version change — the classification as major vs. minor can be determined later, and missing a log is worse than over-logging.

Failure 4 — Session gaps in the operational log: Every inference session must have a paired start/end event. Gaps in session coverage are the most visible Art.12(1) non-compliance signal in an MSA audit.

Failure 5 — No MSA package generation capability: If you cannot extract Art.12 mandatory events in a structured format within 24 hours, you are operationally non-compliant even if the logs technically exist. Build generate_msa_evidence_package before market placement, not after an investigation notice.


See Also

See also: EU AI Act Art.9: Risk Management System as a Living Document — FMEA Integration, Runtime Monitoring, and RMS Version Control (2026) — Art.12 operational logs are the primary evidence source for Art.9 risk management system runtime execution.