Skip to content

served-disclosure receipt: machine-readable record of what the user actually saw at first exposure #4442

@bokelley

Description

@bokelley

Problem

The current spec stops at "publisher reads render_guidance and renders accordingly." But Art 50(5) is about what the user actually saw at first exposure, not what the supply chain intended to show them. Without a post-serve receipt:

  • A publisher can demonstrate pre-serve intent but not actual served disclosure.
  • An advertiser/agency who is the deployer under Art 50 has no machine-readable evidence to wave at counsel proving the disclosure happened.
  • A governance agent auditing delivery can audit the manifest but not the rendered impression.

The regulator's question is post-serve. Currently nothing on the wire answers it.

Proposed wire shape

A new served_disclosure object written back into the impression/event record by the publisher's ad server, carried in delivery reports / validate_content_delivery responses / wherever post-serve event evidence already flows:

{
  "impression_id": "imp_4f9a2c...",
  "served_at": "2026-05-12T14:30:01Z",
  "served_disclosure": {
    "rendered": true,
    "regulation": "eu_ai_act_article_50",
    "jurisdiction": { "country": "DE" },
    "label_text": "KI-generiert",
    "label_language": "de",
    "position": "overlay",
    "persistence": "continuous",
    "rendered_duration_ms": 15000,
    "viewport_coverage_pct": 4.2,
    "first_exposure_ms": 0,
    "rendering_surface": "publisher_ad_server",
    "evidence": {
      "type": "screenshot_hash",
      "value": "sha256:..."
    }
  }
}

rendered: false is a valid value, paired with a not_rendered_reason enum (format_unsupported, creative_self_renders, disclosure_not_required_by_publisher_analysis, error). A missing served_disclosure on an impression where disclosure.required: true was declared upstream is itself an audit signal.

Composition rules

  • One served_disclosure per (impression × jurisdiction) — multi-jurisdictional impressions can carry multiple, keyed by jurisdiction.
  • most-restrictive-wins precedence from render_guidance already covers what should have been rendered; served_disclosure records what was. Discrepancy detection (declared persistence: continuous, rendered_duration_ms < impression duration) is the audit primitive.
  • For self-rendering creatives (MRAID, VPAID), rendering_surface: creative_sandbox plus evidence.type: governance_agent_observation — i.e., the publisher couldn't observe directly and a governance agent's post-hoc get_creative_features rendering is the evidence.

Where it lives in protocol surfaces

  • Delivery reports (get_media_buy_delivery, get_creative_delivery) — primary surface for advertiser/agency to retrieve.
  • validate_content_delivery response — when buyer agents proactively audit a delivery window.
  • Webhook event payloads — optionally, when the publisher pushes impression-level events.

This is additive across all three surfaces; existing consumers ignore the field.

Out of scope

  • Sampling vs full population. Whether every impression carries served_disclosure or a representative sample is a publisher-side policy decision (cost vs evidentiary completeness). Spec should permit both, recommend full population for creative cohorts known to carry disclosure.required: true.
  • Cryptographic binding to the impression. Sufficient that served_disclosure is co-located with the impression record the publisher already attests to; signing comes for free if the delivery report is itself signed (separate issue).
  • PII. served_disclosure is about the label, not the user; nothing in this object touches user identity.

Refs

Priority

Pre-GA candidate. Pairs with #TBD (signed provenance claims) as the two highest-leverage legal-gap closures called out in GA-readiness review.

Metadata

Metadata

Assignees

No one assigned

    Labels

    creativeenhancementNew feature or requestgovernanceIssue concerns the governance protocol domainschemaJSON Schema source-of-truth: definitions, codegen artifacts, validation, hygienespec / protocol

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions