Sponsored display — spec
Table of Contents
1. Purpose
Sponsored-display is the banner format. It sits alongside
sponsored-research (native, in-list) and reuses the same
window._sponsoredResearch object under a .Display key.
The unit is a Criteo-shaped onsite-display entry: build-time PNG
plate (see plates) plus DOM text overlay. The plate carries no
legible copy because flux2-klein cannot spell, and the disclosure
label must be selectable text for data-nosnippet and screen-reader
compatibility anyway — two constraints, one architecture.
Provenance surfaced via a ? affordance on every rendered banner
showing model, sha256, seed, reproducible, synthetic=true.
This is what an audit surface looks like when the underwriter is a
local flux2-klein instance, not a third-party ad server.
ORACLE: src/wal_sh/adtech/sponsored_display/browser.cljs (browser
only — no pure core.cljc; the format is DOM-native).
2. Requirements
- SD1
- Plate is a build-time PNG produced by
wal-sh.adtech.plates.gen; the browser never generates plates. - SD2
- Every word on the banner is DOM text; the plate carries no copy. The plate is the visual anchor; the text is the message.
- SD3
- Disclosure label is selectable text with
data-nosnippeton its container. Screen readers get a proper text alternative. - SD4
- A
?affordance on the banner exposes the creative's provenance JSON —model,sha256,seed,reproducible,synthetic true. Clicking it is a genuine audit surface, not boilerplate. - SD5
- Load order: sponsored-research must be initialised first;
this ns attaches
Displayonto the samewindow._sponsoredResearchobject. Registry-enforced (seepublish.elwal-sh/adtech-systems). - SD6
display-formatreturns nil when the manifest has no plate for the(dir, slot)pair. The renderer must handle nil by not emitting the slot; no fallback image.- SD7
- The RenderingAttributes-shape input matches the Criteo
onsite-display API contract; the
productarg is a sponsored-research SKU with aRenderingAttributesJSON string we parse for thetaxonomy_textkey.
3. Contract signature
Browser (browser.cljs):
(load-manifest! [url]) ; -> Promise, fetches /static/img/sponsored/manifest.json
(pick-plate dir slot) ; -> {:src :width :height :alt :sha256 ...} or nil
(display-format product slot) ; -> Criteo entry map or nil
(render entry) ; -> DOM node
(after container product slot) ; -> mount after existing element
Public surface:
window._sponsoredResearch.Display = {
Plates: {
load: (fn [] -> Promise) ; fetch manifest
pick: (fn [dir slot] -> plate-map or nil)
}
displayFormat: (fn [product slot] -> entry-map or nil)
render: (fn [entry] -> Node)
after: (fn [container product slot] -> nil)
}
Manifest shape (/static/img/sponsored/manifest.json):
{
"generator": {"model": "flux2-klein", "version": "..."},
"plates": [
{"dir": "research", "slot": "leaderboard",
"src": "/static/img/sponsored/research-leaderboard.png",
"width": 728, "height": 90,
"alt": "...", "sha256": "...", "seed": 12345,
"reproducible": true, "synthetic": true},
...
]
}
4. Related literature
- IAB Standard Ad Unit Portfolio (Interactive Advertising Bureau 2017) defines the
dimensions (
leaderboard728×90,mrec300×250,billboard970×250,mobile320×50) that plate generation targets. - Zeng, Kohno & Roesner on bad ads (Zeng, Kohno, and Roesner 2020) characterises the creative-quality failure mode this spec's per-banner provenance addresses: an audit surface tied to the creative, not the container.
- Ali et al. on delivery discrimination
(Ali et al. 2019) motivates the
?affordance — provenance on the creative is the smallest visible unit an outside audit can verify. - ANA 2023 MFA transparency study (Association of National Advertisers 2023) on inventory quality — display's disclosure surface is exactly what the MFA studies argue is under-instrumented.
- Cloudflare Rocket Loader documentation (Cloudflare, n.d.) on script-deferral pattern; the same deferral we use for the banner mount to avoid CLS on the main-content paint.
data-nosnippetis a Google-defined HTML attribute for suppressing snippet extraction; documented at https://developers.google.com/search/docs/appearance/snippet #prevent-snippets.
5. Cross-references
- sponsored-research/spec.org — this module attaches to its
window._sponsoredResearchobject. - plates/spec.org — build-time plate generation via flux2-klein.
- sponsored-formats/spec.org — historical taxonomy of display in the sponsored-format catalogue.
- attribution-audit/spec.org — display impressions and clicks append touchpoints to the ledger.
- ORACLE:
src/wal_sh/adtech/sponsored_display/browser.cljs - web-history — the banner era on the invention of the 468×60,
the leaderboard, and the
<a><img></a>as a first-class ad unit. - [BROKEN LINK: No match for fuzzy expression: *2013–2018: Mobile + programmatic era] on Criteo's shape and the onsite-display API convention.
6. Open questions
- Multi-slot rendering per page. Currently one plate per
(dir, slot)pair; a per-page A/B on plate variants is not wired. The plumbing exists (plate A/B in the manifest) but the renderer picks the first match. - Retina/HiDPI. Plates are 1x; a 2x variant would double the storage cost and quadruple the byte budget. The IAB portfolio (Interactive Advertising Bureau 2017) specifies 1x + 2x pairs; wal.sh ships 1x only.
- Fallback strategy on missing plate. Current behaviour: don't render. Alternative: render the DOM text on a solid greyscale fill. The former is honest (no plate = no banner); the latter keeps the slot dimensions reserved but changes the visual contract.