Article 50 Transparency as an Architecture Decision

Each EU AI Act Article 50 duty translated into a place in the stack, a log row, and an owner — chatbot disclosure in UI chrome, C2PA marking that survives the CDN, and an evidence pack that is not screenshots.

Article 50 gets read as a legal checklist — disclose, mark, label — and handed to legal to “own”. That framing fails at the first audit question, which is never did you intend to disclose? It is show me the disclosure for this session, on this surface, on this date. Only architecture answers that. Our working rule: every Article 50 duty gets three assignments — a place in the stack, a log row, and a named owner — and a duty missing any of the three is not implemented, whatever the policy document says.

Quick anatomy, because the four duties land on different roles and different layers. Art 50(1): providers of AI systems that interact with natural persons must ensure people are informed they are dealing with AI — unless it is obvious to a reasonably well-informed, observant and circumspect person. Art 50(2): providers of systems generating synthetic audio, image, video or text must ensure outputs are marked in a machine-readable format and detectable as artificially generated — with the marking expected to be effective, interoperable, robust and reliable so far as technically feasible. Art 50(3): deployers of emotion-recognition or biometric-categorisation systems must inform the people exposed to them. Art 50(4): deployers must disclose deepfakes (softened, not waived, for artistic and satirical work) and AI-generated text published to inform the public on matters of public interest — unless the text passed human editorial review with someone taking responsibility. Across all of it, the delivery bar: clear, distinguishable, at the latest at the first interaction or exposure, and accessible.

Duty 1 — where the chatbot disclosure lives

Two candidate homes for the Art 50(1) disclosure, and teams keep picking the wrong one.

Option A: the first-turn system response. Instruct the model, via system prompt, to open with “I’m an AI assistant…”. Tempting because it ships in an afternoon. Wrong because it makes a legal obligation depend on a probabilistic system: the disclosure can be lost to prompt injection, dropped when the conversation resumes from history, mangled by a locale the prompt never anticipated, or silently eroded by the next prompt refactor. Worst of all, you cannot prove it fired for any given session without parsing generated text after the fact.

Option B: UI chrome. The disclosure is a deterministic element of the interface — a labelled header, a persistent badge, an interstitial on first use — rendered by the front end before the first token streams. It is versioned in the front-end repo, survives model swaps and prompt refactors, renders identically whether the model behaves or not, and maps exactly onto the statutory delivery bar: clear, distinguishable, at first interaction. Chrome wins. We keep a belt-and-braces line in the system prompt so the model also acknowledges being AI when asked directly — but that line is UX polish, not the compliance control.

The part most teams skip: disclosure as an event. Rendering the badge is necessary; being able to prove you rendered it is what survives an audit. Our front end emits a disclosure event per session with a fixed schema: hashed user ID (salted — the evidence log must not become its own privacy problem), surface (web, iOS, embedded widget, voice line), timestamp, disclosure version (pointing at the exact copy text and locale in the config repo), and session ID. One row per session, ~200 bytes, kept alongside the interaction logs. When someone asks “was this user informed on 14 March?”, the answer is a query, not an argument.

Article 50 duties translated: home, evidence, owner
DutyArchitectural homeLog / evidenceOwner

Art 50(1) — AI interaction disclosure

UI chrome rendered before first token; system-prompt line as backup only

Disclosure event log: user-ID hash, surface, timestamp, disclosure version

Front-end platform team

Art 50(2) — machine-readable marking

C2PA signing + invisible watermark at the generation service, re-applied after transforms

Signing-cert chain, per-asset manifest hashes, detector run results

Media-pipeline team

Art 50(2) — detectability

Detector checks in CI and in production sampling of published assets

Robustness test reports: what marking survives which transform

Media-pipeline team + red team

Art 50(3) — emotion-recognition notice

Notice at the point of exposure (IVR announcement, on-screen banner) gated so the system cannot start unnotified

Notice event log per exposed session; notice copy versions per locale

Product owner of the deploying system

Art 50(4) — deepfake disclosure

Label rendered in-player or adjacent to the asset, driven by the asset’s provenance metadata

Label-render events joined to asset IDs; provenance metadata store

Publishing platform team

Art 50(4) — public-interest text exception

Editorial workflow: AI-drafted flag + named human approver before publish

Workflow records: who reviewed, when, taking responsibility — the exception is itself an evidence duty

Editorial / content operations

Duty 2 — marking that survives your own infrastructure

Synthetic-media marking has a natural home: the generation service, the one chokepoint every generated asset passes through. The clouds increasingly do the first step for you — Azure OpenAI image models attach C2PA Content Credentials to every generated image automatically: a cryptographically signed manifest recording that the content is AI-generated, which service produced it (the softwareAgent field), and when. Google marks Imagen output with SynthID invisible watermarking, and AWS provides watermarking for its own image models — check current docs for exact coverage on each, because modality support moves quarterly.

