Opt-Out Signal Lint for US State Privacy Laws

Finds the ad and analytics code that keeps firing after a visitor’s browser has already sent Global Privacy Control.

Install free

Free for the file open in your editor - no key, no limit. The workspace sweep and the report ask for a key.

VS Code MarketplaceOpen VSX (Cursor, VSCodium)npmMCP server (npx)Docker Hub
ext install ReadyStack.optout-signal-lint
npx @readystack/optout-signal-lint <file>
npx @readystack/optout-signal-lint --mcp

Team? One key for every ReadyStack linter, 5 seats, $149 once

Get the full rule table as a PDF
All 20 rules Opt-Out Signal Lint for US State Privacy Laws checks, each with its source and date, on printable pages you can hand to your team or auditor. We email it now, and once more only if a rule changes. No newsletter.

Get the full version $29

Sweeps the whole workspace, writes the finding list to CSV, JSON or HTML, and returns a CI exit code so the same leak cannot merge twice.

One payment, one licence key for this tool. The key is shown right after payment.

Osano, the nearest hosted consent platform, starts at $199/month.

Buy the full version — $29
ENDEJAESPT

Find a tool

· ReadyStack

Worked example

Real numbers from this tool, line by line.

Six lines that ignore Global Privacy Control

Six lines in one US checkout file ignore Global Privacy Control, and the lint returns nine findings on them — for US front-end developers who own the ad-tag code.

The output, before a word of explanation:

analytics/tags.js
  3: [error] Do Not Track is not an opt-out preference signal under any US state privacy law. The twelve states that require a universal signal recognise Global Privacy Control, not DNT.
  4: [error] Advertising storage defaults to granted, so a GPC visitor is already shared on the very first page load, before any banner logic runs.
  5: [error] A Google Ads (AW-) tag is a share for cross-context advertising. It has to be gated on the opt-out signal, not only on an EU cookie banner.
  5: [error] Google Signals turns Analytics data into cross-context advertising audiences. That is a share you must stop for a GPC visitor.
  6: [error] Meta Pixel init sends identifiers to Meta for cross-context behavioural advertising, which is a sale or share. It must not run for a visitor whose browser sent Global Privacy Control.
  6: [error] Advanced matching is passing a raw email or phone number to an ad platform. That is a sale of an identifier, and the field must be SHA-256 hashed even for a visitor who has not opted out.
  7: [error] The TikTok pixel is cross-context behavioural advertising. A visitor in the twelve opt-out-signal states who sent GPC must not have it loaded at all.
  8: [error] Honouring the signal for California alone misses the other eleven states that require it as of 1 January 2026.
  8: [warn] Since CPRA the required wording is "Do Not Sell or Share My Personal Information", or the single combined link titled "Your Privacy Choices".
—— 9 ——

Nine findings on six lines, in a file that passed review. navigator.doNotTrack is the worst: the signal the states recognise is navigator.globalPrivacyControl, a boolean, and the Sec-GPC header, whose value is 1 and never "true" — a detail that kills server-side opt-outs which compile, ship, and never once evaluate true.

The last finding has a date attached. As of 1 January 2026, twelve states require an opt-out preference signal to be honoured: California, Colorado, Connecticut, Delaware, Maryland, Minnesota, Montana, Nebraska, New Hampshire, New Jersey, Oregon and Texas. A California-only check misses eleven of them.

Why your scanner did not catch it

Your scanner loads a page: it sees the tags that fired for one region, one consent state, one code path. It cannot see the isEU branch that never runs for a US visitor, or a pixel behind a feature flag. And it runs after the deploy, which is after the share. The lint reads the source instead — the same twenty rules, in the editor, before the merge.

What being wrong costs

On 30 September 2025 the California Privacy Protection Agency settled with Tractor Supply for $1.35 million, its largest penalty to date. Failing to provide an effective opt-out from the sale and sharing of personal information, including via Global Privacy Control, was one of the counts. That same month the CPPA joined the Attorneys General of California, Colorado and Connecticut in a coordinated investigative sweep pointed directly at GPC.

The fix

Read the signal once — navigator.globalPrivacyControl === true || req.headers['sec-gpc'] === '1' — gate every tag on it, check the region against all twelve states rather than 'CA', and default ad_storage to 'denied'. Run the lint again and it returns nothing: the same twenty rules, the same file, zero findings.

Opt-Out Signal Lint audits the file you have open for free: all 20 rules, every line, no key, no cap. A licence key adds the different job — the whole-workspace sweep, a CSV, JSON or HTML export, and a CI exit code so a fixed leak cannot merge back in. Osano, the nearest hosted consent platform, starts at $199/month. This is $29 once, one licence key per person or team seat.

15 seconds — what it actually does

Questions people ask

What does Opt-Out Signal Lint actually do?

It reads your source files and flags the exact lines that ignore an opt-out preference signal: ad pixels that initialise unconditionally, consent defaults set to granted, and signal checks written against the wrong value. Each finding names the line, the reason it is a sale or share, and the corrected code.

Who is this for?

Front-end and full-stack developers at US-facing e-commerce and SaaS companies who own the analytics and advertising tag code, and the agencies who inherit those repositories. If someone on your team wired a Meta pixel or a Google Ads tag into a checkout flow, this is the file it reads.

Why will a free page scanner not do this?

A page scanner loads a rendered page and reports the tags that fired for that one region, consent state and code path. It cannot see the isEU branch that never runs for a US visitor, or a pixel behind a feature flag. It also runs after deployment, when the share has already happened.

What is free and what needs a licence key?

The file you have open is fully audited for free — all 20 rules, every line, no key and no cap. A licence key adds a different job: sweeping the whole workspace, exporting the finding list as CSV, JSON or HTML, and a CI exit code so a fixed leak cannot come back in a later merge.

What does the alternative cost?

Osano, the nearest hosted consent platform, starts at $199/month, and a privacy engineer reading the same repository by hand bills far more than that for a single pass. This is $29 once, one licence key per person or team seat,.

Why not just ask ChatGPT or another AI chat?

A general AI chat answers from training data with a cutoff date, cannot read your repository and names no rule version. Opt-Out Signal Lint for US State Privacy Laws checks the file you open against 20 rules from a rule set dated 2026-09-20, and points at the exact line with the fix. For a filing, an audit or a client you need that dated result on your own files.

Ask about this tool

One question, answered by the person who built it. Your email only if you want the answer sent.

Embed this tool on your site (free)

Paste this code into your page. It runs in your visitor’s browser and stays up to date. Nothing your visitors type is stored.

 All embeddable tools

For businesses: your name and logo instead of ours, and each visitor’s result + e-mail in your inbox (only when they tick consent) — Pro from $19/month. See Pro →