Skip to main content

ADR-0182: Navin Enterprise Underwriting and Risk Assessment Agent, an insurance product layer on top of the Control Plane

  • Status: proposed on 2026-11-04, awaiting user validation (see "Points to validate")
  • Date: 2026-11-04
  • Scope: new project navin-enterprise-assurance-souscription/ (FastAPI backend navin_souscription, workers, Navin integration, no frontend of its own: the shared frontend shell of ADR-0180 carries the user interface), additive types of the OpenFGA model (deploy/policies/openfga/model.fga, type souscription_instance and its objects), OPA package eai.assurance_souscription (deploy/policies/opa/assurance_souscription.rego), contracts contracts/v1/assurance-souscription-action-request.schema.json and contracts/v1/assurance-souscription-copilot-event.schema.json, Navin Manager agent template prepared but not published (navin-assurance-souscription-agent)
  • Related documents: ADR-0101 (licence policy), ADR-0103 (vLLM and LiteLLM), ADR-0108 (Opik), ADR-0166 (ClamAV and YARA-X), ADR-0173 (Manager and Enterprise separation), ADR-0174 (Mem0 and Cognee memory), ADR-0175 (Navin Enterprise RAG Agent), ADR-0176 (Banking Back-Office, the reference implementation whose generic modules are copied), ADR-0180 (frontend shell of the sector agents), decision of 2026-11-04 (.navin/continuity/DECISIONS.md, one frontend, backend derived by copy), brief agent_uses_cases/02_Assurance_Souscription_Evaluation_Risques.md

Context​

The customer asks for an underwriting and risk assessment agent for an insurer or a broker: quote and new business intake, conditional risk questionnaire and data collection, eligibility through versioned rules, explainable risk indicators, accumulation and capacity checks, pricing proposals in Decimal per currency under a dated tariff version, review of medical or technical documents, referral to a human underwriter, decision recorded by a human with maker-checker as the authority matrix requires, and an issuance request to the policy administration system, the source of truth of the contract.

The audit of 2026-11-04 (navin-enterprise-assurance-souscription/docs/NAVIN_INTEGRATION_AUDIT.md) confirms that the Control Plane already provides identity and tenant and project context, OPA policy evaluation, OpenFGA, approvals with separation of duties, mandatory file scanning (quarantine, ClamAV, YARA-X, Docling), knowledge bases, memory, connectors with a secret broker, the transactional outbox, OpenTelemetry and Opik traces, Prometheus metrics and the chained audit. The UC-00 product (ADR-0176) provides a complete product layer whose generic modules (configuration, errors, i18n, authorisation, audit, jobs, worker, Control Plane client, RLS session, Action Gateway, connectors, observability, document pipeline, copilot, operations) do not depend on the banking business.

The whole underwriting business is missing: no application, no questionnaire, no eligibility engine, no risk indicator, no pricing, no authority matrix by sum insured and complexity, no issuance request to a policy administration system.

Decision​

1. A product layer, derived by copy of the reference product​

The product is a FastAPI backend (navin_souscription, development port 8473, Redis 6394, prefix /api/v1/assurance-souscription) that re-implements nothing of the platform: it calls the Control Plane through the enterprise_ai SDK. The generic modules of navin_backoffice are copied unchanged (except the package name, the PostgreSQL schema souscription and the action identifiers); they are not shared as a library so that each product stays deliverable and versionable alone (decision of 2026-11-04). No frontend is written: ADR-0180 carries the user interface of every sector agent from product.manifest.json.

2. The policy administration system stays the only source of truth​

The product never creates a policy. An issuance request (issuance_handoffs) goes through the Action Gateway, is sent to the policy_administration connector and stays unknown_pending_confirmation until the source has returned a policy reference and a policy version; source_confirmed is a CHECK constraint requiring both values. The deterministic connector sandbox names itself in every answer (sandbox: true) and never presents itself as a confirmation of the source.

3. Scores are indicators, decisions are human​

