Grinden
Varje text som en AI-agent vill skicka ut ur huset går genom den här grinden. Svenska personuppgifter stoppas med kontrollsiffra, datum och sammanhang som bevis, inte bara för att siffrorna råkar se rätt ut. Datum, belopp och fakturanummer släpps igenom.
- Körs i din webbläsare
- Noll nätverksanrop, inget sparas
- Samma regler som i drift, testade mot originalet
Text
Alla nummer i exemplen är påhittade och räknas fram med rätt kontrollsiffra. Personnumren har födelseår efter 2040 eller är Skatteverkets testnummer, så de kan inte tillhöra någon.
Skyddade namn
Namn i listan är hårda träffar: texten stoppas. I drift läses listan från en fil som bara den lokala modellen får se. Här lever den i din flik tills du stänger den.
Dom
Träffar
Liknade, men föll på kontrollen
Det här får modellen
Så ser agenten det
Samma text som ett verktygsanrop i Claude Code. Kroken skickar anropet till grinden och stoppar med exit 2 om domen är stopp. Texten nedan är den agenten får läsa.
Svaret från tjänsten, som JSON (index i kodpunkter, som i Python)
Självtestet körs.
Texterna i självtestet
Regelboken
Tolv typer. Hårda typer stoppar ensamma. Mjuka typer stoppar först i mängd: fyra kontaktuppgifter i samma text, eller två kontaktuppgifter och fyra namn, ser ut som ett register. Säkerheten är den poäng Presidio får när reglerna körs i drift.
| Typ | Klass | Så kontrolleras den | Säkerhet | |
|---|---|---|---|---|
| Personnummer | hård | Tio eller tolv siffror. Luhn över de sista tio, och datumet måste finnas. Fel kontrollsiffra eller 30 februari ger ingen träff. | 0,95 | |
| Samordningsnummer | hård | Som personnummer, men dagen är 61 till 91: dag plus 60. Datumet kontrolleras efter att 60 dragits av. | 0,95 | |
| Organisationsnummer | hård | Tio siffror, Luhn, och siffra tre och fyra minst 20. Under 20 är det en månad, alltså ett datum eller ett personnummer, inte ett bolag. | 0,90 | |
| Bankgiro | hård | Sju eller åtta siffror med bindestreck och Luhn, och ordet bankgiro, bg eller bg-nr inom 28 tecken före. Samma nummer utan ordet är en referens. | 0,90 | |
| Plusgiro | hård | Två till åtta siffror med bindestreck och Luhn, och ordet plusgiro, pg eller postgiro inom 28 tecken före. | 0,90 | |
| IBAN | hård | SE följt av 22 siffror, med eller utan mellanslag, stora eller små bokstäver. Hela numret flyttas om och måste ge rest 1 vid division med 97. | 0,98 | |
| Kontonummer | hård | Clearingnummer och 7 till 12 siffror, med ordet konto, kontonr, clearing eller clnr inom 28 tecken före. Ingen kontrollsiffra finns, så sammanhanget avgör. | 0,85 | |
| Klientnamn | hård | Lista med skyddade namn, hela ord, skiftlägesokänslig, minst tre tecken, längsta namnet först. I drift läses listan från en fil; här från rutan ovan. | 0,99 | |
| E-post | mjuk | namn@domän med minst en punkt i domänen. Stoppar bara i mängd. | 0,90 | |
| Telefon | mjuk | Svenskt format: 07x, 08 eller riktnummer, med eller utan +46, mellanslag och bindestreck. Stoppar bara i mängd. | 0,75 | |
| Adress | mjuk | Gatunamn som slutar på gatan, vägen, gränd, torg, allé, leden och liknande, följt av ett nummer. | 0,80 | |
| Postnummer | mjuk | Tre siffror, mellanslag, två siffror och en ort med stor bokstav. | 0,70 | |
| Namn (PERSON) | mjuk | Hittas inte i webbläsaren. I drift kommer namn från spaCy sv_core_news_md via Microsoft Presidio, med samma regler som här inlagda som en egen recognizer. | 0,50+ |
Varför inte bara ett mönster?
Ett regelverk som bara tittar på formen flaggar varje datum och fakturanummer, och missar svenska format helt. Mätt på 2 850 svenska affärsmeningar, hälften med en identifierare och hälften lockbeten som liknar en.
Var den sitter
Grinden är en lokal tjänst på min Mac, 127.0.0.1:4201. Tre saker går genom den: varje utgående verktygsanrop från Claude Code via en PreToolUse-krok, varje modellanrop via routern framför språkmodellerna, och texten till Gemini i en tjänst på Google Cloud Run. Stoppas något får jag en fråga i mobilen; ett ja gäller exakt det anropet, en gång, i 30 minuter.
I drift kör samma regler inne i Microsoft Presidio tillsammans med spaCy-modellen sv_core_news_md, som hittar namn. Den delen finns inte i webbläsaren, så här hittas inga namn utom de du själv skyddar. Texter kapas vid 200 000 tecken, och skanningstiden mäts: p95 och p50 syns på Kontoret, tillsammans med antalet skanningar och stopp sedan 30 september.
Den här sidan kör en JavaScript-version av reglerna. Den är testad mot Python-originalet på över 950 texter med samma träffar, dom och maskning, och självtestet ovan kör en del av dem i din webbläsare varje gång sidan laddas. Grinden är stängd som standard: svarar den inte, stoppas anropet. Ett kaosprov dödar den varje natt och kontrollerar att det stämmer, och resultatet publiceras.
Vad den inte gör: hittar namn i webbläsaren, förstår andra länders identifierare, eller ser ett skript som agenten själv skriver och kör. Den sista luckan står i hotmodellen, tillsammans med vad som är gjort åt den. Postmortem från när en för kort tidsgräns gav tre falska stopp finns på plattformssidan.
Samma grind sitter framför agenten som svarar på frågor om plattformen: fråga den något, eller försök skicka ett personnummer och se vad som händer.
Reglerna är öppen källkod: svenska-pii (MIT), ren Python utan beroenden, med Presidio-recognizers som tillval. Godkännandet per anrop finns som agent-permit.