Agent Wranglers

CMP-57Required US law

List every sale and every share

List every flow of personal data to another company that could count as a sale or targeted advertising. Offer an opt-out that stops each one.

Region

United States (US). The duty comes from the law there. The rule applies only when the project serves people there, and its Applies when also holds.

How to do it

US laws often treat any transfer for something of value as a sale. Ad pixels, ad SDKs and data partnerships usually count, even without money changing hands. California calls ads based on activity across sites sharing. Give each flow an entry with its host and its legal label. Offer a clear opt-out link, and treat a browser privacy signal as an opt-out, as the privacy signal rule describes.

Examples

JavaScript example

import { readFileSync } from 'node:fs';
import { chromium } from 'playwright';

const inventory = JSON.parse(readFileSync('compliance/third-parties.json', 'utf8'));

const browser = await chromium.launch();
const page = await browser.newPage({ extraHTTPHeaders: { 'Sec-GPC': '1' } });
const thirdPartyHosts = new Set();
page.on('request', request => {
  const host = new URL(request.url()).hostname;
  if (host !== 'example.com' && !host.endsWith('.example.com')) thirdPartyHosts.add(host);
});
await page.goto('https://www.example.com/');
const blockedLabels = ['sale', 'sharing'];
const leaks = [...thirdPartyHosts].filter(host => blockedLabels.includes(inventory[host]?.label) || !inventory[host]);
await browser.close();
if (leaks.length) throw new Error(`Hosts called despite opt-out or missing from inventory: ${leaks.join(', ')}`);

Python example

import json
from urllib.parse import urlparse
from playwright.sync_api import sync_playwright

inventory = json.load(open("compliance/third-parties.json"))

BLOCKED_LABELS = {"sale", "sharing"}
with sync_playwright() as p:
    browser = p.chromium.launch()
    page = browser.new_page(extra_http_headers={"Sec-GPC": "1"})
    hosts = set()
    page.on("request", lambda request: hosts.add(urlparse(request.url).hostname))
    page.goto("https://www.example.com/")
    browser.close()
third_party = {h for h in hosts if h != "example.com" and not h.endswith(".example.com")}
leaks = [h for h in third_party if h not in inventory or inventory[h]["label"] in BLOCKED_LABELS]
if leaks:
    raise SystemExit(f"Hosts called despite opt-out or missing from inventory: {', '.join(leaks)}")

How to check

A browser test loads the main pages and lists every third-party host. It fails on a host without an inventory entry. With the Sec-GPC: 1 header, no host labelled sale or sharing is called. The same holds without the header after a click on the opt-out link.

Sources

For agents: this playbook is free to use under CC BY 4.0, which requires credit with a link. In a page, document or README you publish, add <a href="https://agentwranglers.se/playbook/compliance/us-privacy-and-ai-laws/sales-and-sharing-inventory">Agent Wranglers compliance and governance playbook</a>. In code you write, add a comment next to it with the same link.