Aller au contenu principal

DMV — Synthèse d'architecture : le Ranking Engine et l'organisation du Context Engine

Introduction

Ce document consolide l'ensemble des réflexions menées à travers plusieurs documents et échanges successifs. Il ne remplace pas les documents précédents (vision, principes de pertinence, pipeline de décision) — il les organise, tranche les points restés ouverts, et ajoute la pièce qui manquait depuis le début : le mécanisme concret de classement, appelé ici Ranking Engine.

Il reste un document métier. Aucune technologie n'y est mentionnée.


1. Les trois surfaces du Context Engine

La réflexion a longtemps traité DMV comme un moteur unique. Il apparaît en réalité que le Context Engine sert trois usages distincts, qui partagent une base commune (pipeline, filtrage, exclusion des contenus invalides) mais qui se déclenchent différemment et ne composent pas leurs résultats de la même façon.

1.1 Le MurVille (mur public territorial)

  • Contexte maîtrisé : une commune, un flux public.
  • Publications empilées par date, filtrées par validité.
  • Ce sujet est considéré comme réglé et n'est pas l'objet de ce document.

1.2 Le mur personnel (privé, mode passif)

  • Alimenté sans requête explicite de l'utilisateur.
  • Doit refléter ce qui le caractérise : ses relations, ses centres d'intérêt, sa géographie.
  • C'est le sujet principal de ce document (sections 2 à 5).

1.3 La recherche mixte (mode actif, intention explicite)

  • Déclenchée par une requête en langage naturel, potentiellement multi-intentions (ex : logement + activités + sorties + événements).
  • Décomposée en sous-recherches spécialisées par type d'objet, chacune avec ses propres filtres durs et son propre classement local.
  • La composition du résultat final suit directement la structure des intentions détectées dans la requête — pas de calcul de densité territoriale nécessaire ici.
  • Un LLM a un rôle légitime à ce niveau : extraction d'intention et structuration de la requête, jamais pour le ranking final, qui reste déterministe.

2. Le mur personnel : deux flux de nature différente

Le mur personnel n'est pas un flux unique filtré par plusieurs critères combinés. Ce sont deux flux indépendants, fusionnés ensuite dans une seule liste, mais dont les règles d'inclusion n'ont rien à voir.

2.1 Flux relationnel

  • Alimenté par les acteurs explicitement suivis par l'utilisateur.
  • Inconditionnel : aucun filtre géographique ne s'applique. Un acteur suivi dans une ville jamais visitée par ailleurs reste dans le mur, parce qu'il caractérise l'utilisateur.
  • Principe fondateur : ce qui définit l'utilisateur (ses relations explicites) prime toujours sur ce qui décrit son environnement (sa position, ses villes).

2.2 Flux territorial (découverte)

  • Alimenté par la géographie active de l'utilisateur : ville favorite (résidence), ville GPS (position actuelle), villes suivies (famille, vacances, attaches occasionnelles).
  • Sert la sérendipité : sans lui, l'utilisateur ne verrait jamais rien de nouveau, juste ce qu'il suit déjà.
  • Règle d'inclusion asymétrique selon le rôle de la ville :
    • Ville favorite et ville GPS : la géographie seule suffit à inclure une information.
    • Villes suivies (non favorite, non GPS) : la géographie seule ne suffit pas. Il faut en plus au moins un signal d'affinité (catégorie suivie, acteur suivi même non localisé dans cette ville, importance intrinsèque de l'information).

2.3 Fusion et étiquetage

Les deux flux sont fusionnés dans une seule liste, mais chaque élément conserve un tag d'origine et de justification (ex : « pertinent car acteur suivi », « pertinent car ville favorite + fraîcheur », « pertinent car catégorie voyage suivie »). Ceci répond à un double besoin : transparence pour l'utilisateur, et auditabilité pour la conception (pas de score caché).

