ADR-0178: Navin Enterprise Insurance Fraud Detection Agent, investigation product layer on top of the Control Plane
- Status: proposed (2026-11-04)
- Deciders: architecture lead, UC-03 (subagent of the parallel session UC-01 to UC-05)
- References:
agent_uses_cases/03_Assurance_Detection_de_Fraude.md, decision of 2026-11-04 "Agents UC-01 to UC-05 built in parallel" (.navin/continuity/DECISIONS.md), ADR-0175 (RAG product), ADR-0176 (Banking Back-Office, pattern of copied generic modules), auditnavin-enterprise-assurance-fraude/docs/en/NAVIN_INTEGRATION_AUDIT.md, contractcontracts/v1/agent-product-manifest.schema.json, OPA packageeai.assurance_fraude(deploy/policies/opa/assurance_fraude.rego), contractscontracts/v1/assurance-fraude-copilot-event.schema.jsonandcontracts/v1/assurance-fraude-action-request.schema.json, Manager templatenavin-assurance-fraude-agent(published: false).
Context
The insurer wants to detect inconsistencies, suspicious declarations and relations between files, then prepare documented investigations for authorised investigators, without ever presenting a suspicion as an established fraud. The brief requires eight modules (signals, entity resolution, document duplicates, detection rules, file networks, alert triage, investigation and chain of evidence, follow-up and feedback), an explicit server-side state machine, a copilot bounded to sourced facts and an absolute prohibition: no accusation, no claim denial, no financial block and no report to an authority derived from a score.
The platform already provides identity, OpenFGA, OPA, the Action Gateway with maker-checker, durable jobs, the document pipeline (ClamAV, YARA-X, Docling behind the Control Plane), RAG, memory and observability (ADR-0176). A generic "Fraud & Anomaly" product is planned on the board but does not exist in the repository: this product does not depend on it.
Decision
1. A score is a review priority indicator, never a decision
Detection results (fraud_signals, detection_runs) carry a numeric indicator, one explanation per signal (rule,
version, input data, contribution) and a coverage status (sufficient, insufficient). The backend knows no
automatic transition towards an unfavourable state for an insured person, a provider or a claim. The only consequences
are internal objects (alert, investigation, hypothesis, follow-up draft) created or transformed by a human through the
Action Gateway. "Confirmed fraud" only appears as investigation_conclusions.outcome = confirmed_by_procedure,
reachable only through a qualified human conclusion reviewed by a second human (maker-checker), with its exact scope.
2. Generic modules copied, business modules written
The navin_fraude backend takes the UC-00 generic modules with no change other than the package name, the schema
(fraude), the prefix (/api/v1/assurance-fraude) and the OPA package: configuration, errors, fr/en/ar i18n, authz,
audit, jobs, worker, Control Plane, RLS session, Action Gateway (registry, contracts), connectors (contracts,
registry, resilience, deterministic sandbox), observability, document pipeline, copilot runtime, ops. The business
modules signals, entities, docchecks, detection, graphs, alerts, investigations, outcomes and the
workflow state machine belong to the product.
3. Versioned state machine and maker-checker
Alert: new, triaged, assigned, investigating, review_pending, closed_explained, closed_inconclusive,
escalated. Investigation: opened, evidence_collection, analysis, review, decision_recorded, closed,
reopened. The transition registry (navin_fraude/workflow/machine.py) carries source state, target state, event,
allowed roles, preconditions and approval requirement; a transition absent from the registry answers 409
transition_not_allowed; a different expected version answers 412. Closures, conclusions, SIU referrals, regulatory
report proposals and ambiguous entity merges require a second human through the same approval workflow as the banking
back-office (OPA fraude.action.approve, never the initiator, never a technical identity).
4. Signal dependency and no triple counting
Every signal carries a dependency_group derived from its source (source_object_ref, document or batch). The
priority of an alert counts the signals of one group once; the explanation shows the dependency. A correlation between
alerts derived from the same source is never presented as independent evidence.
5. Personal data and memory
Hypothesis notes (investigation_notes, classification restricted) never leave the schema: they are neither indexed,
nor sent to memory, nor exported other than through a pseudonymised export subject to OPA fraude.export. The csv and
json exports replace person identifiers with pseudonyms derived from a per-tenant hash. Nationality, religion, origin
and sensitive characteristics are never rule inputs: the engine refuses a rule that references an attribute outside the
allowed list.
6. Evaluation without a learned model
No statistical model is trained or called: the indicators are versioned rules stored as data and robust statistics
computed on real rows (median and median absolute deviation of a comparable group). Precision and recall are only
computed on a labelled synthetic dataset marked as such (backend/tests/datasets), never presented as production
performance.
Consequences
- Positive: no automated accusation; audit, approval and effect kept apart; a later extraction of the generic modules
into a shared library is mechanical; shared frontend driven by
product.manifest.json. - Negative: temporary duplication of the generic modules across five products; the real connectors (claims, policies, payments, external lists) are exercised only in the deterministic sandbox until a source system is attached; pdf, docx and xlsx formats remain unavailable.
- The
navin-assurance-fraude-agenttemplate stayspublished: falseuntil explicit validation.