Score_to_hide_post devient 0 lorsque les éléments révisables n'ont qu'un seul signalement

Résumé

score_to_hide_post peut être ramené à 0 car le job d’arrière-plan Jobs::ReviewablePriorities écrit priority_#{priorities[:high]} comme 0 lorsque la requête de percentile ne renvoie aucune ligne. Le job est déclenché lorsque reviewable_count >= 15, mais le calcul du percentile n’inclut que les éléments révisables qui satisfont HAVING COUNT(*) >= :target_count (où target_count est généralement 2). Si la plupart des éléments révisables n’ont qu’un seul drapeau, la sous-requête de percentile ne renvoie rien → high devient 0score_to_hide_post = ((high * ratio) * scale).truncate(2) est évalué à 0. Cela fait s’effondrer le seuil de masquage à zéro et produit un comportement de masquage incorrect.


Origine (code / faits pertinents)

  • score_to_hide_post est calculé via :
score_to_hide_post = ((high.to_f * ratio) * scale).truncate(2)
  • high est lu à partir du magasin de plugins :
PluginStore.get("reviewables", "priority_#{priorities[:high]}")
  • Cette entrée du magasin de plugins est écrite par Jobs::ReviewablePriorities (le job système).
    Le job s’exécute lorsque :
reviewable_count = Reviewable.approved.where("score > ?", min_priority_threshold).count
return if reviewable_count < self.class.min_reviewables

self.class.min_reviewables est 15.

  • Le job calcule high en utilisant SQL :
SELECT COALESCE(PERCENTILE_DISC(0.5) WITHIN GROUP (ORDER BY score), 0.0) AS medium,
       COALESCE(PERCENTILE_DISC(0.85) WITHIN GROUP (ORDER BY score), 0.0) AS high
FROM (
  SELECT r.score
  FROM reviewables AS r
  INNER JOIN reviewable_scores AS rs ON rs.reviewable_id = r.id
  WHERE r.score > :min_priority AND r.status = 1
  GROUP BY r.id
  HAVING COUNT(*) >= :target_count
) AS x

avec :target_count généralement 2.


Cause racine

Il existe deux seuils distincts qui créent ensemble un écart :

  1. Le job est déclenché lorsqu’il y a au moins min_reviewables (15) éléments révisables supérieurs à min_priority_threshold — il s’agit d’un décompte grossier ignorant l’exigence de :target_count.
  2. Mais le calcul du percentile qui produit high n’inclut que les éléments révisables qui satisfont COUNT(*) >= :target_count (c’est-à-dire au moins 2 reviewable_scores). Si de nombreux éléments révisables n’ont chacun qu’un seul drapeau, la sous-requête ne renvoie aucune ligne et le percentile renvoie la valeur de repli 0.0.

Ainsi, le job peut s’exécuter (car il y a ≥ 15 éléments révisables selon le décompte grossier) mais l’agrégation du percentile n’a pas de lignes qualifiées (car aucune ne satisfait le HAVING), provoquant high à 0 et ensuite priority_high à être écrit comme 0. Cela alimente score_to_hide_post et le fait s’effondrer.


Impact

  • score_to_hide_post devient 0, ce qui peut à tort considérer des publications comme masquées ou autrement casser la logique qui dépend d’un seuil de masquage raisonnable.
  • Cela se produit sur les sites où il existe de nombreux éléments révisables mais chacun n’a qu’un seul drapeau/réviseur, ce qui n’est pas rare dans les communautés petites/moyennes.

Corrections suggérées (options)

  1. S’assurer que la requête de percentile renvoie suffisamment de lignes avant d’écrire
  • Après avoir exécuté la requête de percentile, vérifiez si la valeur du percentile est 0 et si la sous-requête a renvoyé des lignes.
    Si aucune ligne n’a été renvoyée, ne pas écraser le priority_high existant ; au lieu de cela, ignorer l’écriture, conserver la valeur précédente ou revenir à une valeur par défaut configurée.
  • C’est l’approche la plus sûre et la moins invasive.
  1. Ajuster le déclenchement du job pour tenir compte de target_count
  • Modifier la pré-vérification du job afin qu’elle ne s’exécute que lorsque le nombre d’éléments révisables satisfaisant HAVING COUNT(*) >= :target_count est d’au moins min_reviewables.
    En d’autres termes, compter les éléments révisables regroupés par id qui satisfont COUNT(*) >= target_count et ne procéder que si ce décompte est ≥ min_reviewables.
  1. Permettre aux administrateurs de définir manuellement score_to_hide_post ou priority_high
  • Fournir une option dans l’interface d’administration pour saisir ou ajuster directement score_to_hide_post ou priority_high.
  • De cette façon, même si la requête de percentile produit des résultats inattendus (par exemple, en raison d’un échantillon trop faible), le système peut utiliser un seuil raisonnable spécifié par l’administrateur, évitant ainsi les erreurs causées par les calculs automatiques.