cd /news/ai-agents/pixel-patrol-a-gdpr-watchdog-whose-m… · home topics ai-agents article
[ARTICLE · art-116025] src=dev.to ↗ pub= topic=ai-agents verified=true sentiment=· neutral

Pixel Patrol: a GDPR watchdog whose main job is staying quiet

A developer built Pixel Patrol, a GDPR watchdog that crawls websites hourly to detect undeclared trackers and automatically drafts cookie policy updates and Records of Processing Activities rows. The system, built for the All Things Agentic hackathon, uses Playwright for crawling and Gemini 3.5 Flash agents on Vertex AI for classification, but keeps deterministic diffing in TypeScript to avoid false alerts. In testing on a Czech news site, it reported only 12 of 643 differences as real drift.

read4 min views2 publishedAug 30, 2026

I built Pixel Patrol for the All Things Agentic hackathon, and this post is part of that submission. Code is at https://github.com/thatmike1/pixel-patrol.

Cookie policies are documents about software, and they go stale the moment the software changes. Someone in marketing adds a Meta Pixel through the tag manager on a Tuesday afternoon. Nobody tells the person whose name is on the privacy policy. From that afternoon on the site processes personal data it does not declare, and under the GDPR that is the owner's problem, not the marketer's.

Everyone knows the fix. Check the site now and then, update the policy when something changed. Nobody does it, because the checking is boring and the updating is worse. That is not a chatbot-shaped problem. The work has to happen with nobody watching and land as a finished document where work already gets tracked.

Once an hour, Pixel Patrol crawls every site it is responsible for with a real browser (Playwright, in a Cloud Run Job). It records every third-party host and every cookie, both before and after the consent banner is dismissed, and compares the result with a baseline someone approved.

When a tracker appears that nobody decided to add, it identifies the vendor, writes the cookie policy change in Czech as a redline, writes the Records of Processing Activities row the owner is now obliged to file, opens a GitHub issue with both, and emails the owner. No dashboard. The first you hear of it is a ticket in the tracker you already use, with text you can paste.

A raw diff of two host lists is not an alert. On a commercial site the third-party set moves on its own: programmatic ad slots fill with a different vendor on every pageview, and CDN hosts rotate shard names between crawls. An agent that fires on that gets muted inside a week, and a muted watchdog is worse than none.

So hosts are compared by registrable domain, not hostname, and every new domain and cookie is classified against the site's own recent history before anything is reported. On a Czech news site, across 69 real decisions, it saw 643 differences and reported 12. No domain was reported twice.

The split between "this is noise" and "this is drift" is deterministic code. The model never gets to redraw it. Gemini 3.5 Flash, running as two Google ADK agents on Vertex AI, does the judgement on top: one agent decides whether a difference is a first sweep, harmless rotation, or a real tracker and explains why in language the site owner can act on; the second writes the redline and the RoPA row, and it only runs when the first one recorded drift. Everything else, from the diffing to the deduplication to filing the ticket, is plain TypeScript the model cannot reach around. An LLM asked to eyeball two host lists will occasionally miss one, and a missed marketing pixel is the one failure this thing exists to prevent.

One of the demo pages loads toplist.cz

, a real and fairly obscure Czech hit counter. It is there to prove the system will say "I do not know who this is" instead of guessing.

The first run named Mailchimp as the operator, medium confidence, with a written basis pointing at the table entry list-manage.com

sharing a brand token. The model had followed its instructions exactly. The evidence I handed it was wrong: the near-match lookup accepted any four-character substring, so "toplist"

contained "list"

and Mailchimp became a neighbour. One loose includes

, and the output was an invented vendor in a document meant for a regulator.

The fix matches whole words, the exact case is pinned by a test, and the answer is now vendor: null

, unclassified

, low confidence, with a redline telling the owner to find out who runs the domain before publishing anything.

The dead-letter policy was configured, the IAM was right, and a poison message really did get published to the dead-letter topic. Then it vanished. Pub/Sub delivers to every subscription on a topic and drops the message, so a dead-letter topic with no subscription retains nothing, and everything reports success while the evidence is gone. Both dead-letter topics now get a pull subscription with seven-day retention before the first bad message can arrive.

Gemini 3.5 Flash on Vertex AI through the Google ADK. Cloud Scheduler, Pub/Sub with push subscriptions and OIDC tokens, Cloud Run for the agent service, Cloud Run Jobs for the crawler, Firestore, Secret Manager, Cloud Build and Artifact Registry. TypeScript on Node 22, 135 tests under node --test

.

It has been running unattended on five demo sites and two real ones, filing tickets, while I wrote this.

── more in #ai-agents 4 stories · sorted by recency
── more on @pixel patrol 3 stories trending now
sponsored brought to you by zahid.host 4,200+ EU-deployed projects
reading about agents? ship yours in a single git push.

Run your AI side-project on zahid.host

EU-based hosting, git-push deploys, automatic HTTPS, no cold starts. Free tier with a custom domain — perfect for shipping the agent you just read about.

$git push zahid main
Live at https://your-agent.zahid.host
Get free account → Pricing
from €0/mo · no card required
LIVE [news/pixel-patrol-a-gdpr-…] indexed:0 read:4min 2026-08-30 ·