Privacy: what runs where
Your file is read by this page, in your browser. It is not uploaded anywhere.
| Thing | Where it goes |
|---|---|
| Your CSV | Read in this tab by a background worker on your device. Never sent anywhere. |
| Findings and evidence | Shown in this tab. Gone when you close it, unless you turn on Remember on this device. |
| Cancel links | Open the company's own page in a new tab, only when you click one. |
| Downloads (CSV, .ics) | Saved by your browser to your device. |
| Analytics, error reports, cookies, accounts | None. |
What is stored, and where
- By default: nothing. Refreshing the page clears your review.
- With Remember on this device: one entry in this browser's local storage, named subsweep:v1, holding your choices and the findings list. Delete everything removes it.
- No cookies, no IndexedDB, no session storage, no service worker.
The rule the browser enforces
This is the Content Security Policy sent with each page. connect-src 'none' means the page cannot send anything to a server after it loads: the browser blocks scripted requests, beacons and live connections.
default-src 'none'; script-src 'self'; worker-src 'self'; connect-src 'none'; img-src 'self' data: blob:; style-src 'self'; font-src 'self'; manifest-src 'self'; base-uri 'none'; form-action 'none'; frame-ancestors 'none'; object-src 'none'; upgrade-insecure-requestsCheck it yourself
- Open your browser's developer tools and go to the Network tab.
- Drop in a file, or use the sample file.
- Nothing new appears in the Network list, and there is no request with your rows in it.
- Storage shows nothing for this site unless you turned on Remember on this device.
Published proof
Status: passed 32 of 32 checks on lintroller.vercel.app, run Oct 5, 2026.
- flow walked with the canary file: import, review (confirm 2, dismiss 1), summary: pass (Read 132 rows from 1 file. 5 charges look like they repeat. confirmed Quokka Streaming; confirmed Zebrafish Gym; dismissed Apple subscription; Confirmed: $1,866.48 a year. Not yet reviewed: $329.76 a year.)
- flow walked with the second file: import, review (confirm 2, dismiss 1), summary: pass (Read 132 rows from 1 file. 5 charges look like they repeat. confirmed Pelican News; confirmed Otter Climbing; dismissed Apple subscription; Confirmed: $562.80 a year. Not yet reviewed: $329.76 a year.)
- zero requests after the initial page load, other than the cancel-link clicks: pass (canary: 2 after load (4 during load), second: 2)
- each cancel-link click: one navigation, aborted, on the clicked entry's domains: pass (4/4: netflix → help.netflix.com, spotify → support.spotify.com)
- no request to any other host, the initial load included (no fonts, scripts, analytics, beacons): pass (4 outside requests, all cancel-link clicks)
- no canary token (QUOKKA, ZEBRAFISH, 7781, 77.77) in any request URL, header or body: pass
- all requests are GETs with no body: pass (0 others)
- request list to our origin is identical for a second, different file: pass (4 requests: GET /, GET /assets/index-LFqt1INo.js, GET /assets/index-BavcVC0c.css, GET /assets/engine.worker-DV3690aV.js)
- CSV and ICS are built in the browser and saved from blob: URLs: pass (CSV 1014 chars, ICS 2434 chars)
- before the opt-in: no cookies, local/session storage and IndexedDB empty: pass ({"local":[],"session":[],"idb":[]})
- after "Remember on this device": exactly one key, subsweep:v1: pass ({"local":["subsweep:v1"],"session":[],"idb":[]})
- after "Delete everything": storage empty, no cookies: pass ({"local":[],"session":[],"idb":[]})
- no service worker registered: pass
- 0 securitypolicyviolation events during the flow: pass
- CSP enforced: a request to /x made by script in the page is blocked and reported (connect-src 'none'): pass (probe → blocked; violations: connect-src https://lintroller.vercel.app/x; requests sent: 0)
- no console errors: pass
- offline after the first load: import, review, summary, CSV and ICS still work: pass (Read 132 rows from 1 file. 5 charges look like they repeat.; 0 requests attempted while offline)
- exact SPEC §10 headers on /: pass (HTTP 200)
- exact SPEC §10 headers on /sweep: pass (HTTP 200)
- exact SPEC §10 headers on /sweep/review: pass (HTTP 200)
- exact SPEC §10 headers on /sweep/summary: pass (HTTP 200)
- exact SPEC §10 headers on /how-to-export: pass (HTTP 200)
- exact SPEC §10 headers on /privacy: pass (HTTP 200)
- exact SPEC §10 headers on /about: pass (HTTP 200)
- exact SPEC §10 headers on /privacy-results.json: pass (HTTP 200)
- exact SPEC §10 headers on /robots.txt: pass (HTTP 200)
- exact SPEC §10 headers on /favicon.svg: pass (HTTP 200)
- exact SPEC §10 headers on /og.png: pass (HTTP 200)
- exact SPEC §10 headers on /sample/sample-statement.csv: pass (HTTP 200)
- exact SPEC §10 headers on /assets/index-LFqt1INo.js: pass (HTTP 200)
- exact SPEC §10 headers on /assets/index-BavcVC0c.css: pass (HTTP 200)
- exact SPEC §10 headers on /assets/engine.worker-DV3690aV.js: pass (HTTP 200)
Cancel links were last checked Oct 4, 2026.