Pourquoi les ID de bug devraient repartir de 1 dans chaque projet

workflow

Le premier bug signalé dans un tout nouveau projet devrait porter le numéro un. En général, ce n'est pas le cas.

La plupart des outils qui démarrent avec un seul compteur partagé le gardent, parce qu'au début il n'y a qu'un projet et la différence ne se voit pas. Puis le deuxième client arrive, ouvre son premier projet, signale son premier bug, et celui-ci porte le numéro #913. Rien n'est cassé. On a juste l'impression d'être entré dans l'immeuble de quelqu'un d'autre.

J'ai livré la numérotation par projet dans BugDump cette semaine, et le raisonnement vaut au-delà de mon produit. Un ID de bug est l'un des rares éléments de votre modèle de données que les gens prononcent à voix haute, et cela change ce qu'on attend de lui.

Ce que coûte vraiment un compteur global

Il divulgue des informations. Un numéro tiré d'une séquence partagée indique à quiconque le lit le volume total du système, à peu de chose près. Deux bugs signalés à un mois d'écart dans votre projet révèlent combien de bugs tous les autres ont signalés entre-temps. C'est le même type de problème que les numéros de facture tirés d'une séquence partagée, et c'est pour ça que les outils de facturation ont cessé de les utiliser.

Il se lit comme du bruit. #913 ne signifie rien pour la personne qui le regarde. Il ne correspond à aucun 913e bug qu'elle puisse voir. Le nombre est assez grand pour être difficile à retenir et assez arbitraire pour qu'on ne puisse pas vérifier s'il est plausible.

Il gaspille un signal gratuit. Quand la numérotation est par projet, le numéro donne aussi un ordre de grandeur. BD-6 veut dire que ce projet a eu une poignée de bugs. BD-2400 veut dire tout autre chose, et vous l'apprenez sans ouvrir de tableau de bord.

Rien de tout cela n'est rédhibitoire. Beaucoup de bons outils gardent un compteur global pendant des années. Mais c'est une petite taxe payée sur chaque ID, pour toujours, et la correction coûte peu.

Pourquoi le préfixe mérite sa place

La numérotation par projet crée un nouveau problème : les numéros ne sont plus uniques. La tâche 42 existe dans chacun de vos projets.

Le chemin de l'URL règle déjà ça, puisqu'il contient le projet. Mais une conversation n'a pas d'URL. Quelqu'un écrit « tu peux regarder la 42 ? » dans un canal où l'on parle de trois projets, et la phrase est réellement ambiguë.

Une courte clé devant le numéro règle le problème au seul endroit où l'ambiguïté apparaît : la conversation entre humains. BD-42 est sans ambiguïté là où 42 ne l'est pas, et cela coûte trois caractères. Jira a raison sur ce point depuis vingt ans, et Linear, Shortcut et Sentry sont arrivés à la même solution chacun de leur côté.

La clé devrait être déduite, pas exigée. Demander à quelqu'un d'inventer une clé de projet à l'inscription, c'est une petite taxe prélevée au moment où il essaie de faire autre chose. Déduisez-la du nom du projet (Bug Dump devient BD) et laissez les gens la changer plus tard dans les paramètres, ce que la plupart ne feront jamais.

Les trois décisions de conception qui comptent

Une fois qu'on a choisi des numéros par projet avec un préfixe, trois questions décident si le résultat est agréable ou agaçant.

1. Les numéros sont-ils réutilisés après suppression ?

Non. Ils ne doivent jamais l'être.

Si supprimer la tâche la plus récente libère son numéro pour la suivante, alors un lien, un message de commit ou un fil Slack qui mentionne BD-9 peut se mettre à pointer sans bruit vers un autre bug. La panne est silencieuse et peut survenir n'importe quand, la pire combinaison qui soit.

Gardez un compteur qui ne fait que monter. Les trous dans la séquence ne sont pas un défaut ; ils sont la preuve visible que les anciennes références veulent toujours dire ce qu'elles disaient.

