veza/veza-docs/DISCOVERY_ALGORITHM.md
senke 0aa77d2bd9
Some checks failed
Backend API CI / test-unit (push) Failing after 0s
Backend API CI / test-integration (push) Failing after 0s
feat(v0.12.9): ethical bias tests, discovery algorithm docs, CI coverage gates
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>
2026-03-12 08:19:41 +01:00

131 lines
5.9 KiB
Markdown

# 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 :
1. **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.
2. **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.
3. **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.
4. **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 :
```go
// 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.