TASK-ETH-001: 4 discovery bias tests (genre/tag browse, emerging artist visibility, metrics not exposed in JSON). Verifies chronological ordering regardless of play count. TASK-ETH-002: 4 search fairness tests (artist 0 plays discoverable, zero-play tracks not filtered, default sort is chronological, no popularity bias in default ranking). TASK-ETH-003: veza-docs/DISCOVERY_ALGORITHM.md — documents all 6 discovery mechanisms, ethical constraints, and forbidden patterns per ORIGIN specs. TASK-COV-001: CI coverage gates — Go >= 70% (backend-ci.yml), Rust >= 50% (rust-ci.yml with cargo-tarpaulin). Extended Go test scope to core/ and middleware/. TASK-COV-002: Coverage badge JSON artifact on main push (shields.io compatible). All 8 ethical tests PASS. Build clean. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
5.9 KiB
Algorithme de Découverte Veza
Version : v0.12.9 Dernière mise à jour : 2026-03-12 Référence : ORIGIN_BUSINESS_LOGIC.md §11, ORIGIN_FEATURES_REGISTRY.md F351-F375, ORIGIN_UI_UX_SYSTEM.md §13-14
Principes fondamentaux
L'algorithme de découverte de Veza est conçu selon des principes éthiques stricts :
-
Chronologique, pas algorithmique — Le feed et la découverte sont ordonnés par date de création (du plus récent au plus ancien). Aucun critère d'engagement (play count, likes, partages) n'influence l'ordre d'affichage.
-
Pas de ML/IA — Aucun algorithme de machine learning (collaborative filtering, content-based filtering, analyse prédictive) n'est utilisé. La découverte repose exclusivement sur des mécanismes déclaratifs et humains.
-
Visibilité égale — Un artiste émergent avec 0 écoutes a exactement la même chance d'apparaître qu'un artiste établi avec des millions d'écoutes, à condition qu'il soit dans le même genre/tag et que son contenu soit plus récent.
-
Métriques privées — Les compteurs d'écoutes, likes et followers ne sont JAMAIS visibles publiquement. Ils sont réservés exclusivement au créateur dans son tableau de bord analytics.
Mécanismes de découverte
1. Feed personnel (chronologique)
Implémentation : internal/core/feed/service.go
Le feed d'un utilisateur affiche les tracks des artistes qu'il suit, triées par created_at DESC.
Requête : SELECT tracks.*
FROM tracks
INNER JOIN follows ON follows.followed_id = tracks.creator_id
WHERE follows.follower_id = :user_id
ORDER BY tracks.created_at DESC, tracks.id DESC
Aucun facteur de popularité n'intervient. L'ordre est strictement chronologique.
2. Découverte par genre (F353)
Implémentation : internal/core/discover/service.go — GetTracksByGenre()
Browse par genre avec pagination curseur. Tri : created_at DESC, id DESC.
Requête : SELECT tracks.*
FROM tracks
INNER JOIN track_genres ON track_genres.track_id = tracks.id
WHERE track_genres.genre_slug = :slug
AND tracks.status = 'completed'
AND tracks.is_public = true
ORDER BY tracks.created_at DESC, tracks.id DESC
3. Découverte par tag (F353)
Implémentation : internal/core/discover/service.go — GetTracksByTag()
Même principe que par genre, avec les tags déclarés par l'artiste.
4. Nouveautés des genres suivis (F355)
Implémentation : internal/core/discover/service.go — GetTracksFromFollowedGenres()
Affiche les tracks récentes dans les genres que l'utilisateur suit. Tri chronologique.
5. Playlists éditoriales (F141)
Implémentation : internal/core/discover/service.go — GetEditorialPlaylists()
Playlists créées manuellement par l'équipe de curation. Aucune génération automatique.
6. Recherche textuelle (F375)
Implémentation :
- PostgreSQL :
internal/services/search_service.go(ILIKE pattern matching) - Elasticsearch :
internal/elasticsearch/search_service.go(BM25 + fuzziness)
La recherche utilise la pertinence textuelle (BM25 sur Elasticsearch, ILIKE sur PostgreSQL). Le commentaire dans le code est explicite :
// F364: fuzziness for typo tolerance; no boost by popularity (ethical)
Les champs boostés sont title^2 et artist^2 — c'est un boost de pertinence textuelle, PAS de popularité.
Ce qui est explicitement INTERDIT
| Mécanisme | Raison de l'interdiction | Référence |
|---|---|---|
| Collaborative filtering | Optimise la rétention, pas la découverte authentique | ORIGIN_BUSINESS_LOGIC.md §11 |
| Content-based filtering ML | Crée des bulles de filtrage | ORIGIN_BUSINESS_LOGIC.md §11 |
| Analyse prédictive du comportement | Manipulation de l'engagement | ORIGIN_BUSINESS_LOGIC.md §11 |
| Trending basé sur play counts | Favorise les artistes établis | ORIGIN_UI_UX_SYSTEM.md §13 |
| "X personnes écoutent maintenant" | Dark pattern FOMO | ORIGIN_UI_UX_SYSTEM.md §13 |
| Compteurs publics de followers | Biais de preuve sociale | ORIGIN_UI_UX_SYSTEM.md §13 |
| Leaderboards/classements | Gamification interdite | CLAUDE.md règle #3 |
| Badges de performance | XP/streaks interdits | CLAUDE.md règle #3 |
Garanties éthiques testées
Les tests suivants vérifient en continu le respect de ces principes :
| Test | Fichier | Ce qu'il vérifie |
|---|---|---|
TestDiscovery_NoPlayCountBias_GenreBrowse |
discover/ethical_bias_test.go |
Genre browse : ordre chronologique, pas par play count |
TestDiscovery_NoPlayCountBias_TagBrowse |
discover/ethical_bias_test.go |
Tag browse : même vérification |
TestDiscovery_EmergingArtistVisibility |
discover/ethical_bias_test.go |
Artiste 0 plays non défavorisé |
TestDiscovery_MetricsNotExposedInJSON |
discover/ethical_bias_test.go |
play_count/like_count absents du JSON |
TestSearch_ArtistZeroPlays_Discoverable |
services/ethical_search_test.go |
Artiste 0 plays trouvable par nom |
TestSearch_ZeroPlaysTrack_NotFilteredOut |
services/ethical_search_test.go |
Track 0 plays non filtré |
TestSearch_DefaultSortIsChronological |
services/ethical_search_test.go |
Tri par défaut = chronologique |
TestSearch_NoPopularityBias_InDefaultRanking |
services/ethical_search_test.go |
Pas de biais popularité dans le ranking par défaut |
Audit et transparence
Cet algorithme est :
- Documenté : ce fichier constitue la documentation publique
- Auditable : le code source est lisible et les requêtes SQL sont explicites
- Testé : les tests éthiques ci-dessus sont exécutés en CI
- Déterministe : pas de composante aléatoire ou opaque
Toute modification de l'algorithme de découverte doit passer les tests éthiques existants et être documentée ici.