ADR-0191 : Navin Enterprise Agent Supply Chain et Approvisionnement, couche produit industrielle au-dessus du Control Plane
- Statut : proposé (2026-11-04)
- Décideurs : équipe plateforme Navin Enterprise AI, mission UC-09 (
agent_uses_cases/09_Industrie_Supply_Chain_Approvisionnement.md) - Références : décision du 2026-11-04 « Identités des agents Industrie UC-06 à UC-10 » (
.navin/continuity/DECISIONS.md), ADR-0176 (Banking Back-Office, motif des modules génériques copiés), ADR-0181 et ADR-0183 (agents assurance frères), contratcontracts/v1/agent-product-manifest.schema.json, paquet OPAeai.industrie_supply_chain(deploy/policies/opa/industrie_supply_chain.rego), contratscontracts/v1/industrie-supply-chain-copilot-event.schema.jsonetcontracts/v1/industrie-supply-chain-action-request.schema.json, gabarit Managernavin-industrie-supply-chain-agent(published: false).
Contexte
Un site industriel veut voir ses positions de stock multisites, consolider ses besoins (production, maintenance, commandes, sécurité), suivre les engagements de ses fournisseurs, préparer des propositions d'approvisionnement expliquées, faire valider une demande d'achat ou de transfert, puis suivre les confirmations, l'acheminement et les réceptions, sans jamais laisser un modèle de langage commander, engager une dépense, choisir un fournisseur ou annuler une livraison. Le cahier des charges impose huit modules (stock et positions, besoins et couverture, fournisseurs et engagements, propositions, retards et arbitrages, validation et commandes, acheminement et réceptions, performance), une machine à états explicite côté serveur (409 sur toute transition interdite), des quantités et montants en chaînes décimales portant unité et devise sans jamais sommer deux unités ou deux devises, et six scénarios de recette numériques (rupture temporaire 20, proposition 80 pour un besoin net 60 sous MOQ 80, quarantaine 30 non couvrante, dédoublonnage ERP/MES, réception partielle 60 dont 10 rejetées, fournisseur non homologué non exécutable).
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 ERP, WMS, MES ou EDI 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, l'ERP confirme
La projection de couverture (coverage_projections) est un moteur déterministe versionné (engine_version,
ruleset_version, input_snapshot_hash, as_of) : stock projeté(t) = stock utilisable initial + réceptions éligibles
cumulées - besoins alloués cumulés, avec les seules quantités utilisables (le stock bloqué qualité ou en quarantaine n'est
jamais compté). La proposition de réapprovisionnement (replenishment_proposals) applique besoin net, MOQ et multiple
et explique chaque arrondi (explanation, surplus_qty). Elle reste une suggestion : la demande d'achat est un plan
d'action du Gateway, approuvé par un humain autre que son préparateur, transmis à l'ERP par un connecteur, et
supply_order_links.status vaut unknown_pending_confirmation jusqu'à ce que la source ait répondu ; aucun statut
« commandé » n'est jamais écrit localement.
2. Modules génériques copiés, modules métier écrits
Comme ADR-0181 : les modules génériques (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_supply sans autre changement que le nom du paquet, du schéma (supply), du préfixe
(/api/v1/industrie-supply-chain), des ports (3482, 8481, 6402) et du paquet OPA. Les tables métier de la section 18.1
(inventory_snapshots, supply_requirements, supplier_commitments, coverage_projections, replenishment_proposals,
supply_order_links, inbound_shipments, receipt_allocations) plus suppliers, supply_exceptions et
supplier_scorecards sont écrites dans la migration 0001_foundation avec RLS locataire puis projet, clés étrangères
composites (tenant_id, parent_id) et CHECK sur les statuts, les unités et les devises.
3. Indicateurs fournisseurs, jamais décisions
La performance fournisseur (supplier_scorecards) est un indicateur calculé sur les engagements acceptés (OTIF, retards
mesurés contre la promesse initiale, qui n'est jamais effacée par une nouvelle date), avec volume, période et données
manquantes affichés. L'homologation (suppliers.approval_status) est une donnée du référentiel source ; un fournisseur
not_approved rend un scénario not_executable, et la contrainte en base interdit tout lien de commande vers lui.
4. Matrice de délégation et séparation des tâches dans OPA
Le paquet eai.industrie_supply_chain reprend le motif fail-closed : opérations typées, rôles de préparation et
d'approbation en données (eai.config.industrie_supply_chain), second humain obligatoire pour purchase_submit,
transfer_submit, expedite_paid, substitution, supplier_change, order_amend, budget_override et
rule_change, rail toujours none (l'application ne déplace pas d'argent), applies vrai pour les seules actions
supply.* et document.*. Les obligations annoncent proposal_not_order et unknown_pending_confirmation.
5. Unités, devises et dédoublonnage
Toute quantité porte unit (UoM source) et toute valeur currency ; les KPI sont groupés par unité et par devise et ne
sont jamais additionnés entre eux. Un besoin reçu de l'ERP et du MES avec la même référence métier est dédoublonné par
(tenant_id, project_id, dedup_key) : une seule ligne est retenue, les sources sont conservées dans source_refs.
Conséquences
- Positives : aucun effet externe sans plan approuvé et confirmation de source ; calculs reproductibles et expliqués ; isolation par RLS testée ; le même frontend générique affiche le produit grâce au manifeste.
- Négatives : les ERP/WMS/MES réels ne sont pas raccordés ; les scénarios d'acceptation s'exécutent sur le bac à sable déterministe et ne valent pas intégration de production.
- Le gabarit
navin-industrie-supply-chain-agentrestepublished: falsejusqu'à validation explicite.