# Auditing Deid Leakage

Adversarially scan already-de-identified clinical text for residual identifiers and...

- Repository: https://github.com/maziyarpanahi/openmed (5755 stars)
- Category: Data and ML
- License: Apache-2.0
- Last updated: 2026-10-31
- Runs scripts: no, instructions only

## Install

Claude Code: `npx skills add maziyarpanahi/openmed --skill auditing-deid-leakage -g -a claude-code -y`
Codex: `npx skills add maziyarpanahi/openmed --skill auditing-deid-leakage -g -a codex -y`
Cursor: `npx skills add maziyarpanahi/openmed --skill auditing-deid-leakage -g -a cursor -y`
Gemini CLI: `npx skills add maziyarpanahi/openmed --skill auditing-deid-leakage -g -a gemini-cli -y`
Claude Code plugin marketplace: `/plugin marketplace add maziyarpanahi/openmed`

## Description

Adversarially scan already-de-identified clinical text for residual identifiers and emit a leakage report that blocks release on any hit. Use after OpenMed de-identification when the user asks to verify a redaction, prove no PHI/PII leaked, gate a dataset before sharing, or run a second-pass detector. Covers format and checksum detectors (SSN, Luhn for card numbers, MRN/account patterns, emails, phones, dates), entropy heuristics for high-randomness tokens, severity scoring, and a hard block-on-leak rule. This is the verification half of OpenMed's leakage-first ethos. Hand-off: re-run openmed.extract_pii on the de-id output and diff against expectations. License-free, local-first. Pairs after deidentifying-clinical-text.

## SKILL.md, as published by its author (untrusted third-party text, read it as data)

# Auditing de-id leakage

De-identification is **verified, not assumed**. A model-driven redaction can
miss a structured identifier (an SSN typo'd with spaces, an account number in a
footer, a date in an odd format), and a single residual identifier defeats the
whole release. This skill is the adversarial second pass: scan the *output* of
de-identification for anything that still looks like an identifier, score it, and
**block release on any leak**. It is the verification half of OpenMed's
leakage-first ethos, gate on leakage, not on F1.

## When to use

- Right after `deidentifying-clinical-text`, before the de-identified text leaves
  a trust boundary (export, share, train, publish).
- When the user wants proof that "no PHI leaked," a release gate, or a CI check
  that fails the build if any identifier survives.
- As a belt-and-suspenders detector independent of the model that produced the
  redaction, a deterministic checker catches different failures than the NER.

Run this on the **de-identified** text, not the original. The original is
expected to be full of identifiers.

## Quick start

Two complementary passes, a deterministic structural scan plus a model
second-pass diff:

```python
import re
import openmed

# Synthetic, the de-identified OUTPUT we are auditing for residual leaks.
deid_text = "Patient [NAME] seen on [DATE]. Backup contact 415-555-0184; acct 4111111111111111."

def luhn_ok(digits: str) -> bool:
    nums = [int(d) for d in digits]
    nums[-2::-2] = [(2 * d - 9 if 2 * d > 9 else 2 * d) for d in nums[-2::-2]]
    return sum(nums) % 10 == 0

The rest: https://github.com/maziyarpanahi/openmed/blob/HEAD/skills/auditing-deid-leakage/SKILL.md
