ADR-0181 : Navin Enterprise Agent Courtier et Distribution, couche produit de courtage au-dessus du Control Plane
- Statut : proposé (2026-11-04)
- Décideurs : équipe plateforme Navin Enterprise AI, mission UC-05 (
agent_uses_cases/05_Assurance_Courtier_Distribution.md) - Références : décision du 2026-11-04 « cinq agents sectoriels d'assurance développés en parallèle »
(
.navin/continuity/DECISIONS.md), ADR-0175 (produit RAG), ADR-0176 (Banking Back-Office, motif des modules génériques copiés), ADR-0178 et ADR-0179 (agents assurance frères), auditnavin-enterprise-assurance-courtier-distribution/docs/NAVIN_INTEGRATION_AUDIT.md, contratcontracts/v1/agent-product-manifest.schema.json, paquet OPAeai.assurance_courtier(deploy/policies/opa/assurance_courtier.rego), contratscontracts/v1/assurance-courtier-distribution-copilot-event.schema.jsonetcontracts/v1/assurance-courtier-distribution-action-request.schema.json, gabarit Managernavin-assurance-courtier-distribution-agent(published: false).
Contexte
Un courtier ou un réseau de distribution veut comparer des offres de plusieurs assureurs à partir des besoins déclarés
d'un client, préparer un dossier de conseil documenté, transmettre la souscription à l'assureur choisi et suivre les
commissions, sans jamais laisser un modèle de langage choisir, lier, placer ou conseiller à la place d'un humain
habilité. Le cahier des charges impose sept modules (besoins et mandat, panel et habilitations, demandes de devis,
normalisation des offres, comparaison et classement explicable, conseil et traçabilité, dossier de souscription et
suivi), une machine à états explicite côté serveur avec 409 sur toute transition interdite, des montants en Decimal
par devise sans jamais sommer deux devises, et une interdiction absolue : aucune prime calculée ou inventée, aucun
statut d'émission supposé, aucune commission versée depuis cette application.
La plateforme fournit déjà l'identité, OpenFGA, OPA, l'Action Gateway avec maker-checker, les travaux durables, le pipeline documentaire (ClamAV, YARA-X, Docling derrière le Control Plane), le RAG, la mémoire et l'observabilité (ADR-0176). Aucun connecteur assureur réel n'est raccordé dans le dépôt : les connecteurs sont exercés en bac à sable déterministe.
Décision
1. Le modèle propose, l'humain décide, la source confirme
La comparaison (offer_comparisons) est un moteur déterministe versionné (engine_version, ruleset_version,
input_snapshot_hash) sur les seules offres valides au regard d'une version de besoins et d'un scénario de priorités
explicite ; une garantie absente du document source est unknown, jamais covered. La note de conseil
(advice_records) reste draft tant qu'un humain compétent autre que son préparateur ne l'a pas validée (contrainte
validated_by_other_human en base, règle advice_not_validated_by_other_human dans OPA, relation
can_validate ... but not preparer dans OpenFGA). Le choix du client, l'accord de l'assureur et la date d'effet sont
trois événements datés distincts ; le statut d'émission (broker_submissions.issuance_status) est celui que l'assureur a
répondu, unknown_pending_confirmation tant qu'il ne l'a pas fait.
2. Modules génériques copiés, modules métier écrits
Comme ADR-0178 et ADR-0179 : les modules génériques du backend UC-00 (config, errors, i18n, authz, audit,
jobs, worker, controlplane, db/session, Action Gateway, connecteurs, observabilité, pipeline documentaire,
copilote, ops, api/common, app) sont copiés dans navin_courtier sans autre changement que le nom du paquet,
du schéma (courtier), du préfixe (/api/v1/assurance-courtier-distribution) et du paquet OPA. Les dix-sept tables
métier de la section 18.1 sont écrites dans la migration 0001_foundation avec RLS locataire puis projet, clés
étrangères composites (tenant_id, parent_id) et contraintes CHECK sur les statuts, les devises ISO et les montants
accompagnés de leur devise.
3. Prix et statuts : uniquement ce qu'une source a répondu
insurance_quotes.premium_amount est la valeur de l'assureur (source_kind = insurer_api) ou d'un humain avec pièce
justificative (manual_with_evidence, document obligatoire), datée (priced_at, validity_end) et liée au hachage
des conditions (terms_hash). broker_profiles.licence_status est la réponse du registre officiel via un connecteur
licence_registry ; not_checked et unknown ne valent jamais valid, et la contrainte
active_requires_valid_licence interdit l'activation sans licence valide. Les relevés de commissions sont rapprochés
par devise ; attendu et reçu sont conservés séparément, l'écart ouvre un litige, jamais un paiement.
4. Matrice de délégation et séparation des tâches dans OPA
Le paquet eai.assurance_courtier reprend le motif fail-closed des produits frères : seize types d'opération, rôles de
préparation et d'approbation en données (eai.config.assurance_courtier), second humain obligatoire pour
broker_activate, broker_suspend, manual_quote_record, advice_validate, application_submit,
commission_dispute_open, portfolio_transfer et rule_change, autorité minimale par opération et par urgence,
délégations datées révocables, rail toujours none (un courtier ne déplace pas d'argent), applies vrai pour les
seules actions courtier.* et document.*. Les obligations annoncent proposal_not_advice et
unknown_pending_confirmation.
5. Données personnelles et minimisation
Les demandes de devis portent une charge minimisée (minimised_payload) et son hachage ; l'identité du client n'est
envoyée à un assureur que si le mandat l'autorise (broker_mandates.allows_data_sharing). Le copilote ne reçoit que des
faits sourcés ; la mémoire ne retient aucune donnée de santé ni de situation personnelle.
Conséquences
- Positives : six scénarios de recette exécutables par l'API HTTP réelle, politiques testées (
opa test,fga model test), contrats indexés et validés, indicateurs par devise honnêtement vides sans donnée. - Négatives : le gabarit Manager reste un brouillon non publié ; les connecteurs assureurs, registre, CRM et signature électronique ne sont exercés qu'en bac à sable déterministe tant qu'un système source n'est pas raccordé ; les formats pdf, docx et xlsx des rapports restent indisponibles (csv et json seulement) ; aucun frontend n'est livré par cette mission (ADR-0180).