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 backendnavin_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, typesouscription_instanceand its objects), OPA packageeai.assurance_souscription(deploy/policies/opa/assurance_souscription.rego), contractscontracts/v1/assurance-souscription-action-request.schema.jsonandcontracts/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), briefagent_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_performedand the issuance staysprepared.
Points to validate
- 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.
- Is the choice not to share the generic modules as a library (accepted copy) kept for the five insurance products?
- 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.