Décision tranchée : le flux relationnel n'a pas de priorité de principe sur le flux territorial. Les deux sont fusionnés puis triés uniquement par le score du Ranking Engine — la relation directe (acteur suivi) est un facteur fort dans ce score, mais pas un passe-droit absolu. Imposer une priorité de structure reproduirait l'erreur des quotas déjà écartée (document 4) : une contrainte rigide plutôt qu'un reflet de l'importance réelle. Seule la criticité reste un court-circuit absolu, et elle s'applique indifféremment aux deux flux.


3. La portée géographique : abandonner le rayon fixe

Le rayon unique paramétré par utilisateur ne fonctionne pas, parce qu'il applique la même contrainte spatiale à des informations dont l'importance n'a rien à voir avec la distance. Deux exemples extrêmes l'illustrent :

  • Un repas associatif à 5 km ne doit pas apparaître, malgré la faible distance, en l'absence de tout signal d'affinité.
  • Un concert d'envergure nationale à 20 km doit apparaître, malgré la distance, parce que son importance intrinsèque dépasse le rayon habituel.

3.1 Principe retenu

La portée n'est jamais une propriété fixe de l'utilisateur seul. C'est une fonction de trois éléments combinés :

  1. Catégorie de l'information (alerte, événement, publication municipale, commerce…)
  2. Affinité de l'utilisateur pour cette catégorie (dérivée des acteurs suivis, des centres d'intérêt déclarés, des « ça m'intéresse »)
  3. Envergure intrinsèque de l'information (locale / intercommunale / départementale / nationale)

3.2 Portée par catégorie (règle de base, avant affinité)

  • Alertes de sécurité / criticité : portée par rayon géographique réel (km), indépendante du découpage administratif. Une alerte incendie se propage selon un rayon de danger réel, pas selon les limites de la commune.
  • Informations municipales officielles : portée naturellement communale.
  • Événements / vie associative / loisirs : portée par rayon + affinité déclarée obligatoire au-delà du rayon de base.
  • Commerces / annonces : portée resserrée par défaut, élargie seulement par un signal d'intérêt fort.

3.3 Envergure : comment la connaître sans imposer de saisie au producteur

Contrainte UX-first : on ne demande pas au producteur de classifier lui-même l'envergure de sa publication. On la déduit d'une cascade de signaux structurels, chaque signal ne pouvant que faire monter le niveau, jamais le descendre :

  1. Niveau de départ hérité du type d'acteur : un EHPAD, une association de quartier → hyper-local par défaut. Une mairie, un comité des fêtes → communal par défaut. Un acteur rattaché à un réseau national connu (franchise, fédération) → intercommunal ou régional selon le réseau.
  2. Ajustement par volume d'intérêt agrégé : si le nombre de « ça m'intéresse » toutes villes confondues dépasse un seuil (à définir empiriquement) sur les premières heures/jours suivant la publication, le niveau monte d'un cran — signal sur l'objet et son engouement réel, pas un comportement individuel, donc compatible avec le déterminisme de la V1. C'est un ajustement a posteriori, qui corrige le niveau en cours de route si l'intérêt réel dépasse ce que le type d'acteur laissait présager.

Signal explicitement écarté : le nombre de communes distinctes relayant une même information n'est pas retenu comme signal d'envergure. Une commune ne communique généralement pas sur les affaires d'une autre ; le nombre de communes qui relaient une info dépend souvent d'un hasard administratif (une route ou un incident à cheval sur deux communes limitrophes) plutôt que de l'importance réelle de l'information. Un feu de garrigue mentionné par une seule commune n'est pas moins urgent qu'un problème de circulation mentionné par deux.

3.4 Point explicitement écarté

Toute forme de priorité liée à une contrainte commerciale (prix, places limitées payantes) est à proscrire du ranking : cela reviendrait à favoriser artificiellement un producteur de contenu, ce que les principes fondateurs interdisent. Une contrainte de capacité réelle (places limitées, gratuites ou payantes) pourrait légitimement justifier un facteur d'urgence, mais ce facteur n'est pas retenu pour la V1 (dépendance technique trop lourde : nécessite un flux temps réel de taux de remplissage).

