fokan/docs/pilier-vehicules.md
Gautier Stefanini 6870e027c0 Rejouer le quiz effaçait des contrats et un délai de travaux encore ouvert
Trois régressions silencieuses au rejeu, une par question posée.

Les contrats étaient remplacés comme les véhicules, au motif qu'une liste
rejouée n'a pas d'identité stable. C'est vrai d'une voiture, faux d'un
contrat : son type vient d'une énumération fermée. On appariait donc rien
alors qu'il n'y avait rien à deviner, et on payait l'état utilisateur de la
seule saisie opt-in du produit.

La déclaration de travaux ne gardait qu'un mois pour tout le logement. Une
piscine finie en juin et une véranda finie en août partageaient une date
limite — celle de la dernière déclarée, l'autre disparaissant avec son sujet.
Un mois par chantier, un sujet par mois, et deux chantiers du même mois
restent une visite unique au service des impôts. Le formulaire repart à vide
à chaque rejeu, parce que la question porte sur ce qui vient d'arriver ; le
logement, lui, accumule et oublie à treize mois.

Enfin, carte-grise-changement-adresse attendait depuis sa publication un
demenagement_recent que personne n'écrivait. On attendait un écran de
correction d'adresse pour le poser ; le rejeu du quiz le fait depuis le
28/07, il tient les deux adresses dans la même fonction. On pose le mois,
jamais un booléen — sans quoi la fiche annoncerait un mois pour la carte
grise à vie, ce que D-059 venait de corriger sur la piscine.

Vérifié sur une copie de la production : deux déclarations foncières
vivantes après rejeu, cinq contrats gardant leur identifiant, un second
rejeu qui ne bouge plus rien. 905 tests.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-07 13:37:33 +00:00

46 KiB
Raw Permalink Blame History

Pilier Véhicules — ce qu'une carte grise permet de savoir, et ce qu'on en fait

Document de référence du pilier véhicules : ce qu'on sait identifier gratuitement à partir d'une carte grise française, ce qu'on en tire, et surtout ce qu'on a renoncé à en tirer et pourquoi. Le cadrage reste la source de vérité produit ; ce document le décline sur un pilier. Les décisions qui l'ont façonné sont en decisions.md — D-002, D-004, D-011, D-016, D-017, puis D-031 (contrôle technique des deux-roues), D-032 (RappelConso remplace le registre néerlandais) et D-034 (le champ K qualifie les rappels).

Statut des mesures : tous les chiffres de ce document ont été mesurés sur les données réelles, pas estimés. Les requêtes sont reproduites pour ne pas avoir à les refaire.

État d'avancement (5 août 2026)

Identification du véhicule : livrée. Champ K → réception RDW → marque, modèle, année de type, énergie, norme Euro. Gratuit, sans licence SIV, sans coût variable.

Rappels constructeur : livrés. 1 662 campagnes RappelConso (D-032), rattachées par marque + modèle et, quand le foyer a donné son champ K, par numéro de réception — ce qui distingue « ta version » de « ton modèle » sans jamais rien masquer (D-034). Frise chronologique proportionnée, datée campagne par campagne (D-016).

Crit'Air et ZFE : livrés. Classement déduit, croisement avec la Base Nationale des ZFE, trois fiches (D-011), carte des périmètres (D-022).