The indicator engine (risk_assessments) computes from versioned factors (underwriting_rulesets of kind risk_indicators) a score, a probability band and an expected loss kept as distinct values, each with its method, its uncertainty and the list of unknown factors. No row of underwriting_decisions is written by an engine or by the LLM: the decision (accept, request_information, modify, decline, refer) is recorded by a human underwriter through the Action Gateway; exceeding the delegation is prepared as a referral to a senior, never as an acceptance (OPA rule authority_insufficient_for_decision). The eligibility engine routes (eligible, needs_information, refer, out_of_appetite_proposed) and never refuses definitively.

4. Action Gateway and delegation matrix​

The OPA package eai.assurance_souscription decides per operation type (acceptance, refusal, modification, referral, terms proposal, pricing request, issuance request, delegation, rule change, export), amount (sum insured or premium, a Decimal string compared numerically) in one currency, line of business, region, complexity, conflict of interest, authority level and dated revocable delegations. It exposes decision.applies (true for souscription.* and document.* actions only); the approver is never the initiator, an agent or a service; a critical complexity requires two approvals.

5. Pricing in Decimal under a dated tariff version​

A premium proposal (pricing_quotes) is computed in Decimal from an active, dated tariff version (underwriting_rulesets of kind tariff) and a frozen snapshot of the rating characteristics; the steps (base, loadings, taxes) and the rounding rule are kept; a change of a rating characteristic invalidates the proposal. Never a live rate, never a sum across currencies, never a price taken from the text of the LLM.

6. Versioned rules, activated by another human​

Eligibility, indicator factors, authority matrix, tariff, state machine registry and questionnaire are versioned data (underwriting_rulesets): a draft is activated by a human other than its author (CHECK activated_by_another_human, OPA rule_activator_is_author, OpenFGA can_activate ... but not author); an active version is never edited.

7. Versioned state machine​

The statuses of the application and the permitted transitions (section 6 of the brief) are a versioned registry (state_machine_version on every application and every transition); every transition is applied server side with expected_version, and accept, decline, issue and confirm_issuance are not free transitions but the result of a human decision or of a confirmation by the source.

8. Documents, knowledge, memory, copilot​

Same document pipeline as UC-00 (quarantine, ClamAV, YARA-X, Docling, human review when the extraction is ambiguous, the uploader never reviews). A contradiction between the questionnaire and an inspection report creates a contested attribute that keeps both values. The copilot reuses the banking runtime: typed tools read, prepare, side_effect, approval of a side effect by a human other than the owner of the run, DLP governance, events under the assurance-souscription-copilot-event contract (same envelope as the banking one).

9. Template prepared, not published​

The Service Template navin-assurance-souscription-agent is a draft under navin-integration/ and a registry entry navin-manager/agent-templates/*.yaml with status prepared; it is never written under navin-manager/catalog.

Consequences​

  • A third insurance product on the same Control Plane, with the same technical base as UC-00: the duplication debt is accepted and documented (a fix of a generic module must be carried into every copy).
  • The non-automation commitments (the LLM never accepts, refuses, prices or issues) are carried by the database, OPA and OpenFGA, not only by the prompts.
  • The real connectors (policy administration, pricing engine, claims history, capacity) are capability contracts; without a configured connector the accumulation check is not_performed and the issuance stays prepared.

Points to validate​

  1. Does the demonstration authority matrix (tiers 250 000, 2 500 000, 25 000 000 EUR and equivalents) stand in for a customer matrix? It is versioned data per instance.
  2. Is the choice not to share the generic modules as a library (accepted copy) kept for the five insurance products?
  3. The lines of business and regions allowed by default in deploy/policies/opa/data.json.

Rejected alternatives​

  • A score that accepts or refuses automatically under a threshold: refused, incompatible with section 7.4 of the brief and with the explainability duties.
  • A rate read live from an external engine at quote time: refused, not reproducible; the dated version is kept with the proposal.
  • A shared Python library of the generic modules: set aside for now (decision of 2026-11-04).

Delivery plan​

Audit and ADR, contracts and policies, backend foundation (migration 0001 with RLS, outbox, audit), business modules (applications, risk evidence, eligibility, indicators, exposures, pricing), state machine and maker-checker decision, documents and ingestion, copilot and tools, security and resilience tests, six acceptance scenarios through the real API, product manifest and template, fr/en documentation.