Aller au contenu

ADR-005 — chosen_source = array, pas singleton

Statut Accepted
Date 07/05/2026 (S19 mid-week)
Décideurs Romain BAZIL, Nicolas Léonard
Origine Synchro S19 mid-week §5

Contexte

Quand plusieurs sources convergent sur une valeur (ex. 3 sources disent "140 m²" pour la surface habitable) et qu'un AM clique sur "utiliser cette valeur", l'UI capture un seul clic sur une seule source. Conséquence côté data : on enregistre chosen_source = "source_A", comme si l'AM avait préféré cette source aux deux autres.

Dans les faits, les trois sources étaient d'accord. L'AM a juste cliqué sur la plus proche du curseur, ou la première de la liste. Le clic ne reflète pas une préférence réelle.

Décision

Le data model enregistre un array de sources convergentes, pas une seule.

Schéma

Avant (singleton) :

{
  "field": "surface_habitable",
  "value": 140,
  "chosen_source": "data_extraction"
}

Après (array) :

{
  "field": "surface_habitable",
  "value": 140,
  "chosen_sources": ["data_extraction", "haiku_files", "source_declarative"],
  "ui_clicked_source": "data_extraction",
  "validated_by": "am_user_id",
  "validated_at": "2026-05-12T14:32:00Z"
}

  • chosen_sources (array) = toutes les sources qui s'accordaient sur la valeur retenue
  • ui_clicked_source (single) = celle sur laquelle l'AM a cliqué (pour debug UX, pas pour analytics produit)
  • validated_by / validated_at = stamp de validation manuelle, vide si auto-validation

Rationale

Le problème analytics

Si on enregistre chosen_source comme singleton, les analytics produit deviennent :

  • « Source A est cliquée 3× plus souvent que source B »
  • → décision : « on investit plus dans source A »
  • → en réalité, A est juste plus proche du curseur ou plus haute dans la liste

C'est de l'UX bias déguisé en signal qualité. À l'échelle, ça oriente toutes les décisions d'investissement freelances et techniques dans la mauvaise direction.

Le bon signal

Avec l'array :

  • « Sur les surfaces habitables, source A et source B convergent à 87% »
  • « Sur les bilans financiers, source A converge avec source C 65% du temps, mais avec source B seulement 40% »
  • → on peut spécialiser par typologie et arbitrer prix vs qualité sur le golden dataset full-pipeline

Capture passive de la convergence

Chaque enregistrement chosen_sources: [...] avec |array| ≥ 2 = une ground truth gratuite pour le golden dataset. C'est l'application directe du principe "capture passive > annotation forcée" (cf. philosophie produit §4).

Conséquences

Ce qui change

  1. Migration data model côté project-analysis (App TS)
  2. Adaptation UI : le clic AM continue de marcher comme avant, mais ce qui est persisté change
  3. Analytics produit : nouveau champ à exploiter (chosen_sources) pour mesures de convergence
  4. Eval system : peut alimenter passivement les golden_references quand convergence forte

Ce qu'il faut faire

  • Migration schema Drizzle (section_versions ou table dédiée)
  • Backward compatibility sur les enregistrements existants (treat singleton as array of 1)
  • Adapter les pages de visualisation (vue comparative)
  • Documenter dans le doc in-app que la convergence est traçée

Ce qu'il faut éviter

  • Inférer la "préférence" AM à partir de ui_clicked_source seul : c'est le bias qu'on vient de neutraliser
  • Demander à l'AM de cliquer sur toutes les sources convergentes : aucune valeur ajoutée pour lui, on peut le déduire automatiquement

Alternatives écartées

  • Garder singleton + UI qui demande "tu valides toutes les sources convergentes ou juste celle-ci ?" : friction supplémentaire pour l'AM, sans gain réel
  • Inférer la convergence a posteriori sur les données existantes : on perd l'horodatage et le contexte de la décision

Synthèse des échanges

Un clic ne prouve pas qu'une source est meilleure. Quand plusieurs sources portent la même valeur, le système doit conserver toute la convergence et séparer ce signal du simple emplacement du clic dans l'interface.

Voir aussi

Sources