Rishi Raj Jain’s pg_redact is a small but concrete Jev integration: use deterministic rules to find possible identifiers, ask Jev what each span means in context, store the labels beside the message, and let Postgres decide what each role may see.

The pipeline

  • Regexes and token rules collect up to 40 candidates: emails, digit runs, capitalized names, possible addresses, and other suspicious tokens.
  • One Jev request batches a choice question for every candidate against the full message context.
  • The choices are email, phone, name, address, id_number, or none; results below a hard-coded 0.5 winning probability are discarded.
  • The message and accepted spans are written to a Postgres row, with the spans stored as JSONB.
  • A SQL redact() function compares each span’s sensitivity with the viewer’s clearance and replaces restricted values before returning the text.

Why the split is useful

  • Candidate generation stays broad and cheap; Jev handles the semantic distinction between an invoice number and an SSN.
  • Classification happens at ingestion, while authorization happens at read time. A role or sensitivity policy can change without reclassifying every message.
  • The SQL function masks longer strings first, preventing Daniel Brooks from being split awkwardly by shorter overlapping name spans.
  • The API also strips unauthorized values from its structured response, while a separate route exposes the string produced by Postgres for inspection.

What the code actually establishes

  • I inspected the README plus the Jev client, candidate generator, schema setup, classify route, and reveal route in the public repository.
  • The implementation really calls https://api.typesafe.ai/v1/systemone with jev-latest; Jev is not merely mentioned in the README.
  • The code batches all candidate questions into one call and records the selected label and returned probability for accepted spans.
  • The database function genuinely performs role-based masking, but the application supplies the clearance value. This is not database-native identity or row-level-security enforcement.
  • I inspected the code; I did not run it because a Neon database and paid TypeSafe API key are required. This was not a security audit.

The limits matter

  • The article shows one worked support-ticket example, not precision/recall results on a held-out PII dataset.
  • The 0.5 threshold is not justified by application-specific calibration, and the demo treats returned probability as trustworthy without measuring errors.
  • Candidate generation caps the list at 40, so long messages can silently leave text unexamined.
  • Exact string replacement can over-redact repeated text and does not preserve source offsets through later edits.
  • A false negative remains visible to every role. For sensitive data, that failure mode is more consequential than an unnecessary mask.
  • Stored raw messages and spans still contain the PII; masking query output is not encryption, deletion, or protection from privileged database access.

A safer production shape

  • Evaluate candidate recall and Jev classification separately on representative, labeled text.
  • Choose thresholds from the cost of false negatives, not from a generic midpoint.
  • Store source offsets and version the classifier, criteria, and policy used for each record.
  • Treat uncertain or truncated messages as restricted by default and send them to review.
  • Bind clearance to authenticated database roles or tightly controlled server policy rather than accepting it as an ordinary application parameter.

“These rules do not decide what counts as PII and they only suggest candidates for Jev to review.”

The design is reusable because it keeps model judgment narrow and leaves authorization deterministic. Its demo output is evidence that the plumbing works—not evidence that the PII detector is safe enough for production.