La Base Nationale n'est pas suffisante, et ce n'est pas un détail (D-023, 29/07/2026). Relevé le 29/07/2026 : le portail d'État recense 25 agglomérations sous ZFE, la consolidation nationale n'en publie que 19 — six manquaient entièrement (Nice, Lille, Caen, Le Havre, Pau, Nîmes), et trois des dix-neuf publiées portaient une règle fausse (Paris, Grenoble, Nancy). Deux fichiers en git comblent les trous, chacun conçu pour se vider tout seul : zfe-complements.ts (géométrie d'ailleurs, règle vérifiée à la main) et zfe-corrections.ts (règle relue chez la collectivité). Les 25 sont désormais couvertes.

Distribution : livrée côté moteur, en cours de sourcing côté donnée (D-017). La chaîne complète fonctionne — ingestion des codes moteur, identification, règle de silence, fenêtre datée, fiche de prise en charge. Ce qui manque est le référentiel lui-même : 34 codes documentés (les 8 moteurs dominants du parc français + les 26 orthographes de la famille EB), et aucun intervalle exploitable — donc aucune date, pour personne. Voir § 7.

Un trou de câblage relevé le 28/07/2026 (audit § 3) : le champ P.2 n'est proposé que sur la voie « champ K ». Un foyer passé par la recherche marque/modèle laisse tous les moteurs du modèle en lice, l'unanimité ne tranche jamais, et rien n'est affirmé sur sa distribution — alors que codesEnLice sait parfaitement filtrer sur la puissance sans réception. Comme le champ K suppose d'avoir sa carte grise sous la main, c'est probablement la voie majoritaire qui est muette.

Leasing social : fiche livrée le 05/08/2026 (D-051). Voiture électrique à moins de 200 €/mois, sans apport, contrats à partir du 16 juillet 2026. C'est la première fiche du pilier posée sur l'asset foyer et non sur un véhicule — une fiche par voiture possédée aurait produit trois rappels identiques à qui en a trois. Elle porte le barème leasing-social (RFR par part ≤ 16 880 €), et laisse en clair la condition qu'on ne saura jamais tester : plus de 10 km de trajet domicile-travail avec son véhicule personnel, ou plus de 8 000 km/an à titre professionnel. Le foyer tranche, comme pour la vignette Crit'Air.

Entretien courant : abandonné, et c'est une décision, pas un retard. Voir § 2.


1. Ce qu'une carte grise donne, champ par champ

Champ Contenu Ce qu'il débloque État
K Numéro de réception CE Marque, modèle, énergie, norme Euro, année du type demandé au quiz
D.2 Type-Variante-Version Identification exacte de la version — donc du moteur non demandé (§ 3)
P.2 Puissance nette max. en kW Restreint fortement les motorisations en lice demandé, facultatif
B Date de 1re immatriculation Fenêtre de contrôle technique exacte, ancre de la courroie non demandé — voir plus bas
D.2.1 CNIT Rien : souvent vide sur les cartes récentes écarté (D-004)

La date de première immatriculation mérite un mot. Elle est le seul champ dont l'absence coûte de la précision partout : elle daterait le contrôle technique au mois près au lieu de l'estimer, et elle ancrerait la courroie sur une vraie date au lieu du 1er juillet conventionnel. Elle a disparu avec la mécanique plaque (D-004) et n'a jamais été redemandée. date_premiere_immat existe dans le schéma et est lue partout où elle servirait — elle attend seulement d'être remplie.

2. Ce qu'on a renoncé à faire, et pourquoi

2.1 L'entretien courant (vidange, révision)

Le pilier a longtemps porté une table vehicules_entretien destinée aux intervalles constructeur. Elle est morte le 26 juillet 2026, pour une raison qui n'est pas celle qu'on croyait.

Ce n'était pas un problème de source. Trois pistes ont été auditées et fermées :

  • RMI (règlement UE 2018/858 art. 61) : accès garanti mais payant, par marque (Renault ASOS relevé à 26 €/jour, 339 €/mois, 3 521 €/an ; Stellantis et erWin sur le même modèle), redistribution interdite par les CGU.
  • Notices constructeur publiques : testées pour de vrai. Peugeot publie ses guides librement (public.servicebox.peugeot.com) ; l'extraction du guide de la 208 donne 674 ko de texte propre et une seule occurrence de « périodicité », qui renvoie ailleurs — « se reporter au plan d'entretien du constructeur ». Le carnet est papier ou réseau. Renault et Toyota : même schéma.
  • Agrégateurs (chaine-courroie, RTA, odopass, Autodoc) : bases propriétaires protégées par le droit sui generis. Contre-vérification, jamais source.

La vraie raison est dans la notice elle-même :

« La valeur indiquée est déterminée en fonction du kilométrage parcouru et du temps écoulé depuis la dernière révision. » — Guide d'utilisation Peugeot 208, section « Indicateur d'entretien »

Le tableau de bord connaît les deux bornes, la date réelle du dernier entretien et, sur les diesels récents, la dilution d'huile. fokan n'a pas le compteur et ne doit pas le demander — ce serait la question récurrente que la règle d'or interdit. Sur ce sujet, le produit ne pouvait qu'être moins bon qu'une source que l'utilisateur a sous les yeux, et se tromper visiblement là abîmerait la confiance sur les échéances où fokan est seul à savoir.

La fiche revision-constructeur existe toujours (v4) mais ne prétend plus dire quand. Elle porte ce que la voiture ne dit pas : les factures conditionnent la garantie et se réclament à la revente.

2.2 La réputation de fragilité

Le code moteur permettrait de dire « ta chaîne EP6 s'étire », « ton N47 a sa chaîne côté boîte », « ton EA111 a un tendeur fragile ». C'est documenté et indexable. On s'en abstient.

Ligne retenue : on ne parle que de ce qui est opposable ou réclamable. La courroie humide PureTech passe parce qu'il y a une garantie étendue officielle à réclamer ; l'EP6 ne passe pas, parce que ce serait fokan qui déclarerait un défaut sur la voiture de quelqu'un.

2.3 L'additif FAP

Candidat sérieux — opération du plan d'entretien, indexée sur le moteur, oubliée de tous, et un FAP colmaté coûte plus de 1 000 €. Écarté pour deux raisons cumulées : borne purement kilométrique (~120 000 km annoncés, 80 à 200 000 en pratique selon la génération et l'usage), et le combiné affiche déjà « Niveau additif FAP trop faible ». Même impasse que la révision.

2.4 Affiner les rappels avec le code moteur

Hypothèse testée, résultat négatif : le jeu RDW des campagnes (mu2x-mu5e) ne lie une campagne qu'à merk + type, soit marque et modèle. Aucun code moteur, aucun millésime, aucun VIN. Le code moteur n'affine donc rien, et la limite structurelle notée à D-004 restait entière.

La question a fini par trouver une réponse, par un autre chemin (D-034, 30/07/2026). Ce n'est pas le code moteur qui affine, c'est le numéro de réception : RappelConso le publie sur 94,6 % de ses fiches automobiles, au format exact du champ K. Le raffinement existe donc — il ne venait simplement pas d'où on le cherchait, ni de la source qu'on interrogeait. À relire quand une limite paraît structurelle : elle peut n'être que celle du jeu de données consulté.


3. Identifier le moteur — le cœur de D-017

3.1 Pourquoi le moteur et pas le modèle

Courroie ou chaîne est une propriété du moteur, pas de la carrosserie qui le porte. Une clé (marque, modèle, énergie) fait cohabiter dans une même entrée un EP6 à chaîne et un DV6 à courroie. C'est ce qui rendait l'ancien référentiel structurellement faux, indépendamment de son remplissage.

3.2 La source

Le jeu TGK Aandrijving Uitvoering (4by9-ammk) de RDW Open Data, jamais exploité avant D-017 :

curl -s -G "https://opendata.rdw.nl/resource/4by9-ammk.json" \
  --data-urlencode "\$where=typegoedkeuringsnummer='e2*2007/46*0639*34'" --data-urlencode '$limit=5'

Il publie motorcode, cilinderinhoud, aantalcilinders, typegoedkeuringsnummermotor. Mesuré à la source : 6 142 189 lignes, 18 086 codes moteur distincts, 6 732 lignes sans code (0,1 %).

Après synchronisation réelle, restreinte à la catégorie M1 (voitures particulières) comme le reste du référentiel : 3 158 182 motorisations, 5 991 codes moteur distincts, 49 minutes, aucune purge. Les 18 086 codes incluaient camions, autocars et tracteurs — la cible de sourcing est donc trois fois plus petite qu'annoncée.

