Aller au contenu principal

ADR-0179 : Navin Enterprise Agent Gestion des Contrats et Renouvellements (assurance), couche produit miroir du système de polices au-dessus du Control Plane

  • Statut : proposé le 2026-11-04, en attente de validation de l'utilisateur (voir « Points à valider »)
  • Date : 2026-11-04
  • Portée : nouveau projet navin-enterprise-assurance-contrats-renouvellements/ (backend FastAPI navin_contrats, workers, intégration Navin, manifeste produit du socle frontend commun ; aucun frontend propre), types additifs du modèle OpenFGA (deploy/policies/openfga/model.fga), paquet OPA eai.assurance_contrats (deploy/policies/opa/assurance_contrats.rego), contrats contracts/v1/assurance-contrats-renouvellements-action-request et assurance-contrats-renouvellements-copilot-event, gabarit d'agent du Navin Manager préparé mais non publié
  • Documents liés : ADR-0101 (licences), ADR-0103 (LiteLLM), ADR-0108 (Opik), ADR-0166 (ClamAV et YARA-X), ADR-0174 (Mem0 et Cognee), ADR-0175 (RAG, motif de couche produit), ADR-0176 (Back-Office bancaire, modules génériques repris), décisions du 2026-11-04 (.navin/continuity/DECISIONS.md : cinq agents en parallèle, manifeste produit, un seul frontend), audit navin-enterprise-assurance-contrats-renouvellements/docs/NAVIN_INTEGRATION_AUDIT.md, cahier des charges agent_uses_cases/04_Assurance_Contrats_Renouvellements.md

Contexte​

Le cahier des charges UC-04 demande un agent qui analyse les échéances et versions contractuelles, prépare avenants et renouvellements, identifie les risques de résiliation et organise les actions des gestionnaires avec validation des engagements. Il impose que le système de polices reste la source de vérité, qu'aucun délai légal ne soit inventé, que les montants soient en Decimal par devise, que toute modification de couverture, prime ou résiliation passe par une procédure autorisée, et que le LLM propose sans jamais décider.

L'audit du 2026-11-04 montre que le back-office bancaire (ADR-0176) fournit déjà, testés, les modules génériques dont ce produit a besoin : configuration typée, erreurs bilingues, i18n, autorisation fail-closed (OpenFGA et OPA par le Control Plane), audit append-only, travaux durables et outbox, RLS, Action Gateway avec maker-checker et confirmation source, pipeline documentaire avec quarantaine, runtime du copilote (événements, SSE, gouvernance des chiffres), observabilité et opérations. Il n'existe en revanche aucun métier assurance : ni projection de polices, ni règle de préavis, ni prorata, ni campagne de renouvellement, ni demande de résiliation.

Décision​

1. Copie des modules génériques, écriture du seul métier​

Le backend navin_contrats reprend les modules génériques du backend bancaire sans autre modification que le nom du paquet, le schéma SQL (contrats), le préfixe d'environnement (NAVIN_CONTRATS_), le préfixe d'API et les noms des actions OPA, afin qu'une extraction ultérieure en bibliothèque commune reste mécanique. Seuls les modules du §7 et les entités du §18.1 sont écrits : contract_register, deadlines, endorsements, premium_adjustments, renewal_campaigns, retention_reviews, termination_requests, contract_reconciliation.

2. Le système de polices est le maître ; PostgreSQL est un miroir daté​

contract_projections et contract_versions sont des projections horodatées du système de polices (source_status, source_connector, refreshed_at). Deux versions actives qui se recouvrent ouvrent un contract_reconciliation_items au résultat conflict ; l'application ne choisit jamais la plus récente. Aucune table ne crée de couverture parallèle ; l'état actif affiché est celui confirmé par la source.

3. Rien ne s'applique sans un humain ni sans la source​

