Ce qui s’est passé, dans l’ordre

Le plugin a été soumis à l’annuaire WordPress.org le 11 août 2026. Une archive corrigée, la 0.1.3, a suivi le 13 août. Le 16 août, un premier message « Review in Progress » a mis la soumission en attente : un pré-contrôle listant quatre familles de points à corriger avant la revue humaine. Nous avons tout corrigé en une seule version, la 0.1.4, téléversée le 17 août avec une réponse courte dans le fil existant.

Le 25 août, deux messages ont fermé le dossier. Le motif tient en une phrase : la fonctionnalité du plugin est « already widely available in the directory ». Le mode maintenance figure nommément dans la liste d’exemples de l’équipe des plugins, à côté du bouton de retour en haut de page et du compteur de vues. Le second message précise la suite : ne pas resoumettre, même en cas de désaccord ; répondre dans le fil pour discuter ; resoumettre sans répondre entraîne la suspension du compte.

Ce que ce rejet n’est pas

Ce n’est pas une revue du code. Plugin Check passait sans avertissement, les 24 tests d’intégration étaient verts, la checklist de qualité était remplie, l’icône avait été refaite. Rien de tout cela n’a pesé, et rien n’aurait pu peser : la décision porte sur le sujet du plugin, pas sur sa qualité. L’argument du cas d’usage étroit (une réponse 503 propre, l’accès administrateur préservé) avait déjà été fait dans notre réponse du 17 août, sans effet.

La décision du 27 août

Nous avons choisi de ne pas contester et de ne pas resoumettre. Le gain espéré d’une contestation est faible, puisque la catégorie entière est visée. Le risque, lui, est le compte WordPress.org, qui servira au prochain plugin. Le même jour, une tâche a été ouverte : organiser la distribution depuis mesplugins.fr.

Le rejet confirme aussi un constat antérieur : un catalogue réduit à un plugin de maintenance est un plafond de visibilité, et c’est maintenant une impasse d’annuaire. Le prochain produit devra viser un besoin que l’annuaire ne couvre pas.

Le vrai coût du rejet

On pense d’abord à la visibilité perdue. Le coût le plus lourd est ailleurs : un site qui installe le plugin depuis un ZIP n’a aucun moyen d’apprendre qu’une version corrigée existe. Pas même une correction de sécurité. L’écran des extensions reste muet indéfiniment. C’est ce coût-là qu’il fallait supprimer en premier.

Ce que nous avons construit le 29 août

Un canal de mise à jour auto-hébergé, branché sur le mécanisme normal de WordPress plutôt qu’à côté.

Côté site, une seule source de vérité, releases.json, liste chaque version avec son fichier, son empreinte SHA-256, sa taille exacte, les exigences WordPress et PHP et le détail des changements. Un générateur en produit deux fichiers statiques : mise-a-jour.json, que le plugin compare à sa propre version, et informations.json, que WordPress affiche dans « Voir les détails ». Deux fichiers servis par nginx : pas de PHP, pas de base de données, rien à maintenir côté serveur.

Le garde-fou compte autant que le reste. Le générateur recalcule l’empreinte et la taille de chaque archive servie, et refuse d’écrire si une valeur déclarée ne concorde pas. Il s’exécute avant la construction du site : une publication échoue plutôt que de servir un manifeste faux. Nous l’avons vérifié en faussant une taille à la main : sortie en erreur, rien d’écrit.