2. Le préfixe fait-il partie de l'adresse, ou est-ce une décoration ?

C'est la question intéressante, et les deux réponses se défendent.

Si le préfixe est une décoration, BD-42 et 42 sont deux graphies d'une même adresse et ouvrent toutes deux la tâche. Renommer une clé de projet ne coûte alors rien : les libellés se mettent à jour partout, les liens continuent de marcher, personne ne remarque rien.

Si le préfixe fait partie de l'adresse, seul le libellé actuel exact fonctionne. Renommer une clé casse tous les liens qui portent l'ancienne.

J'ai choisi la seconde option, délibérément, après avoir commencé par la première. L'argument qui l'a emporté : une URL dont le préfixe n'est pas la clé de ce projet est, dans tous les cas réalistes, une erreur. Quelqu'un a collé un lien du mauvais projet, a fait une faute de frappe ou suit une référence périmée. Ouvrir la tâche qui se trouve porter ce numéro dans ce projet n'aide personne. On croit que ça a marché, et c'est le mauvais bug qui s'affiche, sans le moindre avertissement.

Un mauvais préfixe renvoie donc une 404, tout comme un numéro complété par des zéros comme BD-007, ou un numéro qu'aucune tâche ne porte. Le numéro seul reste une adresse permanente qu'aucun renommage ne peut casser, et c'est la forme que le produit met dans chaque lien, e-mail et payload de webhook qu'il génère.

Le coût est réel et mérite d'être dit clairement : renommez une clé, et les liens partagés avec l'ancienne ne mènent plus nulle part. C'est le prix à payer pour ne jamais montrer à quelqu'un le mauvais bug.

3. Les deux formes marchent-elles partout ?

Elles devraient. Les gens copient le libellé qu'ils voient, pas celui avec lequel votre application construit ses liens.

Si votre interface affiche BD-42 sur une carte, alors BD-42 collé dans la barre d'adresse doit marcher, sinon vous avez posé un petit piège pour quiconque fait la chose évidente. Acceptez les deux graphies, gardez celle par laquelle le visiteur est arrivé, et générez vous-même la forme canonique.

Ce qui reste un nombre

Le préfixe est pour les humains. Les machines doivent continuer à recevoir des entiers.

Dans BugDump, les payloads de webhook, les réponses de l'API et les arguments des outils MCP portent toujours le numéro, avec le libellé d'affichage à côté dans un champ séparé. Rien de ce qui analysait déjà un payload n'a eu à changer, et personne n'a besoin d'écrire un parser de chaîne pour savoir à quel bug un événement se rapporte.

Cette séparation mérite d'être préservée délibérément à mesure que vous construisez. Le libellé relève de la présentation. Dès qu'il fuit dans vos contrats d'intégration, renommer une clé de projet devient un changement d'API cassant, et un réglage cosmétique devient quelque chose auquel personne n'ose toucher.

Migrer sans casser ce que les gens ont déjà envoyé

Le plus délicat, c'est que des ID existent déjà et circulent déjà, dans des e-mails, des historiques de chat et les tickets d'autres personnes.

Renuméroter les tâches existantes pour que chaque projet démarre proprement à 1 est tentant, et c'est une erreur. Chaque ancienne référence se met à pointer ailleurs sans bruit. L'alternative est plus terne, et c'est la bonne : ne pas toucher aux numéros existants, démarrer le compteur de chaque projet au-dessus de son propre numéro le plus élevé, et laisser les anciens projets garder des ID clairsemés pour toujours. Les nouveaux projets ont une séquence propre à partir de 1, les anciens liens gardent leur sens, et personne n'a besoin d'être prévenu de quoi que ce soit.

La numérotation est une petite fonctionnalité. C'est aussi une fonctionnalité que chaque membre de l'équipe touche des dizaines de fois par jour, ce qui est une assez bonne raison de passer un après-midi à bien la faire plutôt que de vivre indéfiniment avec #913.

Pour aller plus loin