How to stand up a GENIUS Act PPSI compliance program¶
When you need this: You operate (or are building) a permitted payment stablecoin issuer (PPSI) and need an AML/CFT + OFAC sanctions program grounded in the joint FinCEN/OFAC NPRM — Permitted Payment Stablecoin Issuer AML/CFT Program and Sanctions Compliance (Federal Register 2026-06963, published 2026-04-10; comment deadline 9 June 2026). This recipe walks the richer NPRM-grounded
genius_ppsi_stablecoinexample end to end.Prereqs: A working install (
pip install -e ".[dev,dashboard]"). The example spec is bundled atexamples/genius_ppsi_stablecoin/aml.yaml. No external data needed — it runs on the deterministic synthetic generator.Time: ~10 min.
Governance up front: a PPSI is a BSA financial institution with its OWN, PPSI-specific obligations. The GENIUS Act PPSI NPRM (1) stands up a new dedicated OFAC sanctions program at 31 CFR Part 502, (2) EXCLUDES PPSIs from the MSB definition and proposes a PPSI-specific AML/CFT program under GENIUS Act s.4 (so the SAR/program rules cite GENIUS Act s.4 / the NPRM, not the 31 CFR 1022 MSB rules), with SARs filed on suspicious activity, (3) PROPOSES a PPSI-specific currency-transaction report (proposed 31 CFR 1033.310-315, cross-referencing the $10,000 aggregate-day threshold of 31 CFR 1010.311 — a proposed obligation, comment deadline 9 June 2026, modelled as the FINCEN_CTR form), and (4) carries the FATF Travel Rule (Recommendation 16) on cross-border stablecoin transfers. Every rule in the spec maps to one of those obligations and every citation resolves via the regwatch citation map.
Steps¶
1 · Validate the spec¶
aml validate examples/genius_ppsi_stablecoin/aml.yaml
# → OK ... 2 contract(s), 6 rule(s), 3 queue(s).
Two-layer validation runs: JSON Schema (structure) then Pydantic (cross-reference integrity — every rule's escalate_to resolves to a declared queue, every source to a declared contract).
2 · Run the engine at seed 42¶
On the canonical synthetic dataset this fires alerts across the stablecoin typologies (mixing/layering, rapid on-ramp/off-ramp cycling, structuring below the reporting threshold, OFAC SDN screening, adverse media). The vasp_counterparty_exposure rule needs KP/IR/MM counterparty rows to fire — it stays quiet on the default synthetic data, which is the realistic no-false-positive case.
3 · Read the rules¶
| Rule | Logic | Cites |
|---|---|---|
stablecoin_mixing_layering |
custom_sql — fan-in + fan-out churn in a recent 7-day window (≥70% pass-through, both legs ≥$15k) |
GENIUS Act PPSI NPRM (FR 2026-06963), FIN-2019-G001 |
rapid_onramp_offramp_cycling |
custom_sql — mint + redeem in a recent 7-day window, combined ≥$30k |
GENIUS Act s.4, FIN-2019-G001 |
structuring_below_ctr_threshold |
aggregation_window — $5k–$9,999 deposits, ≥3 in 30d, ≥$20k |
GENIUS Act s.4, 31 CFR 1033.310 |
vasp_counterparty_exposure |
custom_sql — outbound stablecoin/wire to KP/IR/MM ≥$5k |
FATF High-Risk Jurisdictions, FATF Recommendation 16 |
ofac_sdn_screening |
list_match (fuzzy 0.85) vs OFAC SDN |
31 CFR Part 502, OFAC SDN — virtual currency addenda |
adverse_media_screening |
list_match (fuzzy 0.85) vs adverse media |
GENIUS Act s.4, FIN-2019-G001 |
4 · Wire the OFAC SDN list¶
The ofac_sdn_screening rule reads the sanctions watchlist. Point it at your real OFAC SDN export (including the virtual-currency-address addenda) at deploy time — the bundled example uses a small demonstrative watchlist so the rule fires on synthetic data. A match obligates an immediate freeze, blocking report, and SAR under 31 CFR Part 502.
5 · Review the SLA + filing forms¶
The spec declares a program.sla block (alert_disposition_days: 30) — the engine records any open-alert-age or batch-lateness breach in sla_report.json (it never raises). Filing forms are FINCEN_SAR and FINCEN_CTR — the latter models the proposed PPSI currency-transaction report (proposed 31 CFR 1033.310-315, ≥$10,000 aggregate-day trigger), distinct from the generic cash CTR. Open the dashboard to inspect:
Verify it worked¶
aml run prints a per-rule alert table and a metrics table; a non-zero total alert count confirms the program is detecting. Cross-check the citations resolve:
python -c "from aml_framework.compliance.regwatch import citation_url; print(citation_url('31 CFR Part 502'))"
Common problems¶
| Symptom | Cause | Fix |
|---|---|---|
ofac_sdn_screening fires 0 alerts |
Your watchlist has no fuzzy match ≥0.85 against any customer name | Confirm the sanctions list is loaded; lower the threshold only with sign-off |
vasp_counterparty_exposure fires 0 |
No KP/IR/MM counterparty_country rows in the data |
Expected on default synthetic data — it fires on real cross-border flows |
| Citation does not resolve | Citation string not in the regwatch map | Use only citation strings present in CITATION_URL_MAP |
Next steps¶
- Add a new detection rule — extend the PPSI typology coverage.
- Configure SLA monitoring — tune the
program.slablock. - Jurisdiction policies — how the PPSI spec compares to the other US/FinCEN specs.