Version 1.1 · 19 septembre 2026 · P0-PRODUCT-015 (1.0 : 29 août 2026)
Publié en ligne, et rédigé par l'équipe technique de GA3DA. Ce qu'il décrit du logiciel est exact — une porte du dépôt le confronte au code à chaque exécution. Il n'a pas encore été relu par un juriste : sa forme, la loi applicable et la juridiction compétente restent à arbitrer. Les durées annoncées sont défendables et motivées, mais certaines juridictions imposent des minimums ou des maximums que ce document ne connaît pas.
Correction datée. Ce document affirmait « il n'y a aucun serveur » jusqu'au 2026-08-29. C'est devenu faux le jour même, quand le mode en ligne a été terminé. La phrase n'est pas réécrite, elle est remplacée par ce qui suit et la correction est datée : un fait daté ne se réécrit pas (commandement IX.5).
Ce que le serveur conserve aujourd'hui, dans un fichier unique (services/server/donnees/magasin.json, non versionné) :
| Donnée | Ce que c'est | Contient une donnée personnelle ? |
|---|---|---|
| Comptes invités | identifiant tiré au hasard, pseudo, date de création, classement Elo, nombre de matchs | le pseudo, s'il est choisi — sinon il est généré |
| Sessions | jeton de 32 octets, compte associé, deux horodatages | non |
| Résultats de match | identifiants des joueurs, score, gagnant, date, graine du mélange | non, au-delà des identifiants techniques |
| Signalements | qui signale, qui est visé, quel match, quel motif, quand | non — le motif vient d'une liste fermée, il n'y a aucun texte libre |
| Blocages | qui a bloqué qui | non |
| Liens sociaux | amitiés (dans les deux sens), demandes d'ami en attente, « fermé aux inconnus », emotes coupées, joueurs mutés | non — que des identifiants techniques, aucun texte libre |
Ajouté le 2026-09-15. Cette ligne manquait, et pour une raison qui a cessé d'être vraie le soir même : jusque-là, les liens sociaux ne survivaient à aucun redémarrage du serveur — ils vivaient en mémoire seule, et chaque déploiement effaçait la liste d'amis de tous les joueurs. Ce n'était donc pas une donnée conservée, c'était une donnée perdue. Elle est conservée depuis, et ce document le dit dans le même geste : une donnée qu'on se met à garder se déclare avant tout le reste.
Ce que le serveur ne conserve PAS, et c'est délibéré :
Le pseudo est le seul texte que le joueur choisisse. Il est donc borné à 24 caractères et dépouillé de ses caractères de contrôle, et rien d'autre ne lui est demandé.
Les durées ci-dessous s'appliquent à partir de maintenant. Elles ont été écrites avant que le serveur n'existe, ce qui est le bon ordre : une durée de conservation se décide avant de collecter, jamais après — après, on garde tout « au cas où », et c'est ainsi qu'on se retrouve avec dix ans de journaux qu'aucune règle ne permet plus de supprimer.
Chaque durée doit pouvoir répondre à la question « pour quoi faire ? » par un usage réel. Une donnée gardée sans usage nommé est une donnée à supprimer. Quand deux usages s'opposent — détecter la triche demande de l'historique, respecter la vie privée demande d'en garder peu — la durée est la plus courte des deux qui rende l'usage possible.
Correction datée du 2026-09-12. Deux lignes de ce tableau étaient fausses, et aucune porte ne pouvait le voir : elle n'en confrontait que trois au code. La session annonçait 24 heures, et le code les appliquait. La justification écrite était circulaire — « au-delà, le jeton n'ouvre plus rien » — puisque c'est nous qui décidions qu'il n'ouvre plus rien. Or le jeton est le compte : le flux OAuth n'est pas écrit, le verbe
lierrefuse, et un joueur invité n'a aucune autre identité. Passé 24 heures sans ouvrir le jeu, le joueur perdait classement, historique, amis et pseudo, sans un mot — le repli automatique vers un compte invité rendait la perte muette. Porté à 12 mois, la fenêtre déjà retenue pour les parties jouées. Le journal de coups annonçait 90 jours quand le code en garde 180, ceux queREPLAY-LOG-007exige — et cette exigence est cochée en citant ce document. Nous conservions donc deux fois plus longtemps que ce que cette page promettait. La ligne dit désormais ce que le code fait. Les valeurs d'avant ne sont pas réécrites ailleurs : elles sont remplacées ici, et la correction est datée (commandement IX.5).
| Donnée | Durée | Pourquoi celle-là |
|---|---|---|
| Compte actif | tant que le compte existe | c'est l'objet du compte |
| Compte supprimé | immédiatement, sans délai ni copie | voir l'encadré ci-dessous |
| Session | 12 mois sans signe de vie | le jeton est le compte tant qu'aucune identité externe n'est liée. Le faire expirer, c'est supprimer le compte — classement, historique et amis compris |
| Parties jouées (score, adversaire, date) | 12 mois | un classement saisonnier et une progression se lisent sur une année. Plus loin, personne ne consulte |
| Journal de coups (replay) | 180 jours | c'est la fenêtre où un litige se signale et s'instruit, et c'est la durée que REPLAY-LOG-007 fixe. Un replay d'il y a un an n'est plus contesté par personne |
| Journaux techniques (erreurs, latence) | 30 jours | un incident se diagnostique dans le mois. Au-delà, ils ne servent qu'à occuper du disque |
| Signalements | 12 mois après traitement | un comportement récidivant se voit sur une année. C'est ce qui permet de distinguer un mauvais jour d'un habitué |
| Sanctions (avertissement, suspension) | 24 mois | une sanction doit peser plus longtemps qu'un signalement, sinon la récidive n'existe pas |
| Sanctions définitives (exclusion) | sans limite, sous identifiant technique seul | une exclusion qui expire n'est pas une exclusion. Mais elle se conserve sans donnée personnelle : un identifiant d'appareil ou de compte, rien d'autre |
| Liens sociaux (amitiés, demandes, réglages d'emote) | tant que les deux comptes existent | une amitié qui expirerait toute seule retirerait quelqu'un que le joueur a choisi d'ajouter, sans le lui dire — exactement le raisonnement déjà tenu pour les blocages. Elle part dans les deux sens à la suppression d'un compte |
| Données de facturation | la durée légale du pays d'établissement | ce n'est pas notre décision, c'est celle du droit comptable |
### Le délai de rétractation de 30 jours n'existe pas, et c'est corrigé ici Corrigé le 2026-09-06. Ce tableau promettait de conserver un compte supprimé 30 jours, « pour qu'une suppression sur un geste malheureux puisse s'annuler ». Le code ne l'a jamais fait : la suppression est immédiate et complète — le compte, ses sessions, ses identités, ses signalements dans les deux sens, et son pseudo qui redevient libre. C'est le code qui a raison, et le document qui est aligné dessus : conserver un compte supprimé pendant un mois serait garder des données que le joueur a explicitement demandé d'effacer, sans le lui avoir dit. Et le pseudo redevenant libre immédiatement, le compte ne serait de toute façon pas restaurable à l'identique — un délai qui ne restaure rien n'est pas une protection, c'est une rétention de plus. Ce que ça implique et qui doit être dit au joueur : la suppression est irréversible. C'est écrit dans
suppression-compte.md.
Se déconnecter n'entre PAS dans cette liste. Le jeu oublie son jeton sur l'appareil, et le serveur garde la session jusqu'à son expiration — la durée du tableau ci-dessus. Un jeton recopié ailleurs reste donc valable ; seule la suppression du compte révoque tout, immédiatement.
Version 1.1, 19 septembre 2026 : le paragraphe ci-dessus ne décrit plus le logiciel. Le jeu envoie désormais un verbe de déconnexion au serveur avant d'oublier son jeton, et le serveur révoque cette session sur-le-champ. Un jeton recopié ailleurs cesse donc d'ouvrir le compte dès que le joueur se déconnecte. Ce qui ne change pas : une session que le joueur ne ferme pas expire toujours au bout de la durée du tableau, et seule la suppression du compte efface le reste. Le paragraphe est laissé tel quel parce qu'il décrivait exactement la version 1.0, et qu'un document qui réécrit son passé ne se relit plus.
Corrigé le 2026-09-19. La version 1.0 rangeait « les données de connexion (jeton de session) à la déconnexion » parmi ce qui est supprimé immédiatement. C'était faux, et mesuré faux :
Salon.fermerSessionest écrite, juste, et n'a aucun appelant de production — il n'existe aucun verbe de déconnexion au protocole, et l'écran Paramètres oublie le jeton localement sans rien envoyer au serveur. Le tableau des durées, lui, disait déjà la vérité (« Session : 12 mois sans signe de vie ») : les deux lignes se contredisaient depuis le 29 août, et c'est la plus rassurante qui était fausse. Ce qu'elle coûtait : un joueur qui se déconnecte croit avoir retiré son accès, et un jeton qui aurait fui — une sauvegarde, un dossier recopié — reste utilisable. Ce qui manque est nommé, pas caché :AUTH-GUEST-004— rotation, révocation et expiration des sessions — est honnêtement décochée au registre. La moitié serveur est prête ; poser un verbe de déconnexion touche les deux côtés du protocole, donc le contrat quetests/protocole-accorde.test.mjsgarde. L'arbitrage appartient à Sebti.
Une durée écrite dans un document et jamais appliquée est pire qu'une absence de règle : elle donne le sentiment que le ménage est fait. Trois exigences en découlent :
### État réel de ces trois exigences, au 2026-08-29 Aucune des trois n'est faite. Le serveur purge les parties terminées de sa mémoire (
Salon.purger, éprouvé par un banc), et rien d'autre : comptes, sessions, résultats, signalements et blocages s'accumulent sans limite dans le magasin. Ce n'est pas bloquant tant que le serveur ne tourne pas en production, et c'est dit ici plutôt que tu : annoncer une règle inapplicable est pire que se taire (commandement IX.4). Ces trois exigences doivent être tenues avant la première mise en ligne publique, pas après.
### État au 2026-09-06 : les trois sont tenues Le relevé du 29 août ci-dessus n'est pas réécrit — c'est un fait daté (commandement IX.5). Voici ce qui a changé, et ce qui reste vrai. Le serveur est en production depuis le 4 septembre, ce qui a rendu ces trois exigences exigibles au sens où le document les posait lui-même. 1. La purge tourne.
services/server/src/retention.ts, appelée par le balayage du serveur, au plus une fois par jour. Elle retire les sessions inactives, les résultats de match et les signalements au-delà de leur durée. 2. Elle sait rougir.services/server/test/retention.test.ts— 13 cas, dont un qui vérifie qu'elle est appelée par le balayage, et un qui vérifie que la durée compte : sans lui, une purge qui viderait tout passerait les autres. Éprouvée en débranchant l'appel, puis en retirant l'intervalle quotidien : les deux font rougir. 3. Le compte rendu est écrit, par catégorie, dans le journal du serveur —[retention <date>] sessions=… resultats=… signalements=…. Une purge muette est indiscernable d'une purge qui ne tourne pas. Les durées vivent désormais dans le code (DUREES_JOURSderetention.ts), et ce document y renvoie au lieu de les porter en double — une valeur recopiée diverge au premier ajustement, et c'est la copie non appliquée qu'on relit (commandement IX.1).tests/legal.test.mjsconfronte les deux à chaque exécution. Ce qui n'est toujours pas fait, et qui n'est pas une purge : les replays ont leur propre rétention (DepotReplays.purger, appelée par le même balayage), et il n'existe aucun journal technique persistant — donc rien à purger de ce côté. La ligne « journaux techniques » du tableau décrit une intention, pas un fichier existant.
Corrigé le 2026-08-29 : la version précédente décrivait un état sans serveur, qui a cessé d'être vrai le jour même. Les faits antérieurs ne sont pas réécrits — ils sont datés et remplacés.