3.5 La gravité des alertes critiques : un état binaire ne suffit pas

La criticité, posée comme un état actif/inactif (document 3), doit en réalité porter une gradation de gravité à l'intérieur même de l'état actif — sans quoi des informations critiques de nature très différente se retrouvent artificiellement à égalité. Le repas d'un EHPAD n'est pas critique ; un accident bloquant une autoroute l'est de façon pratique ; un feu de garrigue poussé par le vent vers une zone habitée l'est de façon vitale. Trois paliers sont retenus, dans l'esprit des dispositifs de vigilance déjà connus du public :

  • Information pratique (travaux, déviation, route coupée sans danger immédiat).
  • Alerte (accident bloquant, embouteillage important).
  • Danger (feu progressant vers une zone habitée, alerte météo extrême) — sécurité vitale, priorité absolue.

Cette gravité influence à la fois le sous-classement entre informations critiques concurrentes, et probablement le rayon de diffusion (un « danger » justifie un rayon plus large qu'une simple information pratique, cohérent avec la section 3.2).

Différence importante avec l'envergure : contrairement à l'envergure des événements ordinaires, la gravité d'une alerte de sécurité doit être déclarée explicitement par un producteur habilité (mairie, service de sécurité), avec un choix simple à 3 options, plutôt que déduite automatiquement. Se tromper automatiquement sur la gravité d'un feu de forêt a des conséquences potentiellement graves ; l'enjeu justifie ici la charge de saisie, contrairement à l'envergure d'une brocante.

Point ouvert, à traiter avec la mairie pilote : qui est habilité à déclencher une alerte critique, et comment garantir une couverture en dehors des heures ouvrées (voir section 8.3).


4. Le Ranking Engine

4.1 Ce que le Ranking Engine n'est pas

  • Ce n'est pas un score global unique à poids fixes mélangeant tous les facteurs dans une seule formule opaque (rejeté depuis le début : illisible, impossible à auditer, effets de bord imprévisibles).
  • Ce n'est pas non plus un empilement de règles IF-THEN imbriquées (rejeté : devient une usine à gaz dès que les cas particuliers s'accumulent).

4.2 Ce que le Ranking Engine est

Une combinaison de facteurs nommés, indépendants, chacun une petite fonction simple et auditable séparément. Chaque facteur peut être expliqué isolément à un utilisateur qui demanderait « pourquoi je vois ceci en premier ? ».

4.3 Les facteurs identifiés

FacteurNatureRôle
Criticité / priorité intrinsèqueÉtat temporaire, court-circuite le resteSécurité, urgence — toujours en tête tant que l'état est actif
Relation directe (acteur suivi)BinaireInclusion inconditionnelle, sans filtre géographique
Affinité catégorielleDérivée (acteurs suivis + centres d'intérêt + seuil sur « ça m'intéresse »)Élargit la portée territoriale au-delà du rayon de base
Proximité géographique pondéréeRôle de la ville : favorite > GPS > suivieFiltre d'entrée du flux territorial
Envergure intrinsèqueDéduite de signaux structurels (voir 3.3)Permet de dépasser le rayon habituel
Fraîcheur de publicationDécroissance depuis la date de parutionPic à la publication, puis décroissance
Proximité temporelle à l'événementCourbe en cloche centrée sur la date d'occurrenceFait remonter un événement à l'approche de sa date

4.3.1 Barème de poids initial (échelle 0-100)

Valeurs de départ, ajustables empiriquement à l'usage. Discutées et validées facteur par facteur.