Côté plugin, la classe MPMM_Updater se branche sur les filtres pre_set_site_transient_update_plugins, plugins_api et upgrader_process_complete, plus plugin_row_meta pour dire, sur la ligne du plugin, d’où viennent les mises à jour. Trois décisions à retenir :

  • rien ne part du site : une requête GET vers une URL fixe, sans aucun paramètre, avec un délai de cinq secondes. Le manifeste est identique pour tout le monde, il ne peut donc rien apprendre de celui qui le lit : pas d’adresse, pas de version de WordPress, pas de compteur, pas de jeton. La réponse est mise en cache douze heures, trente minutes après un échec, et l’écran des extensions n’est jamais bloqué ;
  • l’origine du paquet est contrôlée : le plugin refuse toute archive qui ne vient pas de https://mesplugins.fr ou de https://www.mesplugins.fr, en HTTPS. Sans ce contrôle, un manifeste altéré ferait installer n’importe quelle archive, la faille classique des canaux auto-hébergés ;
  • on peut couper : la constante MPMM_DISABLE_UPDATE_CHECK dans wp-config.php, ou le filtre mpmm_verification_mise_a_jour_active. La classe n’est jamais chargée sur les pages servies aux visiteurs.

Ce canal ajoutait un appel réseau, et la fiche du plugin promettait « ni appel réseau ajouté par le plugin ». La phrase a été réécrite sur le site et dans le readme.txt, qui gagne une entrée de FAQ : le seul appel réseau est la vérification des mises à jour, dans l’administration, sans paramètre, désactivable.

La limite, connue dès le départ

La 0.1.4 ne contient pas le canal. Un plugin ne peut pas se mettre à jour avant de savoir qu’il le doit : le canal ne prend effet qu’à partir de la première version qui l’embarque. Les sites restés en 0.1.4 ne seront jamais prévenus. La page de téléchargement le dit.

La 0.1.5, et trois défauts que seule la publication a révélés

La 0.1.5 est sortie le 9 septembre avec le canal. Aucun des trois défauts n’était visible en relisant le code ; tous sont sortis en exécutant les contrôles sur le paquet réel.

La traduction française n’était pas dans le paquet. Depuis la 0.1.4, la construction excluait les fichiers .po et .mo, parce que WordPress.org devait distribuer le pack de langue. Hors annuaire, personne ne le fait : la 0.1.4 s’affichait en anglais sur les sites français, alors que la fiche promet une traduction complète. Le fichier .mo voyage désormais dans l’archive et le plugin le charge lui-même. Un test vérifie que « Maintenance mode » devient « Mode maintenance » sur un site en fr_FR.

Deux libellés du canal étaient en français dans le code source. Notre règle est que la source est en anglais et que le français est une traduction. Les contrôles statiques exigent une traduction pour chaque chaîne, et ils les ont attrapés.

Le canal n’était pas chargé sous WP-CLI. Un test de bout en bout sur un WordPress jetable (installer la 0.1.5, abaisser sa version à 0.1.4, demander la mise à jour) n’a rien proposé. La classe n’était chargée que dans l’administration ou pendant le cron ; en ligne de commande, ni l’un ni l’autre. Or beaucoup d’hébergeurs mettent à jour par wp plugin update. La condition a été complétée, et le même test passe dans les deux contextes, contre le manifeste réellement en ligne.

Ce dernier point a une conséquence à assumer : la 0.1.5 a été publiée une première fois à 19 h 18, puis remplacée à 19 h 21 par l’archive corrigée, sous le même numéro. Notre règle interdit de modifier une entrée publiée ; elle protège les sites installés, et il n’y en avait aucun en trois minutes. C’est la seule fois où elle sera pliée. À la prochaine correction, on incrémente.

Ce que ça change pour vous

  • Le plugin s’installe depuis la page de téléchargement de mesplugins.fr, puis par l’écran Extensions de WordPress (Ajouter, puis Téléverser).
  • L’empreinte SHA-256 de l’archive est publiée sur cette même page, avec les commandes pour la vérifier vous-même avant l’installation.
  • À partir de la 0.1.5, votre site est prévenu des versions suivantes dans l’écran des extensions comme par WP-CLI, sans rien envoyer sur vous. Les anciennes archives restent servies, pour pouvoir revenir en arrière.
  • Le code est public sur GitHub, avec un gabarit de rapport de bogue.