Paywalls Modules: VAI RTD Provider and Analytics Adapter#14541
Paywalls Modules: VAI RTD Provider and Analytics Adapter#14541paywalls-mike wants to merge 9 commits intoprebid:masterfrom
Conversation
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: dc9bc90910
ℹ️ About Codex in GitHub
Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".
- Register RTD submodule 'paywalls' with init, getBidRequestData, getTargetingData - ORTB2 split: site.ext.vai (iss, aud, dom, kid, assertion_jws) + user.ext.vai (vat, act) - Dynamic vai.js injection via loadExternalScript with poll/hook/timeout - Graceful degradation: never blocks the auction - 22 unit tests covering all acceptance criteria - Added to approvedLoadExternalScriptPaths whitelist
- paywallsRtdProvider_example.html: E2E test with 5 assertions (ORTB2 site/user enrichment, GAM targeting, timing budget, VAI load) - mock-vai.js: local VAI mock for self-contained testing - Supports ?real mode (real vai.js from worker) and ?degrade mode (verifies graceful degradation with unreachable script)
- Overview, build instructions, configuration parameters - ORTB2 split placement: site.ext.vai (provenance) + user.ext.vai (classification) - GAM targeting keys (vai_vat, vai_act) - Activity Controls, privacy section, how-it-works - Testing instructions for unit and integration tests
- Publisher-hosted is preferred (same-origin, no CORS, dom claim match) - Paywalls-hosted uses paywalls.net (not cdn.paywalls.net) - Clarify CDN/server integration vs reverse proxy
- Correct activity name: loadExternalScript (not fetchBids) - Update example default to false (realistic scenario) - Editorial refinements
- Fix broken VAI URL in RTD provider links section (docs.publishers → docs/publishers) - Normalize all VAI URLs to https://docs.paywalls.net/publishers/vai - Align RTD provider heading structure with analytics adapter (# Overview) - Clarify params.waitForIt vs top-level waitForIt distinction - Document __PW_VAI_HOOK__, exp checking, and localStorage key in How It Works
There was a problem hiding this comment.
Pull request overview
Adds Paywalls modules to integrate VAI (Validated Actor Inventory) into Prebid.js auctions, enriching ORTB2/GAM targeting via an RTD provider and emitting per-auction classification via an analytics adapter.
Changes:
- Introduces
paywallsRtdProviderRTD submodule to load VAI and mergesite.ext.vai/user.ext.vaiinto ORTB2 plusvai_vat/vai_actinto GAM targeting. - Introduces
paywallsAnalyticsAdapterto emitvai_vat/vai_actper auction viagtag,dataLayer, or callback (with sampling + de-dup). - Adds module docs, unit tests, integration example pages + mock VAI script, and updates the ESLint allowlist for
loadExternalScriptusage.
Reviewed changes
Copilot reviewed 10 out of 10 changed files in this pull request and generated 8 comments.
Show a summary per file
| File | Description |
|---|---|
modules/paywallsRtdProvider.js |
New RTD provider implementing VAI discovery/loading and ORTB2 + targeting enrichment. |
modules/paywallsRtdProvider.md |
Documentation for RTD config, ORTB2 output, GAM targeting, and activity controls. |
modules/paywallsAnalyticsAdapter.js |
New analytics adapter emitting VAI classification per auction to publisher analytics destinations. |
modules/paywallsAnalyticsAdapter.md |
Documentation for analytics adapter config, output modes, sampling, and privacy notes. |
test/spec/modules/paywallsRtdProvider_spec.js |
Unit tests for VAI payload detection, ORTB2 merge behavior, targeting, and timeouts. |
test/spec/modules/paywallsAnalyticsAdapter_spec.js |
Unit tests for classification reading, emission modes, sampling, and de-dup behavior. |
plugins/eslint/approvedLoadExternalScriptPaths.js |
Approves the two new modules for loadExternalScript. |
integrationExamples/gpt/paywallsRtdProvider_example.html |
E2E example page for RTD provider behavior (including degrade/real modes). |
integrationExamples/gpt/paywallsAnalyticsAdapter_example.html |
E2E example page for analytics emission behavior (including degrade/real modes). |
integrationExamples/gpt/mock-vai.js |
Mock VAI script used by integration examples to simulate vai.js. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| before(function () { | ||
| sandbox = sinon.createSandbox(); | ||
| clock = sandbox.useFakeTimers(1896134400000); | ||
| }); | ||
|
|
||
| after(function () { | ||
| clock.restore(); | ||
| sandbox.restore(); | ||
| }); |
There was a problem hiding this comment.
This spec shares a single Sinon sandbox and fake clock across the entire suite (before/after). Since multiple tests advance the clock and create stubs/spies, this can make the suite order-dependent and harder to debug when a test fails mid-suite. Consider creating/restoring the sandbox + fake timers in beforeEach/afterEach (or resetting the clock in beforeEach) to keep tests isolated.
dc9bc90 to
c2e15ae
Compare
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: c2e15aea5d
ℹ️ About Codex in GitHub
Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".
|
Addressed automated review feedback in commit de4cf00. Implemented fixes:
Regression coverage added for these behaviors. Validation run locally:
|
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: de4cf00754
ℹ️ About Codex in GitHub
Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".
de4cf00 to
12b1099
Compare
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 12b1099de4
ℹ️ About Codex in GitHub
Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".
|
Companion docs PR: prebid/prebid.github.io#6457 |
- P1: Store late VAI hook payloads for subsequent auctions (was dropping permanently after timeout) - Fix waitForIt=0 treated as falsy (use typeof check instead of ||) - Clean up timers and hook in resolve() to avoid leaking globals - Preserve existing __PW_VAI_HOOK__ instead of clobbering - Fix ensureVai skipping injection when __PW_VAI__ is truthy but invalid - Clamp samplingRate to [0,1] with warning - Use Object.create(null) for emittedAuctions map - Fix init() JSDoc to match actual behavior (caches, not injects) - Add regression tests for all bug fixes
12b1099 to
d145be8
Compare
Type of issue
New module (RTD Provider + Analytics Adapter)
Description
Adds two new Paywalls modules that integrate VAI (Validated Actor Inventory) into Prebid.js:
Paywalls RTD Provider (
paywallsRtdProvider.js) — Automates VAI loading, timing, and signal injection into the bid stream:site.ext.vai(domain provenance + signed assertion) anduser.ext.vai(actor classification)vai_vatandvai_actkey-value pairs per ad unitPaywalls Analytics Adapter (
paywallsAnalyticsAdapter.js) — Emits VAI classification (vat,act) per auction to the publisher's analytics pipeline (GA4gtag, GTMdataLayer, or custom callback), enabling publishers to segment performance by traffic class in their existing reporting stack.What is VAI?
VAI classifies page impressions by actor type (human, AI agent, sharing/preview bot, other) and confidence tier (ACT-1 through ACT-3), producing a cryptographically signed JWS assertion that SSPs and DSPs can independently verify. No user identifiers, PII, cookies, or fingerprints are involved — classification is based on aggregate session-level behavioral signals processed entirely in the browser.
ORTB2 placement
Test Results
Lint
Unit Tests
Coverage
All metrics exceed the 80% threshold.
Files Changed
modules/paywallsRtdProvider.jsmodules/paywallsRtdProvider.mdmodules/paywallsAnalyticsAdapter.jsmodules/paywallsAnalyticsAdapter.mdtest/spec/modules/paywallsRtdProvider_spec.jstest/spec/modules/paywallsAnalyticsAdapter_spec.jsplugins/eslint/approvedLoadExternalScriptPaths.jsintegrationExamples/gpt/paywallsRtdProvider_example.htmlintegrationExamples/gpt/paywallsAnalyticsAdapter_example.htmlintegrationExamples/gpt/mock-vai.jsExternal Script Loading
Both modules use
loadExternalScriptto injectvai.js(the VAI classifier). This follows the same pattern as other RTD providers (confiant, geoedge, browsi, humansecurity, 51degrees, etc.). The script URL is configurable and defaults to a publisher-hosted relative path (/pw/vai.js).Privacy
Steps to reproduce / test
Platform details
Other information