Skip to main content

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), audit navin-enterprise-assurance-fraude/docs/en/NAVIN_INTEGRATION_AUDIT.md, contract contracts/v1/agent-product-manifest.schema.json, OPA package eai.assurance_fraude (deploy/policies/opa/assurance_fraude.rego), contracts contracts/v1/assurance-fraude-copilot-event.schema.json and contracts/v1/assurance-fraude-action-request.schema.json, Manager template navin-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-agent template stays published: false until explicit validation.