Ce sont les vrais codes constructeur — HN05, K9K E6, ALH, 1NR-FE — c'est-à-dire le vocabulaire de toute la documentation technique. La source publie même sa propre table de correspondance : on y trouve EB2ADTS (HN05) et EB2FA (HM05), ce qui prouve l'équivalence entre nom commercial et code.

Bug corrigé au passage : sync-vehicules.ts lisait cilinderinhoudbovengrens dans le jeu Energiebron, où la colonne n'existe pas. vehicules_reference.cylindree était NULL sur les 2 908 933 lignes, sans une erreur. La colonne a été supprimée ; la cylindrée est désormais là où la source la met.

3.3 Combien de champs faut-il pour nommer un moteur ?

Mesuré sur les 15 modèles dominants du parc français (~3 800 réceptions, script reproductible dans l'audit D-017) :

Identification 1 seul code moteur 1 seule famille moteur
K seul 7 % 10 %
K + énergie (état avant D-017) 23 % 38 %
K + énergie + P.2 72 % 86 %
K + D.2 98 % 99,8 %

P.2 est retenu, D.2 non. P.2 est un nombre, D.2 deux codes alphanumériques longs ; 14 points de précision supplémentaire ne valent pas ce doublement de saisie.

3.4 P.2 se propose, il ne se saisit pas

Le quiz n'a aucune saisie libre (§ 4.1 du cadrage) — l'en-tête de src/app/api/vehicule/taxonomie/route.ts le rappelle. Un champ numérique libre y avait pourtant été introduit, et il ouvrait une erreur qu'une liste fermée rend impossible : la confusion kW / chevaux. Une puissance en chevaux (181 au lieu de 133) est un nombre parfaitement plausible qui n'existe sur aucune version de la réception ; le filtre écarte alors toutes les motorisations et le produit se tait, sans erreur ni trace, tandis que l'utilisateur croit avoir aidé.

identifierParReception rend donc, par énergie, les puissances réellement homologuées et le nombre de moteurs en lice. Mesuré sur les marques françaises + VW + Toyota (~10 700 couples réception × énergie) :

Valeurs de P.2 possibles Part Cumul
1 35,6 % rien à demander, on l'affiche
2 19,9 % 55,5 %
3 16,8 % 72,3 %
4 10,9 % 83,2 %
5 à 12 16,8 % 100 %

Et surtout : 38,9 % des couples (K, énergie) désignent déjà un seul moteur — la question n'apprendrait rien. Avec P.2, on passe à 81,1 %.

D'où trois comportements, dont deux ne demandent rien :

  1. une seule puissance possible → on l'affiche, confirmée, et on la retient ;
  2. plusieurs puissances mais un seul moteur → on affiche le moteur (« 1,6 l, 4 cylindres » — HN05 ne dit rien à personne) et on ne demande rien ;
  3. sinon → pastilles fermées, le même composant que l'énergie.

Les décimales sont conservées. La source publie 121.40 et certaines cartes grises l'impriment ainsi ; une 208 essence porte à la fois 121.00 et 121.40. Comme la valeur est choisie dans une liste issue du référentiel, elle s'y compare à l'identique — arrondir réintroduirait par le calcul une équivalence que la source ne fait pas.

Piège rencontré à l'implémentation : le pilote rend un numeric[] sous forme de chaîne ("{96.00,133.00}"), pas de tableau. Le .map() levait donc une TypeError qu'un catch de dégradation douce avalait — l'écran ne proposait rien, indiscernable d'un référentiel non synchronisé. Corrigé par json_agg, et le catch journalise désormais au lieu de se taire.

3.4 La règle de silence

On n'affirme que ce sur quoi tous les codes en lice s'accordent, et un seul candidat non documenté suffit à faire taire. C'est « aucune correspondance approchée » (D-004 § 3) appliqué à un référentiel incomplet par construction.

Moins exigeant qu'il n'y paraît : deux moteurs différents s'accordent souvent sur « courroie », qui est la seule chose qu'on ait à dire. Quand les bornes diffèrent, on retient la plus courte — se tromper en avance laisse le choix d'attendre, se tromper en retard sur une courroie coûte un moteur.

3.5 Deux pièges de la source, vérifiés plutôt que supposés

elektromotorindicator ne dit pas ce qu'il semble dire. Il vaut J sur la ligne thermique d'un hybride : il décrit le groupe motopropulseur, pas la ligne. L'utiliser pour écarter l'électrique aurait fait taire tous les hybrides — précisément ceux que D-017 fait entrer. Il est en outre absent de 4,6 M de lignes.

Le discriminant retenu est l'absence de cylindres : une motorisation purement électrique ne porte ni cylindres, ni cylindrée, ni type de carburant, seulement un code (ZK01). Vérifié sur une réception réelle :

motorcode cylindres cylindrée elektromotor hybridemotor lecture
HN05 3 1199 N N thermique pur
HN09 3 1199 J J thermique d'un hybride
ZK01 J N électrique pur

L'énergie doit se lire aussi sur l'asset, pas seulement sur la résolution marque/modèle : la 208 existe en essence, hybride et électrique sous un seul numéro de réception. Sans ce repli, une 208 électrique héritait de la courroie des versions thermiques.


4. La courroie de distribution

4.1 Pourquoi elle, et elle seule

L'audit a produit un constat qu'il n'allait pas chercher : le tableau de bord annonce déjà presque tout — la révision, l'additif FAP, la pression des pneus, la charge de batterie, le colmatage du filtre. Il n'annonce jamais la courroie. Aucun voyant, sur aucune voiture.

C'est le seul angle mort du combiné, et c'est celui qui coûte un moteur. Le pipeline code moteur ne sert qu'à ça — mais « que ça » est exactement la place que fokan revendique.

4.2 Trois niveaux de dire

courroieWindow (src/engine/windows.ts) distingue ce qu'on sait de ce qu'on ignore, au lieu de tout ramener au repli générique :

Ce qu'on sait Ce qu'on dit Confiance Notifie ?
Moteur inconnu selon le kilométrage — préconisation du modèle libre non
Courroie, pas d'intervalle courroie de distribution — intervalle propre au 1.2 PureTech, à vérifier au carnet libre non
Courroie + intervalle avant juillet 2027 (7 ans — préconisation…) estimee oui
Chaîne chaîne de distribution — pas de remplacement programmé libre non

Le niveau intermédiaire n'est pas cosmétique : le foyer peut agir dessus seul, il sait quoi demander à son garagiste. Rendre le repli générique reviendrait à taire une information qu'on possède parce qu'il en manque une autre.

Le basculement décisif est la confiance, pas la date. AVANCE_JOURS associe libre à null : une fiche libre ne peut structurellement pas envoyer de mail. En passant à estimee, la courroie devient éligible dès l'ouverture de la fenêtre, et immédiatement pour une échéance déjà passée.

4.3 L'ancre

Repère = date_premiere_immat si connue, sinon le 1er juillet de l'année déclarée — même convention que ctWindow. Milieu d'année et pas janvier : le biais moyen devient six mois dans un sens ou dans l'autre au lieu de douze mois toujours du même côté.

Une fenêtre déjà dépassée reste à sa date passée, contrairement au CT qui boucle sur son cycle. Une courroie de douze ans sur une voiture qui roule encore est le cas où le rappel compte ; le repousser le ferait disparaître. Le libellé dit « dépassée », jamais « en retard » — c'est un constat sur une pièce, pas un reproche à une personne.

4.4 Une limite structurelle du produit, découverte ici

comportement_fait: reprogrammer_cycle est déclaré sur les fiches et validé par le schéma, mais aucun code ne le lit — la clé n'apparaît que dans src/knowledge/schema.ts. Le statut fait existe dans la table occurrences, rien ne l'écrit.

Corrigé le 06/08/2026 (D-055) — le recalage de cycle sur une date apprise existe, et ce pilier est celui où il change le plus :

  • La courroie remet son compteur à zéro. Sans ancre, la fenêtre se cale sur l'âge du véhicule — le meilleur repère possible pour une courroie d'origine, et le pire pour une courroie déjà changée : un foyer qui l'a fait remplacer l'an dernier sur une voiture de 2012 lisait « échéance dépassée depuis 2018 ». Un remplacement déclaré devient le nouveau repère. La confiance reste estimee : l'ancre corrige le repère, pas la borne, qui demeure une préconisation constructeur en années que le kilométrage peut avancer et que fokan ne suit pas.
  • Le contrôle technique se cale sur le contrôle précédent, ce qui est la règle du Code de la route dès que le premier est passé — le calcul par anniversaire ne faisait que l'approcher, de plus en plus mal à mesure qu'un contrôle passé en avance ou en retard décale la série. Le cycle vient de PERIODICITE_CT et jamais de recurrence : la fiche voiture déclare biennial et celle des deux-roues custom/3, si bien qu'un cycle déduit de la récurrence marcherait sur l'une par coïncidence.

Ce qui ne change pas : sans geste du foyer, la datation sur l'âge reste le seul point de départ, et c'est le cas de la quasi-totalité des véhicules aujourd'hui.

4.5 Les hybrides

courroie-distribution conditionnait sur energie in [essence, diesel], ce qui excluait les hybrides — alors qu'ils ont un moteur thermique, donc une distribution, et que le cas le plus coûteux du parc (PureTech hybride à courroie humide) tombait dedans. Corrigé en v3. Effet mesuré immédiatement : les échéances courroie-distribution sont passées de 3 à 12 sur la base de test.


5. La courroie humide

5.1 Le fait technique

Une courroie humide tourne dans l'huile moteur. L'huile se dilue avec le carburant sur les trajets courts, attaque le revêtement de la courroie qui se délite, et les particules obstruent la crépine de la pompe à huile. Le problème n'est donc pas d'abord la rupture : c'est la perte de pression d'huile qu'elle provoque en amont, sans alerte avant le voyant rouge.

Familles concernées : PureTech 1.0 et 1.2 (moteurs EB) chez Peugeot, Citroën, DS et Opel ; EcoBoost 1.0 et EcoBlue chez Ford.

5.2 La prise en charge — sources primaires uniquement

Toutes les données de la fiche viennent du document officiel Stellantis « PureTech Terms and Conditions », version du 11/05/2026 (eb2conditions.stellantis-support.com), et du communiqué media.stellantis.com du 16/01/2025. Pas de la presse, qui a relayé 175 000 km — chiffre de l'annonce de mars 2024 — alors que le texte en vigueur dit 180 000.

Point Valeur officielle
Couverture 10 ans ou 180 000 km, au premier atteint, depuis le début de garantie (1re immatriculation)
Prise en charge 100 % pièces et main-d'œuvre
Moteurs — atmosphériques 1.0 / 1.2 PureTech produits de juin 2012 à juin 2022
Moteurs — turbo 1.2 PureTech produits d'avril 2014 à décembre 2025
Défauts couverts Perte de pression d'huile (dégradation de la courroie) ; surconsommation d'huile (segmentation avant Euro 6.2, séparateur d'huile au-delà)
Condition d'entretien Plan constructeur respecté, huile comprise — par n'importe quel professionnel
Preuve demandée Les 3 dernières factures détaillées, ou carnet tamponné réseau
Tolérance 3 mois / 3 000 km de retard
Diagnostic et réparation Par le réseau agréé, obligatoirement
Remboursement rétroactif Frais engagés du 01/01/2022 au 31/12/2024, réclamation en ligne

5.3 Ce que fokan en fait

La fiche courroie-humide-prise-en-charge s'applique sur l'attribut distribution_humide, jamais sur un code moteur écrit en dur — même séparation que les fiches ZFE (D-011). Si un moteur quitte le référentiel, l'attribut disparaît au passage suivant et l'échéance s'archive en silence.

Le message n'est pas « ton moteur va casser ». Il est : garde tes trois dernières factures. C'est la seule chose qui transforme une facture de moteur en réparation gratuite, et c'est exactement ce que personne ne fait.


6. Architecture — qui vit où

La règle de tri est celle de D-004 : si je supprime la table et rejoue le pipeline, est-ce que je récupère exactement la même chose ?

Donnée Pourquoi
Les 12 fiches du pilier Connaissance (knowledge/templates/vehicules.yaml) Éditorial, ID stables à vie, relecture par diff, atomicité avec le code, bicéphalie avec les pages SEO
Catalogue RDW (2,9 M configurations) Base (vehicules_reference, vehicules_modeles) Pipeline pur, rejouable à l'identique
Codes moteur (3,2 M lignes) Base (vehicules_motorisations) Idem — aucun jugement humain
Poids du parc immatriculé Base (parc_immatricule) Idem — un comptage, rien d'autre
Campagnes de rappel (1 662) Base (rappels, rappels_modeles, rappels_receptions) Idem — un recopiage de RappelConso, purge comprise
Zones ZFE Base (zfe_zones) Idem — un recopiage, purge comprise
Zones absentes du jeu national (Lille, Caen, Le Havre, Pau, Nîmes) Connaissance (zfe-complements.ts) Non : constater qu'une agglomération manque, aller chercher son tracé ailleurs et vérifier sa règle chez la collectivité est un jugement. La géométrie recopiée atterrit en base (provenance in ('osm','commune')), la déclaration reste en git
Règles périmées du jeu national (Paris, Grenoble, Nancy) Connaissance (zfe-corrections.ts) Idem — chaque correction porte sa date de lecture, sa source et son motif, et disparaîtra le jour où la source rattrapera son retard
Nom des agglomérations ZFE Connaissance (zfe-noms.ts) La source ne renseigne nom que sur 2 zones sur 35 ; choisir « Eurométropole de Strasbourg » plutôt que « Strasbourg » est un jugement
Courroie ou chaîne, par moteur Base (moteurs_distribution) Jugement humain, mais tracé en colonnes (confiance, revu_par, revu_le) donc requêtable — pas en historique git que personne ne lirait

Le moteur de fenêtres ne reçoit aucun référentiel en argument : tout ce que les référentiels savent d'un véhicule est posé sur l'asset par les jobs d'enrichissement, avant réconciliation. Une seule frontière I/O pour tout le pilier, et buildDesiredState ne charge plus rien (invariant n° 5).

Chaîne d'enrichissement

quiz (POST /api/quiz)
  ├─ assets créés
  ├─ rattraperCritairFoyer          ← ne dépend pas de l'adresse
  ├─ enrichirDistributionFoyer      ← ne dépend pas de l'adresse
  ├─ runReconciliation
  └─ si adresse : enrichirRisquesFoyer → Géorisques, ZFE, veille, distribution (rejeu), réconciliation

cron hebdomadaire (dimanche 00h30)
  syncVehiculesRdw → rappels → syncZfe (Base Nationale + Nice)
                            → syncZfeComplements (OSM, limites communales)
                            → syncNucleaire → calendrier scolaire
                            → rafraichirRisquesTousFoyers (par foyer, + moisson PPRT)
                            → syncZonesSecheresse → scolarité

Aucun tracé n'est tenu à la main : les scripts npm run zfe:complements, nucleaire:sync et secheresse:sync n'existent que pour amorcer une base neuve. Et quand deux sources publient la même agglomération, l'officielle prime : chaque complément déclare les SIREN sous lesquels une publication officielle apparaîtrait, et s'efface devant elle plutôt que de se superposer (D-023).

L'enrichissement distribution a été placé hors du passage Géorisques après avoir constaté que celui-ci n'a lieu que si une adresse a été donnée — or l'écran 0 du quiz est optionnel. Un foyer déclarant une voiture sans adresse serait resté sans identification de moteur jusqu'au cron du dimanche.


7. Sourcing — l'état réel et la méthode

7.1 Ce qui est en base

Mis à jour le 28 juillet 2026, à l'occasion de l'audit complet — la version précédente ne décrivait que la famille EB.

scripts/seed-distribution.ts écrit deux ensembles :

a. Les huit moteurs les plus répandus du parc français, sourcés un par un, avec la confiance qui reflète honnêtement la source :

Code Famille Type Intervalle Confiance type / intervalle
YH01 1.5 BlueHDi courroie humide a_verifier / a_verifier
H5F F4 1.2 TCe chaîne (sans objet) moyenne / —
H5H E4 1.3 TCe chaîne (sans objet) moyenne / —
K9K U8 1.5 Blue dCi courroie 60-120 mois, 60-160 000 km moyenne / a_verifier
5F01 1.6 essence (EP6) chaîne (sans objet) a_verifier / —
9H05, 9H06 1.6 HDi courroie a_verifier / —
BH02 1.6 BlueHDi courroie a_verifier / —

b. 26 orthographes de code pour la famille EB (PureTech), campagne eb2_puretech, courroie humide — dérivées de la source (cylindrée 1 199 cm³ / 3 cylindres, restreintes à la nomenclature PSA) et non tapées à la main :

EB2ADT, EB2ADT (HN05), EB2ADTS, EB2ADTS (HN05), EB2DT, EB2DTM, EB2DTS, EB2F, EB2FA, EB2FA (HM05), EB2F LPG, HM01, HM02, HM03, HM05, HN0, HN01, HN02, HN03, HN04, HN05, HN06, HN07, HN09, HNZ, ZM01

Le litre 3 cylindres est un carrefour — Toyota 1KR, Volkswagen CHZ/DLA, Opel B10XE, Renault H4D, Hyundai G3LC — d'où le code exact ZM01 plutôt qu'un préfixe pour le 1.0 PureTech.

Trois niveaux de source, et la colonne confiance les dit : haute = document constructeur daté et versionné (un seul, le DV5) ; moyenne = page officielle du constructeur raisonnant par modèle et se déclarant non exhaustive (renault.fr) ; a_verifier = aucune source officielle publique — c'est le cas de tout le diesel PSA, ni Peugeot ni Citroën ne publiant courroie-ou-chaîne par code moteur. Aucune valeur ne vient de la presse, d'un forum ou d'un site spécialisé.

7.2 Ce qui manque, et pourquoi c'est assumé

Un seul intervalle de remplacement est écrit, et il ne date rien. Le K9K U8 porte la fourchette officielle de Renault (« 5 à 10 ans ou 60 000 à 160 000 km selon les modèles ») — mais c'est une fourchette de marque, pas une préconisation par moteur, d'où confiance_intervalle: a_verifier. Et courroieWindow (src/engine/windows.ts:136) refuse de dater sur un intervalle a_verifier : c'est la règle née d'un vrai faux positif, qui annonçait à un foyer une courroie dépassée depuis deux ans.

Conséquence directe, à regarder en face : couvertureDistribution().peutNotifier vaut zéro. La machinerie complète — ingestion des codes moteur, identification, règle d'unanimité, fenêtre datée, fiche de prise en charge, scheduler — est en place et testée, et la courroie ne se date aujourd'hui pour personne. Le pilier informe, il ne rappelle pas encore.

C'est le seul travail qui change cela, et il ne demande pas une ligne de code : quelques intervalles officiels bien choisis (§ 7.4).

Le raisonnement sur l'absence d'intervalle reste entier : la contrainte de schéma qui l'aurait exigé a été retirée volontairement. « Courroie, intervalle non documenté » est déjà une information utile — elle déclenche la fiche de courroie humide et elle empêche de dire « chaîne » à tort. Une borne inventée pour satisfaire un schéma serait le faux intervalle que D-004 proscrit.

7.3 La méthode : sourcer à la demande, dans le bon ordre

5 991 codes moteur pour les voitures particulières. Les documenter tous serait une fiction ; en documenter quinze bien choisis ferait basculer le pilier du registre « information » à celui de « rappel ». Tout dépend donc du classement.

npm run distribution:queue   # codes non documentés, les plus utiles d'abord
npm run distribution:seed    # amorçage de la famille EB, idempotent

Le premier classement était faux. Il triait par nombre de configurations du catalogue, ce qui mesure à quel point un constructeur a décliné une version, pas combien de voitures existent. Résultat, il proposait de sourcer un moteur Iveco avant le 1.5 dCi : le 8140 43S totalise 25 360 configurations, dont 24 125 pèsent plus de 3 t et se répartissent entre Dethleffs, Autostar, Trigano, Hymer… des carrossiers de camping-cars, un modèle chacun. C'est le piège des « modèles à configuration unique » de D-004, sous une autre forme.

Trois niveaux de tri, du plus juste au plus disponible :

Niveau Source Ce qu'il vaut
1. foyers nos propres assets, via le champ K et l'énergie déclarée Le seul signal qui ne mente pas. Prime même à 1
2. parc immatriculé parc_immatricule (registre RDW) Du vrai parc — néerlandais
3. catalogue vehicules_reference, hors ≥ 3 t Dernier recours

Le niveau 1 restreint par l'énergie déclarée : sans ça, un C5 Aircross hybride créditait aussi le diesel de sa réception, qu'il n'a pas.

Le biais du niveau 2 est visible dans le résultat, et c'est voulu — il est imprimé sous le tableau plutôt que caché dans le code :

  code                foyers   parc NL  modèles
  5G06                     6    22 273       17
  1KR-FE                   0   302 144        6
  1KR                      0   191 014       10
  CHY                      0   142 026        8
  169A4000                 0   114 803       13
  G3LA                     0   103 113        6

Toyota, Volkswagen, Fiat, Hyundai, Suzuki. Le parc néerlandais sous-représente le diesel français : ni K9K ni DV6 n'apparaissent dans les vingt premiers, alors qu'ils dominent le parc français. Ce classement ne dispense donc pas du jugement — il écarte le bruit, il ne désigne pas la France.

7.4 Le classement France, et pourquoi il est tenu à la main

Il n'existe pas de source ouverte française au niveau du modèle. Vérifié : le SDES et data.gouv publient le parc et les immatriculations par commune, carburant, Crit'Air, âge et statut d'utilisateur — jamais par marque et modèle. Le seul signal français disponible est le classement publié par la presse spécialisée (Clio 101 892, 208 73 092, Sandero 64 400 immatriculations neuves en 2025), qui est du flux et non du stock.

D'où MODELES_PARC_FR dans src/knowledge/distribution-moteurs.ts : vingt-quatre couples marque/modèle, tenus à la main, en git plutôt qu'en base (rejouer un pipeline ne les reproduirait pas — règle de tri de D-004). Ils ne servent qu'à classer un travail de sourcing : aucune échéance, aucun contenu utilisateur n'en dépend, et une erreur y fait sourcer dans le désordre, rien de plus.

npm run distribution:queue en tire une seconde vue qui corrige le biais néerlandais par l'autre bout — partir des modèles français, remonter à leurs moteurs :

  code                modèles FR   parc NL
  5F01                         7    19 601     ← EP6, essence 1.6
  YH01                         7     1 276     ← DV5R, 1.5 BlueHDi
  9H05                         7       597     ← DV6, 1.6 HDi
  H5F F4                       6    16 654     ← Renault 1.2 TCe
  H5H E4                       6    10 114     ← Renault 1.6 E-Tech
  BH02                         6     1 725     ← DV6FC BlueHDi
  K9K U8                       6       477     ← 1.5 dCi
  NFU                          5    16 973     ← TU5JP4, 1.6 16v
  8F01                         5     9 268     ← TU3

Le contraste avec le classement néerlandais est frappant : le K9K U8 équipe six des vingt-quatre modèles français les plus répandus et ne compte que 477 voitures aux Pays-Bas. Aucun de ces moteurs n'apparaissait dans les vingt premiers de l'autre vue.

Pour chacun : type de distribution, borne en mois, borne en km, source citable, revu_par. Le type seul est déjà exploitable — l'intervalle peut suivre.


8. Ce qui reste ouvert

  1. Sourcer les intervalles (§ 7.4) — le seul travail qui débloque la fenêtre datée. Aujourd'hui peutNotifier = 0 : le pilier informe, il ne rappelle pas.

  2. Ouvrir le champ P.2 à la voie déclarative (audit § 3) — trois pas proposés, et une mesure préalable : combien de couples marque/modèle/énergie/P.2/année tombent sur un moteur unique ? Si le gain n'est pas là, la question ne doit pas être posée. C'est la même mesure que celle de D-017, appliquée à l'autre voie.

  3. Demander la date de 1re immatriculation (champ B) — un champ, et le CT devient exact tandis que la courroie s'ancre sur une vraie date au lieu du 1er juillet de l'année déclarée.

  4. Filtrer les moteurs en lice par l'annéecodesEnLice ne borne jamais sur dateReception. Sur un modèle vendu quinze ans, c'est ce qui sépare « douze moteurs candidats » de « trois ».

  5. Implémenter comportement_fait (§ 4.4) — sujet transverse à tout le produit, pas au seul pilier véhicules.

  6. carte-grise-changement-adresse est une condition mortecorrigé le 07/08/2026 (D-063). Rien ne posait jamais demenagement_recent : c'était le seul attribut mort sur les 29 du DSL, et on l'attendait du jour où l'adresse deviendrait modifiable dans le hub. Ce jour existait déjà — le rejeu du quiz (D-018) est le seul endroit du produit où l'ancienne adresse et la nouvelle sont dans la même fonction. La fiche passe en v2 : applicabilité sur demenagement_mois (le mois, jamais un booléen qui resterait vrai à vie), stratégie demenagement_carte_grise, fenêtre = 1er du mois suivant, avance de 30 jours pour que le rappel parte à l'ouverture du délai et non neuf jours avant l'amende. icad-coordonnees côté animaux reste, lui, à traiter. Deux conséquences à connaître : la fiche quitte la famille des choses qui ne se font qu'une fois (on déménage plusieurs fois dans une vie, et le second déménagement rouvre le même délai) ; et comme les véhicules sont recréés à chaque rejeu, un « c'est fait » posé dessus ne survit pas au rejeu suivant — c'est le compromis F8 sur les assets multiples, pas un défaut propre à cette fiche.

  7. Ford EcoBoost / EcoBlue — la courroie humide n'est pas que chez Stellantis, et rien n'est encore sourcé côté Ford.

  8. La vignette Crit'Air est une réponse globale au quiz, appliquée à tous les véhicules du foyer. Un foyer à deux voitures dont une seule a sa vignette ne peut pas le dire.

  9. Deux-roues et remorques — annoncés au § 5.3 du cadrage comme option du quiz, jamais implémentés. Le contrôle technique moto est une échéance légale récente, dormante par excellence ; la couverture du référentiel RDW pour la catégorie L reste à vérifier (le code ne filtre aujourd'hui que sur M1).

    Livré le 30/07/2026 (D-031 § 6) — la règle est vérifiée aux sources primaires, et elle était à deux nombres près celle qu'on implémentait déjà : obligation depuis le 15 avril 2024 pour les catégories L (cyclomoteurs, motos, scooters, tricycles, quadricycles), premier contrôle dans les 6 mois précédant le 5ᵉ anniversaire de la première mise en circulation, puis tous les 3 ans. ctWindow fait 4 ans puis 2 ans : la stratégie ct_vehicule accepterait un paramétrage par catégorie sans qu'une ligne de moteur bouge.

    La périodicité est devenue un paramètre de la stratégie ct_vehicule (PERIODICITE_CT), pas une seconde stratégie. Deux fiches en revanche, parce que le contenu diffère : une fiche unique aurait dû écrire « 4 ou 5 ans selon ton véhicule », ce qui ne renseigne personne.

    La couverture RDW de la catégorie L a été vérifiée : elle existe (L3e 34 874, L1e 27 669, L7e 16 616, L1e-B 11 463…). Le référentiel n'y a pourtant pas été étendu, et c'est un choix : l'y ouvrir demande une synchronisation multi-catégories, une recherche de modèles et un barème Crit'Air propre aux deux-roues. Le contrôle technique n'a besoin d'aucun des trois — l'année suffit. Un deux-roues se déclare donc en une question, plutôt que par une recherche de modèle qui ne rendrait jamais rien.

    Aucun Crit'Air n'est estimé pour un deux-roues, et c'est un refus explicite : leur barème n'est pas celui des voitures, et appliquer la table existante produirait une classe plausible et fausse — celle sur laquelle un foyer se fierait pour entrer dans une ZFE. Reste donc ouvert : le barème Crit'Air deux-roues, et l'extension du référentiel à la catégorie L.

    Sources : service-public F37538 ; décret n° 2021-1062 ; arrêté du 23 octobre 2023, modifié le 19 décembre 2025.

  10. Les rappels viennent désormais de RappelConso, et de lui seul (D-032, 30/07/2026). Le registre français est entré le matin à côté du néerlandais (D-031 § 3) ; le porteur de projet a tranché le jour même pour la source française seule.

    Ce qui suit décrit l'état d'avant la bascule, conservé parce qu'il porte la mesure qui l'a motivée. src/knowledge/rappels.ts lisait alors RDW : 5 242 campagnes, rattachées par marque + dénomination, avec deux limites que le fichier reconnaissait lui-même (ni millésimes ni VIN dans la source ; c'était le parc néerlandais). RappelConso — le registre français, alimenté par la DGCCRF, la DGAL, la DGEC et la DGPR — a été appelé et vérifié :

    Relevé le 30/07/2026 Valeur
    Fiches totales 18 259
    dont automobiles et moyens de déplacement 1 755 (1 662 autos/motos/scooters, 37 vélos, 30 accessoires, 2 pneus)
    Fraîcheur dernière publication auto le 29/07/2026
    Fiches mentionnant un airbag 124, dont des Takata publiés en juillet 2026 (BMW, Skoda, Jaguar, Land Rover)

    Champs utiles : marque_produit, modeles_ou_references (souvent avec des plages de VIN), motif_rappel en français, risques_encourus, conduites_a_tenir_par_le_consommateur, date_de_fin_de_la_procedure_de_rappel, nature_juridique_rappel.

    Ce que le retrait coûte, mesuré et assumé : sur les 24 modèles les plus répandus du parc français, le registre néerlandais recensait 586 campagnes, le français 242 ; le premier remontait à 2010, le second à 2018. Un foyer voit donc environ deux fois moins de campagnes, et plus rien avant 2018. En base : 5 246 campagnes et 10 560 rattachements supprimés, 1 662 et 1 909 conservés.

    Ce qu'on gagne n'est pas du volume : une source française pour un parc français, un défaut qu'on lit au lieu de le deviner, un seul chemin d'ingestion — et la disparition de la note qu'il fallait afficher au foyer pour expliquer qu'une même campagne pouvait apparaître deux fois.

    Ce que le français apporte, et c'est tout : motif_rappel (le défaut en prose, rempli sur 1 661 fiches sur 1 662), risques_encourus, et un lien vers la fiche officielle. Les champs conduites_a_tenir, nature_juridique et date_de_fin_de_procedure sont vides à 100 % sur l'automobile — les rappels de véhicules ne passent pas par le circuit de retrait-rappel de la consommation. Vérifié, pas supposé.

    À l'écran : « les écrous de roue peuvent se détacher pendant que le véhicule est en mouvement » remplace « Essieux, roues et pneus ». La pastille de la frise ne se colore plus par gravité — c'était la seule chose que l'autorité néerlandaise évaluait, et colorier au hasard aurait été pire que ne pas colorier. La réserve, elle, ne change pas d'un mot : un rappel désigne un modèle, jamais un exemplaire, donc « ce modèle a fait l'objet d'un rappel » et jamais « ta voiture est rappelée ». Le garde-fou par année de rappelsPourVehicule est conservé tel quel.

    Et le VIN n'est pas demandé : seules 71 fiches sur 1 662 (4 %) en mentionnent, toujours comme une plage de numéros de série qui n'est pas un intervalle lexicographique. Tester l'appartenance par comparaison de chaînes rendrait une réponse fausse.

    Ce que le VIN ne pouvait pas faire, le champ K le fait (D-034, 30/07/2026). Le champ informations_complementaires, qu'on n'ouvrait pas, porte une réception CE lisible sur 94,6 % des fiches automobiles — au format exact du champ K de la carte grise (e2*2007/46*0532*19). C'est la seule donnée de la source qui désigne une version : une « 308 » couvre 103 réceptions de 2007 à 2026, et l'extension, contrairement aux caractères d'un VIN, est un nombre dont l'intervalle a un sens.

    Elle qualifie, elle ne filtre pas, et la nuance est le cœur de la décision. Sur un 3008, l'appariement par réception fait tomber 33 campagnes à une médiane de 1 — tentant, et à ne pas faire : on sait mesurer la précision de ce rattachement, pas son exhaustivité. Une fiche qui omettrait une réception, ou l'écrirait d'une façon que le parseur rate (5,4 % n'en publient aucune de lisible), produirait un silence sur un rappel de sécurité. Les campagnes citant le champ K s'ajoutent donc à celles du modèle et se distinguent à l'écran (« dont N sur ta version »). L'union sert aussi dans l'autre sens — 39 % des fiches n'accrochent aucun modèle du référentiel et redeviennent visibles par leur réception : une C5 Aircross passe de 18 campagnes à 23, dont 12 sur sa version.

    Le parseur (receptionsDeLaFiche) a été écrit d'après un relevé des notations réelles, pas d'après le format théorique — les deux ne se ressemblent pas. Trois refus tenus par des tests : , 308 est un nom de modèle et non une extension (c'est l'astérisque qui distingue une continuation d'un libellé) ; un tiret entre deux bases différentes est une énumération et non une plage (chaînes BMW, dont une écrite à l'envers) ; aucune coquille de la source n'est réparée. Détail des formes en D-034 § 3.

    À ne pas confondre avec le reste du jeu : les 1 138 rappels bébés-enfants et les 498 maison-habitat ne sont pas exploitables aujourd'hui — on ne connaît aucun produit du foyer, et croiser des rappels alimentaires sur « il y a des enfants ici » serait le bruit que le § 4.4 refuse. C'est le premier usage sérieux de la bannette (Phase 2), pas un chantier d'aujourd'hui.

    Sources : RappelConso — open data ; jeu de données ; endpoint https://data.economie.gouv.fr/api/explore/v2.1/catalog/datasets/rappelconso-v2-gtin-espaces/records.


Trois fiches de ce pilier n'ont plus de geste (07/08/2026)

D-059 : zfe-restriction-actuelle, courroie-humide-prise-en-charge et chaine-aac-dv5-prise-en-charge passent en comportement_fait: aucun. Elles décrivent un état du monde — ce que la zone refuse aujourd'hui, une prise en charge constructeur ouverte jusqu'à 10 ans — et non un acte à accomplir. « C'est fait » y était un contresens ; l'écran n'affiche plus aucun geste dessus, plutôt qu'un bouton dont le libellé mentirait.

À ne pas confondre avec zfe-durcissement, qui reste clore : un durcissement programmé est un rendez-vous, avec une date.

Rappel utile pour ce pilier : la sourdine ne s'affiche plus non plus sur une fenêtre libre, qui n'envoie jamais de mail. courroie-distribution sans intervalle sourcé et revision-constructeur sont dans ce cas — leur proposer de couper des rappels laissait croire qu'il en partait.