Avenants, renouvellements, résiliations et réintégrations sont des demandes. Leur machine à états (§6) est un registre de transitions en données (navin_contrats/workflows/machine.py) : état source, état cible, événement, acteur autorisé, lien source ou horloge ; une transition interdite répond 409 transition_not_allowed, une version attendue manquante 428, une version périmée 412. Toute transition à effet externe passe par l'Action Gateway : contrat assurance-contrats-renouvellements-action-request, décision OPA contrats.action.prepare / approve / execute, maker-checker quand la matrice du §15 l'exige, soumission à la source avec clé d'idempotence et statut unknown_pending_confirmation jusqu'à relecture. Une approbation est liée à la version de l'objet : toute modification après approbation invalide l'approbation (approval_void) et interdit l'envoi.

4. Calculs déterministes, versionnés, en Decimal​

Les préavis sont calculés à partir de l'événement prévu par une règle de préavis versionnée (notice_rules : event_basis, days_before, calendar_id, source_uri, effective_from), jamais d'un seuil légal codé. Les impacts financiers sont des propositions en Decimal par devise à partir d'une version tarifaire datée (tariff_versions), avec convention de prorata explicite (day_count_basis 365, 360 ou actual, bornes documentées) et engine_version, ruleset_version, input_snapshot, as_of, explanation. Les scores de rétention sont des indicateurs de priorité expliqués, sans probabilité affichée, et ne ralentissent jamais une demande de résiliation.

5. Communications et documents comme brouillons revus​

Les communications clients sont générées en brouillon (draft) et revues par un humain ; une relance ne crée jamais une seconde offre active. Les demandes de génération documentaire sont versionnées et confiées au service documentaire du Control Plane ; l'ingestion suit quarantaine, ClamAV et YARA-X, Docling, revue humaine quand l'extraction est ambiguë.

6. Observabilité, rapports, licences​

Mêmes choix que l'ADR-0176 : Prometheus, Alertmanager, OpenSearch, Jaeger, Opik (Grafana, Loki et Tempo refusés par l'ADR-0101) ; métriques contrats_* par devise sans identifiant ; rapports csv et json seulement, les autres formats annoncés indisponibles ; aucune dépendance Python ajoutée.

7. Un seul frontend, un manifeste produit, un gabarit non publié​

Le produit ne porte aucun code frontend : product.manifest.json (contrat agent-product-manifest) décrit nom, logo, couleurs, préfixe, ports 3476 / 8475 / 6396, rôles, menus, entités et invites du copilote pour le socle commun. Le gabarit navin-assurance-contrats-renouvellements-agent est préparé (published: false, statut prepared) ; rien n'est écrit sous navin-manager/catalog.

Conséquences​

  • Les invariants du §7 vivent dans le produit et dans le paquet OPA ; le Control Plane n'est pas modifié.
  • L'intégration réelle avec un système de polices, un moteur tarifaire, une facturation, un CRM ou une signature n'est pas démontrée : connecteurs déclarés par capacités, bac à sable déterministe signalé comme tel.
  • La duplication temporaire des modules génériques est assumée ; l'extraction en bibliothèque commune suit la clôture d'UC-00.

Points à valider​

  1. Les règles de préavis et calendriers restent des données saisies par l'organisation avec leur source : aucun défaut juridictionnel n'est livré.
  2. Conventions de prorata acceptées : 365, 360, actual, bornes début incluse et fin exclue.
  3. Rapports csv et json seulement jusqu'à l'existence d'un moteur Navin.
  4. Prépublication seulement : le gabarit reste prepared jusqu'à l'accord explicite de l'utilisateur.

Alternatives écartées​

  • Un référentiel de polices propre : second maître, contraire au cahier des charges.
  • Un prorata générique ou un tarif en direct : non reproductible et non daté.
  • Une probabilité de résiliation affichée sans modèle validé : interdite par le §8.
  • Une bibliothèque Python commune extraite maintenant : instable pendant que cinq produits la consomment.