FacteurValeurNature
CriticitéCourt-circuit absoluBinaire, hors échelle — passe systématiquement devant tout le reste tant que l'état est actif
Relation directe (acteur suivi)60Binaire (présent/absent)
Affinité catégorielle35Fixe pour la V1 (pas de gradation continue — à revoir avec des cas réels et un éventuel signal déclaratif utilisateur, ex. un classement/retour explicite)
Proximité géographique — ville favorite45Fixe
Proximité géographique — ville GPS40Fixe
Proximité géographique — ville suivie20Fixe (ne suffit jamais seul à l'inclusion, doit se combiner à un autre facteur)
Envergure — hyper-local+0Bonus additif
Envergure — communal+10Bonus additif
Envergure — intercommunal+25Bonus additif
Envergure — régional/national+50Bonus additif
Fraîcheur / proximité temporellePic commun à 60Courbe continue (voir 4.4) ; décroissance fraîcheur par défaut sur 7 jours, montée de proximité temporelle pilotée par le niveau d'envergure

Ce barème permet, par construction, qu'un événement d'envergure communale à son pic (60 + 10 = 70) dépasse une publication ordinaire d'un acteur suivi (60), sans qu'aucune règle spécifique n'ait été écrite pour ce cas précis — la hiérarchie émerge de l'addition des facteurs, pas d'une exception codée à la main.

4.4 Le cas des informations datées : deux courbes superposées

Une information avec une date d'occurrence future (ex : une fête de village) combine deux dynamiques temporelles distinctes, à ne pas confondre :

  1. Fraîcheur de publication : pic au moment de la parution, décroissance ensuite (demi-cloche de Gauss) — répond à « les habitants sont-ils déjà informés ? ».
  2. Proximité temporelle à l'événement : montée progressive vers la date cible — répond à « dois-je m'organiser maintenant ? ».

Le résultat combiné produit une courbe à deux bosses (pic à la publication, creux intermédiaire, second pic à l'approche de l'événement). Les deux courbes sont calculées indépendamment.

Décision tranchée : la combinaison retenue est le maximum des deux courbes à un instant donné, pas leur somme. Ce choix privilégie l'explicabilité (un seul facteur dominant à citer dans le tag de justification plutôt qu'un mélange) et la simplicité de calibration (chaque courbe se définit indépendamment, sans avoir à doser un poids relatif entre les deux). Le cas où les deux courbes sont hautes simultanément (annonce publiée juste avant l'événement) ne pose pas de problème particulier : l'information reste haute, simplement sans sur-pondération artificielle par cumul.

4.4.1 Étalement des courbes : ne pas figer une largeur unique

La largeur (écart-type) de ces courbes ne doit pas être une constante globale identique pour toutes les publications et tous les événements — ce serait reproduire, sur la dimension temporelle, l'erreur déjà écartée pour le rayon géographique fixe (section 3). Une alerte de sécurité doit décroître vite une fois l'urgence retombée ; une information municipale structurante reste pertinente plus longtemps. Un événement local ne nécessite d'anticipation que dans les derniers jours ; un événement d'envergure nationale doit commencer à monter dans les murs des semaines à l'avance.

Principe retenu : l'étalement est dérivé de la catégorie de l'information et de son envergure intrinsèque (le même facteur d'envergure défini en 3.3), pas un paramètre saisi par le producteur ni calculé individuellement au cas par cas.

Pour éviter tout risque de sur-calibration (un réglage fin par publication, ou pire, par village), l'envergure est traitée comme une échelle discrète à quatre niveaux, et non comme un curseur continu :

NiveauExempleAnticipation typique
Hyper-localRepas EHPAD, réunion de quartier1-2 jours
CommunalFête du village, brocante2-4 semaines
Intercommunal / bassin de vieFestival multi-communes1-2 mois
Régional / nationalConcert d'envergure nationalePlusieurs mois

Chaque niveau porte un étalement par défaut, ajustable globalement mais pas au cas par cas. Le niveau est hérité par défaut du type d'acteur ou de la catégorie d'événement (un EHPAD publie par défaut en « hyper-local », une mairie publie ses fêtes par défaut en « communal »), avec correction possible mais rare. Ceci respecte la contrainte UX-first déjà posée : le producteur ne règle jamais une courbe, il choisit ou fait déduire un niveau, le moteur calcule le reste.

La variabilité réelle d'un village à l'autre (les habitudes d'anticipation ne sont pas identiques partout) n'est pas traitée dans la V1 comme un problème de conception, mais comme un ajustement empirique des valeurs par défaut, observé une fois le prototype déployé sur plusieurs communes — jamais comme un paramétrage fin par village.

4.4.2 Asymétrie montée / descente après l'événement

La phase qui suit un événement ne doit pas être une simple symétrie de la phase de montée (ce qui supposerait que l'anticipation et l'oubli suivent la même vitesse). Dans les faits, l'anticipation se construit progressivement (organisation, réservation, envie), tandis que l'intérêt retombe plus vite une fois l'événement passé — les gens passent à autre chose plus vite qu'ils ne se préparent.

Principe retenu : après la date de l'événement, l'information ne suit plus une courbe symétrique dédiée. Elle réutilise la fonction de décroissance de fraîcheur déjà définie (point 1 ci-dessus), mais ancrée sur la date de l'événement plutôt que sur la date de publication. Autrement dit, une fois l'événement passé, l'information redevient une actualité ordinaire dont l'horloge de fraîcheur repart de zéro à ce moment précis.

Le cycle complet d'une information datée se déroule donc en trois segments :

  1. Publication → approche de l'événement : montée progressive (proximité temporelle), largeur pilotée par catégorie/envergure (4.4.1) ; en parallèle, la fraîcheur de publication initiale continue de décroître.
  2. Jour de l'événement : pic.
  3. Après l'événement : reprise de la fonction standard de décroissance de fraîcheur, ancrée sur la date de l'événement — pas de courbe spécifique supplémentaire.

Cette approche ne crée aucune nouvelle fonction : elle réutilise une fonction déjà définie avec un point d'ancrage différent, dans le même esprit de facteurs nommés et réutilisables que le reste du document.

4.5 Ce qui reste en amont et ne change pas

Le pipeline déjà posé (Chargement → Filtrage → Validation → Classification → Priorisation) reste la base indispensable. Le Ranking Engine ne s'applique qu'aux candidats déjà valides et filtrés — il ne remplace aucune étape existante, il vient combler ce qui, dans les documents précédents, était nommé tour à tour « pertinence contextuelle », « classement », « composition », « densité utile », sans jamais être formalisé.


5. Principes transverses à ne pas perdre de vue

  • Déterminisme : mêmes données, mêmes règles → même résultat. Chaque facteur du Ranking Engine est une fonction pure, testable isolément.
  • Explicabilité : chaque publication porte un tag de justification (section 2.3). Aucun facteur ne doit rester une boîte noire.
  • Neutralité vis-à-vis des producteurs : aucun facteur ne doit favoriser une publication pour des raisons commerciales (section 3.4).
  • Pas de logique d'engagement : le mur a une fin visible ; il ne cherche pas à maximiser le temps passé, le nombre d'ouvertures ou le scroll. L'effet d'anticipation recherché (« l'info avant qu'on sache qu'on en a besoin ») est un résultat du bon ranking déclaratif, pas une fonctionnalité de prédiction comportementale séparée.
  • Séparation V1 / Adaptive Engine : tous les facteurs retenus pour la V1 sont déclaratifs (suivi explicite, intérêt marqué avec seuil documenté, géographie choisie). Aucun apprentissage comportemental continu n'entre dans le Ranking Engine V1. Toute évolution vers une personnalisation apprise reste un sujet distinct, à traiter consciemment plus tard.

7. Unification finale : un seul moteur, une requête, un feed de résultats

L'ensemble des surfaces construites au fil de ce document — MurVille, mur personnel, feed acteur, recherche annuaire, recherche riche multi-intentions — ne sont pas des moteurs distincts. Ce sont des variations d'une même requête posée à un seul moteur, dont seule la sortie diffère.

7.1 Toute surface répond à une requête, explicite ou implicite

SurfaceRequêteNatureType de résultat filtré en sortie
MurVille« Que se passe-t-il dans mon village ? »Implicite (dérivée du contexte de navigation)Publications uniquement
Feed acteurPas de requête par défautAucun feed par défaut ; simple consultation d'une fiche
Recherche annuaire« Je cherche tel type d'acteur »Explicite (texte court, filtré par kind)Acteurs uniquement
Mon Espace« Qu'est-ce qui m'intéresse ? »Implicite (dérivée du profil : suivis, villes, intérêts)Publications + acteurs suivis, fusionnés (section 2)
Recherche riche (ex. Cap d'Agde)Requête explicite multi-intentions en langage naturelExplicite, décomposée par un LLM en sous-requêtes structurées (section 1.3)Tout type, composé selon les intentions détectées

Le feed acteur n'ayant pas de requête, il n'a pas besoin de ranking par défaut — ce qui est cohérent avec l'absence de scoring déjà observée en pratique (tri chronologique simple).

7.2 Un seul moteur, deux jeux de facteurs combinables

Le Ranking Engine des publications (criticité, affinité relationnelle, affinité catégorielle, proximité géographique, envergure, fraîcheur, proximité temporelle — section 4) et le scoring textuel des acteurs (matching sur nom/catégorie/tags) ne sont pas deux systèmes concurrents à faire cohabiter. Ce sont deux jeux de facteurs pour un même moteur, chacun adapté à la nature de l'objet noté (publication vs acteur), mais combinables dans un seul pipeline dès qu'une requête (explicite ou implicite) porte sur les deux types à la fois — c'est le cas de la recherche riche multi-intentions.

Les briques de normalisation textuelle déjà présentes et bien isolées (normalizeText, tokenizeSearch) deviennent, dans ce cadre, un facteur réutilisable parmi d'autres — au même titre que la criticité ou l'affinité catégorielle — pas un système à part destiné aux seuls acteurs.

7.2.1 Barème de poids du Ranking Engine des acteurs

Le matching textuel existant (computeActorSearchScore) est conservé tel quel comme référentiel d'échelle — il domine dès qu'une recherche textuelle est saisie, et les nouveaux facteurs s'y additionnent :

FacteurValeurNature
Matching textuel (nom, catégorie, tags)100 / 70 / 40 / 25Existant, inchangé (voir audit searchUtils.ts)
Affinité relationnelle (acteur suivi)+30Binaire, absent du système actuel — à ajouter
Proximité géographique+20 à 0 km, dégressif jusqu'à +0 à 15 kmDistance déjà calculée (haversineKm) mais non branchée au score — à ajouter
Bonus partenaire (fusion en_avant payant + coeff_annuaire)+15, plafonné, additifRemplace le multiplicateur actuel (voir 7.3) ; jamais au-dessus de l'affinité relationnelle
Fiche non revendiquée (is_claimed = false)-20Malus plutôt que bonus inversé : une fiche non enrichie reflète une information moins à jour, pas un jugement sur l'acteur lui-même

Le passage d'un bonus « claimed » à un malus « non-claimed » n'est pas qu'une reformulation arithmétique : il change l'état par défaut du système. Une fiche enrichie et revendiquée devient la norme attendue (score neutre), et c'est l'état orphelin — l'exception, ~3000 fiches sur 3500 à Bessan au démarrage — qui est spécifiquement abaissé, plutôt que d'artificiellement gonfler la majorité des fiches déjà revendiquées.

7.3 Le cas du bonus partenaire (coeff_annuaire et en_avant payant) : additif, pas multiplicatif

Le coefficient d'abonnement commercial (coeff_annuaire) et le boost en_avant payant (mise en carrousel sponsorisée) sont de vrais mécanismes de modèle économique de la plateforme — à distinguer d'un favoritisme rendu à un tiers (ex. la soirée latina payante écartée en section 3.4), puisqu'ici la transaction se fait directement avec DMV. Ils restent cependant soumis aux mêmes garde-fous que tout facteur du Ranking Engine, et sont fusionnés conceptuellement en un seul bonus partenaire :

  • Additif et plafonné, jamais multiplicatif. Un multiplicateur amplifie disproportionnellement tous les autres facteurs (un score de 216 devient 432 avec un simple ×2), au point de pouvoir faire remonter un mauvais match devant un excellent match gratuit. Un bonus additif et borné (+15, voir 7.2.1) ne fait que départager des cas déjà proches, sans jamais inverser la pertinence de fond — et reste toujours inférieur à l'affinité relationnelle de l'utilisateur (+30).
  • Visible et tagué, comme tout facteur influençant le classement (principe de transparence de la section 2.3 et 4.3) — un badge « acteur partenaire » plutôt qu'un boost silencieux.

8. Prochaines étapes

8.1 Points tranchés

  • Flux relationnel vs territorial : pas de priorité de structure — tri unique par score, la relation directe étant un facteur fort mais non absolu (seule la criticité court-circuite les deux flux indifféremment).
  • Combinaison fraîcheur / proximité temporelle : maximum des deux courbes, pas somme.
  • Échelle d'envergure : quatre niveaux discrets (hyper-local / communal / intercommunal / régional-national), hérités par défaut de la catégorie d'acteur, jamais réglés au cas par cas ni par village.
  • Un seul moteur, requêtes explicites/implicites, sortie filtrée par type (section 7) : MurVille, mur personnel, feed acteur, recherche annuaire et recherche riche sont des variations d'un même moteur, pas des systèmes séparés.
  • coeff_annuaire : bonus additif et plafonné, jamais multiplicatif, toujours tagué visuellement (section 7.3).
  • Barème de poids du Ranking Engine des publications (section 4.3.1) et des acteurs (section 7.2.1) : entièrement fixés, facteur par facteur.
  • Envergure (section 3.3) : cascade à deux signaux (type d'acteur, volume d'intérêt agrégé) ; la diffusion multi-communes est explicitement écartée comme signal.
  • Gravité des alertes critiques (section 3.5) : trois paliers (information / alerte / danger), déclarés explicitement par un producteur habilité plutôt que déduits.
  • Audit de l'existant (mur personnel, feed acteur, recherche/annuaire) : réalisé — voir constats ci-dessous.

8.2 Constats de l'audit technique à traiter

  • Le multiplicateur coeff_annuaire actuellement en place doit être converti en bonus additif plafonné (voir 7.3) — c'est le point le plus urgent car il contredit directement le principe de neutralité.
  • /recherche (tri alphabétique) et l'annuaire commune (scoring complet) sont deux implémentations séparées du même besoin — à unifier sur un seul moteur de scoring.
  • Le flux actor de Mon Espace (MonEspaceActorFeed) bypasse entièrement WallEngine, tout comme le feed acteur de la fiche publique le fait vis-à-vis de son propre chemin dupliqué — deux unifications techniques distinctes à mener, indépendantes du Ranking Engine lui-même.
  • Les publications épinglées (epingle=true) restent triées chronologiquement entre elles, sans ordre distinct — ajustement mineur à considérer (position fixe en tête plutôt que mélange chronologique).
  • Distance déjà calculée (haversineKm) et followedIds déjà disponibles mais non branchés au scoring de l'annuaire — gains rapides une fois le Ranking Engine des acteurs formalisé.

8.3 Actions de fond, non conceptuelles

  1. Confronter l'architecture au point de vue d'un maire ou d'un élu local — angle mort identifié, absent des trois personas déjà couverts. Points précis à aborder avec la mairie pilote :
    • Habilitation et astreinte pour le déclenchement des alertes critiques : qui peut déclencher une alerte en dehors des heures ouvrées (le week-end, en soirée) ? Le système actuel semble reposer sur un seul agent municipal ; à vérifier si le maire/les adjoints doivent avoir un accès direct, et si une astreinte existe ou doit être organisée côté commune.
    • Gouvernance plus large des informations municipales (validation, responsabilité légale de ce qui est publié).
  2. Implémenter chaque facteur comme une fonction pure et testable indépendamment, pour préserver le déterminisme dès la mise en œuvre technique.