ADR-0099: Active adverse-media re-screen in continuous monitoring
Date: 2026-07-06 Status: Accepted Deciders: Adrian (Soft4U), Claude Opus 4.8
Decision context:
- Latency: one adverse-media agent call per due, monitored case per cadence window — real external API spend, so gated behind a default-off flag + the existing risk cadence (EDD 90d / CDD 180d / SDD 365d). Not on any request path (the scheduled
ContinuousMonitoringWorkflow). Not-due and flag-off are both zero-cost no-ops. - Dependency surface: no new packages. Reuses
run_adverse_media_agent(ADR-0077),is_rescreen_due(ADR-0066), theScreeningResultRecordevidence trail (ADR-0063), and the trigger router (ADR-0083). One newMonitoringCheckTypemember, one_CHECK_TYPE_TRIGGERmapping, one check method, one config flag. - Debuggability: each re-screen writes an append-only
ScreeningResultRecord(screened_by="monitoring-adverse-rescreen") + (on a hit) amonitoring_alertsrow via the existing route — a queryable evidence trail with timestamps, not a transient result. An indeterminate agent run persists a WARNING, never a silent clean. - Reversibility: additive — a new enum member, a new check method, a config flag defaulting off. Reverting removes the check from the suite; the flag-off default means it is inert until deliberately enabled. ~4-file change.
- Blast radius: additive on
run_checkdispatch + one router mapping. No change to the person/UBO re-screen (ADR-0066), the material-change diff, or the alert lifecycle. The default-off flag means production behaviour is unchanged until the Calibration-Review gate flips it. - Alternative considered: emit the result as a
material_changeevent with anadverse_mediasignal (reuses the existing router mapping, no new check type) — rejected because it conflates a fresh subject re-query with the persisted-data diff (a taxonomy-conflation the Calibration checklist forbids) and hides the distinct cadence/evidence stream.
Context
Post-approval monitoring re-screens persons (directors/UBOs) against sanctions/PEP
watchlists on a risk cadence (check_ubo_screening, ADR-0066), and detect_material_changes
surfaces an adverse-media signal — but only from persisted investigation data
(_derive_signals(fiscal_rep_data)), never a fresh query. There is no periodic fresh
adverse-media re-query of the subject entity once a relationship is onboarded. A subject
first named in an enforcement action or serious-crime story after onboarding is therefore
invisible until the next full periodic review — a gap AMLR Art. 26 ongoing-monitoring targets,
and the residual of issue #14 (ADR-0066/0083/0089 shipped the rest). ADR-0093's Tier-B adverse
recall runs at investigation time, not on the monitoring cadence.
Decision
Add a distinct, cadence-gated, cost-flagged adverse-media re-screen to continuous monitoring.
MonitoringCheckType.adverse_media(a new, distinct check — not folded intomaterial_change) with a_CHECK_TYPE_TRIGGER["adverse_media"] = adverse_media_criticalmapping intriggers_for_event.check_adverse_media_rescreen: cadence-gated (is_rescreen_due), behindadverse_media_monitoring_enabled(default False — dark-launched, Calibration-Review-gated to flip). When due + enabled, callsrun_adverse_media_agentfor the subject, compares against the last recorded adverse-media evidence, and emits a MonitoringEvent: a new critical finding →critical(routes toadverse_media_critical); an agent error / indeterminate → WARNING,indeterminate=True, never a benign clean (ADR-0067 fail-closed). Persists an append-onlyScreeningResultRecord(screened_by="monitoring-adverse-rescreen"). No caching across the cadence — always fresh.- Dispatched in
run_check; added to the default check suite (inert while the flag is off). - No migration — reuses
monitoring_events/screening_results/monitoring_alertsand the config flag.
Consequences
Positive
- A subject that becomes adverse-media-relevant after onboarding is detected on the monitoring cadence, not only at the next full review — closing the #14 residual and the AMLR Art. 26 ongoing-monitoring adverse-media gap.
- Distinct check type + evidence stream keeps the taxonomy honest (fresh subject re-query ≠ persisted-data diff ≠ person watchlist re-screen) and gives an auditable per-re-screen trail.
- Reuses the whole alert/route/review lifecycle — a hit routes and (EDD) opens a review case with zero new machinery.
Negative
- Real external API spend per due monitored case when enabled — the reason for the default-off flag + cadence gate; a large EDD population makes this the dominant monitoring cost when flipped on.
- Adverse-media agent recall/precision is imperfect (ADR-0077/0093): a re-screen can miss a real new story (recall) or raise a low-value hit (precision); the fail-closed WARNING covers the error path but not a confident-but-wrong agent result.
- Prior-state comparison depends on a consistent adverse-media evidence representation across investigation and monitoring; a drift there could mis-flag an old finding as "new".
Neutral
- Inert in production until the Calibration-Review gate flips
adverse_media_monitoring_enabled. - Person/UBO watchlist re-screen (ADR-0066) and the material-change diff are unchanged.
Alternatives Considered
Alternative 1: emit as a material_change adverse-media signal (no new check type)
- Reuse the existing
material_change→adverse_media_criticalrouter mapping. - Why rejected: conflates a fresh subject re-query with the persisted-data diff — a taxonomy-conflation the Calibration checklist forbids — and buries the distinct cadence and evidence stream, making "was the subject actively re-screened?" unanswerable from the data.
Alternative 2: do nothing (rely on the next full periodic review)
- Let the Art. 26 periodic review (ADR-0083) catch new adverse media.
- Why rejected: the periodic review can be a year out for EDD; "without undue delay" on a new serious-crime/enforcement signal is exactly what event-driven monitoring exists for, and the detection spine already exists — only the fresh re-query was missing.