Then your own infrastructure destroys it. This is the trap that bites nearly everyone: C2PA manifests live in file metadata, and media pipelines strip metadata as a feature. The thumbnailer re-encodes the image and drops the manifest. The CDN’s image-optimisation layer converts to WebP and drops the manifest. The social-share crop drops the manifest. Six months in, you discover that every asset users actually see is an unmarked derivative of a marked original — the marking exists only in an S3 bucket nobody serves from. Marking is a pipeline property, not a generation property: every transform step either preserves the credential, re-signs the derived asset, or is a compliance bug.

Which is why the duty is really two duties. The metadata layer (C2PA) is rich and verifiable but fragile — it survives nothing that re-encodes. The watermark layer (signal embedded in the pixels or waveform) survives re-encoding and metadata stripping, but degrades under aggressive crops, filters, and adversarial attack — and vendors’ robustness claims deserve the same scepticism as any other vendor claim. The statute asks for effectiveness and robustness so far as technically feasible, not for miracles: our honest implementation is layered marking plus a written robustness statement — a tested table of what our marking survives (resize, WebP conversion, 80% JPEG re-encode) and what it does not (heavy crops, screenshots, deliberate laundering). Detectability you can also operate: detection APIs (Azure’s Content Provenance Detection API among them) let us verify our own published assets on a schedule, which turns “are we still marking?” from an assumption into a monitored metric.

The marking pipeline — where credentials die, and the checkpoints that keep them alive

  1. Generation service produces asset
  2. Attach C2PA manifest + invisible watermark

    At the generation chokepoint. On Azure OpenAI image models the Content Credential is attached automatically; the watermark rides in the pixels.

  3. Evidence store: original + manifest hash

    The signed original and its manifest hash are retained — the reference every later verification compares against.

  4. Transform pipeline (resize / transcode / crop)

    The danger zone: re-encoding strips file metadata by default.

  5. Manifest survived the transform?
  6. Re-sign derived asset

    The transform service holds signing credentials and re-attaches a manifest to every derivative it emits.

  7. Publish via CDN

    CDN image-optimisation features are audited and pinned — an “optimisation” toggle is a marking-removal toggle.

  8. Scheduled detector sweep on published assets

    Sampled live URLs run through manifest validation and watermark detection — marking as a monitored metric.

  9. Verification results → evidence log

    Pass rates, failures, and the robustness statement updates that follow.

Duties 3 and 4 — notices at the point of exposure, and the exception that is really a workflow

Emotion-recognition notices follow the chatbot-disclosure pattern with one twist: the people to inform are the exposed, not the users. In the classic case — call-centre voice analytics scoring caller frustration — the operator sees the dashboard but the caller is the exposed person, so the notice lives in the IVR flow (“this call is analysed by AI…”), and the architecture decision is a gate: the analytics pipeline does not start for a call whose notice event has not been logged. Same event schema as the disclosure log — hashed identifier, surface, timestamp, notice version. The GDPR/LED duties for the underlying biometric processing run in parallel; the Art 50(3) notice does not discharge them.

The deepfake duty inverts the flow: the label a viewer sees should be derived from provenance metadata, not typed in by an editor who remembered. If the asset carries a credential, the player renders the label; the label-render event joins to the asset ID in the logs. And the Art 50(4) text exception — no disclosure needed where AI-drafted public-interest text passed human editorial review with someone taking responsibility — is the most architectural clause in the article: claiming it requires a workflow system that records the AI-drafted flag, the named reviewer, and the approval timestamp. The exception is itself an evidence duty. A newsroom that cannot produce its review records cannot claim its exception.

Why screenshots are not evidence

A screenshot proves one rendering, on one device, on the day someone took it — usually the week before the audit. It says nothing about the sessions that matter: every user, every surface, every day since the duty applied. Auditors of operational controls want the same thing security auditors want: configuration plus events. The versioned config proves what the system was built to do; the event log proves it did it, per session. Build the pack below and screenshots become decoration.

Pack item 1 — versioned disclosure and notice config

The disclosure copy, per locale and surface, in a config repo with deploy history. Any given date maps to the exact text and placement in force. Include the UI component version that renders it — “disclosure v14, deployed 2026-03-02, surfaces: web+iOS, locales: 24”.

Pack item 2 — the event logs

Disclosure events, notice events, label-render events — hashed IDs, surface, timestamp, version. Retention matched to your audit horizon. The query that answers “show me this session’s disclosure” should take minutes, and someone should have actually run it before the auditor does.

Pack item 3 — the marking evidence

Signing-certificate chain, sample manifests from each generation surface, the robustness statement with its test results, and the scheduled detector-sweep reports on published assets. This is the difference between “we enabled Content Credentials” and “our published assets are verifiably marked, at this measured pass rate”.

Pack item 4 — the exception records

Editorial-review workflow extracts for every published AI-drafted piece claiming the Art 50(4) exception, and the reasoning memo for any surface where you rely on the Art 50(1) “obvious to a reasonably well-informed person” exception — written down before someone challenges it, with the user-research basis if you have any.