Spaces:
Sleeping
Sleeping
| """ | |
| Case Compiler β Multi-modal synthetic fraud cases (CMS SynPUF + messy evidence). | |
| Per-case output is a directory: | |
| <base_dir>/<case_id>/ | |
| medicare_records.db # SQLite, CMS SynPUF-aligned | |
| intercepted_comms/ # .txt emails (50 benign + 1 smoking gun) | |
| scanned_claims/ # degraded CMS-1500 single-image PDFs | |
| Primary typology: Anti-Kickback Statute (AKS) kickback disguised as a | |
| "research grant" β the smoking gun lives in intercepted_comms/ (needle in | |
| haystack, OCR-noised NPI), and the crime lives in the PDE + carrier_claims | |
| tables (anomalous volume spike + upcoded claim with a degraded PDF). | |
| Secondary typologies: shell-company chain (tier-scaled depth), dead-patient | |
| claim, duplicate billing. Ground-truth rows are planted into the | |
| `ground_truth(kind, payload_json)` table the grader already reads from. | |
| Quality primitives (kept from the previous CMS-only compiler): | |
| - Luhn-valid NPIs with 80840 prefix | |
| - Benford's-law-shaped dollar amounts | |
| - Pareto heavy-tail amounts (optional) | |
| - CMS DE-SynPUF field names (DESYNPUF_ID, BENE_BIRTH_DT, etc.) | |
| """ | |
| from __future__ import annotations | |
| import json | |
| import hashlib | |
| import math | |
| import os | |
| import random | |
| import sqlite3 | |
| from datetime import datetime, timedelta | |
| from pathlib import Path | |
| from typing import Any | |
| from fraud_hunter_env.npi_utils import generate_valid_npi | |
| from .pdf_evidence import ClaimEvidence, render_claim_pdf | |
| # ββ Benford & Pareto sampling ββββββββββββββββββββββββββββββββββββββββββββββββ | |
| _BENFORD = [0.301, 0.176, 0.125, 0.097, 0.079, 0.067, 0.058, 0.051, 0.046] | |
| def _benford_amount(rng: random.Random, lo: float = 50.0, hi: float = 5000.0) -> float: | |
| first = rng.choices(range(1, 10), weights=_BENFORD, k=1)[0] | |
| for _ in range(1000): | |
| exp = rng.uniform(math.log10(max(1.0, lo)), math.log10(max(2.0, hi))) | |
| raw = 10 ** exp | |
| s = str(round(raw, 2)).lstrip("0.") | |
| if s and int(s[0]) == first and lo <= raw <= hi: | |
| return round(raw, 2) | |
| return round(rng.uniform(lo, hi), 2) | |
| def _pareto_amount(rng: random.Random, xm: float = 1000.0, alpha: float = 1.5) -> float: | |
| u = rng.random() | |
| return round(xm / (u ** (1 / alpha)), 2) | |
| def _rand_date(rng: random.Random, start: str, end: str) -> str: | |
| s = datetime.strptime(start, "%Y-%m-%d") | |
| e = datetime.strptime(end, "%Y-%m-%d") | |
| delta = (e - s).days | |
| return (s + timedelta(days=rng.randint(0, max(delta, 1)))).strftime("%Y-%m-%d") | |
| # ββ OCR noise for unstructured evidence ββββββββββββββββββββββββββββββββββββββ | |
| _OCR_NOISE_MAP = {"0": "O", "1": "l", "5": "S", "8": "B"} | |
| def _inject_ocr_noise(text: str, rng: random.Random, n_errors: int = 2) -> str: | |
| """Replace digits with visually-similar glyphs to force agent data-cleaning.""" | |
| chars = list(text) | |
| candidates = [i for i, c in enumerate(chars) if c in _OCR_NOISE_MAP] | |
| if not candidates: | |
| return text | |
| rng.shuffle(candidates) | |
| for idx in candidates[:max(1, n_errors)]: | |
| chars[idx] = _OCR_NOISE_MAP[chars[idx]] | |
| return "".join(chars) | |
| # ββ CMS SynPUF schema ββββββββββββββββββββββββββββββββββββββββββββββββββββββββ | |
| _SCHEMA_SQL = """ | |
| CREATE TABLE beneficiary_summary ( | |
| DESYNPUF_ID TEXT PRIMARY KEY, | |
| BENE_BIRTH_DT TEXT, | |
| BENE_DEATH_DT TEXT, | |
| BENE_SEX_IDENT_CD TEXT, | |
| BENE_RACE_CD TEXT, | |
| BENE_ESRD_IND TEXT, | |
| SP_STATE_CODE TEXT, | |
| BENE_COUNTY_CD TEXT, | |
| SP_ALZHDMTA INTEGER DEFAULT 0, | |
| SP_CHF INTEGER DEFAULT 0, | |
| SP_CHRNKIDN INTEGER DEFAULT 0, | |
| SP_CNCR INTEGER DEFAULT 0, | |
| SP_COPD INTEGER DEFAULT 0, | |
| SP_DEPRESSN INTEGER DEFAULT 0, | |
| SP_DIABETES INTEGER DEFAULT 0, | |
| SP_ISCHMCHT INTEGER DEFAULT 0, | |
| SP_OSTEOPRS INTEGER DEFAULT 0, | |
| SP_RA_OA INTEGER DEFAULT 0, | |
| SP_STRKETIA INTEGER DEFAULT 0, | |
| MEDREIMB_IP REAL DEFAULT 0, | |
| BENRES_IP REAL DEFAULT 0, | |
| PPPYMT_IP REAL DEFAULT 0 | |
| ); | |
| CREATE TABLE inpatient_claims ( | |
| CLM_ID TEXT PRIMARY KEY, | |
| DESYNPUF_ID TEXT, | |
| CLM_FROM_DT TEXT, | |
| CLM_THRU_DT TEXT, | |
| PRVDR_NUM TEXT, | |
| CLM_PMT_AMT REAL, | |
| AT_PHYSN_NPI TEXT, | |
| OP_PHYSN_NPI TEXT, | |
| OT_PHYSN_NPI TEXT, | |
| CLM_ADMSN_DT TEXT, | |
| ADMTNG_ICD9_DGNS_CD TEXT, | |
| CLM_DRG_CD TEXT, | |
| ICD9_DGNS_CD_1 TEXT, | |
| ICD9_PRCDR_CD_1 TEXT, | |
| FOREIGN KEY(DESYNPUF_ID) REFERENCES beneficiary_summary(DESYNPUF_ID) | |
| ); | |
| CREATE TABLE outpatient_claims ( | |
| CLM_ID TEXT PRIMARY KEY, | |
| DESYNPUF_ID TEXT, | |
| CLM_FROM_DT TEXT, | |
| CLM_THRU_DT TEXT, | |
| PRVDR_NUM TEXT, | |
| CLM_PMT_AMT REAL, | |
| AT_PHYSN_NPI TEXT, | |
| OP_PHYSN_NPI TEXT, | |
| OT_PHYSN_NPI TEXT, | |
| ADMTNG_ICD9_DGNS_CD TEXT, | |
| ICD9_DGNS_CD_1 TEXT, | |
| HCPCS_CD_1 TEXT, | |
| FOREIGN KEY(DESYNPUF_ID) REFERENCES beneficiary_summary(DESYNPUF_ID) | |
| ); | |
| CREATE TABLE carrier_claims ( | |
| CLM_ID TEXT PRIMARY KEY, | |
| DESYNPUF_ID TEXT, | |
| CLM_FROM_DT TEXT, | |
| CLM_THRU_DT TEXT, | |
| PRF_PHYSN_NPI TEXT, | |
| TAX_NUM TEXT, | |
| HCPCS_CD TEXT, | |
| LINE_NCH_PMT_AMT REAL, | |
| LINE_ICD9_DGNS_CD TEXT, | |
| FOREIGN KEY(DESYNPUF_ID) REFERENCES beneficiary_summary(DESYNPUF_ID) | |
| ); | |
| CREATE TABLE prescription_drug_events ( | |
| PDE_ID TEXT PRIMARY KEY, | |
| DESYNPUF_ID TEXT, | |
| PRVDR_NPI TEXT, | |
| SRVC_DT TEXT, | |
| PROD_SRVC_ID TEXT, | |
| DRUG_NAME TEXT, | |
| QTY_DSPNSD_NUM REAL, | |
| DAYS_SUPLY_NUM INTEGER, | |
| PTNT_PAY_AMT REAL, | |
| TOT_RX_CST_AMT REAL, | |
| FOREIGN KEY(DESYNPUF_ID) REFERENCES beneficiary_summary(DESYNPUF_ID) | |
| ); | |
| CREATE TABLE corporate_registry ( | |
| entity_id TEXT PRIMARY KEY, | |
| entity_name TEXT, | |
| tax_id TEXT, | |
| parent_entity_id TEXT, | |
| ubo_id TEXT, | |
| incorporation_date TEXT, | |
| state TEXT, | |
| npi_code TEXT, | |
| FOREIGN KEY(parent_entity_id) REFERENCES corporate_registry(entity_id) | |
| ); | |
| CREATE TABLE general_ledger ( | |
| tx_id TEXT PRIMARY KEY, | |
| tx_date TEXT, | |
| debit_account TEXT, | |
| credit_account TEXT, | |
| amount REAL, | |
| memo TEXT, | |
| entity_id TEXT, | |
| FOREIGN KEY(entity_id) REFERENCES corporate_registry(entity_id) | |
| ); | |
| CREATE TABLE referral_payments ( | |
| payment_id TEXT PRIMARY KEY, | |
| payer_npi TEXT, | |
| payee_npi TEXT, | |
| amount REAL, | |
| payment_date TEXT, | |
| memo TEXT | |
| ); | |
| CREATE TABLE ground_truth (kind TEXT, payload_json TEXT); | |
| CREATE TABLE case_metadata (key TEXT PRIMARY KEY, value TEXT); | |
| CREATE TABLE evidence_documents ( | |
| doc_id TEXT PRIMARY KEY, | |
| claim_id TEXT, | |
| pdf_path TEXT, | |
| tier INTEGER, | |
| is_scanned INTEGER DEFAULT 1, | |
| expected_fields_json TEXT, | |
| FOREIGN KEY(claim_id) REFERENCES carrier_claims(CLM_ID) | |
| ); | |
| -- ββ Government contracting domain βββββββββββββββββββββββββββββββββββββββ | |
| CREATE TABLE government_contracts ( | |
| contract_id TEXT PRIMARY KEY, | |
| agency TEXT, | |
| vendor_entity_id TEXT, | |
| contract_value REAL, | |
| award_date TEXT, | |
| expected_product TEXT, | |
| disclosed_unit_price REAL, | |
| actual_unit_cost REAL, | |
| FOREIGN KEY(vendor_entity_id) REFERENCES corporate_registry(entity_id) | |
| ); | |
| CREATE TABLE contract_invoices ( | |
| invoice_id TEXT PRIMARY KEY, | |
| contract_id TEXT, | |
| line_item TEXT, | |
| amount REAL, | |
| invoice_date TEXT, | |
| FOREIGN KEY(contract_id) REFERENCES government_contracts(contract_id) | |
| ); | |
| CREATE TABLE contract_deliveries ( | |
| delivery_id TEXT PRIMARY KEY, | |
| contract_id TEXT, | |
| delivered_product TEXT, | |
| delivery_date TEXT, | |
| FOREIGN KEY(contract_id) REFERENCES government_contracts(contract_id) | |
| ); | |
| -- ββ PPP / pandemic loan domain ββββββββββββββββββββββββββββββββββββββββββ | |
| CREATE TABLE loan_applications ( | |
| loan_id TEXT PRIMARY KEY, | |
| entity_id TEXT, | |
| program TEXT, | |
| claimed_employees INTEGER, | |
| claimed_monthly_payroll REAL, | |
| loan_amount REAL, | |
| application_date TEXT, | |
| FOREIGN KEY(entity_id) REFERENCES corporate_registry(entity_id) | |
| ); | |
| CREATE TABLE payroll_records ( | |
| payroll_id TEXT PRIMARY KEY, | |
| entity_id TEXT, | |
| period_end TEXT, | |
| employee_count INTEGER, | |
| total_payroll REAL, | |
| FOREIGN KEY(entity_id) REFERENCES corporate_registry(entity_id) | |
| ); | |
| -- ββ Foreign-affiliation disclosure ββββββββββββββββββββββββββββββββββββββ | |
| CREATE TABLE foreign_affiliations ( | |
| entity_id TEXT PRIMARY KEY, | |
| foreign_parent_name TEXT, | |
| foreign_country TEXT, | |
| disclosure_status TEXT, | |
| FOREIGN KEY(entity_id) REFERENCES corporate_registry(entity_id) | |
| ); | |
| """ | |
| _ICD9_CODES = ["401.1", "428.0", "250.0", "414.0", "491.2", "311", "715.0"] | |
| _HCPCS_CODES = ["99213", "99214", "99215", "99203", "99204"] | |
| _STATES = ["CA", "TX", "NY", "FL", "IL", "PA", "OH", "GA", "NC", "MI"] | |
| _LEGIT_DRUGS = ["Lisinopril", "Atorvastatin", "Metformin", "Amlodipine", "Levothyroxine"] | |
| _SCRUTINIZED_DRUGS = ["OxyContin", "Subsys", "Suboxone", "Fentanyl", "Adderall"] | |
| _PHARMA_SHELLS = ["Apex Research Partners", "Helix Consulting Group", "Meridian Scientific LLC", | |
| "Solara Advisors", "Beacon Clinical Partners"] | |
| _FRAUD_DOCTORS = ["Dr. Aris Thorne", "Dr. Marcus Vale", "Dr. Celia Drake", "Dr. Julian Crane", | |
| "Dr. Helen Voss"] | |
| # Gov contracting / PPP / foreign affiliation references | |
| _AGENCIES = ["DoD", "VA", "GSA", "HHS", "DHS", "DoE"] | |
| _FRAUD_CONTRACTORS = ["Vanguard Logistics LLC", "Sentinel Defense Group", | |
| "Atlas Procurement Corp", "Polaris Industrial Inc", | |
| "Crestline Supply Co"] | |
| _PRODUCTS_EXPECTED = ["Kevlar Vest Plate", "Field Radio v3", "Ruggedised Laptop", | |
| "Surgical Tray Kit", "Backup Generator 5kW"] | |
| _PRODUCTS_SUBSTITUTED = ["Generic Vest Plate", "Discontinued Radio v1", | |
| "Refurbished Laptop", "Open Surgical Tray", | |
| "Used Generator 3kW"] | |
| _FOREIGN_PARENTS = [("Tianjin Holdings Group", "CN"), | |
| ("Volga Industrial OAO", "RU"), | |
| ("Caspian Trading FZE", "AE"), | |
| ("Pyongyang Heavy Industries", "KP"), | |
| ("Caracas Enterprises SA", "VE")] | |
| # CPT bundles where unbundling is the textbook fraud pattern. | |
| # The "bundle_code" should be billed instead of the components. | |
| _UNBUNDLING_PAIRS = [ | |
| ("80053", ["80048", "84520", "84443"]), # comprehensive metabolic panel | |
| ("80061", ["83718", "83721", "84478"]), # lipid panel | |
| ("99213", ["99202", "36415"]), # office visit + draw | |
| ] | |
| # Off-label marketing: drug β its FDA-approved indication ICD code(s). | |
| # Billing the drug for any other ICD is the off-label red flag. | |
| _OFFLABEL_DRUGS = { | |
| "Subsys": {"approved_icd": ["199.0", "199.1", "162.9"]}, # cancer pain | |
| "Suboxone": {"approved_icd": ["304.00", "304.10"]}, # opioid use disorder | |
| "OxyContin":{"approved_icd": ["199.0", "338.3"]}, # cancer / chronic pain | |
| } | |
| # ββ Public entry point βββββββββββββββββββββββββββββββββββββββββββββββββββββββ | |
| def generate_multimodal_aks_case( | |
| base_dir: Path | str, | |
| case_id: str, | |
| tier: int = 1, | |
| rng_seed: int | None = None, | |
| ) -> Path: | |
| """ | |
| Build one multi-modal fraud case under ``<base_dir>/<case_id>/``. | |
| Returns the case directory path. | |
| """ | |
| base_dir = Path(base_dir) | |
| case_dir = base_dir / case_id | |
| case_dir.mkdir(parents=True, exist_ok=True) | |
| db_path = case_dir / "medicare_records.db" | |
| if db_path.exists(): | |
| db_path.unlink() | |
| comms_dir = case_dir / "intercepted_comms" | |
| scans_dir = case_dir / "scanned_claims" | |
| comms_dir.mkdir(exist_ok=True) | |
| scans_dir.mkdir(exist_ok=True) | |
| # Deterministic seeding: combine the case_id with an optional seed so the | |
| # same (case_id, seed) pair always reproduces byte-for-byte. | |
| if rng_seed is None: | |
| digest = hashlib.sha256(case_id.encode("utf-8")).digest() | |
| rng_seed = int.from_bytes(digest[:8], "big") % (2**31) | |
| rng = random.Random(rng_seed) | |
| conn = sqlite3.connect(str(db_path)) | |
| cur = conn.cursor() | |
| cur.executescript(_SCHEMA_SQL) | |
| cur.execute("INSERT INTO case_metadata VALUES (?, ?)", ("tier", str(tier))) | |
| cur.execute("INSERT INTO case_metadata VALUES (?, ?)", ("seed", str(rng_seed))) | |
| cur.execute("INSERT INTO case_metadata VALUES (?, ?)", ("case_id", case_id)) | |
| corps, bens = _plant_background(cur, rng, tier) | |
| typologies = _plant_fraud(cur, rng, tier, corps, bens, comms_dir, scans_dir) | |
| cur.execute("INSERT INTO case_metadata VALUES (?, ?)", | |
| ("typologies", json.dumps(typologies))) | |
| conn.commit() | |
| conn.close() | |
| return case_dir | |
| # ββ Background (legitimate) data βββββββββββββββββββββββββββββββββββββββββββββ | |
| def _plant_background(cur, rng: random.Random, tier: int): | |
| n_legit_corps = 5 + tier * 3 | |
| n_bens = 20 + tier * 10 | |
| n_carrier = 80 + tier * 40 | |
| n_pde_providers = 12 + tier * 4 | |
| corps: list[tuple[str, str, str]] = [] | |
| for i in range(n_legit_corps): | |
| eid = f"E_L{i:03d}" | |
| name = (f"{rng.choice(['Legit','Professional','Mercy','Main Street','Harbor'])} " | |
| f"{rng.choice(['Medical','Health','Clinical','Wellness'])} " | |
| f"{rng.choice(['LLC','Corp','Inc','Ltd'])} {i}") | |
| state = rng.choice(_STATES) | |
| npi = generate_valid_npi(rng) | |
| cur.execute("INSERT INTO corporate_registry VALUES (?,?,?,?,?,?,?,?)", | |
| (eid, name, f"TX-{1000+i}", None, f"U_L{i:03d}", | |
| _rand_date(rng, "2010-01-01", "2023-12-31"), state, npi)) | |
| corps.append((eid, name, npi)) | |
| bens: list[tuple[str, str, str | None]] = [] | |
| for i in range(n_bens): | |
| bid = f"BENE_{i:04d}" | |
| dob = _rand_date(rng, "1940-01-01", "1960-12-31") | |
| dod = _rand_date(rng, "2024-01-01", "2026-04-01") if rng.random() < 0.10 else None | |
| cur.execute( | |
| "INSERT INTO beneficiary_summary " | |
| "(DESYNPUF_ID, BENE_BIRTH_DT, BENE_DEATH_DT, BENE_SEX_IDENT_CD, " | |
| " BENE_RACE_CD, SP_STATE_CODE) VALUES (?,?,?,?,?,?)", | |
| (bid, dob, dod, rng.choice(["1", "2"]), | |
| rng.choice(["1", "2", "3"]), rng.choice(_STATES)), | |
| ) | |
| bens.append((bid, dob, dod)) | |
| # Carrier claims (legitimate volume) | |
| for i in range(n_carrier): | |
| cid = f"C_L{i:05d}" | |
| bid, _, dod = rng.choice(bens) | |
| _, _, npi = rng.choice(corps) | |
| sdate = _rand_date(rng, "2024-01-01", "2026-03-01") | |
| if dod and sdate > dod: | |
| sdate = (datetime.strptime(dod, "%Y-%m-%d") | |
| - timedelta(days=rng.randint(5, 100))).strftime("%Y-%m-%d") | |
| amt = _benford_amount(rng, 80, 1500) | |
| cur.execute("INSERT INTO carrier_claims VALUES (?,?,?,?,?,?,?,?,?)", | |
| (cid, bid, sdate, sdate, npi, "TX-P", | |
| rng.choice(_HCPCS_CODES), amt, rng.choice(_ICD9_CODES))) | |
| # PDE background noise β many providers, few scripts each, common drugs. | |
| legit_prescriber_npis = [generate_valid_npi(rng) for _ in range(n_pde_providers)] | |
| pde_counter = 0 | |
| for npi in legit_prescriber_npis: | |
| for _ in range(rng.randint(5, 15)): | |
| pde_id = f"PDE_L{pde_counter:06d}" | |
| pde_counter += 1 | |
| bid, _, _ = rng.choice(bens) | |
| cur.execute("INSERT INTO prescription_drug_events VALUES (?,?,?,?,?,?,?,?,?,?)", | |
| (pde_id, bid, npi, | |
| _rand_date(rng, "2025-01-01", "2025-12-31"), | |
| f"NDC-{rng.randint(10000,99999)}", | |
| rng.choice(_LEGIT_DRUGS), | |
| rng.randint(30, 90), rng.randint(30, 90), | |
| round(rng.uniform(2.0, 15.0), 2), | |
| round(rng.uniform(10.0, 60.0), 2))) | |
| return corps, bens | |
| # ββ Fraud planting βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ | |
| def _emit_pdf( | |
| cur, | |
| scans_dir: Path, | |
| tier: int, | |
| rng: random.Random, | |
| ev: ClaimEvidence, | |
| ) -> str: | |
| """Render the CMS-1500 and log to evidence_documents. Returns pdf path.""" | |
| pdf_path = scans_dir / f"{ev.claim_id}.pdf" | |
| expected = render_claim_pdf(pdf_path, ev, tier=tier, rng=rng) | |
| # Store a path relative to the case directory so the agent (whose CWD is | |
| # the sandbox'd case dir) can open it with a stable string. | |
| rel_path = str(pdf_path.relative_to(scans_dir.parent)).replace(os.sep, "/") | |
| cur.execute( | |
| "INSERT INTO evidence_documents VALUES (?,?,?,?,?,?)", | |
| (f"DOC_{ev.claim_id}", ev.claim_id, rel_path, tier, 1, | |
| json.dumps(expected)), | |
| ) | |
| return rel_path | |
| def _plant_fraud( | |
| cur, | |
| rng: random.Random, | |
| tier: int, | |
| corps: list[tuple[str, str, str]], | |
| bens: list[tuple[str, str, str | None]], | |
| comms_dir: Path, | |
| scans_dir: Path, | |
| ) -> list[str]: | |
| typologies: list[str] = [] | |
| # ββ 1. Shell-company chain (tier-scaled depth) ββββββββββββββββββββββββββ | |
| fraud_ubo_id = f"U_FRAUD_{rng.randint(1000, 9999)}" | |
| shell_depth = max(2, min(tier + 1, 5)) # tier 1 β 2 shells, tier 5 β 5 shells | |
| shell_names: list[str] = [] | |
| prior_eid: str | None = None | |
| fraud_entity_npi: str | None = None | |
| for layer in range(shell_depth): | |
| eid = f"E_FRAUD_{layer}" | |
| name = (f"{rng.choice(['Shadow','Phantom','Ghost','Dark','Apex','Helix'])} " | |
| f"{rng.choice(['Operations','Medical','Consulting','Research','Advisors'])} " | |
| f"{'LLC' if layer < shell_depth - 1 else 'Corp'}") | |
| state = rng.choice(_STATES) | |
| is_terminal = layer == shell_depth - 1 | |
| npi = generate_valid_npi(rng) if is_terminal else None | |
| if is_terminal: | |
| fraud_entity_npi = npi | |
| cur.execute("INSERT INTO corporate_registry VALUES (?,?,?,?,?,?,?,?)", | |
| (eid, name, f"TX-F{layer}", prior_eid, fraud_ubo_id, | |
| _rand_date(rng, "2020-01-01", "2023-01-01"), state, npi)) | |
| cur.execute("INSERT INTO ground_truth VALUES (?,?)", | |
| ("entity", json.dumps({"name": name, "kind": "corporation"}))) | |
| if prior_eid is not None: | |
| cur.execute("INSERT INTO ground_truth VALUES (?,?)", | |
| ("shell_link", json.dumps( | |
| {"child": name, "parent": shell_names[-1]}))) | |
| shell_names.append(name) | |
| prior_eid = eid | |
| # ββ 2. Fraud provider (the doctor) ββββββββββββββββββββββββββββββββββββββ | |
| fraud_prov_name = rng.choice(_FRAUD_DOCTORS) | |
| fraud_npi = generate_valid_npi(rng) | |
| cur.execute("INSERT INTO ground_truth VALUES (?,?)", | |
| ("entity", json.dumps( | |
| {"name": fraud_prov_name, "kind": "provider", "npi": fraud_npi}))) | |
| # Also record the doctor in corporate_registry so CaseHandle.all_entity_names() | |
| # returns them and the CoT-grounding check can recognise the name. | |
| cur.execute("INSERT INTO corporate_registry VALUES (?,?,?,?,?,?,?,?)", | |
| (f"E_PROV_FRAUD", fraud_prov_name, "TX-PROV", None, f"U_P_FRAUD", | |
| _rand_date(rng, "2018-01-01", "2022-01-01"), | |
| rng.choice(_STATES), fraud_npi)) | |
| # ββ 3. AKS kickback: PDE spike + smoking gun email + referral payment ββ | |
| shell_company = shell_names[-1] # deepest shell is the "pharma front" | |
| target_drug = rng.choice(_SCRUTINIZED_DRUGS) | |
| anomalous_scripts = 150 + tier * 50 | |
| grant_amount = 25000.0 + tier * 5000.0 | |
| planted_pde_ids: list[str] = [] | |
| for i in range(anomalous_scripts): | |
| pde_id = f"PDE_FRAUD_{i:06d}" | |
| planted_pde_ids.append(pde_id) | |
| bid, _, _ = rng.choice(bens) | |
| cur.execute("INSERT INTO prescription_drug_events VALUES (?,?,?,?,?,?,?,?,?,?)", | |
| (pde_id, bid, fraud_npi, | |
| _rand_date(rng, "2025-02-01", "2025-11-30"), | |
| f"NDC-{rng.randint(10000,99999)}", | |
| target_drug, rng.randint(30, 120), rng.randint(30, 120), | |
| round(rng.uniform(50.0, 150.0), 2), | |
| round(rng.uniform(500.0, 1200.0), 2))) | |
| # Ledger + referral payment trail for the "research grant" | |
| payment_date = _rand_date(rng, "2025-01-05", "2025-01-30") | |
| tx_id = f"TX_KICKBACK_{rng.randint(100000, 999999)}" | |
| cur.execute("INSERT INTO general_ledger VALUES (?,?,?,?,?,?,?)", | |
| (tx_id, payment_date, "Consulting Expense", "Cash", | |
| grant_amount, f"Research grant to {fraud_prov_name}", | |
| f"E_FRAUD_{shell_depth - 1}")) | |
| cur.execute("INSERT INTO referral_payments VALUES (?,?,?,?,?,?)", | |
| (f"RP_{rng.randint(100000,999999)}", | |
| fraud_entity_npi or "UNKNOWN", fraud_npi, grant_amount, | |
| payment_date, "speaker_fee / research_grant")) | |
| # Benign email haystack + smoking gun (OCR-noised NPI) | |
| smoking_gun_idx = rng.randint(10, 40) | |
| for i in range(50): | |
| fp = comms_dir / f"email_{i:02d}.txt" | |
| if i == smoking_gun_idx: | |
| noisy_npi = _inject_ocr_noise(fraud_npi, rng, n_errors=2) | |
| body = ( | |
| "CONFIDENTIAL β DO NOT FORWARD\n" | |
| f"To: {shell_company} Disbursals\n" | |
| f"From: Regional VP of Sales\n" | |
| f"Date: {payment_date}\n\n" | |
| f"Authorize 'Research Grant' payment of ${grant_amount:,.0f} " | |
| f"to {fraud_prov_name}.\n" | |
| f"Since the payment cleared last month, his {target_drug} " | |
| "script volume is up 400%.\n" | |
| "Make sure the paperwork looks like a legitimate consulting fee.\n\n" | |
| f"Provider Identifier for records: NPl {noisy_npi}\n" | |
| ) | |
| fp.write_text(body, encoding="utf-8") | |
| else: | |
| fp.write_text( | |
| f"Subject: Weekly update\n\n" | |
| f"Nothing to report for week {i}. Regards, Compliance.\n", | |
| encoding="utf-8", | |
| ) | |
| smoking_gun_path = f"intercepted_comms/email_{smoking_gun_idx:02d}.txt" | |
| # Also emit a degraded CMS-1500 PDF for one of the fraudulent PDE claims, | |
| # so the agent has a multi-modal thread (PDE β PDF claim β email). | |
| # Pick any beneficiary β tie the PDF to a synthetic carrier_claim so the | |
| # evidence_documents FK resolves. | |
| pdf_bid, pdf_dob, _ = rng.choice(bens) | |
| pdf_cid = "C_FRAUD_AKS_PDF" | |
| pdf_service_date = _rand_date(rng, "2025-03-01", "2025-10-01") | |
| pdf_amount = round(rng.uniform(500.0, 1200.0), 2) | |
| cur.execute("INSERT INTO carrier_claims VALUES (?,?,?,?,?,?,?,?,?)", | |
| (pdf_cid, pdf_bid, pdf_service_date, pdf_service_date, fraud_npi, | |
| "TX-F", "J0171", pdf_amount, "401.9")) | |
| pdf_rel = _emit_pdf(cur, scans_dir, tier, rng, ClaimEvidence( | |
| claim_id=pdf_cid, beneficiary_id=pdf_bid, beneficiary_dob=pdf_dob, | |
| beneficiary_dod=None, provider_name=fraud_prov_name, provider_npi=fraud_npi, | |
| service_date=pdf_service_date, hcpcs_code="J0171", icd9_code="401.9", | |
| amount=pdf_amount, diagnosis_text="Chronic pain management follow-up", | |
| )) | |
| # Ground truth: AKS contradiction + rich payload so the grader can verify | |
| # either the email or the PDE spike as primary evidence. | |
| cur.execute("INSERT INTO ground_truth VALUES (?,?)", | |
| ("contradiction", json.dumps({ | |
| "evidence_a": smoking_gun_path, | |
| "evidence_b": f"provider_npi:{fraud_npi}", | |
| "kind": "aks_violation", | |
| "fraud_npi": fraud_npi, | |
| "shell_company": shell_company, | |
| "target_drug": target_drug, | |
| "pdf_evidence": pdf_rel, | |
| "grant_amount": grant_amount, | |
| }))) | |
| typologies.append("aks_violation") | |
| # ββ 4. Dead patient claim βββββββββββββββββββββββββββββββββββββββββββββββ | |
| dead_bens = [b for b in bens if b[2] is not None] | |
| if dead_bens: | |
| bid, dob, dod = dead_bens[0] | |
| bad_date = (datetime.strptime(dod, "%Y-%m-%d") | |
| + timedelta(days=rng.randint(20, 60))).strftime("%Y-%m-%d") | |
| cid = "C_FRAUD_DEAD" | |
| cur.execute("INSERT INTO carrier_claims VALUES (?,?,?,?,?,?,?,?,?)", | |
| (cid, bid, bad_date, bad_date, fraud_npi, "TX-F", | |
| "99215", 350.0, "428.0")) | |
| cur.execute("INSERT INTO ground_truth VALUES (?,?)", | |
| ("contradiction", json.dumps({ | |
| "evidence_a": f"beneficiary:{bid}", | |
| "evidence_b": f"claim:{cid}", | |
| "kind": "dead_patient_claim"}))) | |
| _emit_pdf(cur, scans_dir, tier, rng, ClaimEvidence( | |
| claim_id=cid, beneficiary_id=bid, beneficiary_dob=dob, | |
| beneficiary_dod=dod, provider_name=fraud_prov_name, | |
| provider_npi=fraud_npi, service_date=bad_date, | |
| hcpcs_code="99215", icd9_code="428.0", amount=350.0, | |
| diagnosis_text="Congestive heart failure β follow-up", | |
| )) | |
| typologies.append("dead_patient_claim") | |
| # ββ 5. Duplicate billing ββββββββββββββββββββββββββββββββββββββββββββββββ | |
| bid_dup, dob_dup, _ = bens[0] | |
| dup_date = "2025-10-10" | |
| for suffix in ["A", "B"]: | |
| cid = f"C_FRAUD_DUP_{suffix}" | |
| cur.execute("INSERT INTO carrier_claims VALUES (?,?,?,?,?,?,?,?,?)", | |
| (cid, bid_dup, dup_date, dup_date, fraud_npi, "TX-F", | |
| "99214", 200.0, "401.1")) | |
| _emit_pdf(cur, scans_dir, tier, rng, ClaimEvidence( | |
| claim_id=cid, beneficiary_id=bid_dup, beneficiary_dob=dob_dup, | |
| beneficiary_dod=None, provider_name=fraud_prov_name, | |
| provider_npi=fraud_npi, service_date=dup_date, | |
| hcpcs_code="99214", icd9_code="401.1", amount=200.0, | |
| diagnosis_text="Essential hypertension, unspecified", | |
| )) | |
| cur.execute("INSERT INTO ground_truth VALUES (?,?)", | |
| ("contradiction", json.dumps({ | |
| "evidence_a": "claim:C_FRAUD_DUP_A", | |
| "evidence_b": "claim:C_FRAUD_DUP_B", | |
| "kind": "duplicate_bill"}))) | |
| typologies.append("duplicate_bill") | |
| # ββ 6. Upcoding (tier β₯ 2) β PDF narrative contradicts HCPCS ββββββββββββ | |
| if tier >= 2 and len(bens) > 1: | |
| bid_up, dob_up, _ = bens[1] | |
| cid = "C_FRAUD_UPCODE" | |
| cur.execute("INSERT INTO carrier_claims VALUES (?,?,?,?,?,?,?,?,?)", | |
| (cid, bid_up, "2025-12-01", "2025-12-01", fraud_npi, "TX-F", | |
| "99215", 850.0, "401.1")) | |
| cur.execute("INSERT INTO ground_truth VALUES (?,?)", | |
| ("contradiction", json.dumps({ | |
| "evidence_a": f"claim:{cid}", | |
| "evidence_b": f"provider_npi:{fraud_npi}", | |
| "kind": "upcoding"}))) | |
| _emit_pdf(cur, scans_dir, tier, rng, ClaimEvidence( | |
| claim_id=cid, beneficiary_id=bid_up, beneficiary_dob=dob_up, | |
| beneficiary_dod=None, provider_name=fraud_prov_name, | |
| provider_npi=fraud_npi, service_date="2025-12-01", | |
| hcpcs_code="99215", icd9_code="401.1", amount=850.0, | |
| diagnosis_text="Routine BP check. No acute issues. Patient stable.", | |
| )) | |
| typologies.append("upcoding") | |
| # ββ Tier-gated additional typologies ββββββββββββββββββββββββββββββββββββ | |
| if tier >= 2: | |
| _plant_unbundling(cur, rng, bens, fraud_npi, typologies) | |
| if tier >= 3: | |
| _plant_phantom_beneficiary(cur, rng, bens, fraud_npi, typologies) | |
| _plant_off_label_marketing(cur, rng, bens, fraud_npi, typologies) | |
| if tier >= 4: | |
| contractor_a = _plant_double_billing(cur, rng, typologies) | |
| contractor_b = _plant_cost_pricing_fraud(cur, rng, typologies) | |
| if tier >= 5: | |
| contractor_c = _plant_product_substitution(cur, rng, typologies) | |
| contractor_d = _plant_ppp_fraud(cur, rng, typologies) | |
| # Foreign affiliation attaches to one of the gov-contracting fraud entities, | |
| # so the agent has to cross domains to discover it. | |
| _plant_foreign_affiliation(cur, rng, contractor_d, typologies) | |
| return typologies | |
| # ββ Per-typology helpers (tier 2+) ββββββββββββββββββββββββββββββββββββββββββββ | |
| def _register_contractor(cur, rng: random.Random, role: str) -> tuple[str, str]: | |
| """Register a fraud contractor in corporate_registry. Returns (entity_id, name).""" | |
| eid = f"E_FRAUD_CONTRACT_{role}_{rng.randint(1000, 9999)}" | |
| name = rng.choice(_FRAUD_CONTRACTORS) + f" #{rng.randint(10, 99)}" | |
| state = rng.choice(_STATES) | |
| cur.execute("INSERT INTO corporate_registry VALUES (?,?,?,?,?,?,?,?)", | |
| (eid, name, f"TX-CTR-{role}", None, f"U_CTR_{role}", | |
| _rand_date(rng, "2015-01-01", "2022-12-31"), state, None)) | |
| cur.execute("INSERT INTO ground_truth VALUES (?,?)", | |
| ("entity", json.dumps({"name": name, "kind": "contractor"}))) | |
| return eid, name | |
| def _plant_unbundling(cur, rng, bens, fraud_npi: str, typologies: list[str]) -> None: | |
| """Bundle that should have been billed as one code is split into components.""" | |
| bundle_code, components = rng.choice(_UNBUNDLING_PAIRS) | |
| bid, _, _ = rng.choice(bens) | |
| sdate = "2025-09-12" | |
| component_cids: list[str] = [] | |
| for i, comp in enumerate(components): | |
| cid = f"C_FRAUD_UNBUND_{i}" | |
| component_cids.append(cid) | |
| cur.execute("INSERT INTO carrier_claims VALUES (?,?,?,?,?,?,?,?,?)", | |
| (cid, bid, sdate, sdate, fraud_npi, "TX-F", | |
| comp, _benford_amount(rng, 60, 200), "401.1")) | |
| cur.execute("INSERT INTO ground_truth VALUES (?,?)", | |
| ("contradiction", json.dumps({ | |
| "evidence_a": f"claim:{component_cids[0]}", | |
| "evidence_b": f"claim:{component_cids[-1]}", | |
| "kind": "unbundling", | |
| "bundle_code": bundle_code, | |
| "components": components, | |
| }))) | |
| typologies.append("unbundling") | |
| def _plant_phantom_beneficiary(cur, rng, bens, fraud_npi: str, | |
| typologies: list[str]) -> None: | |
| """Claim filed for a beneficiary_id that does not exist in beneficiary_summary.""" | |
| phantom_bid = f"BENE_PHANTOM_{rng.randint(10000, 99999)}" | |
| cid = "C_FRAUD_PHANTOM" | |
| sdate = _rand_date(rng, "2025-04-01", "2025-11-30") | |
| cur.execute("INSERT INTO carrier_claims VALUES (?,?,?,?,?,?,?,?,?)", | |
| (cid, phantom_bid, sdate, sdate, fraud_npi, "TX-F", | |
| "99214", _benford_amount(rng, 200, 600), "250.0")) | |
| cur.execute("INSERT INTO ground_truth VALUES (?,?)", | |
| ("contradiction", json.dumps({ | |
| "evidence_a": f"claim:{cid}", | |
| "evidence_b": f"beneficiary:{phantom_bid}", | |
| "kind": "phantom_beneficiary", | |
| "phantom_bid": phantom_bid, | |
| }))) | |
| typologies.append("phantom_beneficiary") | |
| def _plant_off_label_marketing(cur, rng, bens, fraud_npi: str, | |
| typologies: list[str]) -> None: | |
| """Drug prescribed for a diagnosis outside its FDA-approved indication.""" | |
| drug = rng.choice(list(_OFFLABEL_DRUGS.keys())) | |
| approved = set(_OFFLABEL_DRUGS[drug]["approved_icd"]) | |
| off_label_icd = next((c for c in _ICD9_CODES if c not in approved), "401.1") | |
| bid, _, _ = rng.choice(bens) | |
| sdate = _rand_date(rng, "2025-05-01", "2025-11-30") | |
| pde_id = f"PDE_FRAUD_OFFLABEL_{rng.randint(10000, 99999)}" | |
| cur.execute("INSERT INTO prescription_drug_events VALUES (?,?,?,?,?,?,?,?,?,?)", | |
| (pde_id, bid, fraud_npi, sdate, | |
| f"NDC-{rng.randint(10000, 99999)}", drug, | |
| rng.randint(30, 90), rng.randint(30, 90), | |
| round(rng.uniform(50.0, 200.0), 2), | |
| round(rng.uniform(800.0, 2000.0), 2))) | |
| cid = "C_FRAUD_OFFLABEL" | |
| cur.execute("INSERT INTO carrier_claims VALUES (?,?,?,?,?,?,?,?,?)", | |
| (cid, bid, sdate, sdate, fraud_npi, "TX-F", | |
| "99214", _benford_amount(rng, 100, 400), off_label_icd)) | |
| cur.execute("INSERT INTO ground_truth VALUES (?,?)", | |
| ("contradiction", json.dumps({ | |
| "evidence_a": f"pde:{pde_id}", | |
| "evidence_b": f"claim:{cid}", | |
| "kind": "off_label_marketing", | |
| "drug": drug, | |
| "approved_icd": list(approved), | |
| "billed_icd": off_label_icd, | |
| }))) | |
| typologies.append("off_label_marketing") | |
| def _plant_double_billing(cur, rng, typologies: list[str]) -> str: | |
| """Same line-item invoiced twice against one government contract.""" | |
| eid, _ = _register_contractor(cur, rng, "DBL") | |
| contract_id = f"CTR_DBL_{rng.randint(1000, 9999)}" | |
| line = "Helmet liner, qty 50" | |
| amt = round(rng.uniform(15000, 40000), 2) | |
| cur.execute("INSERT INTO government_contracts VALUES (?,?,?,?,?,?,?,?)", | |
| (contract_id, rng.choice(_AGENCIES), eid, amt * 2, | |
| _rand_date(rng, "2024-06-01", "2024-12-31"), | |
| "Helmet liner", round(amt / 50, 2), round(amt / 50, 2))) | |
| inv_a = f"INV_{contract_id}_A" | |
| inv_b = f"INV_{contract_id}_B" | |
| same_date = _rand_date(rng, "2025-01-15", "2025-03-15") | |
| cur.execute("INSERT INTO contract_invoices VALUES (?,?,?,?,?)", | |
| (inv_a, contract_id, line, amt, same_date)) | |
| cur.execute("INSERT INTO contract_invoices VALUES (?,?,?,?,?)", | |
| (inv_b, contract_id, line, amt, same_date)) | |
| cur.execute("INSERT INTO ground_truth VALUES (?,?)", | |
| ("contradiction", json.dumps({ | |
| "evidence_a": f"invoice:{inv_a}", | |
| "evidence_b": f"invoice:{inv_b}", | |
| "kind": "double_billing", | |
| "contract_id": contract_id, | |
| }))) | |
| typologies.append("double_billing") | |
| return eid | |
| def _plant_cost_pricing_fraud(cur, rng, typologies: list[str]) -> str: | |
| """Disclosed unit price >> actual unit cost on a cost-plus government contract.""" | |
| eid, _ = _register_contractor(cur, rng, "CPF") | |
| contract_id = f"CTR_CPF_{rng.randint(1000, 9999)}" | |
| actual_cost = round(rng.uniform(50, 200), 2) | |
| disclosed = round(actual_cost * rng.uniform(2.5, 4.5), 2) # gross markup | |
| cur.execute("INSERT INTO government_contracts VALUES (?,?,?,?,?,?,?,?)", | |
| (contract_id, rng.choice(_AGENCIES), eid, | |
| disclosed * rng.randint(500, 2000), | |
| _rand_date(rng, "2024-03-01", "2024-09-30"), | |
| "Field maintenance kit", disclosed, actual_cost)) | |
| cur.execute("INSERT INTO ground_truth VALUES (?,?)", | |
| ("contradiction", json.dumps({ | |
| "evidence_a": f"contract:{contract_id}:disclosed_unit_price", | |
| "evidence_b": f"contract:{contract_id}:actual_unit_cost", | |
| "kind": "cost_pricing_fraud", | |
| "contract_id": contract_id, | |
| "markup": round(disclosed / max(actual_cost, 0.01), 2), | |
| }))) | |
| typologies.append("cost_pricing_fraud") | |
| return eid | |
| def _plant_product_substitution(cur, rng, typologies: list[str]) -> str: | |
| """Delivered product differs from the one specified in the contract.""" | |
| eid, _ = _register_contractor(cur, rng, "SUB") | |
| contract_id = f"CTR_SUB_{rng.randint(1000, 9999)}" | |
| expected = rng.choice(_PRODUCTS_EXPECTED) | |
| substituted = rng.choice(_PRODUCTS_SUBSTITUTED) | |
| cur.execute("INSERT INTO government_contracts VALUES (?,?,?,?,?,?,?,?)", | |
| (contract_id, rng.choice(_AGENCIES), eid, | |
| round(rng.uniform(200000, 800000), 2), | |
| _rand_date(rng, "2024-02-01", "2024-08-31"), | |
| expected, round(rng.uniform(800, 1500), 2), | |
| round(rng.uniform(200, 600), 2))) | |
| delivery_id = f"DLV_{contract_id}" | |
| cur.execute("INSERT INTO contract_deliveries VALUES (?,?,?,?)", | |
| (delivery_id, contract_id, substituted, | |
| _rand_date(rng, "2024-09-01", "2025-02-28"))) | |
| cur.execute("INSERT INTO ground_truth VALUES (?,?)", | |
| ("contradiction", json.dumps({ | |
| "evidence_a": f"contract:{contract_id}:expected_product", | |
| "evidence_b": f"delivery:{delivery_id}:delivered_product", | |
| "kind": "product_substitution", | |
| "expected": expected, | |
| "delivered": substituted, | |
| }))) | |
| typologies.append("product_substitution") | |
| return eid | |
| def _plant_ppp_fraud(cur, rng, typologies: list[str]) -> str: | |
| """PPP loan claims an employee count well above what payroll records show.""" | |
| eid, _ = _register_contractor(cur, rng, "PPP") | |
| loan_id = f"PPP_{rng.randint(100000, 999999)}" | |
| real_employees = rng.randint(3, 15) | |
| claimed = real_employees + rng.randint(40, 120) | |
| claimed_payroll = claimed * rng.uniform(4500, 7000) | |
| loan_amt = round(claimed_payroll * 2.5, 2) | |
| app_date = _rand_date(rng, "2020-04-15", "2021-05-31") | |
| cur.execute("INSERT INTO loan_applications VALUES (?,?,?,?,?,?,?)", | |
| (loan_id, eid, "PPP", claimed, round(claimed_payroll, 2), | |
| loan_amt, app_date)) | |
| # Plant 3 quarters of payroll records that contradict the claimed count. | |
| for q in range(3): | |
| period_end = _rand_date(rng, "2020-03-31", "2021-09-30") | |
| cur.execute("INSERT INTO payroll_records VALUES (?,?,?,?,?)", | |
| (f"PAY_{loan_id}_{q}", eid, period_end, real_employees, | |
| round(real_employees * rng.uniform(4500, 7000), 2))) | |
| cur.execute("INSERT INTO ground_truth VALUES (?,?)", | |
| ("contradiction", json.dumps({ | |
| "evidence_a": f"loan:{loan_id}", | |
| "evidence_b": f"payroll:{eid}", | |
| "kind": "ppp_fraud", | |
| "claimed_employees": claimed, | |
| "actual_employees": real_employees, | |
| }))) | |
| typologies.append("ppp_fraud") | |
| return eid | |
| def _plant_foreign_affiliation(cur, rng, contractor_eid: str, | |
| typologies: list[str]) -> None: | |
| """Undisclosed foreign parent for a domestic vendor.""" | |
| foreign_parent, country = rng.choice(_FOREIGN_PARENTS) | |
| cur.execute("INSERT INTO foreign_affiliations VALUES (?,?,?,?)", | |
| (contractor_eid, foreign_parent, country, "undisclosed")) | |
| cur.execute("INSERT INTO ground_truth VALUES (?,?)", | |
| ("contradiction", json.dumps({ | |
| "evidence_a": f"entity:{contractor_eid}", | |
| "evidence_b": f"foreign_parent:{foreign_parent}", | |
| "kind": "foreign_affiliation", | |
| "country": country, | |
| }))) | |
| typologies.append("foreign_affiliation") | |
| # ββ CLI removed ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ | |
| # The case-bank generator CLI lives in `data_gen/build_case_bank.py`. | |
| # This module exposes only `generate_multimodal_aks_case()` for programmatic use | |
| # (the environment imports it directly for on-the-fly fallback generation). | |