ADR-0060: NaturalPerson AMLR fields — plural nationality, PEP classification/RCA, place_of_birth
Status: Accepted Date: 2026-06-16 Supersedes: none Superseded by: none Deciders: Adrian (Soft4U), Claude Opus 4.8
Decision context:
- Latency: none (model fields) + one additive migration (add 2 columns + backfill on investigation_persons).
- Dependency surface: no new packages. Touches the canonical person model, the InvestigationPerson ORM, migration 064, and the goAML mapper/xml_builder (backend + compliance-package copies).
- Debuggability: legacy
nationality/is_pepare kept and synced via validators, so existing readers are unaffected; the new fields are explicit and typed. - Reversibility: branch revert +
alembic downgrade -1(drops the 2 added columns). Models additive. - Blast radius: additive across ~12 files; the back-compat sync keeps
.nationality/.is_pepconsumers working untouched. - Alternative considered: drop the singular fields and migrate all readers (rejected — high churn/risk; synced legacy fields are zero-risk and removable later).
Context
Three structural defects in the operative person model: singular nationality (AMLR requires plural —
multiple nationalities are risk-relevant); boolean PEP (cannot represent RCA — relatives & close
associates, AMLR Art. 17); and missing place_of_birth (AMLR-new mandatory, hardcoded None in the
goAML mapper). These are structural choices configuration cannot fix, independent of the still-draft
field-level RTS (Art. 28(1)).
Decision
Additive change with back-compat sync:
PepStatus:PepClassificationenum (not_pep/pep/rca) +rca_of; legacyis_pepkept and synced (a validator resolves toward the stronger PEP signal — never suppresses a PEP).PersonSchema:nationalities: list[str]+place_of_birth; legacynationalitykept, synced tonationalities[0].- ORM
InvestigationPerson+ migration 064:nationalitiesJSONB (backfilled from the singular column) +place_of_birth; legacynationalitycolumn retained; PEP classification lives in the existingpep_statusJSONB (no column change). - goAML:
birth_place←place_of_birth(no longer hardcodedNone); all threenationality1/2/3carried per the goAML 5.0.2 XSD (model→IR→XML, both backend + compliance copies, XSD sequence order); RCA classification ⇒is_peptrue.
Consequences
Positive
- Multi-nationality, RCA, and place_of_birth are representable end-to-end and flow into goAML filings.
- Back-compat sync keeps every existing
.nationality/.is_pepreader working with zero churn.
Negative
- A second nationality representation (singular kept, synced) until a future cleanup drops it; one migration. PEP enum stored in the existing JSONB.
Neutral
IndividualProfile.additional_nationalities(KYC persona) is a separate model, untouched.
Alternatives Considered
Alternative 1: Drop nationality/is_pep outright and migrate all consumers
Rejected — 10+ .nationality and 6 .is_pep consumers; high churn and regression risk. Synced legacy
fields are zero-risk and can be removed in a later dedicated cleanup.
Alternative 2: Carry only the primary nationality into goAML (nationality1)
Rejected — the goAML 5.0.2 XSD defines nationality1/2/3; truncating to one would drop a dual-national
UBO's nationality from the FIU filing. The IR + mapper + xml_builder were extended to carry all three.