The preflight is regex, checksums, and one sentence-shape heuristic — no model judgment in the detection path. Here's exactly what runs, and what it does and doesn't catch.
pipeline
A hit at pre-check stops the request before Gemini ever sees it. Post-check re-runs PII detection on Gemini's own reply, in case the model repeats something back that shouldn't leave. Nothing runs an LLM to decide; both gates are the same pure functions.
pii detection
Format regexes cast a wide net; a checksum decides whether a candidate is real. A random 16-digit number matches the card pattern about 1 time in 10 before Luhn narrows it down — same idea for IBAN.
\d{3}-\d{2}-\d{4}mod 10 == 0 on the Luhn-weighted sum.mod 97 == 1 check.local@domain.tld pattern.injection detection
why no model in the loop
inspectable
Every block traces to one line of matched text. No confidence score to argue with, no "the model felt unsafe."
no adaptive surface
There's no judgment call to attack with a crafted prompt — you can't gaslight a regex into thinking "ignore-previous-instructions" means something else.
cheap and fast
Runs before the Gemini call, not after — a bad prompt never burns model latency or a token, let alone gets a response.
testable to zero ambiguity
Pure functions, no I/O. Same input, same output, every time — the whole detector is 64 asserted test cases.
what this doesn't catch
One layer of defense-in-depth, not a verdict on your data. It catches what's pattern-shaped and stays honest about what isn't.