Releases 4.75.0
Everything that was added, changed, removed or fixed. The summary by branch first, then the detail of each version. Mistakes and points left open are listed too: a log that only mentioned successes would be useless.
The change log is written in French.
Summary by branch
Each branch groups its fixes. The numbers are counted in the log, never written after the fact: they add up what each version already files under “Créations” (additions), “Bugs corrigés” (bugs fixed), “Évolutions” (improvements)… Click a branch to read its detail.
4.75 1 version · 18 octobre 2026 4 improvements 3 changes 3 bugs fixed
4.75.0 — 18 octobre 2026
IriX, l'Eggdrop, est arrêté : OverCore tient seul les services ; la page Commandes ne montre à chacun que ce que son grade permet ; le site et le panel ne présentent plus IriX comme actif.
Évolutions
- IriX (l'Eggdrop) est arrêté depuis le 18/10/2026 01:31 (skill
arreter-irix, retour écrit avant) ; OverCore (Node, SID 004) tient les cinq services, les cessions et le reflet. Sans autre tenant, le reflet du réseau est repris dès la fin du burst (plus de table des connectés vide à la relance). - Page Commandes fermée par défaut : sans connexion au compte du site, seules les commandes ouvertes à tous, à envoyer en privé aux services ; connecté, celles de son grade ; opérateur du réseau, tout ; plus aucun nom interne à l'écran. Elle sort de la liste blanche du service worker (cache v4).
- OverNick envoie à OverScript des lignes machine (demande d'identification, résultat de grade).
- Installateur : OverCore posé sans Eggdrop quand Node.js ≥ 14.14 ; Eggdrop + IriX deviennent l'ancien chemin (pages Installation et Guide à jour).
Modifications
- Pages publiques (Commandes, Nos robots, Présentation, Compatibilité, parc, pied de page) et 16 pages du panel : ce qui dépend de l'état d'IriX passe par
irix_arrete(), chargé avant l'appel. - Journal d'OverCore : plus de « IriX le cède / reprend » sans autre tenant ; « fermeture : ERROR » devient « lien fermé par le serveur ».
Tools/wsl-portproxy.ps1: en mode miroir de WSL, plus aucun relais (il renvoyait le PC vers lui-même) ;Tools/garde-ports.ps1le surveille et supprime seul un relais qui boucle.
Bugs corrigés
- Le relais 80/443 bouclait sur le PC (31 095 connexions, ports épuisés, bancs figés).
- La page Commandes montrait les commandes d'IRCop à un navigateur non connecté (preuve de pseudo de 30 min gardée) ;
?tout=1ouvrait tout à n'importe qui. test-masquage-panelrougissait en prod depuis l'arrêt d'IriX.
4.74 1 version · 12 octobre 2026 4 improvements 1 warning
4.74.0 — 12 octobre 2026
Trois mots de passe erronés bloquent un pseudo ; OverCore tient le reflet du réseau ; les pages du site disent qui sert quoi.
Évolutions
- Trois mots de passe erronés sur un même pseudo en 24 heures — par
IDENTIFY,GHOST,DROP,SUPPRIMEou le formulaire d'identification du site — le bloquent 15 minutes, puis 30, 60… à chaque récidive, 24 heures au plus ; pendant le blocage, aucun essai n'est examiné. Le propriétaire est prévenu par courriel (si une adresse est connue) et les opérateurs sur le salon des services. Le débloquent : l'échéance, une connexion au compte du site, un « mot de passe oublié » mené à son terme, ou un opérateur depuis le panel (page Utilisateurs). - OverCore écrit désormais le reflet du réseau en base — qui est connecté, les sessions, les serveurs en ligne — que le panel et le site lisent ; IriX le lui a cédé le 11/10/2026 au soir. Le panel reconnaît OverCore comme référence du lien de services quand c'est lui qui tient ce reflet.
- Page des commandes refaite : seules les commandes servies sont comptées et listées — dans les salons, les treize « ! » (alias compris) d'OverTchat ; en privé, les cinq services d'OverCore et ce qu'IriX garde encore. Les autres sont rangées dans une section repliée, « Commandes retirées », qui dit pour chacune par quoi la remplacer. Les verbes d'OverNick
SETPASS,LOGOUT,CONFIRME,ACCESSetEXPIREy figurent. - Accueil, « Nos robots », le parc, le règlement des salons, la page d'un salon, « Bien démarrer » et l'inscription : IriX n'y est plus présenté comme le robot des salons, OverCore est présenté, la modération assistée est dite gelée, et le blocage après trois mots de passe erronés est expliqué.
Avertissements
- En cédant le reflet, IriX a fermé les sessions ouvertes à cet instant : la page « Connexions » du panel reste incomplète jusqu'à la reconnexion de chacun ; « Connectés » est complète.
4.73 1 version · 11 octobre 2026 3 improvements
4.73.0 — 11 octobre 2026
La console d'OverCore s'ouvre avec le mot de passe du pseudo.
Évolutions
- La console d'OverCore (locale, en lecture seule, port 3336) vérifie le mot de passe du compte — celui de l'identification auprès d'OverNick — et non plus celui de la partyline d'IriX. Un mot de passe signalé exposé est refusé tant qu'il n'est pas changé.
- Chaque connexion à la console, refus compris, est notée au journal du panel et annoncée par courriel.
/msg IriX consolepass,helloetsyncownerrenvoient vers ce fonctionnement (retrait le 25/10/2026). Le panel ne propose plus de mot de passe de console à part.
4.72 1 version · 11 octobre 2026 (nuit) 2 improvements
4.72.0 — 11 octobre 2026 (nuit)
L'avis du salon des adultes et les purges horaires passent chez OverCore.
Évolutions
- L'avis « réservé aux adultes » à l'entrée de #rencontres (et l'expulsion d'un âge déclaré sous 18 ans) vient désormais d'OverTchat, avec les mêmes textes.
- Les purges par ancienneté (journal d'événements 90 jours, sessions fermées 30 jours, audit du site 90 jours) sont faites chaque heure par OverCore.
4.71 1 version · 10 octobre 2026 (nuit) 3 improvements
4.71.0 — 10 octobre 2026 (nuit)
Les grades de salon passent chez OverNick : /msg IriX access est remplacé.
Évolutions
/msg OverNick ACCESS #salon(votre grade),ACCESS accept|refuse #salon(une proposition),ACCESS add|del #salon <pseudo> [grade]: mêmes réponses qu'avant chez IriX./msg IriX accessrépond désormais par un mot d'orientation (français puis anglais).- Une proposition de grade (
!newowner,!newop,!newvoice) et son rappel à l'identification disent d'accepter auprès d'OverNick. - Panel : la page des robots ne présente plus IriX comme membre de
#!Bots!; un robot se déclare par/msg OverBot OPBOTADD.
4.70 1 version · 10 octobre 2026 (soir) 2 improvements 1 bug fixed
4.70.0 — 10 octobre 2026 (soir)
IriX quitte les salons : OverTchat les tient seul.
Évolutions
- IriX (le robot Eggdrop) ne siège plus dans aucun salon ; OverTchat, le service des salons, y reste opérateur et sert tout ce qu'IriX y faisait. IriX reste joignable par
/msg IriX. - Les actions du panel sur les salons (fermer, suspendre, réactiver, sujet, modes) passent par OverTchat. Une commande « ! » retirée reçoit un mot d'orientation.
Bugs corrigés
- Un « !do » servi par OverTchat n'est plus annulé par la protection native de l'Eggdrop.
4.69 1 version · 10 octobre 2026 (après-midi) 2 improvements 3 bugs fixed
4.69.0 — 10 octobre 2026 (après-midi)
OverTchat siège dans les 7 salons et y reprend l'essentiel de ce qu'IriX faisait.
Évolutions
- OverTchat (le service des salons) entre avec l'@ dans les salons enregistrés.
- Servis désormais par OverCore : l'historique du chat du site, les sujets et les modes enregistrés des salons (restaurés après un redémarrage), le nombre de présents (sans nos services), l'anti-flood et les mots interdits, les annonces automatiques (envoyées par OverTchat), et les commandes « ! » des salons (!op, !v, !kick, !ban, !newowner…), qui répondent par OverTchat.
Bugs corrigés
- Un opérateur qui se connectait juste après une relance d'OverCore n'entrait pas dans le salon des opérateurs.
- Deux écrivains possibles de l'état des bans pendant quelques minutes après chaque démarrage.
!statsrépond (chez IriX, il ne répondait jamais).
4.68 1 version · 10 octobre 2026 3 improvements
4.68.0 — 10 octobre 2026
Arrêt d'IriX, lot ③ : les comptes d'IriX sont servis par OverNick.
Évolutions
- OverNick :
LOGOUT(fermer sa session) etSETPASS <ancien> <nouveau>(changer le mot de passe de son pseudo, mêmes règles que le site). À l'identification, les grades de salon proposés sont rappelés (texte et ligne machine pour OverScript). /msg IriX auth,passetdeauthrépondent désormais par une orientation vers OverNick (jusqu'au 24/10/2026, puis retrait). La console d'IriX (consolepass) est inchangée.- Les actions du panel (KICK, BAN, modes) exigent un opérateur IDENTIFIÉ sur sa connexion.
4.67 1 version · 9 et 10 octobre 2026 1 addition 4 improvements 4 bugs fixed
4.67.0 — 9 et 10 octobre 2026
Les cinq services sont chez OverCore ; IriX commence à rendre le reste (huit fonctions reprises).
Évolutions
- OverNick est servi par OverCore depuis le 09/10 : IriX ne porte plus aucun service. Essais réels verts : identification, GHOST, auto-op à l'identification, identification depuis le site, suppression de compte par lien.
- Canal machine OVS 1 allumé : OverScript 0.6.44 (publié le 09/10) s'inscrit auprès d'OverCore.
- IriX a son porteur « IriX-Services » (migration 052) : sans lui, IriX restait muet depuis le départ de son dernier service (auth, panel, partyline, travaux, avis de grade).
- Arrêt d'IriX, lots ①②⑥ : la file d'actions du panel, l'avis de travaux, l'entrée des opers dans leurs salons, l'alerte du chat, les courriels d'alerte, la purge des comptes web, le journal des modes et l'état des bans sont servis par OverCore (IriX les cède par réclamation en base) ; la base peut naître sans IriX (migration 000, le socle des 46 tables).
Bugs corrigés
- Suppression de compte par lien impossible depuis le 05/10 (fonction retirée encore appelée) : le second facteur est désormais un code renvoyé par
/msg OverNick CONFIRME <code>. overcore.json(secrets) remis en 600 : les scripts de reprise le rendaient lisible par tous.- IA : une promotion automatique ne s'annonce plus réussie quand rien n'a été écrit.
- Six bancs rouges de la campagne du 09/10 corrigés (dont la console TLS : la boucle locale IPv4 de WSL ne refuse plus un port fermé, la sonde ident attendait 5 s).
Créations
Web/sql/052-irix-porteur.sql,Web/sql/000-socle-irix.sql;Robots/overcore/lib/{modq,travaux, cession,operjoin,chatalerte,modtrace}.js; bancs de frontière Node↔Tcl de chaque fonction reprise.
4.66 1 version · 8 octobre 2026 1 addition 3 improvements 1 bug fixed
4.66.0 — 8 octobre 2026
OverCore sert désormais OverTchat et OverBot ; IriX ne garde plus qu'OverNick.
Évolutions
- OverTchat (les salons : LIST, INFO, et pour les opérateurs OP, KICK, BAN, TOPIC, MODE, INVITE…) est servi par OverCore depuis le 08/10, à l'identique d'IriX.
- OverBot (le prêt de robots : ADDBOT, MANDAT, listes, et ses automatismes : demandes du panel, état des robots, op rendu aux robots prêtés) est servi par OverCore depuis le 08/10 ; l'op des robots passe désormais par le lien, un chemin fiable.
- Les G-lines posées par les services frappent (4.65.0) ; les trois reprises du 07-08/10 ont chacune leur script éprouvé et leur commande de retour.
Bugs corrigés
- IA : un arbitrage du panel ne s'applique qu'une fois ; une installation neuve crée elle-même ce dont la promotion automatique a besoin.
Créations
Robots/overcore/lib/overbot-auto.js,lib/botreg.js; bancstest-chan-*,test-bot-*.
4.65 1 version · 7 octobre 2026 (soir) 1 addition 3 improvements 3 bugs fixed
4.65.0 — 7 octobre 2026 (soir)
Les G-lines posées par les services frappent enfin, et OverCore sait désormais tout faire d'OverHub.
Bugs corrigés
- Serveur : une G-line
*@hôteposée par les services (OverHub, IriX) était enregistrée sans sa part « utilisateur » et ne frappait personne, depuis le 29/07. Corrigé et basculé le 07/10 à 20:34. Une seule G-line avait jamais été posée ainsi en service : un essai du 20/09. - Panel, page « Moteur IA » : cinq affirmations rendues fidèles au code (ce qui entre dans la file de l'IA, ce qui l'entraîne, les seuils, la quarantaine de 48 h).
- Sauvegarde quotidienne : les paquets servis et les débris de bancs n'y entrent plus (534 → ~13 Mo) ; les bancs ramassent leurs débris, et un lien symbolique n'est plus jamais suivi.
Évolutions
- OverHub, étapes 2 et 3 dans OverCore : sanctions réseau (G/Z-lines, levées, listes) et commandes sur un client (KILL, SAJOIN, SAPART, CHGHOST, CHGIDENT, SVSNICK), à l'identique d'IriX ; prêtes, pas encore servies (la reprise d'OverHub se fera sous accord).
- Réserve des opérateurs : depuis le réseau local, une place est gardée même serveur plein.
- Sonde des services : ne compte plus que les vrais services (
+S).
Créations
- Bancs
Servers/overtchat-hybrid/tests/test-tkl-uline.py,Robots/overcore/test-hub-sanctions.js,test-hub-serveur.js,Web/tests/test-ia-page-jointure.php.
4.64 1 version · 7 octobre 2026 (après-midi) 1 addition 3 improvements 1 bug fixed
4.64.0 — 7 octobre 2026 (après-midi)
Le réseau sait se calmer tout seul : un salon pris d'assaut se ferme aux inconnus le temps que ça passe, et une même adresse ne peut plus ouvrir des dizaines de connexions.
Évolutions
- Retour au calme par salon (OverCore) : au-delà de 6 arrivées de pseudos non identifiés en une minute sur un salon, l'entrée est ralentie (
+j) ; si ça continue, seuls les pseudos identifiés entrent (+R) ; dix minutes de calme, et OverCore retire exactement ce qu'il a posé — jamais un mode posé par un humain. Un avis le dit dans le salon. - Anti-clones (OverCore) : plus de 3 connexions sous la même adresse, ou 8 dans la même plage, sur tout le réseau ; les connexions en trop sont coupées (jamais un pseudo identifié ni un opérateur), et une récidive vaut un bannissement temporaire.
- En service en mode « journal » : tout est décidé et noté, rien n'est encore posé ni coupé. La charte du site le dit (section 10).
Bugs corrigés
- Le banc qui fait tourner OverCore contre un vrai serveur rougissait depuis le 05/10 (attentes périmées depuis la reprise d'OverHub) ; il repasse au vert, et la bissection a montré que le code était juste.
Créations
Robots/overcore/lib/calme.js,lib/adresses.js; bancstest-calme.js,test-calme-serveur.js.
4.63 1 version · 7 octobre 2026 1 addition 3 improvements 1 bug fixed
4.63.0 — 7 octobre 2026
Le chat du site n'ouvre plus sans passer par sa porte, et chaque connexion au réseau est comparée aux listes publiques d'adresses abusives.
Évolutions
- Jeton du chat exigé : un script qui ouvre le tunnel du chat sans passer par le formulaire du site est refusé (le jeton à usage unique de la 4.62.0 n'est plus seulement noté).
- Listes d'adresses abusives (OverCore) : chaque connexion est comparée à DroneBL et EFnet RBL (par DNS) et à la liste officielle des sorties Tor (téléchargée, lue localement). En service en mode « journal » : les adresses listées sont notées, personne n'est encore banni. La charte du site le dit (section 10).
- Installation chez un tiers :
config.phpdésigne désormais le serveur IRC de l'installation (et non celui du réseau d'origine) — page Admin, page Protection, mot de passe des liens et dossier des jetons du chat.
Bugs corrigés
- Un renvoi de banc vers un fichier qui n'a jamais existé (
test-secrets-conf.sh).
Créations
Robots/overcore/lib/dnsbl.js; bancstest-dnsbl.js,test-dnsbl-serveur.js,Bootstrap/tests/test-config-chemins-ircd.sh. Lanceur Windows reconstruit.
4.62 1 version · 6 octobre 2026 1 addition 4 improvements 1 bug fixed
4.62.0 — 6 octobre 2026
Le serveur IRC se défend seul contre les inondations venues d'adresses qui changent : plafonds par plage d'adresses, mode panique gradué, et une serrure sur le tunnel du chat du site.
Évolutions
- Plafonds par plage (/24 en IPv4, /48 en IPv6) dans le serveur lui-même, en plus de l'adresse exacte : rythme des connexions, connexions simultanées, connexions pas encore enregistrées (refusées avant la négociation TLS). La table du rythme ne se laisse plus effacer par une rafale d'adresses.
- Mode panique gradué, automatique : au palier 1 les limites se resserrent ; au palier 2, seules les adresses déjà vues sur le réseau dans les 30 derniers jours peuvent se connecter (les autres sont refusées : message en clair sur le port non chiffré, réponse 503 au chat du site, connexion simplement fermée sur le port TLS) ; retour au calme automatique, un palier à la fois. Commande opérateur
PANICpour lire l'état ou forcer un palier. - Jeton du chat du site : la porte du chat délivre un jeton à usage unique que le serveur consomme à l'ouverture du tunnel ; aucune clé secrète. En service en mode « journal » (le serveur note les connexions sans jeton, sans les refuser) avant de l'exiger.
- Places réservées : les blocs
allowmarquésreserved(robots et services) et les serveurs liés échappent aux plafonds.
Bugs corrigés
- Le banc qui fait tourner le vrai code d'IriX contre le serveur rougissait depuis le 05/10 pour deux doublures périmées (base de données, chargement interne de Tcl) ; il repasse au vert.
Créations
Servers/overtchat-hybrid/src/plafonds.c; bancstest-plafonds.py,test-panique.py,test-ws-jeton.py,test-ws-jeton.php; route?p=ws-jeton(jeton de reconnexion du chat).
4.61 1 version · 5 octobre 2026 (soir) 2 additions 3 improvements 3 bugs fixed
4.61.0 — 5 octobre 2026 (soir)
Les grades de salon redevenus des grades DE CE salon, et un premier rempart devant le réseau contre les inondations venues d'adresses qui changent.
Évolutions
- Pare-feu par plage d'adresses devant l'IRC (6667/6697) et le site (8443/8880) : une même plage (/24 en IPv4, /48 en IPv6) ne peut pas ouvrir plus de 90 connexions nouvelles par minute ni en tenir plus de 60 à la fois ; refus immédiat au-delà, réseau local jamais limité. Unité
overtchat-pare-feu.service, règles lues dans une copie appartenant à root ; l'installateur les pose sans les activer. - Apache en MPM event : le chat du site n'est plus plafonné à 150 connexions simultanées (environ 1 000) ; phpMyAdmin passe par un pool PHP-FPM dédié ; le tunnel du chat abandonne en 5 secondes si le serveur IRC ne répond pas, au lieu de tenir un processus une heure.
!userlistouvert au propriétaire identifié d'un salon, pour les grades de ce salon seulement.
Bugs corrigés
!newowner,!newop,!newvoicedonnaient un grade sur TOUT le réseau, sans prévenir le nommé : ils proposent désormais un grade de CE salon, que le nommé accepte ou refuse (access accept|refuse #salon).- Le panel disait d'un propriétaire de salon qu'il se change « depuis Eggdrop » : faux, corrigé.
- La documentation du serveur affirmait que les services faisaient déjà l'anti-flood par salon : c'était faux en service.
Créations
Config/nftables/overtchat-limites.nft,Config/systemd/overtchat-pare-feu.service,Config/php-fpm/overtchat-phpmyadmin.conf,Config/apache/mpm-event-overtchat.conf; bancstest-pare-feu(95 constats) ettest-newowner-salon.- Lanceur Windows reconstruit avec l'installateur de cette version.
4.60 1 version · 4 au 5 octobre 2026 1 addition 9 improvements 4 bugs fixed
4.60.0 — 4 au 5 octobre 2026
Le site contrôlé page par page, les comptes protégés contre ceux qui sondent, les couleurs IRC enfin rendues dans le chat du site — et le premier service du réseau confié au successeur d'IriX.
Évolutions
- OverCore reprend OverWeb (05/10) : premier service sorti d'IriX, à l'identique (PING, STATS, HELP, VERSION, STATUS, APPEL). OverCore introduit et retire un service à chaud ; la reprise passe par un outil qui simule d'abord et écrit son retour avant d'agir. OverHub suit : sa lecture (USERS, SERVERS, CHANS, STATS, MAP) et GLOBOPS sont prêts dans OverCore.
- Annonces du réseau encadrées aux couleurs du projet ; les octets de contrôle refusés à l'écriture et retirés à l'envoi ; délai minimal de 60 secondes entre deux annonces.
- Chat du site : le gras, les couleurs et l'italique envoyés depuis IRC s'affichent au lieu des codes bruts.
- Opérateurs reconnus sur le serveur lui-même ; l'identification appartient à la CONNEXION (une reprise de pseudo n'hérite plus de l'identification d'un autre).
- Mot de passe exposé : un avis à chaque connexion tant qu'il n'a pas été changé.
- Essai découverte : un compte d'essai gelé est gardé 6 mois (courriel à 5 mois) puis effacé ; le profil gelé est caché.
- #rencontres réservé aux adultes aussi sur IRC : avis à l'entrée, expulsion sur âge déclaré inférieur à 18.
- OverPur change le mot de passe d'un robot sans le sortir de ses salons.
- Mentions légales (
?p=mentions) et licence rendue cohérente ; traductions anglaises des pages de salon, des Rencontres, des messages du routeur et des états de profil.
Bugs corrigés
- Audit du site public page par page : les portes des Rencontres, de la visio et des profils refermées aux anonymes ; la page des versions ne publie plus de détail interne ; une page privée n'est plus gardée en cache par le navigateur ; en-têtes de sécurité complétés.
- Comptes : l'inscription, l'essai et le mot de passe oublié ne disent plus si une adresse ou un compte existe (ni par le texte, ni par le temps de réponse) ; un pseudo ne peut plus être réservé d'avance par le renvoi d'inscription ; le « mot de passe oublié » exige un vrai second canal.
!delban: un opérateur de salon ne lève plus un ban du RÉSEAU (seul un administrateur) ; le règlement le dit.- Panel : rechargement du serveur IRC possible sans
sudoquand le service l'interdit, et seulement sur autorisation explicite.
Créations
Tools/reprendre-service.sh(reprise d'un service par OverCore : simulation par défaut, retour écrit avant) ;Web/inc/apres-reponse.php(tâches lentes après la réponse, contre les oracles de temps) ; bancstest-voix-repli,test-delbanet ceux des lots de l'audit.
4.59 1 version · 4 octobre 2026 1 addition 4 improvements 6 bugs fixed 1 removal
4.59.0 — 4 octobre 2026
Une journée de sécurité : chaque page du panel d'administration contrôlée et corrigée, la base de données réduite au strict nécessaire, le lien d'OverCore enfin dit juste, et le code mort des robots Eggdrop retiré.
Évolutions
- Base de données durcie : le compte du site n'a plus de droits que sur sa base (il portait
GRANT ALL ON *.*, lecture de fichiers comprise) ; MariaDB ne lit ni n'écrit plus de fichiers hors d'un dossier réservé (secure_file_priv),local_infilecoupé ; rejouable parTools/durcir-systeme.sh(§4), qui ne relance jamais MariaDB (cela relancerait IriX seul). - Panel, sessions : refermées dans la minute si le mot de passe change ou si le pseudo est suspendu ; un pseudo suspendu ne se connecte plus ; inactivité de 24 minutes (la charte le dit) ; les sondages automatiques ne comptent plus comme activité.
- Panel, affichage : seuls les boutons que le niveau permet ; adresses et IP masquées sous Admin ; les robots du réseau marqués dans « Connectés » ; « Démarrer / Redémarrer IriX » retirés (IriX ne repart jamais seul) ; journal d'audit étendu aux actions sensibles.
- OverCore écrit l'état de sa ligne de lien (battement chaque minute) et IriX n'y touche plus : Statut et Liens ULine ne disent plus « rompu » ni ne proposent de « rétablir » le lien.
Bugs corrigés
- Console SQL contournable :
SELECT '/*', LOAD_FILE(…), '*/'passait pour une lecture ; autres bases,PROCESSLIST,WITH … UPDATEdésormais refusés ou classés écriture ; export CSV protégé contre les formules. - Connexion : le temps de réponse disait si un compte existait et était verrouillé.
- Un tableau en paramètre (
?x[]=) faisait une erreur 500 sur le panel. - Rotation du mot de passe de la base :
ALTER USER/FLUSHrefusés au compte réduit, et un échec après coup laissait la base sur un mot de passe inconnu (désormaisSET PASSWORD). - Banc
test-chanbansrouge en prod depuis le retrait de#accueil(02/10), sans alerte. - Juge des mises en ligne : « 0 en echec » sans accent pris pour un échec.
Suppressions
- File d'installation des robots OverOp Eggdrop :
Tools/overop-pool.php,overtchat-botpool.{service,timer}(retirés aussi de la prod), alias sudoersOVERTCHAT_POOL, bouton « Demander un robot de plus ».
Créations
- Bancs :
test-console-sql,test-masquage-panel,test-live-robots,test-panel-securite-04-10; contrôle « MariaDB » deaudit-securite(8 ter).
4.58 1 version · 1er au 3 octobre 2026 7 improvements 5 bugs fixed
4.58.0 — 1er au 3 octobre 2026
Trois journées de cohérence : les règlements, la charte et les commandes disent ce que fait le code ; la visio passe toujours par le relais du réseau ; le chat du site et OverScript partagent les mêmes commandes ; le site se lit en anglais jusque dans ses scripts ; une installation tierce est éprouvée de bout en bout.
Évolutions
- Visio et webcam toujours par le relais du réseau (TURN seul, plus de pair à pair ni de STUN de Google) : l'adresse IP de chacun est masquée à son correspondant ; charte §12 « Visio, webcam et analyses automatiques ».
- Caméra au choix (PC ou téléphone, choix retenu), bouton « ✕ Annuler » sur l'essai et la photo du profil ; localisation par la ville quand la position manque.
- Chat du site : commandes alignées sur OverScript (motifs entiers,
/joinà clef,/topic,/meen privé,/aide). - Panel : groupe « Salons » ; « Annonces du réseau » ; courriels aux couleurs du projet, vue d'ensemble et rejets expliqués.
- Traduction : six pages publiques et les textes de leurs scripts en anglais.
- Accueil : encart Facebook (un lien, rien qui piste).
- Installation tierce (essai réel en conteneur) : GD posé, empreinte factice au coût de PHP, plus aucun chemin vers
~lu chez un tiers, robots réservés, fichiers d'état rendus au compte après une commande en ligne ; Lanceur republié.
Bugs corrigés
/msg IriX passn'avait jamais changé le mot de passe d'un membre (bind remplacé).- Textes publics faux :
git cloned'un dépôt privé à l'accueil, durées de la charte, suppression de compte, ce qu'un op peut faire, la modération par IA (« sanctionne selon le mode » / « pas en service » → un classificateur au modèle vide, aucun salon en sanction automatique). - Visio/webcam : « votre profil est suspendu » affiché alors qu'il ne l'était pas.
regchan/!regchanet l'enregistrement au panel ne semaient pas la ligneauto_config;regchanannonçait un succès sur refus SQL.- Salons :
#accueilretiré,#Csadminmarqué salon d'administration.
4.57 1 version · 30 septembre 2026 3 additions 4 improvements 4 bugs fixed
4.57.0 — 30 septembre 2026
Une journée de sécurité et de finitions : le panel ferme six défauts d'autorisation, la visio chiffrée fonctionne enfin, le site se lit en anglais jusque dans sa charte, l'accueil des Rencontres est refait, et la garde du « premier venu opérateur » est vue agir en service.
Évolutions
- Rencontres : nouvel accueil (connexion au profil, « Je découvre », nombre de personnes sur le réseau et dans
#rencontres, « autour de vous » par tranches dans 50 km) ; un membre au profil valide entre sans refaire l'essai caméra/micro (la visio l'exige toujours). - Traduction : la Charte, le Règlement des salons et le cadre des règles du chat en anglais.
- Sécurité (système) : 18 correctifs Debian ; Apache sans version ; SSH en clés seules ; relais TURN durci et enfin chiffré (
Tools/coturn-letsencrypt.sh— la clé était illisible par coturn depuis le ~21/09) ;Tools/durcir-systeme.shrend ces réglages rejouables. - Mise à jour d'OverScript signée (Ed25519) : le dépôt signe chaque paquet (
Tools/overscript-deposer.sh), clé générée par SerVuS (Tools/overscript-cle-generer.sh).
Bugs corrigés
- Panel : un Admin pouvait fermer le compte d'un Net-admin (profil_bannir) ; IRCop en dur sur les accès de salon ; console SQL contournable par
/*! */; accès à la partyline non journalisés ; réinitialisation de mot de passe d'un compte protégé ; injection de lignes de journal. - Bandeau « Service perturbé » affiché à tort depuis le 27/09 (OverCore jugé par son lien).
?p=carte-pointslisible par tout compte connecté (désormais la porte de la carte).- En-tête
Host:recopié dans les réponses (php -Sderrière le proxy) : ôté par Apache.
Créations
- Migration
048-web-users-desactive-par.sql(le débannissement ne rallume que ce qu'il a éteint). Web/inc/rencontres-accueil.php,js_json(),site_hote(),journal_nettoyer().- Bancs :
test-panel-securite-30-09,test-rencontres-accueil,test-durcissements-30-09,test-overscript-signature(PHP et shell),test-durcir-systeme.
4.56 1 version · 22 septembre 2026 14 checks
4.56.0 — 22 septembre 2026
Le mot de passe de la base a quitté les réglages pour un fichier qui ne contient que des secrets, IriX est le sixième et dernier pseudonyme protégé, et un propriétaire de salon peut enfin faire agir la file de modération sur son propre salon.
Le soir du 23 septembre — licences en règle, fond de carte chez nous, installateur vérifié
Ce qui part chez autrui porte désormais sa licence, la carte ne dépend plus de personne, et l'installateur refuse une archive qu'il n'a pas vérifiée.
- Licences jointes aux copies (point 90,
LICENCES-COMPOSANTS.md§12.A) : - Leaflet, TensorFlow.js et NSFWJS arrivent avec leur
LICENSE, et le modèle NSFWJS est épinglé sur@v4.4.0; - notre
LICENSEpart dans/dl/site, dans l'archive Hybrid et à côté de l'exécutable du Lanceur (reconstruit, et redéposé) ; - son périmètre couvre maintenant
Robots/etLanceur/, et exclut les composants tiers ; - une page
?p=licencesexiste, liée depuis le pied de page. Banctest-licences-tierces. - Le fond de carte est auto-hébergé :
- deux fichiers PMTiles de données OpenStreetMap, 337 Mo au total, dans
Web/.run/carte/; - les tuiles CARTO exigeaient une clé personnelle depuis le 26/08, et envoyaient l'IP de chaque visiteur chez un tiers ;
- 🔴
php -Signore les requêtes Range : mesuré, il rend 200 et le fichier entier. D'oùtuiles.php, qui ne sert qu'un morceau à la fois ; - carte vue dessinée sur l'Europe, Paris et Montréal. Banc
test-tuiles, 17 blessures sur 17. - L'installateur vérifie ses 9 téléchargements tiers :
- chacun a une empreinte SHA-256 épinglée, mesurée sur deux téléchargements identiques. Avant, seul l'en-tête gzip était contrôlé, et rien pour mysqltcl et tcltls ;
- Eggdrop passe en https, et tcltls est pris sur une révision figée. Banc
test-empreintes-sources, 12 blessures sur 12. - OverScript 0.6.28 publiée, et SerVuS s'est mis à jour depuis le client en 24 s. Elle apporte les mots de passe qui ne se relisent plus, la console qui dit vrai,
/ctcpet la réponse au PING privé seul. Deux trous ont été trouvés par la mutation complète, puis corrigés, dont une protection des mots de passe en double, que sa blessure mesurait à la place de l'originale.
4.55 1 version · 22 septembre 2026 not broken down
4.55.0 — 22 septembre 2026
Un grade de salon ne vaut plus que sur son salon, et le trombinoscope dit enfin dans quel état est une fiche — sans apprendre à personne qui se cache.
4.54 1 version · 22 septembre 2026 1 check
4.54.0 — 22 septembre 2026
Un grade de salon peut désormais se PROPOSER au lieu de s'imposer : la personne reçoit un courriel, et tant qu'elle n'a pas accepté d'un clic, le grade ne lui donne rien — ni sur le site, ni sur IRC. La moitié la moins visible du travail est que cet accès reste VISIBLE et RETIRABLE.
Éprouvé en service
Filtre appliqué par MariaDB, lecture brute qui voit la ligne, re-pose qui confirme, défaut à oui, table revenue à son état de départ. La page répond 200 sur 8880 et 8443 et refuse proprement un jeton invalide. IriX rechargé, lien ULine rétabli, aucune erreur Tcl.
⚠ Ce qui n'est pas éprouvé : aucun courriel n'est parti pour de vrai. Tout le chemin l'est, sauf l'acceptation par le relais.
4.53 1 version · 21 septembre 2026 not broken down
4.53.0 — 21 septembre 2026
Trois choses que personne ne gardait : le nom des robots, l'icône des paquets, et le salon qu'une installation tierce héritait du nôtre. La première rougit encore — c'est son rôle, et elle s'éteindra quand les six empreintes seront posées.
4.52 1 version · 15 septembre 2026 2 additions 2 improvements 8 bugs fixed 2 checks 4 mistakes 2 warnings
4.52.0 — 15 septembre 2026
Dix mesures du panel mentaient sans lever la moindre erreur. Deux d'entre elles mentaient ACTIVEMENT — dont une qui rendait le succès muet : une demande de robot accordée n'affichait rien du tout.
Bugs corrigés
- 🔴🔴 Une demande de robot accordée n'affichait RIEN. La page du propriétaire traitait quatre états sur cinq, et le manquant était le seul état heureux : un séparateur, puis le silence — et le formulaire « Demander un robot » qui réapparaissait comme si l'on n'avait jamais rien demandé. Le propriétaire pouvait redéposer une demande déjà accordée. Le succès était le seul état muet.
- 🔴🔴 La tuile « Sessions — connexions ouvertes » affichait 0 pendant que cinq personnes étaient sur le lien. Le même compteur avait annoncé 89 sur un réseau presque vide en juillet : un compteur qui a menti dans les deux sens ne mentait pas sur sa valeur, il mentait sur son libellé.
- 🔴 Le score de modération des messages privés ignorait le poids d'une règle valant zéro et se trompait de seuil par défaut — le plus grave des dix, parce qu'il décide d'une sanction.
- 🔴 Le bandeau de CHAQUE page retenait le premier lien activé par ordre de création, pas celui qui porte réellement le lien.
- 🔴 La page Anope nommait UnrealIRCd sous un lien porté par Overtchat-Hybrid : un dialecte annoncé pour un autre.
- Les appels vidéo restaient sur « Appel de X… » pour l'éternité quand la personne venait de partir : le serveur refusait la trame et le disait, mais aucun client ne lisait la réponse.
- Le port du panel était écrit trois fois, les ports des microservices trois fois, et les sept types de signalisation cinq fois — chaque écriture pouvant dériver sans que rien ne casse.
- Une classe de style du panel avait été posée dans une page du site : le texte s'affichait sans style. Et
.note.ok, employée par trois pages, n'avait jamais été définie — un succès s'affichait comme une simple remarque.
Créations
- Six bancs qui croisent un même fait écrit dans deux langages — c'est le défaut le plus productif de ce dépôt : un fait écrit à N endroits diverge N−1 fois, et la divergence ne casse rien, elle fait mentir. Sont désormais gardés : la table des accès par salon (créée deux fois), le plafond d'échecs du botnet, les sept événements de son journal et leurs sept couleurs, les cinq états d'une demande de robot (jusqu'aux boutons de l'opérateur), et les quatre vocabulaires de profil.
- La liste des états d'une demande, en un seul endroit — elle n'existait pas : le code portait neuf mentions en clair réparties sur trois fichiers.
Évolutions
- Le lanceur de bancs sait lire un troisième format de résumé. Trois bancs du lanceur Windows étaient comptés zéro et annoncés « muets » : ils ne le sont pas, ce sont 66 vérifications qui n'entraient dans aucun total.
- La page Botnet nomme ce qu'elle affiche au lieu de choisir entre deux mots par un raccourci : un raccourci à deux branches est une liste fermée qui ne se déclare pas comme telle.
Avertissements
- ⚠⚠ Trois différences ne doivent PAS être « harmonisées », et chacune est désormais gardée pour qu'un nettoyage la casse bruyamment : l'état de repos du botnet n'est pas une action qu'on demande ; l'état « partiel » est calculé et jamais enregistré ; et « Secret » à l'entrée du chat n'est pas « Ne se prononce pas » sur une fiche de rencontre — deux écrans, deux publics.
- ⚠ La lecture de la réponse par les deux clients vidéo est gardée par un banc, mais n'a pas été éprouvée à deux personnes sur un vrai appel. C'est le seul endroit de la séance où « écrit et éprouvé » n'est pas « en service ».
Erreurs
- 🔴🔴 Mes propres passes de vérification mesuraient la PRODUCTION là où elles croyaient mesurer une copie. Toutes celles qui éprouvaient un fait écrit en Tcl n'avaient donc jamais éprouvé ce côté-là. Le signe qui l'a révélé : des vérifications qui restent vertes par famille entière — une garde absente est isolée, un groupe entier qui ne réagit pas désigne la mesure, pas la garde.
- Ce journal avait un trou de 39 entrées : les travaux du 13 au soir et du 14 septembre n'y figuraient pas. Rattrapés ici, aux deux versions précédentes.
- Deux de mes corrections ont été rattrapées par des gardes qui ne les regardaient pas : l'une avait créé une liste que seul un banc employait, l'autre avait posé la mauvaise classe de style. Une vérification éprouve ce qu'elle protège, jamais ce que la correction a déplacé à côté.
- 6,6 Go de copies de travail laissés par mes propres passes, faute d'un nettoyage qui survive à un arrêt prématuré.
Vérifié
- 258 contrôles au vert, 9 661 vérifications, zéro échec, un seul non lançable ici (il exige les droits d'administration). Aucun contrôle bloqué, plus aucun contrôle muet.
- Le site répond et ne rend aucune erreur ; les fichiers corrigés sont bien ceux que le navigateur reçoit.
4.51 1 version · 14 septembre 2026 3 additions 3 improvements 7 bugs fixed 2 removals 2 checks 4 mistakes 3 warnings
4.51.0 — 14 septembre 2026
Les sondes du panel montraient un robot de prêt sous le nom d'IriX, le registre des robots de service était vide depuis cinq jours sans que rien ne sonne, et le panel remplissait à lui seul 86 % du journal du bot en surveillant ses propres ports.
Bugs corrigés
- 🔴🔴 Le panel montrait OverOp-A sous le nom d'IriX. Les deux tournent sur le même exécutable — seul le chemin de leur configuration les distingue —, et la sonde cherchait un nom de programme. Aucune alarme ne pouvait sonner : les deux moitiés étaient vraies, elles ne parlaient simplement pas du même sujet. Trois mensonges corrigés d'un coup : l'identité du bot, le serveur qui porte le lien, et un dialecte annoncé pour un autre.
- 🔴🔴 Le registre des robots de service était vide depuis le 09/09 à 16:19:32 — une reconstruction de la base l'avait vidé en silence. Résultat : 4 076 rejets en cinq jours, de 329 à 1 028 par jour. ⚠ Aucun des deux chemins d'inscription ne pouvait le rattraper : l'un est manuel, l'autre ne se déclenche que sur une demande en attente — or les robots étaient déjà posés. Un registre vidé par une reconstruction ne se re-remplit jamais tout seul. Réparé par la commande officielle, jamais par une écriture directe : elle refuse un nom pris, contrôle le plafond et journalise qui a déclaré quoi.
- 🔴 Le panel sondait sa propre console 3 700 fois par jour — 86 % du journal du bot. La sonde se connectait à chaque port pour savoir s'il écoutait ; elle lit désormais la table du noyau et ne se connecte qu'aux ports fermés.
- 🔴 La modération IA refusait l'action « warn » alors qu'elle était proposée à l'écran : le choix était offert, rejeté, et le travail perdu.
- Le chat web n'était soumis à aucune limite de rythme. Le contrôle juge l'adresse du socket, qui vaut la boucle locale derrière le relais — donc exemptée. ⚠ Et l'on ne pouvait pas « observer d'abord, armer ensuite » : désarmé, le contrôle n'écrit rien du tout. Observer exigeait déjà d'armer.
- Mot de passe oublié : trois cibles, une seule formulation. Site, pseudonyme et opérateur ne se réinitialisent pas de la même façon — chacune a désormais sa preuve, et une cible inconnue ne retombe jamais sur « site » par défaut.
aptétait cassé depuis un téléchargement laissé en plan : la trace accusait une signature manipulée, ce n'était qu'un résidu. Réparé, puis prouvé.
Créations
- La configuration du serveur IRC entre dans les sauvegardes — elle n'était dans aucune archive, et c'est le ménage qui l'a rendu visible.
- Un banc qui croise ce qui TOURNE avec ce qui est DÉCLARÉ : c'est l'absence de ce croisement qui a laissé le registre vide cinq jours. Trois observateurs avaient raison séparément, et l'écart entre eux était invisible.
- Un banc du rythme des pages à jeton, et un contrôle de toute liste du panel contre la base.
Évolutions
- HSTS monte d'un palier ;
connect-srcetstyle-src-elempassent en application effective. - Reprise de pseudonyme : la commande sait couper au séparateur, et la réinitialisation dit la vérité sur ce qu'elle a fait.
- Un désaveu suspend le pseudonyme et refuse le changement de mot de passe — éprouvé de bout en bout en service.
Suppressions
- 3 990 Mo de copies de travail laissées dans le cache par mes propres harnais de séance — 82 % du cache, 36 % du dossier personnel. ⚠ Vérifié avant : aucun fichier écrit après la copie. 📌 Un harnais de mesure qui laisse 500 Mo par essai devient le premier encombrement de la machine.
- Cinq copies de secours de la configuration du serveur, dont trois portaient des mots de passe en clair à côté du fichier de production. Supprimées seulement après avoir prouvé qu'elles étaient dans l'archive chiffrée.
Avertissements
- ⚠⚠ Les sept archives chiffrées ne sont PAS du déchet. La rotation tourne seule et chaque archive est vérifiée par déchiffrement : rien à nettoyer là. Le vrai risque est ailleurs — les copies ponctuelles en clair.
- ⚠⚠ Devant tout nom de programme cherché dans la liste des processus : combien de processus portent ce motif ? Trois familles de ce dépôt partagent leur exécutable.
- ⚠ Un état « absent » ne lève délibérément pas d'alerte : un service jamais mis au monde ne doit pas s'annoncer en panne. C'est juste, et c'est ce qui a rendu le registre vide invisible.
Erreurs
- Ma première note accusait la mauvaise table, comptait trois robots au lieu de quatre et annonçait une cadence fausse. Corrigé après mesure.
- J'ai répété à SerVuS un travail déjà fait, parce que la documentation l'annonçait ouvert.
- Mon propre correctif retenait « le premier trouvé » — et dix autres endroits avec lui.
- Rechute de la règle des correctifs le jour même où je l'écrivais, attrapée par une garde.
Vérifié
- 32 passages du minuteur, zéro connexion : la preuve en service que la sonde ne parle plus aux ports ouverts.
- Le repli de la sonde n'avait jamais été vu fonctionner — il l'est désormais.
4.50 1 version · 13 septembre 2026 (nuit) 3 additions 1 improvement 2 bugs fixed 2 checks 1 mistake 3 warnings
4.50.0 — 13 septembre 2026 (nuit)
Un banc d'essai écrivait dans la base de PRODUCTION à chaque campagne, et c'est lui qui déclenchait les coupures de service qu'on cherchait depuis des semaines.
Bugs corrigés
- 🔴🔴
test-chargement.tclécrivait dans la production — 84 écritures par campagne. Il bouchonnait tout Eggdrop et rien de la base : en chargeant les modules pour de vrai, leurs assainisseurs de démarrage vidaient l'identifiant courant des cinq pseudo-clients du réseau. Le vrai robot les croyait absents, les réinjectait, et le serveur tuait les neufs par collision — une salve de cinq à chaque campagne. C'est l'amorce de la panne qui a coûté deux fois quinze heures de « Service perturbé ». Trouvé par dichotomie sur 223 bancs, mesuré avant/après, pas supposé. - 🔴 Une ligne du chat perdait son fond sur les navigateurs qui ne connaissent pas
color-mix()en CSS : un moteur qui ignore la fonction ignore la déclaration entière. Corrigé par la technique standard — valeur simple d'abord, raffinée ensuite.
Créations
- Un banc des exemptions de bannissement (
tests/test-bans-exemption.py), qui monte son propre serveur : la production n'est jamais touchée. L'exemption de la boucle locale était déclarée, documentée, et vérifiée par rien — on s'en serait aperçu le jour où elle aurait dû servir, réseau coupé, sans savoir pourquoi. - Un banc du contrat avec OverScript (
Web/tests/test-overscript-couplage.php). Le client de bureau vit dans un dépôt séparé : il ne peut pas se défendre contre un changement fait ici, et le lanceur de bancs disait « tout est au vert » sans l'avoir regardé. - Le bloc de la boucle locale dans le modèle du dépôt — une installation neuve héritait du même manque.
Évolutions
- Le serveur IRC tourne sur le binaire recompilé (
make install), avec sauvegarde horodatée du binaire et de sa configuration, et la commande de retour arrière écrite avant le geste. Sept secondes de bascule, contrôlée à 100 s : services actifs, aucune boucle de redémarrage, quatre ports, dix clients, zéro erreur au journal.
Avertissements
- ⚠⚠ Le relevé de compatibilité des navigateurs LIT le code ; il ne remplace pas l'ouverture d'un navigateur. Il ne voit ni un rendu, ni une mise en page cassée, ni une connexion permanente qui refuse de s'ouvrir. Un banc qui laisserait croire qu'il couvre tout serait pire que pas de banc : on cesserait d'aller voir.
- ⚠ Une Z-line mord malgré l'exemption : elle vise l'adresse avant tout compte. Le banc le constate — sans cela, l'exemption pourrait devenir un blanc-seing sans que rien ne le dise.
- ⚠ Le lecteur de configuration ne se plaint pas d'une classe inconnue : il la fabrique aux valeurs par défaut. Une classe oubliée ne produit donc aucune erreur.
Erreurs
- Comparer deux copies du dépôt a échoué sans le dire : celle qui servait de référence n'avait pas sa configuration, les deux sorties étaient vides — ce qui ressemblait à une égalité. Le verdict était juste, pour la mauvaise raison.
Vérifié
- La compatibilité du point d'entrée public
?p=nickssur les 64 combinaisons, pas sur un échantillon : le chat l'interroge toutes les 60 s et un client extérieur peut le lire. - Le contrat d'OverScript, point par point — six appels machine et trois pages : rien à modifier, et c'est désormais gardé.
4.49 1 version · 13 septembre 2026 (soir) 3 additions 4 improvements 3 checks 4 mistakes 2 warnings
4.49.0 — 13 septembre 2026 (soir)
On demandait aux gens de remplir un profil avec photo avant de les laisser vérifier que leur caméra fonctionne. Et treize bancs d'essai annonçaient des pannes qui n'existaient pas — ou se taisaient sur celles qui existaient.
Créations
- Une page « Par où entrer » (
?p=entrer). Deux portes, et on choisit avant de subir des contrôles qu'on n'a pas demandés : discuter — le chat, votre âge et rien d'autre — ou rencontrer, en trois étapes. - Une étape d'essai caméra et micro (
?p=essai), qui ne demande ni compte, ni profil, ni âge. On voit son image, on parle, une barre bouge. Rien n'est enregistré ni transmis : tout se passe sur votre appareil, et seul le résultat (« répond » / « ne répond pas ») est retenu le temps de la visite. - La page des commandes se règle sur votre grade. Qui prouve son pseudonyme ne voit plus que ce que son grade ouvre, avec le compte de ce qui est masqué et un « Tout voir » à un clic. ⚠ C'est un réglage d'affichage, pas une protection — la page le dit à l'écran, et le grade reste vérifié par le robot au moment où la commande est tapée.
Évolutions
- L'ordre du parcours était à l'envers. La salle visio exigeait un profil confirmant vos 18 ans — donc déjà créé, photo comprise — avant d'ouvrir la caméra. Celui dont le matériel ne répondait pas ne l'apprenait qu'après avoir tout rempli. L'essai passe désormais devant.
- La salle visio se met en pause quand son onglet passe à l'arrière-plan, après trois secondes de grâce. Votre caméra et votre micro cessent de diffuser, la conversation tient, tout revient au retour. ⚠ Et un micro que vous aviez coupé à la main reste coupé : sans cette précaution, on reprenait la parole en se croyant muet.
- La salle visio demande maintenant que votre pseudonyme soit vérifié sur le réseau par le robot, et qu'il corresponde à votre compte. Sans quoi la salle se met en pause plutôt que de vous éjecter, et vous propose de rouvrir l'accès.
- Le chat n'a rien de tout cela à passer, et c'est garanti par un contrôle automatique : il ne demande que l'âge, comme avant.
Avertissements
- Recevoir cette version ne recompile pas le serveur IRC. Les correctifs de bannissement livrés en 4.48.0 attendent toujours une fenêtre de recompilation : jusque-là, un banni revient.
- Sur la page des commandes, ce qui est masqué reste tapable : la liste range, elle n'interdit pas.
Erreurs — les miennes, et ce qu'elles ont appris
- Deux fonctions écrites ce jour-là n'étaient appelées par personne. Un contrôle automatique les a signalées le jour même de leur écriture : plus le code est frais, moins il a d'appelants.
- Un banc annonçait huit pages en panne — les huit étaient saines. Il dérivait la liste des pages, mais recopiait à la main la liste de ce qu'il fallait charger, six lignes sous un commentaire qui dénonce exactement ce travers.
- Un autre s'arrêtait à sa ligne 103 depuis toujours, sur une fonction qui n'a jamais existé : huit contrôles au lieu de soixante-dix. Un banc qui meurt à mi-parcours n'annonce pas un échec, il annonce moins de contrôles — et personne ne les compte.
- Trois bancs accusaient du code parfaitement juste. C'est la forme la plus coûteuse : on finit par ne plus les lire.
Vérifié
- 231 contrôles au vert, 8726 vérifications, zéro échec — contre seize échecs le matin même. Le seul contrôle non lancé demande des droits d'administrateur sur la machine.
- Chaque correction a été blessée hors du dépôt pour vérifier qu'elle garde encore quelque chose — chaque blessure devant faire réagir le contrôle qu'elle visait, et non « un contrôle quelconque ». S'y ajoutent des blessures qui devaient, elles, rester vertes : un contrôle doit aussi ne pas s'alarmer quand rien d'important ne change.
- Les pages livrées répondent en service, et la production n'a jamais été modifiée pendant les mesures.
4.48 1 version · 13 septembre 2026 3 additions 2 improvements 5 bugs fixed 3 checks 2 mistakes 2 warnings
4.48.0 — 13 septembre 2026
Le site n'avait aucun en-tête de sécurité. En les posant, on a découvert que quatre protections du serveur ne protégeaient rien — et l'une d'elles depuis toujours.
Bugs corrigés
- N'importe qui pouvait choisir l'adresse que le site lui attribuait. Il suffisait d'ajouter un en-tête à sa requête. Toutes les protections qui comptent « par adresse » s'effondraient avec elle : le plafond de tentatives de connexion au panneau d'administration exposé sur Internet, les plafonds d'inscription et de contact, et le journal d'audit — qui enregistrait alors l'adresse que l'attaquant dictait, y compris celle d'un tiers innocent. Fermé et vérifié en service, des deux côtés à la fois : le relais jette désormais ce que le visiteur écrit, et le site ne lit plus que ce que le relais a constaté.
- Les bannissements du réseau IRC n'empêchaient personne de revenir. Ils frappaient bien les personnes déjà connectées — c'est ce qu'on voit — puis n'interdisaient plus rien : le banni se reconnectait dans la seconde. Le mécanisme était écrit, listé, annoncé aux opérateurs ; il n'était simplement appelé par personne. Un bannissement qui échoue en silence est pire que pas de bannissement : on cesse de surveiller.
- Et un bannissement temporaire ne s'arrêtait jamais. Poser « une heure » revenait à poser « toujours ». Ce défaut-là dormait sans conséquence tant que les bannissements ne mordaient pas : le correctif précédent l'aurait réveillé.
- Les visiteurs du chat du site échappaient entièrement au contrôle de rythme de connexion — la seule voie d'entrée publique dans ce cas. Le mécanisme est écrit et prêt, volontairement désarmé : l'activer gêne aussi les visiteurs ordinaires, et c'est un arbitrage qui revient à l'exploitant.
- La modération automatique des caméras est restée hors service une demi-journée, le temps qu'on s'aperçoive qu'une des nouvelles règles la bloquait. Voir « Erreurs ».
Créations
- Le site pose enfin les en-têtes de sécurité que tout site public devrait poser : il interdit d'être affiché dans le cadre d'un autre site, de voir son adresse partir chez les sites visités, et n'autorise que les scripts qu'il a lui-même signés, par un jeton tiré au hasard à chaque visite. Les permissions sensibles — caméra, micro, position — ne sont ouvertes que sur les pages qui en ont besoin, et fermées partout ailleurs, panneau d'administration compris.
- Deux règles supplémentaires sont posées « en observation » : elles ne bloquent rien encore, mais signalent ce qu'elles bloqueraient. Les signalements arrivent dans un journal du serveur, que
php Tools/csp-rapports.phprésume. C'est ce qui permettra de les activer sans casser le chat ni la visio. - Trois contrôles qui manquaient, chacun écrit après avoir constaté qu'il aurait trouvé le défaut du jour : un qui vérifie que la configuration du serveur web sur le disque est bien celle qui est servie, un qui vérifie qu'un bannissement interdit réellement de revenir, et un qui cherche le code écrit que personne n'appelle — le défaut qui a coûté le plus cher aujourd'hui.
Évolutions
- Les gestes de l'interface ne sont plus écrits dans les pages elles-mêmes mais rassemblés en un seul endroit. C'était le préalable indispensable aux nouvelles règles de sécurité.
- Les demandes d'administration sans retour en arrière demandent désormais confirmation côté serveur, et non plus seulement dans le navigateur.
Avertissements
- ⚠⚠ Les correctifs du serveur IRC ne sont pas encore en service. Ils demandent de recompiler et de redémarrer le serveur, donc de couper le réseau quelques instants — une fenêtre à choisir. D'ici là, un banni revient. ⚠ Cela vaut aussi pour toute installation qui se met à jour : recevoir cette version apporte les sources corrigées, pas un serveur corrigé. Une installation neuve compile, donc n'est pas concernée ; une installation existante doit recompiler pour que ces trois correctifs prennent effet. Recevoir une correction n'est pas l'appliquer.
- ⚠ La montée en puissance de l'en-tête qui force le HTTPS attend d'avoir vu passer un renouvellement de certificat, prévu vers le 19 septembre.
Erreurs
- En posant la règle sur les scripts, j'ai cassé la modération automatique des caméras pendant une demi-journée, sur le site en service. La bibliothèque qui l'assure a un besoin que j'avais exclu — j'avais vérifié le code du projet, pas les bibliothèques qu'il embarque, qui ne sont pas dans le dépôt. Aucune de mes mesures ne pouvait le voir : les outils en ligne de commande n'appliquent pas ces règles. Seul un vrai navigateur les applique.
- Deux contrôles exigeaient noir sur blanc le comportement fautif sur l'adresse des visiteurs, dans deux langages différents et dans les mêmes mots. Ils décrivaient la norme du protocole, pas cette installation.
Vérifié
- Les 22 campagnes du serveur IRC passent, dont les deux nouvelles. Les contrôles du site aussi.
- Chaque nouveau contrôle a été blessé volontairement pour s'assurer qu'il sait échouer — 25 blessures sur celui des en-têtes, 3 sur celui des bannissements, 3 sur celui du code sans appelant.
- ⚠⚠ Une mesure d'ensemble a révélé une quinzaine de contrôles en échec que personne ne regardait, sans rapport avec ce travail : vérifié en les rejouant sur la veille, ils échouaient déjà. Un seul a été refermé depuis.
4.47 4 versions · 5 septembre 2026 → 8 septembre 2026 12 additions 9 improvements 6 changes 14 bugs fixed 1 removal 11 checks 4 mistakes 5 warnings
4.47.3 — 8 septembre 2026
Le site annonçait « Service perturbé » à ses visiteurs alors que tout fonctionnait — pendant quinze heures.
Bugs corrigés
- La page d'accueil annonçait que l'enregistrement des pseudos et la gestion des salons étaient interrompus. C'était faux. Les services répondaient normalement : n'importe quel visiteur obtenait leur aide à la seconde. Ce qui était faux, c'est l'état conservé en base — et tout l'affichage en découle, sans que rien ne le confronte à la réalité.
- Le programme qui doit remettre cet état d'accord ne corrigeait que dans un sens. Il savait détecter un lien annoncé vivant qui ne l'était plus ; il ne voyait pas le cas inverse, qui est celui qui s'est produit. Il relance désormais une vérification auprès du serveur — il n'écrit jamais un état sans preuve, ce qui reviendrait à se tromper dans l'autre sens.
- Le site acceptait des noms de salon que le serveur refuse. Les salons déjà enregistrés ont été vérifiés un par un : aucun n'est devenu inaccessible.
Créations
- Un contrôle qui parle vraiment aux services au lieu de relire la même donnée. Il pose la question qu'un visiteur poserait, et refuse la seule situation qui soit à coup sûr un mensonge : les services répondent, et l'état conservé les déclare hors ligne.
- Chaque page du site et du panel est désormais réellement affichée à l'essai — les 16 pages publiques et les 31 pages d'administration. Jusqu'ici on vérifiait que leurs noms concordaient, jamais qu'elles s'affichent.
- Un contrôle qui détecte qu'une série d'essais a été interrompue en laissant un fichier modifié.
Évolutions
- Un constat, pas un changement : les actions du panel sont graduées par niveau et refusées par défaut, mais la lecture de ses pages ne l'est pas — une seule page sur trente et une refuse un compte de niveau le plus bas. Rien n'a été modifié : c'est désormais mesuré et tenu, et un contrôle le dira si une page change de camp.
4.47.2 — 5 septembre 2026 (nuit)
Renommer son bot n'empêche plus d'installer le projet — et le client de bureau reçoit enfin le correctif signalé le matin même.
Créations
- Un contrôle qui transforme réellement les fichiers de migration avant de vérifier ce qu'ils produisent, au lieu de relire le code qui les transforme.
Évolutions
- Les mises à jour de la base s'appliquent quel que soit le nom donné au bot. Jusqu'ici, qui le renommait n'obtenait aucune migration : le programme refusait par prudence, mais il refusait tout, et le site s'ouvrait avec des tables manquantes. Les fichiers du projet ne sont pas touchés — seule leur lecture est adaptée à l'installation.
- Un nom de bot qui ne peut pas servir de nom de table est refusé clairement, plutôt que deviné.
Bugs corrigés
- La vérification qui suit une mise à jour de base cherchait au mauvais endroit dès que le bot portait un autre nom : elle n'aurait rien trouvé, et « aucune table » se serait affiché exactement comme « aucune table créée » — juste après vingt-deux mises à jour réussies.
- Un contrôle interne comparait une mesure à elle-même : il passait au vert quel que soit le fichier examiné.
Modifications
- OverScript 0.6.17 est publié — Windows, Linux AppImage et Linux .deb. Le client proposera la mise à jour à qui est en 0.6.16.
- Le ménage de la machine : d'anciennes copies de fichiers de configuration et les restes d'une installation abandonnée en juillet, soit 201 Mo libérés. Rien de vivant n'y touchait, et une archive a été gardée de côté.
Éprouvé
- Le correctif des mises à jour a été mesuré de la seule façon qui tranche : les vingt-deux fichiers appliqués deux fois, avec et sans le nouveau nom, sur deux bases jetables. Mêmes réussites, mêmes échecs, mêmes tables, mêmes colonnes — le changement ne touche que le nom.
- Chaque correctif a de nouveau été retiré volontairement pour vérifier que le contrôle censé le protéger passait bien au rouge.
- La publication du client a été constatée de l'extérieur, comme la verrait quelqu'un qui vient d'installer : les trois paquets se téléchargent et le journal des nouveautés est à jour.
Avertissements
- ⚠ Un contrôle du client de bureau est instable : sur cinq exécutions, trois réussissent, une s'interrompt, une signale des échecs qui se contredisent entre eux. Ce sont des attentes trop courtes sur des actions d'interface, pas un défaut du client — mais un contrôle qui échoue une fois sur cinq finit par être ignoré, et c'est alors le vrai échec qu'on ne verra pas.
4.47.1 — 5 septembre 2026 (soir)
Une relecture hostile de la journée : quatorze griefs, neuf réels — et trois d'entre eux portaient sur les contrôles écrits le matin même.
Créations
- Un contrôle qui affiche réellement les 31 pages du panel et vérifie qu'aucune ne casse. Jusqu'ici, les contrôles se contentaient de relire les fichiers : une page en erreur les aurait tous laissés au vert.
- Un garde-fou contre les outils écrits sans jamais être employés — un travers qui s'était reproduit quatre fois dans la journée.
Évolutions
- Les identifiants de la base sont cherchés au même endroit par tous les outils du projet. Cinq d'entre eux les lisaient ; l'un suivait un ordre différent des quatre autres.
- Le contrôle qui empêche de viser le dépôt au lieu de l'installation couvre désormais tout le site, et non plus seulement les bancs d'essai.
- Le résumé d'un lien ULine prend la couleur du plus grave de ses écarts, et son survol les énumère tous.
Modifications
- Trois seuils de vigilance relevés : ils étaient placés si bas qu'aucune situation réelle ne pouvait les franchir.
Bugs corrigés
- Un lien en cours de connexion était signalé en rouge comme un lien mort, le temps qu'il monte.
- Un texte d'aide de la page Anope disait le contraire de ce que fait le programme.
- La page d'accueil du site comptait les lignes de code du bot au mauvais endroit : chez qui installe le projet, le chiffre tombait à zéro et la phrase disparaissait.
- Un fichier temporaire portait un nom prévisible dans un script lancé avec les droits d'administrateur.
- Deux bancs d'essai laissaient des répertoires derrière eux à chaque exécution, tout en se déclarant au vert.
Suppressions
- Deux outils internes écrits la veille et jamais employés. Retirés plutôt que branchés de force : ce qui existait déjà couvrait mieux le besoin.
Éprouvé
- Chaque correctif a été retiré volontairement pour vérifier que le contrôle censé le protéger passait bien au rouge. Ceux qui restaient verts ont été réécrits.
- Une de ces vérifications a d'abord donné un faux résultat rassurant ; elle a été refaite.
- Les 31 pages du panel s'affichent en production, le site répond de l'extérieur, et les quatre services tournent.
Avertissements
- 🔴 Qui renomme le bot ne peut appliquer aucune mise à jour de la base. Les fichiers de migration sont écrits pour le nom par défaut ; le programme refuse proprement plutôt que d'abîmer quelque chose, mais il refuse tout. Ouvert dans les chantiers, avec trois voies pour le fermer.
- ⚠ Un cas reste vérifié dans le code sans l'avoir été en service : il demanderait d'arrêter un service en fonctionnement.
4.47.0 — 5 septembre 2026
La journée où l'on a mesuré ce qu'un TIERS reçoit vraiment — et où la campagne d'une installation neuve est passée de vingt et un échecs à zéro.
Créations
Web/inc/instance.php— le lecteur commun des modules Tcl et des chemins de l'instance.Web/inc/irixconf.php—irix_config(), sortie deconfig.phppour qu'elle puisse voyager.Web/inc/ulines.php— le croisement liens × pseudo-clients, fonction pure.Web/tests/_saut.phpetTools/tests/_saut.sh— le troisième état d'un banc.Web/sql/022-uline-responsable.sql— la colonneresponsable, posée aussi côté bot.- Cinq bancs :
test-ulines-detail.php,test-edition-machine.php,test-instance-irix.php,test-irixconf.php,test-svc-uid-purge.tcl.
Évolutions
- Le troisième état d'un banc — sauté.
Tools/bancs.shne connaissait que deux issues, alors que son propre commentaire portait la règle : « un banc qu'on ne peut pas lancer n'est pas un banc qui échoue — et ne doit pas non plus compter comme réussi. » Cinq politiques coexistaient, et deux comptaient au VERT un banc qui n'avait rien mesuré. Le code 77 est désormais compté à part, avec son motif. 🔴 La borne est écrite : « je n'ai pas réussi à mesurer » n'est PAS un saut, c'est un échec. - Le critère (c) du point 9 ne mesurait rien — « que la campagne de l'édition passe » rendait le même compte sous
betaet souspayante. Reformulé, et instrumenté par un banc dont l'attendu varie avec l'édition de la machine. - Le responsable d'une ULine — colonne déclarative, qui voyage par deux chemins parce que les migrations du site passent avant qu'IriX ait démarré une seule fois.
Modifications
- Dix-huit bancs basculés vers le lecteur commun ; onze en mouraient chez un tiers.
- Cinq chemins d'IriX — modules, contrôle, journal, configuration — dérivés de l'instance et non du dépôt. Chez un tiers, la page IriX affichait zéro module et les trois boutons pointaient un fichier inexistant.
Web/pages/ulines.php,Web/pages/anope.php,Web/public/assets/app.css— les volets.
Bugs corrigés
svc_config.current_uidsurvivait à la chute du lien — deux trous, deux remèdes : la coupure (disconnect_socket, cadré par socket) et le redémarrage (svc::db_init, qui épargne les liens vivants en mémoire).apply.shpouvait migrer la mauvaise base — il croise désormais sa cible avec celle du panel.- Cinq bancs mesuraient l'environnement de la machine au lieu de leur sujet : le nom du réseau cherché en dur au lieu d'
APP_NAME, la forme de$HOME, la configuration git d'une installation qui n'est pas un clone, un préfixe de tables déduit d'une table du site. - Un contrôle de sécurité passait au vert à vide —
test-json.phpécartait chaque fichier faute de dépôt git, et son constat sur les secrets n'examinait plus rien.
Éprouvé
- Le vidage des UID, constaté EN SERVICE après le redémarrage demandé par SerVuS : assainissement à
14:18:51, lien remonté à14:19:29, bot toujours actif à 95 secondes — le délai qui compte, un Tcl cassé en silence mourant à 89. - Quatre installations tierces montées dans des conteneurs isolés, dont une menée jusqu'à la campagne complète.
- Cinq passes de mutation : 14 sur 14, 11 sur 11, 7 sur 7, 6 sur 6, 4 sur 4 en rouge.
- 158 bancs sur la production, un seul échec —
run-tests.sh, qui refuse un binaire plus vieux que ses sources. - Les pages rendues, pas relues : aucun banc du panel ne les rend, et une erreur fatale les laisserait tous verts.
Avertissements
- ✅ Le binaire
overtchatda été recompilé le soir même, sur accord explicite de SerVuS. ⚠⚠ Et la mesure a corrigé le diagnostic : le binaire périmé était celui du clone de travail (17/08, dix sources plus récentes), pas celui de la production — dont le binaire du 02/09 était déjà en phase, tout comme celui qui s'exécute, installé le 02/09 à 18:43. Trois exemplaires coexistent, et « le serveur » n'en désigne aucun sans qu'on dise lequel. 📌 Campagne après recompilation : 158 bancs au vert, 6565 constats, zéro échec. - ⚠ Le
config.phpde la production a été édité avant que le fichier qu'il référence y soit porté : quelques secondes pendant lesquelles une requête aurait rendu une erreur.
Erreurs
- ⚠⚠ La mesure d'écart a été écrite trois fois, et les deux premières mentaient en sens opposés : l'une vidait le dépôt sans peupler l'instance et rendait un chiffre pire qu'avant le correctif ; l'autre comparait deux bacs construits différemment et inventait des régressions. Une mesure d'écart n'a de sens que si les deux termes ne diffèrent QUE par ce qu'on mesure.
- ⚠⚠ Une doctrine écrite dans un seul langage ne s'applique qu'à moitié : le troisième état, posé en PHP, laissait deux bancs shell mourir pour la raison même qu'il traite.
- ⚠ Deux constats cherchaient un MOT là où il fallait chercher un GESTE. Une garde neutralisée en « si faux » garde tous ses mots ; seule la mutation l'a montré.
- ⚠ Un helper écrit et appelé nulle part ne répare rien — deux fois en deux jours, et son existence rassure.
4.46 1 version · 4 septembre 2026 3 checks
4.46.0 — 4 septembre 2026
Six points fermés, trois versions d'OverScript, et une journée passée à mesurer ce que les documents affirmaient.
L'outillage : ce qui prononce le vert doit être éprouvé aussi
- 🔴 L'extraction d'une procédure Tcl était recopiée dans trente bancs, en vingt-quatre versions — dont vingt-trois fausses sur les signatures à valeur par défaut. Une seule écriture désormais, 775 lignes retirées, et chaque banc lancé avant et après : les trente rendent exactement la même ligne de résumé.
- 🔴 Les vingt-et-une migrations SQL n'avaient aucun banc. Elles en ont un, qui garde leur numérotation, leur rejouabilité et leur ordre de dépendance. ⚠ Et l'installateur jetait la sortie de l'applicateur dans
/dev/null: l'échec était détecté, le motif perdu — sur le chemin d'une installation neuve, là où personne n'est présent pour relancer. - 🔴 Cinq blocs de repli HTML s'affichaient en toutes lettres sur
?p=versions, page publique. Le moteur échappe le HTML brut, à raison ; ces balises étaient donc du texte. La série de contrôles surveillait cinq symboles et aucune balise.
4.45 1 version · 3 septembre 2026 not broken down
4.45.0 — 3 septembre 2026
Trois versions d'OverScript publiées le même jour, et une demande de SerVuS tenue.
4.44 1 version · 2 septembre 2026 not broken down
4.44.0 — 2 septembre 2026
Une journée passée à mesurer ce que le projet AFFIRMAIT, et à corriger ce que la mesure a démenti.
4.43 1 version · 31 août 2026 3 additions 2 changes 3 checks 3 mistakes
4.43.0 — 31 août 2026
Une porte publique en écriture, la première — et ce qu'il a fallu poser autour.
Créations
Web/inc/overscript-rapport.php— réception, stockage, relecture. La table se crée au premier besoin, motif decontact_table_ensure().Web/pages/overscript.php— l'onglet du panel, avec sa pastille de rapports neufs. ⚠ C'est la seule page du panel qui affiche du texte écrit hors du réseau : elle le dit, et l'échappe comme tout le reste.- La route publique
?p=overscript-rapport.
Modifications
Web/site/versions-overscript.phpannonce l'essai macOS, et ne propose aucun fichier pour Mac — il n'y en a pas. Un encadré qui aurait l'air d'une offre ferait chercher ce qui n'existe pas.Markdown/MOBILE.mdouvre la réflexion sur une application mobile.
Erreurs
- ⚠ Une classe CSS inventée,
btn-on, est passée sous le radar :test-vues.phpignore les attributs contenant du PHP, et la mienne était dans une condition. Le banc est resté vert. Corrigée au motif du projet (badge accent/badge off) — le vocabulaire CSS du panel est clos. - ⚠ Ma route avait écarté
?p=overscriptde?p=nicksde plus de 2000 caractères, ce qu'un banc interdit pour qu'elle reste parmi les routes JSON sans session. Déplacée — plutôt que d'assouplir le banc pour me donner raison. - 🔴 Et cette entrée de journal a elle-même été écrite deux fois. La première a traversé un
bashnon protégé : tous les accents graves ont été exécutés, et ce qu'ils encadraient — chaque nom de fichier — a été remplacé par la sortie de la commande, c'est-à-dire par du vide. Le texte restait lisible, les noms avaient disparu. 📌 Un document ne se compose pas dans une chaîne qui passe par le shell.
Vérifié
- La porte éprouvée de bout en bout en service :
GETrefusé (405), corps illisible refusé (400), message vide refusé (400), rapport accepté et rangé en base avec toutes ses colonnes, table créée toute seule. test-routes.php,test-vues.php,test-panel-actions.phpettest-overscript.php: tous verts après ajout du talon de pastille.- Côté client : 536 constats statiques, 151 au rendu réel, et quatre blessures de mutation sur le module d'envoi, toutes détectées — dont une qui fait boucler le banc sans fin, ce qui a imposé un délai maximal à la passe de mutation elle-même.
4.42 1 version · 31 août 2026 3 additions 4 changes 1 removal 4 checks 2 warnings
4.42.0 — 31 août 2026
Le code était juste. C'est son emploi qui manquait — pour la cinquième fois.
Créations
IriX/tests/test-topic-s2s.tcl— 41 constats, dix blessures de mutation toutes mordantes. ⚠⚠ Le constat central : les deux formes du verbe ne se distinguent pas par expression régulière. Au burst le troisième champ est le poseur, en service c'est le sujet, et un sujet comme « rendez-vous samedi 20 » satisfait le motif long. On compte les paramètres comme IRC les compte — au premier" :"—, exactement comme le daemon (parc >= 5,src/cmd/m_channel.c).IriX/tests/test-burst-clients.tcl— 22 constats, sept blessures toutes mordantes, dont l'ordreLINKED→fileeventqui est la cause même du défaut.::soc::topic_ecrire— le point d'écriture unique de la colonne.
Modifications
::soc::ulines::auto::on_topic_s2s— lit les deux formes, appelée depuis la boucle de burst et depuis une brancheTOPICneuve du dispatcher S2S. ⚠ Le burst n'enregistre aucun événement : il annonce l'état, pas un changement. Sans cette distinction, chaque montée de lien fabriquerait un faux « sujet changé » par salon.::soc::ulines::auto::track_burst— rebranchée sur la boucle bloquante, aveclabeleten_burst. La boucle ne refait plus le travail à la main.::soc::pub_topic— tronquait à la taille de la colonne ni ce qu'il écrit, ni ce qu'il envoie. Le sujet partait entier sur IRC (le serveur en accepte 360), l'UPDATEn'en gardait que 255, etdb_topic_checkrétablissait le texte court 30 s plus tard : le posteur voyait son sujet se raccourcir tout seul.::soc::chanq::_ecrire_topic— délègue au point d'écriture unique.
Suppressions
::soc::raw::on_421et son bind. ⚠⚠ La raison qui le gardait — « retirer l'un ou l'autre perd quelque chose » — avait été raisonnée, jamais mesurée :on_numericenregistre le texte entier du numérique, nom de la commande compris. Un banc l'exécute désormais pour de bon.
Avertissements
- 🟡
extraire, la procédure que six bancs recopient pour sortir une proc du fichier, cherche les accolades par position et casse dès qu'une signature a deux arguments par défaut. Le symptôme est bruyant, donc sans mensonge silencieux ; la version appariée est danstest-burst-clients.tcl, les autres copies restent à aligner. - ⚠ Les correctifs de burst n'agissent qu'à l'établissement du lien : un
.rehashne suffit pas, il faut redémarreririx.service.
Vérifié
- Les deux bancs neufs, blessure par blessure — 17 mutations, toutes mordantes, dont les six de câblage.
- ⚠ La passe de mutation elle-même a été corrigée deux fois : un banc qui plante n'affiche aucun « ÉCHEC » et ressemble à un banc vert ; et la restauration doit vivre dans un
finally, faute de quoi un incident laisse le code blessé sur le disque — c'est arrivé. - ⚠⚠ Mesuré que
bancs.shne peut pas servir de référence sur le poste Windows : seize bancs y rougissent (sockets, encodage,phpabsent) qui sont verts sous WSL. La mesure valable est celle du clone WSL. - 128 bancs au vert, 5759 constats sous WSL, contre 126 / 5691 avant — l'écart concorde exactement avec ce qui a été ajouté.
4.41 1 version · 31 août 2026 1 addition
4.41.0 — 31 août 2026
Un banc qui n'empêche pas les trente procédures mortes — il empêche la trente-et-unième.
Créations
IriX/tests/test-verbes-atteignables.tcl— 9 constats, six blessures de mutation, toutes mordantes. Tout verbe lié doit être classé : atteignable par un client, ou inatteignable avec sa raison écrite. 32 verbes sont ainsi nommés, chacun avec le pourquoi. ⚠ La liste est dérivée du fichier, jamais recopiée — une liste recopiée dans un banc mesure ce que le banc croit, pas ce que le code fait. ⚠ Une raison de moins de 25 caractères est refusée : sans cela la liste deviendrait un tapis. Ce garde-fou a d'abord attrapé les miennes, deux raisons qui disaient « idem ».
4.40 1 version · 31 août 2026 1 check
4.40.0 — 31 août 2026
on_SERVER n'était pas un cas isolé : c'est un motif, et il touche une trentaine de procédures.
Éprouvé
IriX/tests/test-burst-serveur.tcl passe de 23 à 34 constats, cinq blessures de mutation, toutes mordantes. Trois constats neufs lisent la source du dispatcher : ils gardent l'EMPLOI, pas seulement la procédure — on_SERVER était parfaite et n'était appelée de nulle part.
4.39 1 version · 31 août 2026 1 addition
4.39.0 — 31 août 2026
La page « Serveur IRC » ne montre plus un extrait de la configuration, mais ce que le serveur ANNONCE.
Créations
IriX/tests/test-annonce.tcl— 24 constats, six blessures de mutation, toutes mordantes. Les deux qui comptent portent sur ce qui doit être écarté : une ligne005finit par une phrase en anglais (:are supported by this server), et un découpage naïf ferait de « are », « supported » et « by » des capacités du serveur ; le premier champ, lui, est notre propre pseudonyme. ⚠ Une clef d'annonce doit avoir la forme d'un jeton : un serveur bavard ne doit pas pouvoir écrire ce qu'il veut dans une clef primaire.
4.38 1 version · 31 août 2026 1 addition
4.38.0 — 31 août 2026
Trois colonnes que le panel affichait depuis toujours, et que personne n'avait jamais écrites.
Créations
IriX/tests/test-burst-serveur.tcl— 23 constats, six blessures de mutation dont cinq mordent. Le constat central : sansPROTOCTL, le SID reste VIDE et ne vaut surtout pas « 1 », mesuré sansPROTOCTL— avec lui, il passerait pour une bonne raison qui n'est pas la bonne.
4.37 1 version · 31 août 2026 1 addition 1 check
4.37.0 — 31 août 2026
Le serveur déclarait le service, le client écoutait le mauvais numéro — et aucun des deux dépôts n'avait de banc capable de le voir.
Créations
IriX/tests/test-edition.tcl— 27 constats. Le lecteur d'édition Tcl était le seul des trois langages sans banc, et::soc::edition_au_moinsn'avait aucun appelant, y compris dans les bancs — l'état exact où se trouvait son homologue bash la veille. ⚠ Le lecteur reste mort ; il est désormais mort et mesuré. Cela n'ouvre pas la phase 3 du point 9. Les deux constats qui portent le banc : une édition demandée inconnue refuse, mesurée sur l'installation la plus complète — c'est le défaut derequire_grade, où unlsearchrendant-1comparé par>=ouvre au lieu de refuser ; et les deux gardes contre les notes_editionet_bots_chan, qui citent en toutes lettres les valeurs cherchées.
Éprouvé
Les 18 campagnes du serveur, la suite complète du dépôt, et — hors dépôt — OverScript en 0.4.1 puis les 504 constats de sa suite. Mutation des deux côtés : n'écouter que le 310 rougit le constat du 320 ; cesser de lire le texte rougit le helpop et le robot.
4.36 1 version · 30 août 2026 1 addition 1 check 3 warnings
4.36.0 — 30 août 2026
edition_au_moins() n'avait aucun appelant — et c'est ce qui rendait la phase 3 du point 9 dangereuse.
Créations
Tools/tests/test-edition-sh.sh— 27 constats, dont les quatorze comparaisons de rang que rien n'exerçait. ⚠ Tout se joue dans un bac à sable : un banc qui écrirait dansConfig/config.jsonpour s'éprouver changerait l'édition de l'installation le temps de son passage, et la laisserait changée s'il était interrompu. Un constat vérifie que la configuration réelle n'a pas bougé.
Éprouvé
5 mutations, toutes attrapées, et chacune sur les constats qui la visent :
| Blessure | Ce qui rougit |
|---|---|
| le rang devient une égalité stricte | les 5 cas « au moins une édition inférieure » |
> au lieu de >= | les 4 cas d'égalité, écrits exprès pour elle |
| une édition demandée inconnue OUVRE | le constat du défaut prudent inverse |
le défaut prudent ouvre (beta → payante) | les 2 constats de lecture |
| le banc n'écrit plus dans son bac à sable | 9 constats — le montage lui-même |
Avertissements
- ⚠ Trois affirmations du registre étaient périmées, et sont corrigées :
Web/tests/test-compat.phpn'éprouve pas les quatre éditions — il ne contient pas une fois le mot « édition » ; l'installateur fait 12 509 lignes et non 10 429 ; il porte 353 définitions de fonction et non 333. 📌 Les deux chiffres avaient été annoncés « mesurés » — ils se sont périmés à leur tour. Un compte écrit à la main ne survit pas à la séance. - ⚠ Le même trou existe en Tcl :
::soc::edition_au_moins(IriX/cmds/irix-edition.tcl) n'a aucun appelant non plus, y compris dans les bancs. Sur les trois lecteurs, seul le PHP a un appelant en production (Web/inc/compat.php). - ⚠ Aucune phase 3 à 8 ne se ferme sans un geste ou une décision de SerVuS — mesuré phase par phase. La 6 est la seule dont le bloqueur n'est pas un geste mais une décision produit : quelle page appartient à quelle édition.
4.35 1 version · 30 août 2026 2 bugs fixed 1 check 3 warnings
4.35.0 — 30 août 2026
Le troisième privilège mort — et un raisonnement de confidentialité qui a cessé d'être vrai sans le dire.
Bugs corrigés
- ⚠⚠ Le
ifde WHOIS mêlait deux révélations de nature différente : l'hôte réel — ce que le privilège nomme — et les modes de la cible, qui ne relèvent d'aucun privilège. Y greffer la garde sans scinder aurait retiré aux opérateurs quelque chose que personne n'avait décidé de leur retirer. 📌 Une condition partagée par deux effets n'est plus une condition : c'est une coïncidence, et elle se paie au premier qui veut n'en régler qu'un. - ⚠⚠ TRACE serait devenu le contournement. Son commentaire assumait d'afficher l'hôte réel : « c'est ce qu'un opérateur vient chercher, et il l'obtient déjà par WHOIS ». Le raisonnement était juste — tant que WHOIS le donnait à tout opérateur. Il est mort à l'instant où WHOIS s'est resserré, et rien dans le code ne l'aurait dit. 📌 Un raisonnement de confidentialité qui s'appuie sur « on l'obtient déjà ailleurs » meurt le jour où « ailleurs » se resserre.
Éprouvé
60 constats, 4 mutations toutes attrapées — dont celle qui refusionne le if de WHOIS (seul le constat de la scission rougit) et celle qui rouvre TRACE.
⚠⚠ DEUX DE CES CONSTATS NE POUVAIENT PAS ROUGIR, et c'est la mutation qui l'a dit. Ils comparaient les réponses entières reçues par les deux opérateurs — or un numérique porte le nom de son destinataire : « 205 Mod … » contre « 205 Oper … ». Les lignes différaient toujours, quel que soit l'hôte montré. La mutation qui rouvrait TRACE est restée verte. Les constats extraient désormais l'hôte du masque avant de comparer. 📌 Comparer deux réponses entre elles ne mesure rien tant qu'on n'a pas ôté ce qui diffère pour une autre raison que celle qu'on éprouve.
Avertissements
- ⚠ Ce resserrage touche les grades
ircopetmoderateur, qui ne portent passee-realhost— même doctrine que pouroverrideetsee-secret. - ⚠ Il reste deux bits morts (
chghost,admin) et un à ne jamais brancher (svs-commands). Le raisonnement de chacun est dansinclude/conf.h. - ⚠⚠ Toujours pas en service : cela attend la recompilation du point 55.
4.34 1 version · 30 août 2026 3 changes 2 bugs fixed 1 check 3 warnings
4.34.0 — 30 août 2026
Trois planificateurs ne retiraient rien avant de poser — et le registre disait qu'il n'y en avait qu'un.
Bugs corrigés
- ⚠⚠
chatalerte::schedule,raw_log_purge_schedule,topic_schedulereposaient sans rien retirer. Chaque.rehashleur ajoutait une chaîne parallèle :system_readyettopic_startedvivent dansIriX-src.conf, que le re-source remet à vide, donc la garde d'amorçage rouvre — et l'ancienne chaîne n'est pas annulée, personne n'ayant son identifiant. Pourchatalerte, deux chaînes qui se croisent annoncent deux fois la même alerte. ⚠raw_log_purge_schedulea deux sites d'amorçage : il accumulait le plus vite, et le registre ne le mentionnait pas. - ⚠ Deux
killutimerétaient inopérants sans le dire (irix-oper.tcl,modes_du_bot) : ils passaient un nom de procédure là où un identifiant de minuteur est attendu. L'appel levait, lecatchavalait, le minuteur survivait. 📌 Uncatchautour d'un appel faux le rend indistinguable d'un appel juste.
Modifications
IriX/cmds/IriX-sql.tcl—::soc::after_remplacer, une seule procédure qui balaie la file réelle avant de poser. ⚠ Elle ne garde pas d'identifiant en variable, et c'est la leçon déjà payée parrehash_schedule: une variable vit dansIriX-src.conf, que le rechargement réinitialise — l'identifiant est perdu, le minuteur devient orphelin et intuable. La file, elle, ne ment pas.IriX/cmds/irix-oper.tcl— le balayage y est écrit en ligne, à dessein : ces lignes s'exécutent au CHARGEMENT du fichier, sourcé bien avant que la procédure partagée n'existe. Un appel y serait la « proc inexistante ».IriX/tests/test-minuteurs.tcl— règle C, qui manquait entièrement.
Éprouvé
12 constats, 5 mutations toutes attrapées — les trois planificateurs blessés un par un, l'amorçage du cycle des sujets, et le détecteur rendu aveugle.
⚠⚠ Le banc ignorait la troisième file. Eggdrop en tient deux, Tcl une troisième, et la liste de planificateurs de ce banc exigeait un crochet devant timer : after $DELAI … n'y entrait pas. Les trois fautifs lui étaient invisibles — et à test-boucles.tcl aussi, qui garde le défaut symétrique (une boucle ne doit pas MOURIR ; celles-ci se MULTIPLIAIENT).
Avertissements
- ⚠ La règle neuve est étroite, et ça s'est mesuré avant de l'écrire. « Toute procédure qui pose un
afterdoit retirer » dénonçait onze procédures justes — des délais à un coup, qui n'ont rien à retirer. Seul l'auto-réarmement est gardé. 📌 Un banc qui accuse onze innocents pour deux coupables finit ignoré, et c'est le coupable qui gagne. - ⚠⚠ La règle a été VERTE À VIDE à sa première exécution. En corrigeant les trois planificateurs, on leur avait retiré le
afterlittéral qu'elle cherchait : elle ne voyait plus aucune boucle, et le constat portait sur un ensemble vide. C'est le plancher qui l'a dit, pas le constat. 📌 Une règle écrite sur la FORME fautive meurt avec elle — il faut qu'elle reconnaisse aussi la forme corrigée. - ⚠⚠ Rien n'est en service. IriX charge ces fichiers au démarrage : il faut un
.rehashou un redémarrage, donc l'accord de SerVuS. 📌 Un.rehashsuffit et se répare seul — le code neuf balaiera les chaînes anciennes au premier cycle.
4.33 1 version · 30 août 2026 3 bugs fixed 1 check 3 warnings
4.33.0 — 30 août 2026
Trois menus de l'installateur dessinaient hors cadre — et « hors cadre » était littéral.
Bugs corrigés
- ⚠
_eggdrop_grades_menu,_panel_service_detail,_panel_server_detaildessinent maintenant comme les douze autres écrans. ⚠ Ce n'était pas une affaire de largeur : la plus longue entrée fait 59 colonnes pour un cadre d'au moins 64, sans couleur ni caractère large — rien à mal compter. - ⚠⚠ Deux aggravants non répertoriés : les deux panels de détail appelaient
_services_overview/_servers_overview, dont le contrat écrit exige « un cadre déjà ouvert par l'appelant », sans en ouvrir. Ils produisaient des bordures│ … │et un├───┤sans toit ni plancher, suivis de_kvhérités sans bordure du tout : trois dialectes empilés dans un écran. - ⚠
Bootstrap/tests/test-ui-cadre.shétait plus fragile que le code qu'il éprouve : il n'extrayait pas_ui_localeet rougissait 24/36 dans un shell sansLANGUTF-8,${#s}comptant alors des octets. Le script réel, lui, appelle_ui_localeà son chargement. Le banc pose désormais sa locale. 📌 Un banc qui rougit selon l'environnement n'accuse pas le code : il apprend à ne plus être cru.
Éprouvé
39 constats, verts avec et sans locale, dont trois neufs, dérivés et non énumérés — un menu ajouté demain avec un heredoc rougira sans que personne pense à l'inscrire : tout écran de menu ouvre un cadre · le plancher qui empêche le vert silencieux · plus aucun heredoc de menu.
Deux mutations, toutes deux attrapées : remettre un heredoc dans un menu (les deux constats de forme rougissent) ; faire rendre le découpage en fonctions à vide (seul le plancher rougit — c'est exactement son rôle).
Avertissements
- ⚠⚠ Ce banc était vert pendant tout ce temps, et il ne mentait pas. Il prouve qu'un cadre ouvert se referme à la même colonne ; ces trois-là n'en ouvraient jamais, donc l'invariant était vrai chez eux et vide. Il filtre par ailleurs sur
_menu_add/_menu_gate, que ces menus n'emploient pas. 📌 Ce qu'un banc ne regarde pas ne devient visible qu'en changeant la QUESTION, jamais en durcissant la mesure existante. - ⚠ Le constat neuf a rougi à sa première exécution — sur un COMMENTAIRE. Celui qui venait d'être écrit pour expliquer le défaut retiré, et qui en cite la forme. Les lignes de commentaire sont désormais écartées. Une phrase qui documente un défaut corrigé ressemble exactement au défaut.
- ⚠ Le morceau (b) du point 48 — l'option
--web— reste fermé : il attend trois décisions non techniques, dont unphp -Slancé en root et atteignable par tout utilisateur local.
4.32 1 version · 30 août 2026 1 bug fixed 1 check 4 warnings
4.32.0 — 30 août 2026
Un second privilège mort, et la mesure de ce qu'il ne faut SURTOUT pas brancher.
Bugs corrigés
- ⚠⚠
OPRIV_SEE_SECRETn'était lu nulle part. Il gouverne désormais les cinq endroits qui montrent ce qui est caché :NAMES,LIST,WHO, les salons rendus parWHOIS, et l'affichage de la clé+k— voir la clé, c'est pouvoir entrer, et c'est le site qui compte le plus des cinq. ⚠ Ce resserrage corrige une contradiction : le grademoderateurdeTools/opers-sync.shporte en commentaire « rien pour voir ce qui est caché », et voyait pourtant tout. Les quatre autres grades portentsee-secretet sont inchangés. ⚠ La forme de chaque garde est conservée telle quelle : elle diffère d'un site à l'autre (NAMES/WHOadmettent l'opérateur local,LIST/WHOISexigent+o). Cette asymétrie est antérieure et n'a pas été mesurée — l'uniformiser au passage aurait changé deux choses à la fois.
Éprouvé
Deux mutations, symétriques et toutes deux attrapées : le privilège jamais lu — les quatre constats de refus rougissent ; personne ne voit plus rien — les quatre témoins rougissent. Les cinq sites sont blessés à chaque fois.
⚠⚠ UN FAUX VERT A ÉTÉ PRIS EN CHEMIN, et c'est le fait le plus utile de cette version. Le constat « il n'énumère pas les membres du salon caché » passait au vert sans mesurer le privilège : channel_send_names écarte aussi les utilisateurs invisibles pour les non-membres, et le serveur pose +i à l'enregistrement. Le seul occupant du salon d'essai était donc invisible — le silence observé avait deux causes possibles, et la seule qu'on croyait mesurer n'était pas celle qui agissait. Un MODE Chef -i écarte la seconde. 📌 Tant qu'une seconde cause peut produire le même silence, on ne mesure pas la première. Le constat rougit maintenant sous mutation — avant, non.
Avertissements
- ⛔
OPRIV_SVSCMDSNE DOIT PAS ÊTRE BRANCHÉ sur le modèle des deux précédents : ce serait une panne totale des services. Les commandes SVS* n'ont qu'un créneau serveur, inaccessible à tout opérateur client, et leur vrai rempart estMFLG_ULINE+ulines{}— une autorisation par identité de serveur, strictement plus sûre. IriX et Anope passent en clients U-linés : ils ne portent jamaisUMODE_OPERet n'ont aucun bloc oper. Une garde calquée suroverriderejetterait 100 % de leur trafic. 📌 Ce bit n'est pas un oubli : son modèle d'autorisation a été remplacé par un meilleur. Le raisonnement complet est écrit dansinclude/conf.h, à côté du#define— c'est là que le lira celui qui se posera la question. - ⚠
OPRIV_CHGHOSTetOPRIV_ADMINsont des bits qui MENTENT dans un/STATS o: le premier garderait une commande qui n'existe pas pour un opérateur, le second n'a aucun référent (la commandeADMINest publique, il n'y a pas d'UMODE_ADMIN, et le pouvoir est déjà décomposé enDIE,RESTART,REHASH,SQUIT,CONNECT). Décision à prendre : leur donner un objet, ou les retirer. Ce ne sont pas des correctifs. - ⚠
OPRIV_SEE_REALHOSTse branchera, mais pas d'un seul&&: leifdeWHOISrévèle l'hôte réel et les umodes dans la même condition, etTRACEaffiche l'hôte réel sans aucune garde — il deviendrait le contournement. Il restreindrait aussi deux grades. - ⚠⚠ Toujours pas en service : comme les 4.30.0 et 4.31.0, cela attend la recompilation du point 55.
4.31 1 version · 30 août 2026 4 changes 2 bugs fixed 1 check 3 warnings
4.31.0 — 30 août 2026
Le serveur disait « une exemption silencieuse est un piège », et il n'en disait qu'une sur six.
Bugs corrigés
- ⚠⚠ Cinq actes en force n'étaient annoncés à personne. Ils le sont désormais sur le masque
o(SNO_OPERATEURS) : l'entrée (+b,+i,+k,+l,+J), la parole (+m, ban, mute),KICK,TOPIC,INVITE. ⚠sendto_realopsécrit aussi au journal — un seul appel couvre les deux besoins, et unilogde plus ferait une entrée en double. - ⚠⚠ L'annonce décrivait un acte qui pouvait ne pas avoir lieu. La notice privée partait dès le passe-droit accordé, mais
+j(limitation d'arrivées) et+Mrefusent encore après : l'opérateur lisait « votre statut vous en dispense », puis se voyait refuser. Les deux envois sont déplacés après la dernière garde. Défaut préexistant, sans rapport avec l'extension — il s'est vu en cherchant où poser l'avis nouveau. 📌 Un message vrai au moment où on l'écrit peut devenir faux deux gardes plus bas : ce qui compte n'est pas ce qu'on sait, c'est ce qui va se produire.
Modifications
src/channel.c— annonce à l'entrée et à la parole, l'une et l'autre au point où l'acte est acquis.src/cmd/m_channel.c— annonce surKICK,TOPIC,INVITE. ⚠ PourKICK, trois gardes peuvent céder pour une seule expulsion : un drapeau les rassemble et l'avis part une fois, après+Qetprotection_shields(), qui refusent encore plus bas.conf/overtchat.conf.example—OPER_OVERRIDE_NOTIFYétait posé sans une ligne d'explication. Il en a maintenant, dont celle qui compte : le mettre à « no » ne retire aucun droit, il rend seulement les passages en force invisibles.tests/test-oper-outrepasse.py— un veilleur (opérateur portant+s), et les constats des six actes.
Éprouvé
⚠ Aucun compte n'est écrit ici : python3 tests/test-oper-outrepasse.py et ./Tools/bancs.sh les donnent. Quatre mutations, toutes attrapées :
| Blessure | Ce qui rougit |
|---|---|
| l'avis d'entrée retiré | les trois constats qui en dépendent |
| on annonce aussi les actes de plein droit | le seul garde-fou du faux signalement |
la notice postée avant la garde +j — l'état d'avant | « aucune dispense ne lui a été annoncée » |
| l'avis de parole retiré | le constat correspondant |
⚠⚠ La deuxième est la plus importante des quatre. Un serveur qui signalerait tout acte d'un opérateur passerait les cinq constats d'annonce sans rien mesurer — et noierait les vrais avis sous le bruit des actes légitimes, ce qui revient à ne plus rien signaler. Le constat qui l'attrape est le seul de la campagne à vérifier une absence.
Avertissements
- ⚠ Sur la parole, l'avis part à chaque ligne, sans compteur. Repesé puis retenu : un état « déjà signalé » n'existerait que pour les membres, laisserait le salon sans
+nsans réponse, et taire la deuxième ligne d'un abus est exactement ce qu'on ne veut pas. La soupape estOPER_OVERRIDE_NOTIFY. - ⚠ L'avis ne nomme pas laquelle des trois gardes de
KICKa cédé : en nommer une quand deux ont cédé sous-dirait, et les nommer toutes demanderait d'assembler une phrase pour un détail que personne ne relira. - ⚠⚠ Toujours pas en service. Comme la 4.30.0, cela attend la recompilation du point 55, et partira dans le même geste.
4.30 1 version · 30 août 2026 4 changes 4 bugs fixed 1 check 3 warnings
4.30.0 — 30 août 2026
Un privilège se configurait sans jamais rien produire — et le lanceur de bancs mesurait le binaire de la veille.
Bugs corrigés
- ⚠⚠
tests/run-tests.shne vérifiait que l'EXISTENCE du binaire d'essai, jamais son âge. Trois sources du point 55 lui étaient plus récentes, et les dix-huit campagnes mesuraient donc le serveur d'avant. Le sens inverse est le vrai danger, et il est silencieux : une régression écrite danssrc/ne se voit pas tant qu'on ne recompile pas, et tout reste vert. Le lanceur refuse désormais, en nommant les fichiers coupables — il ne compile pas lui-même : un lanceur qui construit en douce efface justement l'écart qu'on veut voir. - ⚠⚠
OPRIV_OVERRIDEn'était lu nulle part. Défini dansinclude/conf.h, accepté dans les blocs oper, documenté dansovertchat.conf.example, distribué par grade parTools/opers-sync.sh— et rien dans le serveur ne le consultait. Tout opérateur passait outre, que le privilège lui ait été accordé ou non ; le lui retirer ne lui retirait rien. Il est désormais lu aux huit endroits qui accordent un passe-droit de salon :oper_passe_outre()desrc/channel.c(JOIN et PRIVMSG, donc+b,+i,+k,+l,+m,+Jet le mute), puis MODE, KICK ×3, TOPIC et INVITE danssrc/cmd/m_channel.c. ⚠ Ce que cela change en exploitation : les gradesglobal,ircopetmoderateurne demandent pasoverride— ils passaient outre quand même, désormais non. C'est ce que ces grades disent depuis toujours ; le serveur ne les lisait pas.netadmin(« all ») etadminsont inchangés. - ⚠
INVEXétait annoncé deux fois dans le005— la forme nue en plus d'INVEX=I. La nue est retirée : un client qui range les jetons dans un sac gardait le dernier vu, donc celui sans valeur, et en déduisait la lettre au lieu de la lire. - ⚠ Le commentaire de
chanmode_req_symbol()illustrait le barème sous sa forme abandonnée (q:iqa), quatre-vingts lignes sous la table qui le contredisait. L'exemple est retiré plutôt que corrigé : un barème recopié à la main diverge, et c'est le défaut même que ce jeton existe pour corriger chez les clients.
Modifications
Servers/overtchat-hybrid/src/conf.c—oper_has_priv(), qui LIT un privilège sans parler à personne. ⚠ Elle existait déjà sous le nomhas_priv()dansm_oper.c, maisstatic, hors de tout en-tête, et envoyant un numérique au client en même temps qu'elle répondait : le code des salons n'avait donc queIsAnyOper()sous la main. Un service rendu inaccessible finit par être réécrit de travers, ou pas du tout.Servers/overtchat-hybrid/include/conf.h,src/channel.c,src/cmd/m_channel.c— la déclaration, et le passe-droit ramené à un seul endroit par fichier (oper_passe_outre,oper_outrepasse) plutôt qu'à huit copies d'une même règle.Servers/overtchat-hybrid/tests/harness.py— constat neuf : aucun jeton du005annoncé deux fois. Le doublon avait survécu parce que rien ne lisait l'accueil dans son ENSEMBLE, seulement trois jetons interrogés par leur nom.Servers/overtchat-hybrid/tests/test-oper-outrepasse.py— un second opérateur, identique au premier à un privilège près, et dix constats.
Éprouvé
18 campagnes vertes, 32 constats pour la campagne 17 (10 neufs), et 5 mutations rejouées, toutes attrapées :
| Blessure | Ce qui rougit |
|---|---|
| le privilège n'est jamais lu — l'état d'avant | 6 constats, tous les refus neufs |
| plus personne ne passe outre | 10 constats, dont les témoins positifs |
le doublon INVEX remis | le constat du 005, qui nomme le jeton |
le constat du 005 ne lit aucune ligne | il rougit (« 0 jeton lu ») |
| une source plus récente que le binaire | le lanceur refuse et nomme le fichier |
⚠ Les deux dernières comptent autant que les trois autres. La quatrième éprouve que le constat neuf peut rougir : sans la seconde moitié de sa condition, il aurait passé au vert en ne lisant rien — zéro doublon parmi zéro jeton. Et la seconde éprouve le défaut symétrique : un banc qui ne vérifie que les refus reste vert sur un serveur où plus personne ne passe outre.
Avertissements
- ⚠⚠ Un banc peut mesurer un autre exemplaire de la chose sans le dire. Ici ce n'était ni une cible inexistante ni un motif trop large : le montage était juste, la cible était juste, et c'est l'objet mesuré qui n'était plus celui qu'on croyait. Le premier réflexe devant un rouge inexplicable — relire le code — ne pouvait rien donner : le code était juste, et il l'était depuis la veille.
- ⚠
OPRIV_SEE_SECRETn'est lu nulle part non plus (visibilité des salons+s/+pdans NAMES, LIST, et la clé+k), niCHGHOST,SEE_REALHOST,ADMIN,SVSCMDS: six privilèges sur vingt et un. Ils ne sont pas corrigés ici — chacun est une décision distincte. - ⚠⚠ Rien de tout ceci n'est en service. Ces correctifs vivent dans le serveur C : ils n'atteindront la production qu'à la recompilation, celle qu'attend déjà le constat du point 55. Ils partiront donc dans le même geste, ce qui se décide avant, pas après.
4.29 1 version · 28 août 2026 1 addition 1 improvement 2 bugs fixed 2 checks 1 mistake 7 warnings
4.29.0 — 28 août 2026
Le serveur DIT désormais qui peut poser quel mode — et deux des règles qu'il appliquait n'étaient pas celles qu'on croyait.
Évolutions
CHANMODEREQ, un jeton005neuf : le serveur annonce le grade minimal de chaque mode de salon, sous la formeq:qa,o:klLjJntispRMCNSTzQVKcDuoh,h:beImv,*:O,!:rPdA—qaohvpour les préfixes,*pour l'opérateur IRC,!pour « le serveur seul ». ⚠ Dérivé de la tablechanmodes[], commechanmode_all_letters()dérive le004: aucune chaîne écrite à la main. Un mode ajouté demain y entre seul. ⚠ Jeton non standard : les autres clients l'ignorent, et son absence doit rester sans effet — c'est ce qui garde OverScript utilisable ailleurs.
Bugs corrigés
- ⚠⚠
+i— fermer le salon — n'exigeait qu'un HALFOP. N'importe quel%pouvait donc fermer la porte du salon de quelqu'un d'autre. DésormaisCHFL_CHANOPS. - ⚠⚠
+O— réserver le salon aux opérateurs IRC — n'exigeait qu'un CHANOP. Un@ordinaire pouvait fermer un salon à tout le monde sauf aux IRCops, y compris à lui-même dès sa prochaine entrée. Il faut maintenant être opérateur IRC. ⚠ Cela a demandé un mécanisme neuf :needsn'encode que des statuts de salon, et la valeur0y signifie déjà « serveurs et services uniquement ». D'où un champ à part,oper_only, testé avanthave & needs— l'ordre porte tout le sens, l'inverse aurait laissé un chanop passer par la branche du statut.
Erreurs
- ⚠⚠ « Seul l'Owner pose
+i» a été écrit, essayé, et ANNULÉ le jour même. Sur ce serveur, le fondateur d'un salon reçoitCHFL_CHANOPet rien de plus :+qest réservé aux services, donc aux seuls salons enregistrés. Exiger l'Owner rendait+iimpossible sur tout salon ordinaire — plus personne n'aurait pu fermer sa porte, sauf un IRCop passant outre. C'est la campagnetest-commandesqui l'a dit, par cinq constats rouges décrivant un usage parfaitement légitime : ouvrir un salon privé et le fermer. Tranché par SerVuS : le chanop. 📌 Un mode qu'on ne peut pas poser n'est pas une règle sévère, c'est un mode mort.
Créations
Servers/overtchat-hybrid/tests/test-modes-grade.py— 18ᵉ campagne, inscrite au lanceur le jour même. ⚠⚠ Elle ne porte aucune liste de modes : elle lit le jeton sur une vraie connexion, puis, pour chaque mode qu'il annonce, envoie deuxMODE— au grade juste en dessous (le serveur doit refuser) et au grade annoncé (il doit accepter). C'est le seul montage où le jeton ne peut pas mentir : trop peu, la première moitié rougit ; trop, la seconde.
Éprouvé
- 103 constats au vert, et cinq mutations attrapées, chacune sur les constats qui la concernent :
+iremis à halfop (2 rouges),+Oprivé de sa garde (3), le barème dérivé à l'envers (31), le jeton retiré du005(1, et la campagne s'arrête d'elle-même), une lettre trouée dans le jeton. - ⚠ Le
005a été LU sur une vraie connexion, jamais déduit du source. Le jeton fait 63 octets — le tampon des jetons deisupport_build()en tenait 64, et unsnprintfqui déborde tronque en silence : le client aurait lu un barème amputé de ses derniers modes, ce qui est pire que pas de barème. Porté à 96.
Avertissements
- ⚠⚠ Trois défauts de la campagne, tous du même genre : un banc qui ne mesure pas ce qu'il croit. Ils valent d'être nommés parce qu'ils ressemblaient tous les trois à un défaut du serveur.
- Les acteurs muets mouraient en cours de route. La campagne éprouve une trentaine de modes deux fois ; ceux qui ne sont pas à la manœuvre se taisent plus longtemps que
pingfreqet le serveur les coupe. Le mode alors sous examen paraissait coupable d'un dégât qui ne venait que de la durée. - Le succès était mesuré sur l'ÉCHO, pas sur l'ÉTAT.
+Orougissait alors que le serveur l'avait posé : l'avis d'outrepassement était arrivé le premier, et la fenêtre de lecture s'était refermée dessus. On lit désormais le324— etNAMESpour les grades, qui n'y figurent jamais. - ⚠⚠ Un serveur d'essai d'une mutation précédente avait survécu et tenait le port. Les deux campagnes suivantes ont mesuré son binaire en annonçant 31 constats rouges qui ne disaient rien de leur propre blessure — et ces chiffres ont failli être écrits ici comme une preuve. La campagne refuse maintenant de démarrer si le port est pris : parler au mauvais serveur ne se distingue en rien de marcher.
- ⚠⚠ ET LE QUATRIÈME A ÉTÉ DIAGNOSTIQUÉ DEUX FOIS À CÔTÉ. La campagne passait lancée seule et rougissait en dix-huitième position, sur les cinq modes de grade. J'ai accusé un délai de lecture, puis un tampon mal vidé ; le vert obtenu entre-temps n'était que de la chance. La cause est le « : » du paramètre final : le
353s'écrit… #salon :~Chef @Chanop, le premier nom porte le deux-points, et l'extraction le ratait — donc uniquement quand le pseudo cherché se trouvait en tête, au hasard de l'ordre des présents. 📌 Une intermittence n'est presque jamais une question de vitesse : c'est un cas particulier qu'on ne rencontre qu'une fois sur deux. Chercher d'abord ce qui VARIE d'une exécution à l'autre. ⚠ Le marqueur PING/PONG posé au passage reste un gain — la campagne ne dépend plus d'aucun délai — mais il n'était pas le correctif. - ⚠ Trouvé au passage, non corrigé :
OPRIV_OVERRIDEest défini (include/conf.h) et le mot-cléoverrideest accepté dans les blocs oper (src/conf.c), mais la constante n'est lue nulle part. Tout IRCop passe outre, que le privilège lui ait été accordé ou non, et le retirer d'un bloc oper n'a aucun effet. C'est un droit qui paraît réglable et ne l'est pas. - ⚠ Et :
INVEXest annoncé deux fois dans le005(src/ircd.c).
4.28 2 versions · 28 août 2026 2 additions 4 bugs fixed 6 checks 1 mistake 1 warning
4.28.1 — 28 août 2026
Le serveur annonçait ses modes de salon différemment selon à qui il parlait — et cette fois la correction a été RECOMPILÉE et MISE EN SERVICE.
Bugs corrigés
- ⚠⚠ Le
PROTOCTLenvoyé aux serveurs pairs était périmé. Il annonçaitbeI,k,lLj,cimnprstuCDKMNOPQRSTVz: il y manquaitJ(groupe C, anti-retour après expulsion) etA(groupe D, salon archivé), tous deux présents dans la table et dans le005envoyé aux clients.PROTOCOL.mddocumentait la version fausse. ⚠ Le mode d'échec attendait son heure : un pair qui reçoit une liste incomplète ne sait pas quelle arité donner àJ, et décale ses paramètres dès qu'unMODEen porte un.
Créations
Web/tests/test-chanmodes.php— il dérive les quatre groupes de la tablechanmodes[]et compare les trois copies (le005, lePROTOCTL, la documentation), plus les grades, eux aussi écrits deux fois. ⚠ Il compare des ensembles de lettres, jamais des chaînes : l'ordre n'a aucune valeur de protocole, et un banc qui rougit sur un tri finit par ne plus être lu.
Éprouvé — la mise en service, sur accord de SerVuS
- Recompilation propre (
make cleanpuismake) : 34 fichiers, zéro avertissement. Les 17 campagnes du serveur passent — elles montent leurs propres serveurs surbuild/, jamais sur celui qui tourne. - Sauvegarde du binaire en service AVANT le geste, avec la commande de retour arrière écrite noir sur blanc avant qu'on en ait besoin.
- Constaté à 100 s — le contrôle tardif n'est pas du zèle, ce projet a vu un service mourir à 89 s :
overtchatdetirixactifs,NRestarts=0sur les deux (donc aucune mort suivie d'une relance), empreinte du binaire en service identique à celle qui vient d'être compilée, aucune erreur au journal. - ⚠⚠ Et le
005a été LU sur une vraie connexion, pas déduit du source :CHANMODES=beI,k,lLjJ,cimnprstuACDKMNOPQRSTVz. IriX a retrouvé son lien ULine et traitait déjà le trafic. Les 4 ports déclarés écoutent, les 2 robots tournent, 120 bancs au vert.
Erreurs
- ⚠ Fausse alerte de ma part en cours de vérification : j'ai cru voir 2 ports à l'écoute pour 4 déclarés. Mon filtre ne connaissait pas
6900(liens) ni8000(webchat), tous deux volontairement sur la boucle locale. C'est le travers déjà nommé — mesurer par un autre chemin que celui du code.
4.28.0 — 28 août 2026
Le panel de l'installateur avait une couche de rendu complète et pas un seul banc. Le premier écrit a trouvé un cadre qui ne se refermait pas.
Créations
Bootstrap/tests/test-ui-cadre.sh— le premier banc du rendu du panel : la mesure de ce qui se voit, la fermeture du cadre, et la cohérence des menus.
Bugs corrigés
- ⚠⚠ Une ligne plus longue que le cadre poussait la bordure droite dehors.
_ui_padborne son rembourrage à zéro, donc rien ne repliait le texte : le cadre se déchirait sur cette ligne et se refermait sur la suivante. Ce n'est pas un cas d'école — la largeur a pour plancher 64 colonnes, et le sous-titre du bandeau porteversion · user@host · chemin d'installation. Les lignes trop longues sont désormais coupées, et le disent par une ellipse. ⚠ La coupe retire les couleurs de la ligne coupée : couper au milieu d'une séquence d'échappement laisserait une couleur qui ne se referme jamais et déteint sur tout ce qui suit. - ⚠⚠ Le sous-menu « Services optionnels » cumulait quatre écarts — le seul des quinze menus du fichier à en porter.
[0] Retourétait offert sans aucune branche (il retombait dans la boucle parente, ce qui ressemble à un retour mais n'en est pas un) ;_menu_addétait appelé sans_menu_has, donc les clés étaient construites puis jamais consultées ; aucune branche par défaut, si bien qu'un choix invalide ne produisait rien du tout ; et les entrées s'affichaient hors cadre, les barres verticales pendant dans le vide. - Le choix du mode d'IriX n'avait aucune sortie annoncée. Pour en ressortir sans changer de mode, il fallait taper une réponse invalide ou faire Ctrl-D — sur un menu qui décide quels modules le bot chargera au prochain démarrage.
Éprouvé
- Passe de mutation à huit blessures, aucun trou, avec le nom du constat qui rougit relevé à chaque fois.
- ⚠ Deux trous trouvés par la mutation, et corrigés : les constats de cohérence des menus raisonnent par fonction, et ne voyaient donc pas le sous-menu imbriqué dans
_panel_install— lui retirer sa garde laissait le banc vert, la fonction en contenant une autre. Le cas est désormais nommé, faute de pouvoir se dériver : découper descaseimbriqués en bash demanderait un analyseur, et un analyseur approximatif rendrait des faux positifs — donc un banc qu'on finit par ignorer.
Avertissements
- ⚠ Deux dialectes coexistent dans ce panel : sur quinze menus, six seulement emploient
_menu_add/_menu_gate. Les neuf autres dessinent leurs entrées à la main, et trois le font encore en texte brut hors cadre. Le banc ne garde que les six — c'est écrit dans son en-tête plutôt que découvert.
4.27 1 version · 28 août 2026 3 additions 3 bugs fixed 2 checks 1 mistake 1 warning
4.27.0 — 28 août 2026
Les deux derniers morceaux de la phase 5 devaient être du travail de documentation. Chacun cachait un défaut qui se voyait à l'écran.
Créations
Web/inc/niveaux.php— la correspondance des cinq échelles de gravité du projet, à un seul endroit.Web/tests/test-niveaux.php— il dérive les cinq listes de leurs sources et exige que la table les connaisse toutes.Bootstrap/tests/test-alerte-silence.sh— le silence des alertes, par cause.
Bugs corrigés
- ⚠⚠ La ligne la plus grave du journal s'affichait EN VERT.
::soc::alerte::leverécrit sa trace par untoupper, ce qui fabriqueCRIT— un mot qui n'appartient à aucune des cinq échelles. La coloration de la page des journaux ne connaissait queERRORetWARN; la ligne tombait donc sur la règle suivante, « contientSOC→ vert », posée par la ligne même qui l'avait écrite. Une affirmation qui ment dans le sens rassurant. - ⚠⚠ Le plafond des six heures était GLOBAL, et son commentaire mentait sur son propre code. Il annonçait « 6 h entre deux alertes identiques », mais l'étape en échec n'entrait nulle part dans la décision. Une mise à jour qui échoue à 03:00 sur un dépôt injoignable faisait taire six heures l'alerte de 04:00 disant que la base a disparu. Il compte désormais par clé, comme le bot le fait depuis le 16/08 — la même doctrine, portée au voisin qui ne l'avait jamais reçue.
- Le fichier d'état du silence se purge en s'écrivant : il grossissait d'une ligne par cause, pour toujours, sur une machine que personne ne regarde.
Erreurs
EDITIONS.mdcomptait cinq niveaux au serveur C ; l'enumen porte six —LOG_FATAL, celui dedie_fatal(), qui ne rend jamais la main. Et la ligne nommait les symboles :level_names[]imprimeWARN, jamaisWARNING.
Éprouvé
- Deux passes de mutation, dix-huit blessures, aucun trou, et le nom du constat qui rougit relevé à chaque fois.
- ⚠ Une leçon en chemin : deux gardes protègent la lecture d'un niveau. Cassées séparément, le banc reste vert ou rougit ailleurs ; cassées ensemble, une heure d'Eggdrop passe pour un niveau. Une mutation restée verte ne prouve pas que le code est inutile — elle peut aussi dire qu'une seconde garde tient.
Avertissements
- ⚠ La phase 5 n'est pas CONSTATÉE close. Son critère est qu'un incident provoqué volontairement parte avec le bon niveau — et cela envoie un vrai courriel. Le code est complet ; le geste revient à l'exploitant.
4.26 1 version · 28 août 2026 2 additions 3 changes 2 bugs fixed 3 checks 1 mistake 1 warning
4.26.0 — 28 août 2026
Le filet des rapports était posé, mais deux chemins d'envoi passaient à côté — et le seul moyen d'y remédier a été de l'écrire trois fois.
Créations
Web/tests/corpus-rapport.txt— un seul fichier de cas, lu par trois bancs dans trois langages. C'est la seule chose qui empêche les trois implémentations de la doctrine du rapport de diverger.Bootstrap/tests/test-doctrine-rapport-sh.sh— le banc de la moitié bash.
Modifications
Bootstrap/overtchat-setup.shporte la doctrine en bash. L'alerte de mise à jour filtre désormais les incidents, l'étape en échec et les chemins, et dit au lecteur combien d'éléments ont été retirés. ⚠ Les en-têtesTo:etFrom:n'y passent pas, délibérément : un message sans destinataire ne protège rien.Components/Service/lib/Tcl/Stable/IriX-std.tclporte la doctrine en Tcl.irix:send_mailfiltre le corps et le sujet — ce dernier finit sur une ligne de commandemutt -s, donc dans la table des processus de la machine.IriX/tests/test-std.tclreçoit le chapitre du corpus et celui du contournement.
Bugs corrigés
- ⚠⚠
--PASS2était nommé dans le filtre PHP et pourtant inatteignable.\bexige un caractère de mot avant le premier tiret, et devant--PASS2il n'y a jamais qu'une espace. Mesuré sur la forme réelle du fichier de robots —- b OverOp-T --PASS2 deuxmots— le filtre retirait zéro élément. C'est le secret de lien botnet, en clair dansIriX.user. Un motif qui cite un cas sans l'attraper ment mieux qu'un motif qui l'ignore. - La première écriture bash de l'étape IPv6 caviardait tous les horodatages : elle comptait deux deux-points au lieu de trois, et
14:00:00en a deux. Attrapée par le corpus le jour même.
Avertissements
- ⚠⚠ La doctrine est désormais écrite TROIS fois — PHP, Tcl, bash. Ni bash ni Tcl ne peuvent appeler le PHP : l'alerte de l'installateur part précisément quand l'installation va mal, et
IriX-std.tcltourne dans un Eggdrop. Un calcul écrit des deux côtés diverge un jour. La seule parade est le corpus partagé. Toute correction à l'une des trois commence par une ligne ajoutée au corpus — un cas absent n'y est éprouvé nulle part.
Erreurs
- ⚠⚠ Un banc écrit ce jour-là prouvait que la fonction existe, jamais qu'elle sert. Le chapitre Tcl « personne ne contourne le filet » rejouait le filtre lui-même sur la matière, puis constatait que le filtre filtre. Le corps de
send_maildébranché, il restait vert. Seule la passe de mutation l'a vu. Il intercepte désormais ce quemuttreçoit réellement.
Éprouvé
- Les trois implémentations rendent le même texte sur les 30 cas du corpus, chacune dans son banc.
- Passe de mutation à sept blessures, toutes attrapées : le
\bfautif remis en PHP, la frontière heure/adresse cassée en Tcl puis en bash, le filtre débranché du corps du courriel, celui des incidents de l'installateur, un cas gardien retiré du corpus, et le corpus réduit à ses commentaires. - ⚠ Par quel mécanisme cela voyage — mesuré, parce que c'est la question qui a manqué cinq fois :
overtchat-setup.shest la première entrée de son propreCORE_WATCHED, donc il se met à jour lui-même ;IriX-std.tclest écrasé par_irix_sync_source, sans garde « seulement si absent ».
4.25 1 version · 27 août 2026 2 additions 3 improvements 3 bugs fixed 4 checks 1 mistake 3 warnings
4.25.0 — 27 août 2026
Un rapport automatique sortait de la machine sans que personne regarde ce qu'il emportait — et le pire chemin était le plus discret.
Créations
Web/inc/doctrine-rapport.php— le filtre des rapports. (Point 9, phase 5 deMarkdown/EDITIONS.md.)Web/tests/test-doctrine-rapport.php(47 constats) etIriX/tests/test-rapport-sql.tcl(22 constats).
Bugs corrigés
- ⚠⚠ Les gardes d'erreur SQL faisaient sortir la requête par courriel.
db_execetdb_selmettaient jusqu'à 201 caractères de la requête dans le détail d'une alerte — et toute alertecritpart par courriel. Une écriture ratée sur la table des comptes faisait donc sortir pseudos, adresses et empreintes de mots de passe, sans que personne ait rien écrit ni rien décidé. - ⚠⚠ Et la clé fuyait aussi, derrière un commentaire juste. Le code disait « la clé porte le début du message MySQL, jamais la requête » — vrai à la lettre, faux en pratique : sur une erreur de syntaxe, MySQL recopie lui-même un fragment de la requête après
near '. La clé partait en clair quatre lignes au-dessus du détail. ::soc::sql_formene rend désormais que le verbe et la table ;::soc::sql_err_netcoupe ce que MySQL recopie, et garde tout ce qui précède — « Unknown column », « Table doesn't exist » nomment ce qu'il faut réparer.
Évolutions
- Le filtre est appliqué à
Tools/alerte-courriel.php, point de passage unique : le Tcl ne poste rien lui-même, il lanceexec phpdessus. Filtrer là couvre les dix appels à matière brute d'un seul geste. - ⚠ La clé, la source et le sujet passent par le filet, pas seulement le détail — sept des dix appels construisent la clé avec un fragment de message système.
- Le courriel dit combien d'éléments ont été retirés, et dit aussi que le filet a des trous : un lecteur qui le croirait entièrement expurgé cesserait de faire attention en amont.
Erreurs
- ❌
Markdown/EDITIONS.mdfaisait de cette phase le prolongement d'une fonctionsans_secret()qui n'a jamais existé. Balayage refait : aucun masquage d'aucune sorte dans tout le dépôt. La parade était à écrire, pas à reprendre.
Avertissements
- ⚠⚠ LE FILET NE RATTRAPE PAS LE CAS QUI L'A MOTIVÉ, et c'est mesuré. Une requête SQL ne contient ni IP, ni courriel, ni secret au format
mot=valeur: le filtre n'en retire rien, et le pseudo sort. La correction est donc à la source, et le banc affirme cette limite au lieu de la taire. Élargir un filet jusqu'à ce qu'il attrape le cas du jour est la façon la plus sûre de le rendre inutile pour tous les autres. - ⚠⚠ Le Tcl n'est pas rechargé : les deux procs n'existeront dans le processus vivant qu'après un redémarrage d'IriX. Ce geste n'a pas été fait.
- ⚠ Deux chemins d'envoi restent hors du filet, et le banc les nomme :
Bootstrap/overtchat-setup.sh(sendmail -t) etComponents/Service/lib/Tcl/Stable/IriX-std.tcl(mutt) — ce dernier étant dans la bibliothèque distribuée.
Éprouvé
- Deux pièges de motif, tous deux mesurés sur les journaux vivants. Un motif IPv6 naïf caviarde 100 % des lignes — 1304 sur 1304, puis 447 sur 453 — parce qu'il prend l'horodatage
14:00:00pour une adresse. Et un motif alternatif mal posé découpait une adresse abrégée par le milieu :‹retiré›devenaitfe80[retiré:ip]:fe23:4567:890a. - Le banc Tcl exécute les deux procs au lieu de lire leur source : écrire du code prouve qu'il existe, jamais qu'on peut s'en servir.
- Mutation à 16 blessures, sans trou — et elle a trouvé quatre constats faux que la relecture n'avait pas vus : un qui vérifiait qu'une variable existe au lieu qu'elle serve ; un qui lisait le nom d'un fichier dans un commentaire au lieu du
require; un qui accusait unputlogdélibéré ; et un qui restait vert quand le motif du masque cassait, parce que le motif du courriel effaçait l'hôte — en laissant le pseudo. - Campagne complète : 115 bancs au vert, 5315 constats.
4.24 2 versions · 27 août 2026 2 additions 7 improvements 5 bugs fixed 9 checks 2 mistakes 5 warnings
4.24.1 — 27 août 2026
Une correction ne pouvait pas atteindre une installation — et le banc qui aurait dû le dire regardait le dépôt.
Bugs corrigés
- ⚠⚠ Le défaut est dans le mécanisme de livraison, pas dans ce qui est livré.
Servers/overtchat-hybrid/contrib/install-service.shne posait les quatre fichiers de politique que s'ils manquaient. Une installation déjà en place gardait donc, pour toujours, la documentation du jour de sa pose : aucune correction ne pouvait plus l'atteindre, ni sur la production, ni chez un tiers. - Mesuré, pas supposé : le format d'une empreinte a été corrigé dans le dépôt le 16/08 — quatre champs au lieu de trois. Le 27/08, onze jours plus tard, le fichier posé en production annonçait toujours trois champs. ⚠ Et le format à trois est accepté en lecture : il vaut une itération au lieu de cent mille, sans le moindre avertissement. Un exploitant qui suit son propre fichier obtient une protection cent mille fois moins chère à casser, qui a l'air de fonctionner.
- ⚠⚠ Le registre affirmait « corrigé dans les 8 endroits, dont le fichier installé ». La première moitié était vraie, la seconde fausse.
Évolutions
- Le modèle (
.example) est désormais redéposé à chaque passage, hors de toute condition : il n'est lu par aucun serveur et n'est rempli par personne, donc le remplacer ne peut rien détruire. La politique (.conf) n'est toujours écrite que si elle manque — les entrées de l'exploitant sont intouchables. - Et une documentation vieillie est dite : l'exploitant est renvoyé au modèle frais posé à côté. ⚠ La comparaison porte sur les seules lignes de commentaire — comparer les fichiers entiers crierait dès la première entrée ajoutée, pour toujours, et un avertissement permanent n'est plus un avertissement.
- ⚠ La forme n'est pas neuve : ce script appliquait déjà exactement cette doctrine à
overtchat.conf, vingt lignes plus haut. Elle n'avait jamais été étendue aux politiques.
Erreurs
- ⚠⚠ Un commentaire mentait sur ce que son propre code faisait. Le docbloc de
botpool_retirer()annonçait « les QUATRE endroits en base » au-dessus d'une énumération qui en portait cinq, et appelait la dernière « le septième endroit » d'un total qui en compte huit. Le même faux était recopié dansWeb/inc/botpool.phpet dans le registre. Les chiffres sont retirés — on énumère, on ne dénombre plus. - ⚠ La liste des « cinq pseudonymes à protéger » du point 10 était périmée, et fausse dans les deux sens : trois noms disparus y figuraient, et un robot bien vivant (
OverOp-A) n'y figurait pas.
Éprouvé
- ⚠⚠ Le banc est resté vert onze jours pendant que le défaut nuisait.
test-conf-modele.shportait déjà le bon constat — mais il balaie le dépôt, qui était juste. Un banc qui ne lit jamais l'installation ne peut pas voir un défaut de livraison. Il passe de 9 à 15 constats, dont un qui regarde l'installation : le seul du fichier à le faire. - ⚠⚠ Et ce constat a rougi POUR DE VRAI avant que le geste soit fait — l'épreuve qu'on ne peut pas fabriquer. Mutation à 5 blessures, sans trou, dont le retour de l'ancienne condition liée.
test-botpool-retrait.phpgagne un chapitre de complétude : autant d'étapes décrites au docbloc que d'écritures réellement faites. Il passe à 45 constats, mutation à 5 blessures, sans trou. ⚠ Il a fallu le corriger en naissant : il accusait le texte qui répare — celui qui cite l'ancien chiffre pour le dénoncer — au lieu de celui qui affirme. On cherche désormais la forme affirmative, pas le mot.- Les modèles à jour sont posés en production — sauvegarde dans
~/‹retiré›. ⚠ Trois étaient périmés, pas un. Les.confn'ont pas été touchés : ils portent 84 et 12 entrées vivantes. - Campagne complète : 113 bancs au vert, 5246 constats.
Avertissements
- ⚠
Servers/n'est distribué par aucun canal — décision encore ouverte. La correction profite donc à la production et à qui clone le dépôt, pas encore à un tiers qui passe par l'installateur.
4.24.0 — 27 août 2026
L'installateur sait installer sans personne devant — et il refuse de partir plutôt que d'inventer une réponse.
Créations
--auto, dansBootstrap/overtchat-setup.sh: les six étapes de l'assistant enchaînées sans une seule question — site → serveur IRC → Eggdrop → IriX → unités systemd. Le mode manuel n'a pas bougé : c'est l'assistant, et il existait déjà. (Point 48 du registre, deuxième morceau.)Bootstrap/tests/test-auto.sh— 42 constats.
Évolutions
- ⚠⚠ Le mode automatique ne lit JAMAIS l'entrée standard, et c'est tout le sujet. Un
readsans personne devant ne rend pas une réponse : il rend une chaîne vide obtenue par EOF, que plus rien ensuite ne distingue d'une réponse donnée. L'installation se serait poursuivie sous des valeurs que personne n'a choisies, en affichant « configuré »._site_askrend donc la valeur prévue et le dit surstderr— jamais surstdout, qui est la réponse puisque la fonction est appelée dans un$( ). - Un contrôle avant vol,
_auto_prevol, placé avant la première écriture sur le disque : il exige le nom de l'installation,OVERTCHAT_SQL_PASSet une élévation sans mot de passe, puis nomme ce qui manque. Un refus ne laisse donc rien derrière lui — mesuré : le bac à sable reste vide et le journal de la production intact. - Les valeurs se donnent par l'environnement :
OVERTCHAT_DOMAINE,OVERTCHAT_RESEAU,OVERTCHAT_COURT,OVERTCHAT_MAIL_FROM,OVERTCHAT_MAIL_TO,OVERTCHAT_SERVEUR,OVERTCHAT_AUTO. Ce qui reste au défaut d'exemple est annoncé, pas subi. _as_rootpasse ensudo -nsous--auto: une invite de mot de passe que personne ne remplira n'attend plus sans fin et sans message.
Bugs corrigés
(Trouvés en écrivant le mode, pas après.)
- ⚠⚠ Le gel. Les trois boucles de
_site_installreposent leur question tant que la réponse ne convient pas. En automatique, la réponse suivante est identique à la précédente : le refus se serait répété sans fin et sans rien écrire à l'écran. Pas un échec — un arrêt muet._auto_bouclecoupe au second tour : un second tour n'est pas une seconde chance, c'est la preuve que la valeur fournie est refusée. - ⚠⚠ Le secret vide. Le mot de passe SQL d'IriX n'a de valeur par défaut nulle part. Sans garde,
IriX.jsonaurait été écrit avecpass:"", l'écran aurait dit « configuré », et le bot n'aurait jamais joint la base.
Avertissements
- ⚠ Une seule question de consentement reçoit « non » : installer une archive dont l'empreinte n'a pas pu être vérifiée. Les autres portent sur ce que l'installation vient faire —
--autoest cet accord. Celle-là demande de passer outre un contrôle d'intégrité, sur une archive qui s'extrait par-dessus la racine d'installation. - ⚠ Anope n'est pas dans le socle automatique : son mot de passe de lien se lit dans le bloc
linkdu serveur IRC, qui n'existe pas encore sur une installation neuve. Il se pose ensuite, paranope-config. - ⚠ Le serveur posé par défaut est
unrealircd, pas celui du projet.overtchat_ircdn'est distribué par aucun canal — décision encore ouverte —, donc un mode automatique qui le choisirait échouerait chez tout tiers, au milieu de l'installation. - ⚠⚠ Une installation complète de bout en bout n'a jamais été menée. Le banc éprouve les gardes, pas le parcours : il y faudrait une machine nue et la compilation d'un serveur IRC. C'est le geste qui manque, et il va sur la machine tierce. Écrire du code prouve qu'il existe, jamais qu'on peut s'en servir.
Éprouvé
Bootstrap/tests/test-auto.sh: 42 constats, et une passe de mutation à 16 blessures, sans un seul trou — le gel, le secret vide, l'alerte écrite sur la mauvaise sortie, l'ordre du contrôle avant vol, le menu non sauté, le troisième paramètre ignoré.- ⚠ Le constat qui vaut pour la suite est celui de complétude : il compare le nombre de boucles de question de
_site_installau nombre de gardes. Une boucle ajoutée demain sans sa garde fera rougir le banc. - Lancé pour de vrai dans un
HOMEdétourné : refus en nommant les trois manques, sortie en code 2, rien de créé, journal de production intact. - Campagne complète : 113 bancs au vert.
4.23 3 versions · 24 août 2026 1 addition 22 improvements 6 bugs fixed 2 checks 7 warnings
4.23.2 — 24 août 2026
Après chaque salon approuvé, le panel demandait à l'exploitant d'éditer un fichier que plus rien ne lit.
Bugs corrigés
- ⚠⚠ Une consigne morte, affichée à chaque approbation de salon. Le panel disait : « ajouter
allow channel { … }àConfig/unrealircd/salons.confpuis rehash […] Sans le premier, le salon reste inaccessible. » Les trois moitiés de la phrase étaient fausses en même temps — ce fichier n'est lu par aucun code depuis le retrait d'UnrealIRCd le 28/07, sa syntaxe est celle d'un serveur qui ne tourne plus, et le « rehash » visait un démon arrêté. Un exploitant qui suivait la consigne éditait un fichier inerte, croyait le salon ouvert, et le demandeur se prenait un refus en essayant d'entrer. - ⚠ Le second endroit, plus discret : l'encart de la page des demandes nommait le même fichier et disait qu'il fallait « ajouter l'exception à la main ». La fermeture, elle, était bien réelle — mais le fichier était le mauvais, et « à la main » niait l'existence de l'outil.
- Les deux nomment désormais le geste vivant :
Tools/salons-exceptions.sh --appliquer, qui relit la table des salons, pose les exceptions et recharge le service.
Évolutions
- Un banc neuf,
Web/tests/test-consignes.php, garde une FAMILLE et non un cas. Le défaut n'a rien de propre aux salons : il se reproduira le jour où un outil sera renommé. Le contrôle dérive donc la liste des scripts cités depuis les sources du panel elles-mêmes, et exige que chacun existe. Il vérifie aussi que le script prescrit comprend l'option qu'on dit de taper, et que celle-ci est lue et pas seulement documentée.
Avertissements
- ⚠⚠ Ce n'était pas un oubli de documentation : la documentation, elle, avait été corrigée.
SECURITY.mddéclare ce fichier inerte en capitales,ARCHITECTURE.mdetRESEAU.mdle qualifient d'hérité, et le fichier s'auto-dénonce dans son propre en-tête. Seul le texte affiché n'avait pas suivi — et c'est le pire des deux mondes : le document que personne ne lit dit vrai, l'écran que tout le monde lit ment. - ⚠ Le remplaçant existait depuis des semaines.
Tools/salons-exceptions.sha été écrit pour combler exactement ce trou — il le dit dans son propre en-tête. Personne n'avait mis le message à jour. - ⚠ Aucun banc ne couvrait ces pages, et aucun n'aurait rougi si la consigne avait été corrigée. C'est ce trou-là que le banc neuf ferme.
Éprouvé
Mutation, quatre passes, quatre rouges : represcrire l'héritage inerte (3 échecs), ne plus nommer le geste (1), rendre le script introuvable (4), lui retirer l'option qu'on dit de taper (1). Restauré, 12 constats verts.
⚠ Un cinquième constat existe pour empêcher la sur-correction : le « rehash » du panel vise l'Eggdrop, et celui-là est bien vivant. Une garde trop large, écrite dans l'élan, l'aurait interdit avec le reste.
4.23.1 — 24 août 2026
Le bilan de la page Versions écrivait « 1 créations ».
Bugs corrigés
- ⚠ Les pastilles du bilan par branche ne s'accordaient pas au nombre. Les libellés étaient figés au pluriel, si bien qu'une rubrique ne portant qu'une seule entrée affichait « 1 créations », « 1 évolutions », « 1 bugs corrigés ». Le défaut se voyait surtout à l'ouverture d'une branche — c'est-à-dire au moment où la page est la plus regardée : le jalon 4.23.0, publié une demi-heure plus tôt, l'affichait.
- ⚠ Le compteur de versions critiques accordait déjà, seul de la page. Une garde qui couvre un compteur sur six rassure sans protéger.
- Le bilan général accorde désormais aussi « version », « branche » et « critique ».
Évolutions
- Chaque rubrique porte maintenant ses deux formes, écrites plutôt que dérivées. ⚠ L'accord ne s'obtient pas en ajoutant un « s » : « bug corrigé » en prend deux, et une règle mécanique se serait trompée sur la moitié des cas.
journal_accord()choisit entre les deux — et rend le singulier pour zéro, comme le veut le français.
Éprouvé
test-journal.php passe de 34 à 46 vérifications. Le constat qui compte n'est pas que la fonction soit juste, mais que la page l'appelle : le banc lit le source de Web/site/versions.php et exige qu'il n'y reste aucun libellé affiché sans accord — une fonction juste que rien ne branche est le défaut le plus fréquent de ce projet.
Mutation, quatre passes, quatre rouges : la page cesse d'appeler l'accord (2 échecs), l'accord rend toujours le pluriel (3), « bug corrigé » n'accorde que son premier mot (1), une rubrique perd sa forme singulière (3). Restauré, le banc revient au vert.
4.23.0 — 24 août 2026
Une branche entière passée à faire marcher le projet CHEZ QUELQU'UN D'AUTRE.
Évolutions
Ce qui change pour qui installe le projet ailleurs
- L'installateur pose enfin ce qu'il annonçait. Les unités systemd, les fichiers d'Apache et les quatre familles de fichiers système atteignent désormais une installation tierce — auparavant l'écran les affichait, et rien n'arrivait. Une installation neuve laissait quatorze services au repos sans que rien ne le dise.
- Eggdrop se pose et IriX démarre.
make installvisait son propre répertoire source ettcl-tlsmanquait : deux défauts qui arrêtaient l'installation net. - Le client SQL est nommé MariaDB explicitement. Le métapaquet employé jusque-là menait à MariaDB sur Debian et tirait MySQL 8 sur Ubuntu, où il entre en conflit avec le serveur que tout le reste du projet suppose.
- Le premier enrôlement du propriétaire fonctionne. Il n'avait jamais pu fonctionner, et le compte naissait avec un masque sans ident.
- Reposer les contrôles d'intégrité est devenu un geste que l'on décide, au lieu d'un effet de bord. Deux fichiers de configuration naissaient par ailleurs lisibles par tout le monde.
- La liste des communes part enfin avec l'archive. Le contrôle de ville était éteint en silence sur toute installation tierce — il fonctionnait ici, et nulle part ailleurs.
- L'assistant d'installation prend les couleurs du site.
Ce qui change pour le robot et le réseau
- Plus aucun cycle du bot ne peut s'arrêter en silence. Six boucles le pouvaient ; chaque tâche périodique déclare maintenant son rattrapage, et un contrôle refuse celles qui ne le déclarent pas.
- IriX ne fabrique plus des minuteurs à l'infini. Il s'en étouffait.
- L'alerte parle enfin de la panne qui l'empêchait de parler — le cas précis où elle se taisait.
- Après une rupture de lien, le SID choisi est celui que le serveur accepte.
- Les journaux d'IriX ont un plafond de taille, et une veille extérieure le surveille.
Ce qui change pour les visiteurs
- Le chat ne s'ouvre plus en double et ne redemande plus le pseudonyme. Sortir du chat n'ouvre plus un onglet à chaque clic.
- La touche Tab complète les pseudonymes et les salons.
- Le grade s'affiche devant le pseudo, et les grades du réseau ne se confondent plus avec ceux du salon. La liste des pseudonymes réservés se replie quand elle s'allonge.
- Le champ « Ville » peut se remplir tout seul, si le visiteur le demande — et seulement s'il l'accepte.
- La charte disait trois choses fausses à ses lecteurs, et un contrôle croise désormais les durées qu'elle annonce avec celles que le code applique. La page d'accueil, elle, annonçait un nombre de serveurs compatibles périmé : il se dérive maintenant de sa source au lieu d'être écrit à la main.
Ce qui change au panel
- Les traces d'administration reçoivent une date de péremption : elles gardaient des adresses sans aucune purge.
- Un bouton demande un robot de plus — la file d'installation des robots n'avait aucun producteur.
- Une fin de prêt n'écrit plus qu'une seule ligne au journal.
Créations
Vingt-huit fichiers, dont vingt-quatre bancs d'essai : six pour l'installateur (Bootstrap/tests/), six pour le robot (IriX/tests/), douze pour le site et le panel (Web/tests/). S'y ajoutent la veille extérieure d'IriX (Tools/veille-irix.php) et son unité de minuterie, plus une migration de base.
Rien n'a été supprimé du dépôt pendant cette branche.
Avertissements
- ⚠⚠ Le motif dominant de la branche n'est pas refermé pour autant. « Cela marche ici » ne dit rien de ce que reçoit un tiers, et les bancs d'essai ne l'attrapent pas : plusieurs de ces défauts sont restés verts pendant qu'ils cassaient une installation neuve. Le contrôle qui les a trouvés a toujours été le même — installer pour de vrai, ailleurs.
- ⚠⚠ Les bancs d'essai eux-mêmes ont menti, et souvent. Une dizaine d'entrées de cette branche le racontent : un banc resté vert parce qu'il mesurait le commentaire du correctif, un autre qui fabriquait lui-même la commande qu'il devait trouver, un troisième qui mesurait du HTML là où le défaut vivait dans le navigateur. Ce qui l'a dit à chaque fois, c'est la passe de mutation — casser exprès ce que le banc prétend garder —, jamais la relecture. Un banc qui n'a jamais été vu rougir ne garde rien.
- ⚠ La distribution du serveur reste entière.
Servers/n'est distribué par aucun canal ; chez un tiers, l'installation d'Overtchat-Hybrid échoue et le réseau tourne sur un autre serveur, donc aucun correctif du serveur ne l'atteint. C'est une décision en attente, consignée dansMarkdown/CHANTIERS.md. - ⚠ Ce que ce jalon ne dit pas : ce qui reste ouvert ne se lit pas ici mais dans
Markdown/CHANTIERS.md, affiché au-dessus de cette page, et il s'y dérive des titres plutôt que de se recopier.
4.19 57 versions · 16 août 2026 → 24 août 2026 6 critical 43 additions 50 improvements 28 changes 71 bugs fixed 1 removal 10 checks 54 mistakes 87 warnings
4.19.56 — 24 août 2026
Deux lignes du carnet avaient perdu leur chevron de citation, et la page publique le montrait : quatre astérisques en clair et un tableau disparu.
Bugs corrigés
- ⚠⚠ Un tableau entier ne naissait pas. Dans le point 43, la ligne d'en-tête était citée (
> | … |) mais son séparateur|---|---|ne l'était pas. Le moteur ne voyait plus deux lignes de tableau mais un paragraphe suivi d'un autre : l'en-tête retombait en texte et ses barres verticales s'affichaient au visiteur. Aucune balise n'était pourtant déséquilibrée — c'est exactement le mode d'échec quetest-markdown.phpavait été armé pour voir le 14/08.
- ⚠ Un gras traversait la frontière d'une citation. Toujours au point 43, le
**s'ouvrait sur une ligne non citée et se fermait sur la ligne citée suivante. Le moteur met en forme à l'intérieur d'un bloc, jamais entre deux : les quatre astérisques partaient en clair sur la page.
Éprouvé
Le contrôle rougissait avant, il est vert après, sur le même document et à cinq minutes d'intervalle : 2 astérisques doubles survivants → 0, et 127 <table> rendus pour 128 suites de lignes en « | » → 128 pour 128. Le compte des groupes se dérive du source, il n'est pas écrit.
Avertissements
- ⚠⚠ Le banc était ROUGE depuis 24 commits. Le gras a été introduit le 23/08 à 19:36 (
65ca1a3), le tableau le 24/08 à 17:32 (d07694f) ; entre les deux, la campagne n'a pas été relancée et le rouge n'a été entendu par personne. Le hookpre-commitne lance pas les bancs — il valide la syntaxe et le manifeste — donc rien n'attrape ce cas au moment où il naît.
- ⚠ Le motif est le même deux fois : une ligne à qui il manque son
>. Il ne casse ni la syntaxe ni un banc de balises ; il ne se voit qu'en rendant le document et en comparant au source. Les deux fautes sont nées dans des encadrés écrits vite, en fin de constat.
4.19.55 — 24 août 2026
Le client SQL est nommé MariaDB, et non plus un métapaquet qui change de sens selon la distribution.
Bugs corrigés
- ⚠⚠
default-mysql-clientmène à MariaDB sur Debian, mais tire MySQL 8 sur Ubuntu — qui entre en conflit avecmariadb-serveret rend « held broken packages ». Or la familledebiande l'installateur couvre les deux : Ubuntu y est rangé parID_LIKE. Un exploitant Ubuntu qui suivait l'installateur obtenait donc un client MySQL et ne pouvait plus poser le serveur que tout le reste du projet suppose — l'écran de configuration demande littéralement « Hôte MariaDB ».
- ⚠ Les quatre autres familles nommaient déjà MariaDB explicitement (
mariadb,mariadb-clients,mariadb-client).debianétait la seule à passer par un métapaquet ambigu : ceci l'aligne.
Éprouvé
Mesuré sur les deux distributions avant de trancher : le paquet est déjà installé en production (Debian 13, 1:11.8.6) et disponible sur Ubuntu 24.04 (1:10.11.14). Rien ne régresse.
test-deps-eggdrop.sh passe à 20 vérifications, dont cinq qui exigent que chaque famille nomme un paquet MariaDB. Mutation : remettre le métapaquet → 2 échecs.
4.19.54 — 24 août 2026
Les fichiers de configuration système atteignent enfin une installation tierce — et ils y arrivent ADAPTÉS, pas bruts.
Éprouvé
test-systeme.sh passe de 62 à 73 vérifications. Deux mutations, deux attrapées — dont le remplacement global, pris par le constat qui vérifie qu'un commentaire n'est pas réécrit.
⚠ Le constat sur une vraie installation tierce reste à prendre.
4.19.53 — 24 août 2026
L'installateur peut de nouveau poser Eggdrop, et IriX démarre : deux défauts qui empêchaient TOUTE installation neuve, l'un depuis longtemps.
Bugs corrigés
- ⚠⚠
make installd'Eggdrop visait son propre répertoire de sources. Le Makefile d'Eggdrop refuse ce cas en toutes lettres. La compilation réussissait — binaire et modules produits — puis l'installation mourait, et le rollback effaçait les traces derrière lui. Les sources sont désormais déplacées dans.src-build, etmake installvise le répertoire que la suite attend.
- ⚠⚠
tcl-tlsn'était déclaré nulle part, alors queIriX-sql.tclfaitpackage require tlsà sa dixième ligne. Une fois Eggdrop posé et IriX déployé, le démarrage mourait sur « can't find package tls ». Il est ajouté aux dépendances d'IriX et traduit dans les cinq familles de paquets.
- ⚠ Un nom de paquet faux ne peut plus mentir :
_pkg_presentteste la capacité — il demande à Tcl s'il sait chargertls— et une famille inconnue le déclare manquant, jamais présent. C'est la leçon déjà écrite pourmysqltcl: répondre « présent » sans savoir est le pire des choix.
Éprouvé
Bootstrap/tests/test-deps-eggdrop.sh, banc neuf : 14 vérifications, trois mutations attrapées. Et ce banc s'est fait prendre en s'écrivant — son constat comptait le make install cité dans un commentaire en plus du vrai appel.
⚠ Le constat qui manque : l'installation neuve de bout en bout, sans correctif local.
4.19.52 — 24 août 2026
Tab complète les pseudonymes et les salons dans le champ de message, comme dans tout client IRC.
Éprouvé
Web/tests/test-chat-completion.php, banc neuf : 41 constats au vert. Les deux fonctions éprouvées sont pures et sont extraites de chat.js puis lancées sous node — on éprouve l'original, jamais une copie réécrite en PHP.
Trois mutations, trois attrapées : garde du dièse retirée (1 échec), comparaison rendue sensible à la casse (6 échecs), et regex construite depuis le préfixe — celle-ci fait échouer node lui-même, ^[z n'étant pas une expression régulière valide. C'est la démonstration de ce que le projet répète : un pseudo IRC contient des caractères qu'une regex interprète.
⚠ Le constat qui manque, et il est nommé : le geste au navigateur.
4.19.51 — 23 août 2026
Deux liens internes portaient _blank écrit à la main : le correctif de la veille les avait manqués, et c'est la production qui l'a dit.
Bugs corrigés
- ⚠⚠
?p=charteET?p=reglementÉCHAPPAIENT AU CORRECTIF. La passe de sortie laisse intact tout ce qui porte déjà untarget— c'est voulu, mais cela signifie qu'un_blankécrit à la main lui échappe entièrement. Les deux liens sont passés au nom de l'onglet compagnon.
4.19.50 — 23 août 2026
Sortir du chat n'ouvre plus un onglet à chaque clic, et y revenir ne redemande plus le pseudo — c'était le même _blank qui causait les deux.
Bugs corrigés
- ⚠⚠ UN ONGLET DE PLUS À CHAQUE SORTIE. La passe qui dirige les liens de la page du chat posait
target="_blank"— un nom anonyme, qui ne désigne aucun contexte réutilisable. Les liens internes reçoivent désormais le nom d'un onglet compagnon, dérivé de l'identité du réseau comme l'est déjà celui du chat : deux onglets en tout, quel que soit le nombre de clics.
- ⚠⚠⚠ ET C'EST LE MÊME CODE QUI REDEMANDAIT LE PSEUDO. Un onglet ouvert avec
noopenervit dans un groupe de contextes isolé, et un nom de fenêtre ne se résout que dans son propre groupe. Depuis cet onglet, lewindow.open('', NOM)du script de retour ne retrouvait pas l'onglet du chat : il obtenait une fenêtre vierge, la refermait, et laissait le lien naviguer — la page chat se rechargeait à neuf, d'où le panneau pseudo alors qu'une conversation était ouverte à côté.
- ⚠ Les liens qui SORTENT du site gardent
_blank+noopener, et c'est délibéré : leur donner notre nom d'onglet les mettrait dans notre groupe de contextes, où la page distante pourrait lire et réécrirewindow.opener.location.
Éprouvé
45 constats au vert. Trois mutations, trois attrapées : remettre _blank sur les liens internes (6 échecs), neutraliser la détection d'externalité (3 échecs), faire rendre _blank au nom du compagnon (3 échecs).
⚠ Le constat qui manque, et il est nommé : deux onglets et un vrai clic dans un navigateur. Aucun banc PHP ne le remplacera.
4.19.49 — 23 août 2026
Le premier enrôlement du propriétaire fonctionne — il n'avait jamais pu fonctionner, et son banc fabriquait lui-même la commande qui manquait.
Bugs corrigés
- ⚠⚠⚠
on_passMOURAIT À SA PREMIÈRE LIGNE UTILE.find_owner_on_ircappelaitusers, qui n'est pas une commande Eggdrop — le bon nom estuserlist, que le projet écrit partout ailleurs (IriX-sql.tclfait mêmeforeach u [userlist n], exactement le même usage). Conséquence : sur toute installation neuve,/msg IriX pass …rendaitinvalid command name "users", aucun masque n'était posé, aucun compte owner ne naissait. Le correctif du 21/08 sur la forme du masque portait donc sur du code inatteignable.
- ⚠⚠ ET LE BANC ÉTAIT VERT PARCE QU'IL FABRIQUAIT LA COMMANDE MANQUANTE.
test-register.tclchargeait le vraifind_owner_on_irc, puis définissait lui-mêmeproc users {} { … }. Il éprouvait le code dans un monde où la commande absente existait. Son bouchon s'appelle désormaisuserlist. Un bouchon ne doit porter que des noms que l'hôte fournit vraiment.
Éprouvé
Deux mutations, deux attrapées : remettre set users [users] arrête le banc sur l'erreur même de la production ; retirer le * de tête du masque donne 2 échecs sur 24. Restauré, le banc rend 24 vérifications au vert.
4.19.48 — 23 août 2026
Une fin de prêt n'écrit plus qu'une ligne au journal, et le banc du mandat cesse de regarder un bouchon là où il croyait regarder le code.
Bugs corrigés
- ⚠⚠ DEUX LIGNES AU JOURNAL POUR UNE SEULE FIN DE PRÊT.
terminerjournalise — c'est la porte — etbalayerjournalisait aussi, pour marquerexpireplutôt queok. Chacune avait raison séparément ; ensemble elles écrivaient deux fois. Mesuré en base : ids 15 et 16 du journal des prêts, même seconde, sur le mandat qui a servi à constater le point 30. Les expirations d'avant le 14/08 n'en ont qu'une : le doublon est né le jour oùterminers'est mis à journaliser, sans qu'on regarde ce que ses appelants faisaient déjà. balayerpasse désormais l'issue àterminerau lieu de réécrire : une seule ligne, avec la bonne valeur. C'est la règle que la brancheMANDATFINappliquait déjà chez elle — « une porte, une rédaction ».
Évolutions
extrairesait charger une procédure à arguments par défaut. Il prenait la première fermante venue pour la fin de la liste d'arguments — sur{chan motif {par ""}}, c'est celle de l'argument. Le défaut dormait parce que la seule procédure chargée ainsi n'avait aucun argument.
Avertissements
- ⚠⚠ LE BANC BOUCHONNAIT
terminer, et deux mutations du VRAI code le laissaient VERT — lui faire écrireokquoi qu'on lui passe, et lui faire cesser d'écrire. C'est exactement le défaut que le point 30 avait déjà rencontré : le banc bouchonnaitechus, et sa clauseWHERE— là où vivait le défaut — n'était éprouvée par personne. La parade avait été trouvée alors ; elle est appliquée ici au second cas. - ⚠ Le bouchon reste en place : il sert à éprouver l'ordre des gestes sans toucher à une base. Les deux approches se complètent — l'une regarde la porte, l'autre le chemin.
- ⚠⚠ UNE ACCOLADE NUE DANS UN COMMENTAIRE TCL CASSE LA PROCÉDURE QUI LE CONTIENT. « Le corps commence au
{suivant », écrit dans un commentaire, a referméextrairetrente lignes trop tôt — et le message parlait d'un « close-brace » ailleurs. C'est le jumeau du commentaire dans unswitch, que ce dépôt connaît déjà pour avoir coupé le serveur 89 secondes. - ⚠ 213 vérifications au banc du mandat, 6 mutations essayées, 6 attrapées. 41 bancs Tcl au vert.
4.19.47 — 23 août 2026
La file d'installation des robots a enfin un producteur : un bouton au panel. Le service qui la consomme tournait à vide depuis le premier jour.
Créations
botpool_deposer()et l'actionbotpool_demander— le panel dépose une lignepending, le service dédié l'installe au passage suivant de son minuteur, dans les cinq minutes. Grade requis : Admin, le même que décider un prêt de robot. Tranché par SerVuS le 23/08/2026 : un bouton, pas un déclencheur automatique — le parc ne grandit jamais sans quelqu'un devant l'écran, ce qui importe puisque l'exécutant pose de vrais Eggdrop.Web/tests/test-botpool-panel.php— 31 constats. Il garde la jointure, qui était précisément ce que personne n'éprouvait.
Bugs corrigés
- ⚠⚠ LA FILE N'AVAIT AUCUN PRODUCTEUR — point 35, ouvert le 17/08. Les deux seuls
INSERTdu dépôt vivaient dans une procédure Tcl que personne n'appelait, et n'a jamais appelée. Mesuré : la table porte une seule ligne depuis sa création,AUTO_INCREMENTà 2, et cette ligne ne peut pas venir du code — la procédure engendre le nom en prenant la première lettre libre, soitOverOp-A, or la ligne porteOverOp-Tet un pseudo humain là où le code passe « auto ». - ⚠⚠ LE MIROIR PHP N'AVAIT QUE DEUX GARDE-FOUS SUR QUATRE. Il connaissait
plafondetechecs, ignoraitencoursettrop_tot— et personne ne l'avait vu parce qu'il ne servait qu'à AFFICHER un avertissement. Une moitié de garde-fou qui n'a jamais rien gardé ne se remarque pas.encoursest le plus important pour un bouton : sans lui, deux clics déposent deux lignes et l'exécutant pose deux robots. - ⚠ Trois endroits affirmaient au présent une chaîne automatique inexistante : le texte affiché par la page du panel (« OverBot dépose une ligne ici »), et son en-tête qui promettait « cette page NE FAIT RIEN ». Les deux sont corrigés — et l'argument de l'en-tête est conservé, parce qu'il reste juste : il vise deux chemins d'écriture concurrents, or la file n'en avait aucun. Le bouton ne crée pas un second chemin, il crée le premier.
Avertissements
- ⚠⚠ UN BANC A ATTRAPÉ UNE VRAIE ERREUR DE MA MAIN : j'avais supposé une colonne
nickqui n'existe pas — elle s'appellename.test-colonnes.phpcroise chaque colonne citée dans le PHP avec le schéma réel, et il a rougi. Sans lui, la requête aurait levé en production, au premier clic, dans untryqui l'aurait avalée en un message poli et faux. - ⚠ Le banc croise les trois constantes du panel avec celles du robot, et la mutation le vérifie dans les deux sens : changer le plafond d'un côté sans l'autre fait rougir. Deux écritures valent deux vérités — le panel aurait dit « plafond atteint » sur un parc que le robot juge ouvert.
- ⚠ 31 constats, 14 mutations essayées, 14 attrapées. 53 bancs PHP au vert.
- ⚠ Ce qui reste à constater : un vrai clic qui dépose une ligne, et le service qui la ramasse. ⚠⚠ Il posera un vrai robot — c'est le seul constat de ce point qui ne se simule pas.
4.19.46 — 23 août 2026
Les traces d'administration du site reçoivent enfin une date de péremption — 90 jours — et c'est le robot qui les efface.
Créations
::soc::audit::purger— la purge des traces d'administration du site, appelée depuis le scan horaire du robot. Durée et emplacement tranchés par SerVuS le 23/08/2026. ⚠ Horaire et non quotidien parce que c'est là que vivent déjà les purges par ancienneté — événements et sessions.- ⚠ La table appartient au SITE, et c'est le robot qui la purge. Ce n'est pas une bizarrerie : le site n'a aucun mécanisme périodique, quand le robot en tient déjà un, éprouvé, avec son rattrapage. Écrire un second ordonnanceur pour une seule purge aurait coûté plus cher que la purge. Les deux se parlent sans frontière : même fichier de configuration, même compte, même base, même préfixe de table — mesuré.
Évolutions
- La charte annonce désormais 90 jours pour ces traces, là où elle avouait hier que rien ne les purgeait. ✅ L'aveu aura suffi à faire poser la purge — c'était tout son objet : une page publique qui décrit un manque oblige à le combler, là où un point de registre attend.
Avertissements
- ⚠⚠
DELETE … WHERE, JAMAISTRUNCATENIDROP, et un banc le garde. Le plafond de l'ASV compte ses refus dans cette même table, etasv_rate_block()ouvre en grand quand elle est absente — pour ne pas transformer un défaut d'installation en coupure de service. Une purge trop violente désactiverait donc silencieusement la limitation de débit. - ⚠ Aucune interaction possible entre les deux : la fenêtre du plafond est d'une heure, la rétention de 90 jours. 89 jours et 23 heures de marge.
- ⚠ La purge sera INERTE jusqu'en novembre : mesuré le 23/08, la table porte 22 lignes et aucune de plus de seize jours. D'où le comptage avant/après, copié sur
::soc::hist::purger— sans lui, rien ne distinguerait « rien à purger » de « refusé en silence » pendant plus de deux mois. - ⚠⚠ LE BANC DE LA CHARTE A ROUGI SUR DU CODE JUSTE, et il avait raison de le faire. En ajoutant un second
variable JOURSau fichier du robot — 90 pour l'audit, 30 pour l'historique — la résolution du banc prenait la première trouvée : il annonçait « les messages publics : le code dit 90 » sur une purge à 30 jours. Chaque durée est désormais résolue dans son propre namespace, en cherchant la déclaration la plus proche avant leDELETE. - ⚠ C'est la quatrième fois de la journée pour ce motif — le motif plus large que la chose. Il s'est produit deux fois dans le banc du chat, une fois dans celui de la charte ce matin, et une fois dans le même ce soir.
- ⚠ 19 constats à la charte, 52 bancs PHP au vert.
4.19.45 — 23 août 2026
Le champ « Ville » du chat peut se remplir tout seul, si le visiteur le demande — et la position ne quitte jamais sa machine sans avoir été arrondie.
Créations
- La géolocalisation facultative de l'ASV — demandée par SerVuS le 16/08/2026, point 25 du registre. Une case à cocher, jamais cochée par défaut, propose au navigateur de donner la position ; le champ Ville se remplit, et le visiteur peut corriger. C'est la première permission navigateur de ce projet : rien d'autre n'y demandait la position, la caméra ou les notifications.
Web/tests/test-asv-geo.php— 26 constats. Il lit le VRAI fichier de villes, parce que c'est le seul moyen d'éprouver « Lyon rend Lyon ». ⚠ Si le fichier n'a pas été réimporté, ces constats sont sautés, jamais rouges : un clone frais ne doit pas rougir pour une raison qui n'est pas un défaut.- La route
?p=asv-ville, en POST uniquement. ⚠ Apache journalise la ligne de requête entière, paramètres compris : une position enGETfinirait en clair dans les journaux, à côté de l'adresse IP, sans purge écrite.
Évolutions
Config/villes.txtporte trois colonnes de plus — latitude, longitude, population — ajoutées EN FIN. Les insérer avant le rang aurait fait de la troisième colonne une latitude, et « Paris » serait redevenu « París » au WHOIS. Le fichier passe de 2,1 à 5,2 Mo ; le chemin d'entrée du chat n'y perd que ~6 %, les colonnes ajoutées n'étant jamais lues par le contrôle de ville.- L'importeur reprend désormais les noms français depuis le jeu de données par langue de GeoNames (~8 Mo de plus au téléchargement). ⚠ Ce téléchargement est facultatif : s'il échoue, l'import continue avec les noms d'origine. Un réseau capricieux ne doit pas empêcher de refaire une liste de villes.
- Un second garde-fou refuse un import dont les coordonnées seraient absentes ou hors du périmètre. Le premier ne comptait que des lignes : un changement d'ordre des colonnes chez GeoNames aurait produit le bon NOMBRE de villes avec des coordonnées absurdes, et la géolocalisation aurait désigné une commune au hasard.
Bugs corrigés
- ⚠⚠ QUATRE DÉFAUTS TROUVÉS EN ÉPROUVANT, AUCUN EN RELISANT. La première écriture rendait « le lieu le plus proche » — la réponse évidente, et la fausse. Mesurée sur des positions réelles, elle rendait :
| Position | Ce qui sortait |
|---|---|
| Lyon | « Mutualité Préfecture Moncey » (un quartier) |
| Paris | « Paris 04 Hôtel-de-Ville » (un arrondissement) |
| Montréal | « Ville-Marie » (idem) |
| Bruxelles | « Brussels » (le nom anglais) |
| Genève | « Geneva » (idem) |
- Un quartier est toujours plus proche du point que le centre de sa ville. Les quartiers sont désormais écartés à l'import : leur nom reste tapable, mais une position ne peut jamais les désigner. La liste des noms acceptables et la liste des lieux désignables sont deux choses, et c'est le fichier qui porte la différence.
- ⚠⚠ Les arrondissements portent le MÊME code GeoNames que les vraies communes — « Paris 04 Hôtel-de-Ville » est un
PPL, exactement comme « Paris ». Seul le nombre d'habitants les sépare : 27 332 contre 2 138 551. D'où la règle finale : dans un rayon proche, le plus PEUPLÉ l'emporte ; au-delà, le plus proche. - Le nom français existait déjà dans le fichier, mais comme variante — donc jamais choisi par une position. Le premier import avait rencontré ce problème pour la SAISIE en août ; il se reposait ici pour l'AFFICHAGE.
Avertissements
- ⚠ La position est arrondie DEUX FOIS — par le navigateur avant l'envoi, et par le serveur avant l'usage. Deux décimales, soit ~1,1 km : assez pour la bonne commune, trop grossier pour une rue. Le premier arrondi évite que la position précise quitte la machine ; le second garantit qu'elle ne sert à rien de plus fin, même postée à la main. Un contrôle côté navigateur seul ne protège personne.
- ⚠ Rien n'est écrit nulle part : ni base, ni journal, ni session. Les coordonnées traversent la mémoire du processus et disparaissent avec lui.
- ⚠⚠ SIX CONSTATS DU BANC ÉTAIENT CREUX, et la passe de mutation les a désignés un par un. Trois cherchaient un mot que la mutation laissait en place — vider
GEO_EXCLUSn'efface pas « PPLX » du commentaire juste au-dessus. Deux reposaient sur des données de fantaisie qui rendaient le même résultat avec et sans la règle. C'est le troisième banc de la journée à mentir, et le troisième où seule la mutation l'a vu. - ⚠ Le dernier constat non attrapé est documenté comme tel dans le banc : la garde sur les positions impossibles fait double emploi avec le plafond de distance. Elle reste une économie de 140 000 calculs, pas une protection.
- ⚠ 26 constats, 14 mutations essayées, 13 attrapées. 52 bancs PHP au vert.
4.19.44 — 23 août 2026
La charte disait trois choses fausses à ses visiteurs. Elle dit désormais ce que le code fait — et un banc l'y tient.
Bugs corrigés
- ⚠⚠ « Les conversations publiques ne sont pas archivées intégralement » était FAUX. Chaque message écrit dans un salon public du webchat est inséré en base et gardé 30 jours. La charte affirmait l'inverse, et cette archive ne figurait dans aucune ligne de son tableau. SerVuS a tranché pour dire la vérité plutôt que de retirer la fonction : la ligne existe maintenant, avec sa durée et son usage.
- ⚠⚠ L'ASV donné pour conservé « la durée de la connexion » — FAUX aussi. Publiée, la ligne entre dans le réservoir
WHOWASdu serveur : 4 096 entrées relues après le départ, qui n'expirent pas avec le temps mais seulement quand autant d'autres connexions se sont succédé. - ⚠⚠ L'adresse IP ne figurait nulle part dans le tableau des données, alors qu'elle est enregistrée entière à deux endroits. Ce n'était pas un mensonge mais une omission — et une page qui énumère ce qu'on collecte en taisant la donnée la plus identifiante ne vaut pas mieux qu'une page absente. Elle y figure, avec ce qui est vrai : masquée aux autres utilisateurs par le serveur, et une purge qui manque encore côté site, annoncée plutôt que passée sous silence.
- ⚠ Le code affirmait l'inverse, et c'était faux dans l'autre sens : « l'ASV est toujours enregistré et sert la modération », écrit dans
asv.phpet dans la page du chat. Rien ne l'enregistre — la route valide, compose, répond, sort. - Deux durées données pour « limitée » sont désormais chiffrées : 90 jours pour les événements de salon, 30 jours après la fin d'une session.
Évolutions
- La puce sur la publication de l'ASV dit maintenant ce que « visible » veut dire : ces informations peuvent servir à vous rechercher — le réseau sait rendre la liste des personnes ayant publié une ville donnée — et elles restent lisibles après le départ. ⚠ Quelqu'un qui accepte d'être vu n'accepte pas forcément d'être listé.
Créations
Web/tests/test-charte-retention.php— il croise les durées annoncées au visiteur avec celles que le code applique. ⚠ Ce dépôt a déjà établi qu'aucun contrôle automatique n'attrape une affirmation en français ; ce banc ne prétend pas relire la charte. Mais une durée est un nombre, et un nombre se compare — porterJOURS 30à 90 sans toucher à la page la fait désormais rougir. Aucune durée n'est recopiée dans le banc : toutes sont extraites du code à chaque exécution.- ⚠ Son contrôle le plus important n'est pas la comparaison mais l'OMISSION : il énumère les purges du code et signale celles dont la charte ne parle pas. C'est ce qui aurait attrapé le défaut d'origine — lequel n'était pas une valeur fausse, mais une table entière dont personne n'avait parlé.
Avertissements
- ⚠⚠ CE BANC A MENTI TROIS FOIS PENDANT SON ÉCRITURE, et la passe de mutation l'a dit les trois fois. Aucune relecture n'en a vu une seule : 1. VERT sur une valeur fausse — un motif traversant courait de
_sessionsjusqu'au premierINTERVALdu fichier : le banc annonçait « le code dit 90 » sur une purge à 30 jours ; 2. ROUGE sur du code juste — le Tcl échappe ses backticks, le motif en exigeait un nu ; 3. VERT sur une durée changée — il cherchait chaque valeur dans la page entière : « 90 jours », écrit pour les événements, validait la ligne des messages publics. Une valeur trouvée au mauvais endroit valait confirmation. - Les trois sont le même défaut — le motif plus large que la chose — et il s'est produit dans le banc écrit pour attraper des écarts. Une durée se vérifie désormais dans la ligne du tableau qui la concerne, jamais dans la page.
- ⚠ Un point reste ouvert et il est nommé dans la charte : la table d'audit du site garde des adresses IP sans aucune purge, sa migration le dit en toutes lettres. L'annoncer au visiteur oblige à la poser.
- ⚠ 16 constats, 10 mutations essayées, 10 attrapées.
4.19.43 — 23 août 2026
On entre dans le chat SUR PLACE, et ce sont les autres pages qui en sortent : deux onglets au maximum, là où il y en avait trois.
Évolutions
- Le lien « Chat » n'ouvre plus d'onglet. Le modèle tient en une phrase : le chat est la page où l'on est, et tout le reste en sort. Demandé par SerVuS le 23/08/2026, et son compte est l'argument : avec un onglet neuf pour le chat, lire la charte depuis l'accueil laissait trois onglets — accueil, chat, charte. En entrant sur place, il en reste deux, et rien n'est perdu, puisque depuis le chat tout ressort en onglet.
- ⚠ Ce changement n'aurait pas été sûr ce matin. Revenir en arrière depuis le chat détruit la page, donc la conversation — et rien ne l'annonçait. C'est la demande de confirmation, posée quelques heures plus tôt, qui le rend acceptable. Les deux demandes de SerVuS de cette journée ne sont pas indépendantes : la seconde autorise la troisième.
- ⚠⚠ L'onglet du chat SE NOMME LUI-MÊME désormais. Ouvert sur place, il ne reçoit aucun nom du lien qui l'a mené là — et un onglet sans nom ne peut pas être retrouvé par les autres pages, qui en ouvriraient un second. Il se nomme donc à l'ouverture, quelle que soit la façon dont on est arrivé : lien, favori, adresse tapée, ou onglet déjà ouvert avant la mise à jour.
- Le lien « Chat » est désormais la seule exception de la passe de sortie : il mène à la page où l'on est déjà, et le faire sortir ouvrirait un second chat depuis le chat lui-même. ⚠ Les aperçus d'habillage (
?p=chat&logo=…), eux, sortent normalement : la comparaison est exacte, jamais un préfixe.
Suppressions
site_nav_cible()— elle ne rendrait plus que du vide. La règle est maintenant une absence, ce qui la rend plus facile à enfreindre sans y penser : il n'y a plus de fonction à oublier d'appeler, juste un attribut à ne pas ajouter. Un contrôle d'exhaustivité la garde.
Avertissements
- ⚠⚠ Une découpe automatique a emporté DEUX FONCTIONS de trop, parce qu'un ancien bloc de commentaire identique subsistait plus haut dans le fichier et que la recherche a trouvé celui-là. Rattrapé par le banc — fonction introuvable à l'exécution — et non par la relecture. Un repère de découpe doit être unique, et se vérifier comme tel.
- ⚠ Un intitulé de banc avait survécu à la règle qu'il décrit : il disait encore « seul le lien du chat vise un autre onglet » alors que plus aucun lien n'en vise. Il était vert, et il mentait poliment. Resserré.
- ⚠ 40 constats, 22 mutations essayées, 22 attrapées.
4.19.42 — 23 août 2026
Le verrou peut survivre à son onglet quinze secondes : pendant ce temps, revenir au chat ouvrait une page blanche.
Bugs corrigés
- ⚠⚠ Une page VIERGE pouvait s'ouvrir à la place du chat. Le verrou porte une échéance de quinze secondes — c'est ce qui empêche un onglet tué brutalement d'interdire toute reconnexion pour toujours. Mais pendant cette fenêtre, le verrou dit « conversation en cours » alors que l'onglet n'existe plus : la bascule ne retrouvait rien et ouvrait un onglet blanc. Le visiteur cliquait « Chat » et obtenait une page vide, sans rien pour le lui expliquer — pire que le défaut d'origine, qui lui donnait au moins un chat.
- L'onglet vierge est reconnu à son adresse et refermé aussitôt, sans empêcher le lien : il ouvre alors le chat, ce qui est exactement ce qu'il faut faire quand il n'y a plus de conversation à rejoindre.
- ⚠ Ce cas n'a pas été trouvé en relisant, mais en mesurant la page servie. Le verrou et l'onglet sont deux choses, et l'un peut mentir sur l'autre — c'est la même leçon que le reflet
_onlinedu bot, sur un autre sujet.
Avertissements
- ⚠⚠ Un constat du banc était CREUX, pour la seconde fois dans la même séance, et la mutation l'a dit les deux fois. Il cherchait les lignes qui referment l'onglet vierge — or elles restent écrites quand on neutralise la condition qui les commande. Un constat doit exiger la CONDITION, pas ses effets. Avoir appris la leçon trois constats plus haut n'a pas suffi à me la rappeler : seule la passe de mutation l'a fait.
- ⚠ 12 mutations essayées, 12 attrapées, 36 constats.
4.19.41 — 23 août 2026
Revenir au chat n'y touche plus, et le quitter se demande. La version précédente avait introduit une régression : elle est corrigée le jour même.
Bugs corrigés
- ⚠⚠ RÉGRESSION DE LA 4.19.40, trouvée par SerVuS en la mesurant. Le lien « Chat » visait un onglet nommé pour éviter d'en ouvrir deux — mais un lien qui vise un onglet existant le NAVIGUE, donc le recharge, donc coupe la conversation : « ça reste sur l'onglet actif mais ça ferme la connexion et revient au panneau de pseudo ». Le remède était pire que le mal : avant le nom, un second onglet s'ouvrait et le premier restait vivant.
- Le clic est désormais intercepté : quand une conversation tourne, la page bascule sur l'onglet du chat sans le naviguer. Mesuré avant d'être écrit —
window.open('', nom), URL vide, retrouve l'onglet nommé sans y toucher : un marqueur posé en mémoire y survit et l'adresse ne bouge pas. Avec une URL, le contexte est navigué. C'est un caractère, et il porte toute la différence. - ⚠ La bascule est gardée par le verrou : sans conversation en cours, le lien fait son travail ordinaire. Sur un nom qui n'existe pas,
window.openouvrirait une fenêtre vide — pire que tout. - ⚠⚠
beforeunloadenvoyait leQUITavant toute question, ce qui rendait impossible d'en poser une : répondre « rester » aurait gardé la page sur une connexion déjà close par nous-mêmes, fil affiché, mort, et rien pour le dire. Le départ n'est certain qu'une fois la question tranchée : leQUITdescend danspagehide, qui est de surcroît plus fiable sur mobile.
Évolutions
- Quitter une conversation se demande. Fermer ou recharger la page du chat pendant une connexion déclenche l'avertissement du navigateur. Demandé par SerVuS le 23/08/2026. ⚠ Le texte affiché n'est pas le nôtre : depuis 2016 les navigateurs imposent le leur. ⚠ Et la question ne paraît que si le visiteur a interagi avec la page — règle des navigateurs contre les pièges à fermeture. Ce n'est donc pas une garde, c'est un garde-fou.
- Le verrou du chat est décrit à UN seul endroit, en PHP. Il était écrit en dur dans le client, et il faut désormais le lire depuis deux endroits : la page du chat, qui le pose, et toutes les autres, qui doivent savoir s'il y a une conversation en cours avant de laisser un lien la recharger.
Avertissements
- ⚠ Une piste a été écartée : griser le bouton « Chat » tant qu'une conversation tourne. Elle aurait lu la même clé que le verrou — donc aucune protection de plus — et un verrou resté coincé serait devenu un bouton mort et muet, là où le refus actuel dit au moins quoi faire.
- ⚠⚠ Trois constats du banc étaient CREUX, et la passe de mutation les a trouvés — pas la relecture. L'un cherchait le nom d'une fonction, qui reste écrit même quand on retire l'appel ; deux autres interrogeaient une page produite par la fonction même qu'ils vérifiaient, donc ne pouvaient jamais rougir. Le vrai risque était ailleurs : changer la clé côté serveur sans changer la valeur de repli du client ferait lire au site une clé que le chat n'écrit pas — aucune erreur, aucun rouge, juste la panne. C'est ce que le banc mesure maintenant.
- ⚠ 11 mutations essayées, 11 attrapées, dont la régression exacte ci-dessus.
4.19.40 — 23 août 2026
Il ne peut plus s'ouvrir deux chats : le lien vise un onglet nommé, et le navigateur ramène à la conversation en cours au lieu d'en ouvrir une seconde.
Évolutions
- Le lien « Chat » vise un onglet NOMMÉ au lieu d'un onglet anonyme. Un lien vers un nom déjà pris ne crée rien : le navigateur retrouve l'onglet qui le porte et bascule dessus. Depuis n'importe quelle page du site, cliquer « Chat » ramène donc à la conversation en cours. Demandé par SerVuS le 23/08/2026 : « empêcher d'ouvrir plus de 1 page Chat ».
- ⚠ Ce mécanisme ne tient AUCUN état, et c'est ce qui le rend préférable : c'est le navigateur qui sait quels onglets existent. Rien à poser, rien à faire expirer, rien qui puisse rester coincé — et l'onglet fermé en rouvre un neuf, sans délai d'attente.
- ⚠ Le nom est dérivé de l'identité du réseau, jamais écrit en dur. Les noms de fenêtre ne sont pas cloisonnés par site : deux instances ouvertes dans le même navigateur se seraient partagé un nom fixe, et la seconde aurait volé l'onglet de la première — en coupant sa conversation, soit le défaut même que ce mécanisme corrige.
Bugs corrigés
- ⚠ Deux entrées vers le chat contournaient la règle — la carte de la page d'erreur et un lien de la page de contact ouvraient le chat dans l'onglet courant, quand le menu et le pied faisaient l'inverse. Trois écritures pour la même chose, donc trois comportements. Les deux passent désormais par la même fonction.
Avertissements
- ⚠⚠
rel="noopener"est RETIRÉ du lien du chat, et ce n'est pas un oubli. La règle du HTML est explicite : sousnoopener, tout nom d'onglet autre que_top,_selfet_parentest traité comme un onglet anonyme. Le garder annulerait le nom en silence — on croirait le correctif posé alors qu'il n'agirait pas. Le laisser tomber est sans danger sur ce lien et sur aucun autre : il pointe vers notre propre site, même origine, alors que la protection vise une page tierce qui réécriraitwindow.opener. Tous les autres liens ouverts en onglet le gardent. - ⚠ Un banc garde précisément cette régression : rajouter le
noopener« oublié » — ce qu'un relecteur bien intentionné fera un jour — fait rougir. Sans lui, le chat se serait remis à s'ouvrir en double sans qu'une ligne ne le dise. - ⚠ Une piste a été écartée et il faut dire pourquoi : griser le bouton « Chat » tant qu'une conversation tourne. Elle aurait lu la même clé que le verrou — donc aucune protection de plus, seulement affichée plus tôt — et un verrou resté coincé serait devenu un bouton mort et muet, là où le refus actuel dit au moins quoi faire. Elle aurait de surcroît exigé du JavaScript sur toutes les pages du site, qui n'en chargent aucune aujourd'hui.
4.19.39 — 23 août 2026
Le chat ne se laisse plus quitter en place : depuis sa page, tout lien s'ouvre ailleurs et la conversation reste. Et un fichier d'état oublié d'une liste cesse de faire échouer chaque vérification de mise à jour.
Créations
Web/tests/test-chat-onglet.php— rien ne gardait le correctif qui fait sortir le chat dans son propre onglet : aucune vérification du projet ne nommait cet attribut, et il pouvait disparaître d'une ligne sans que rien ne le signale. Le banc rend la page et relit les liens qui en sortent, plutôt que de chercher un mot dans un fichier — trouver le mot prouverait qu'on l'a écrit, jamais qu'il agit. Huit façons de casser le correctif ont été essayées sur lui : il les attrape toutes.
Bugs corrigés
- ⚠⚠ Depuis la page du chat, chaque lien du site coupait la conversation. Ouvrir le chat dans son propre onglet ne protegeait que le premier clic. Une fois dedans, la barre de navigation, le menu replié, les quatre groupes du pied de page, le logo et trois liens du corps restaient des liens ordinaires — plus de vingt en tout. Le visiteur qui cliquait « Charte » depuis le chat perdait exactement ce que le correctif précédent prétendait sauver, et la moitié manquante n'avait jamais été nommée nulle part.
- ⚠ L'attribut n'est pas écrit vingt fois, et c'est le fond du correctif : le pied porte ses liens en dur, la navigation les produit en boucle, la page du chat en ajoute trois. Trois écritures valent trois vérités, et le lien qu'on ajoutera dans six mois n'en connaîtrait aucune. La page du chat relit désormais sa propre sortie en une seule passe, qui ne peut rien oublier — y compris ce qui n'est pas encore écrit.
- ⚠⚠
Runtime/state.default.jsonne figurait dans aucune des deux listes de la mise à jour. Surveillé sans être distribué, il était réclamé au dépôt amont, qui ne l'a pas : échec permanent à chaque vérification, donc une alerte de plus à chaque passage. C'est la panne exacte deConfig/travaux.jsonle 31/07/2026 et deConfig/overop.jsonle 20/08 — la troisième fois pour le même motif. Il porte les chemins absolus d'une machine et n'a jamais rien à faire en amont. - ⚠ Ce dernier défaut ne se voyait pas sur un poste de travail : le fichier n'existe pas dans un clone, c'est l'installateur qui l'écrit. La vérification était donc verte là où l'on travaille et rouge là où le fichier vit.
Modifications
- Les droits de
Runtime/state.default.jsonont été alignés sur ceux de son jumeau sur l'installation en service. L'installateur les pose déjà ainsi depuis le 20/08 ; le fichier en place avait été écrit avant ce correctif et n'en avait jamais bénéficié.
Avertissements
- ⚠ Le point du registre qui portait ce défaut décrivait encore l'état d'avant le 16/08/2026 : il réclamait trois choses déjà écrites depuis, et passait sous silence la seule qui manquait vraiment. Un point du registre se remesure au moment où l'on travaille dessus.
4.19.38 — 21 août 2026
L'installateur pose enfin les fichiers d'Apache, et le compte propriétaire du bot ne naît plus avec une porte ouverte.
Créations
IriX/tests/test-register.tcl— le module qui enrôle le propriétaire du bot n'avait aucune vérification automatique, alors que c'est le seul qui écrive le fichier des comptes : c'est lui qui crée le compte, lui accorde les pleins pouvoirs, et écrit le masque par lequel le bot le reconnaîtra.
Évolutions
- L'écran « Services système » de l'installateur pose désormais les cinq fichiers d'Apache — action 4. Ils vont à trois endroits différents : les hôtes virtuels d'un côté, le fichier des ports d'écoute à la racine d'Apache, la page de maintenance dans un dossier servi.
- ⚠ Ils sont posés sans être activés, et c'est la décision qui commande tout le reste : activer l'hôte virtuel sécurisé avant d'avoir obtenu un certificat empêche Apache de démarrer — c'est le site entier qui tombe, pas seulement cette entrée. L'activation reste un geste de l'exploitant, et l'installateur affiche la marche à suivre plutôt que de la faire à sa place.
- ⚠ Le fichier des ports d'écoute n'appartient pas au projet : il vient du paquet Debian, et le poser l'écrase. L'installateur en conserve donc l'original — et deux protections l'entourent, parce qu'une seule ne suffisait pas : ne jamais reprendre la sauvegarde au second passage, et ne jamais sauvegarder notre propre fichier en le prenant pour l'original. Ce second cas a été trouvé en mesurant l'installation en service.
- Le désinstalleur a été mis en accord : il ne supprime jamais ce fichier — il le restaure, ou dit qu'il ne le peut pas. Son rechargement d'Apache, jusque-là inconditionnel, passe maintenant par une vérification préalable.
Bugs corrigés
- ⚠⚠ Le compte propriétaire d'IriX naissait avec un masque qui n'exigeait aucun identifiant : toute connexion venue du même domaine réseau était reconnue comme le propriétaire du bot. Sur la machine de développement ce domaine était celui du réseau local ; chez quelqu'un d'autre, c'eût été celui de son fournisseur d'accès — des milliers d'abonnés. Le masque exige désormais l'identifiant de celui qui s'enrôle.
- ⚠ Ce défaut ne se voit pas sur une installation en service : le chemin qui pose ce masque ne s'exécute qu'au tout premier enrôlement. Il ne pouvait être trouvé qu'en se demandant ce que reçoit une installation neuve.
Avertissements
- ⚠ Le masque déjà posé sur l'installation en service n'est pas effacé par cette version — un correctif empêche d'en fabriquer un nouveau, il ne nettoie pas l'existant. Il a été retiré à la main le jour même, le bot arrêté le temps du geste : il garde son fichier de comptes en mémoire et le réécrit en s'arrêtant, si bien qu'une modification à chaud aurait été perdue.
- ⚠ La pose des fichiers système n'a pas encore été lancée sur une machine réelle — écrire à ces emplacements demande un mot de passe. Les vérifications automatiques l'exécutent sur une arborescence factice.
4.19.37 — 21 août 2026
Les grades du réseau et ceux du salon ne se ressemblent plus.
Évolutions
- Le chat affiche deux choses qui n'ont rien à voir : le badge « owner » désigne un rôle sur le réseau, tandis que le « ~ » devant un pseudo désigne le propriétaire du salon. On peut être l'un sans être l'autre — et jusqu'ici les deux portaient la même couleur, côte à côte à l'écran.
- Les badges de réseau deviennent des pastilles à contour, là où ceux du salon restent pleins et carrés. La règle se lit sans qu'on ait à l'apprendre : plein = ici, dans ce salon ; contour = ailleurs, sur le réseau.
- ⚠ Les symboles
~,@,+ne changent pas. Ils sont la convention de tous les clients IRC : les modifier pour lever une ambiguïté qui nous est propre ferait payer à l'usage commun une confusion qui nous appartient. - ⚠ Deux repères plutôt qu'un — la forme et le remplissage — parce qu'un seul se perd pour qui distingue mal les nuances de couleur, ou sur un écran mal réglé.
Avertissements
- ⚠ Cette distinction tient à l'ordre des règles de style : la mise en forme du badge de réseau annule le fond posé plus haut, et c'est la dernière écrite qui l'emporte. La déplacer rendrait les deux familles identiques sans provoquer la moindre erreur. Une vérification automatique garde désormais cet ordre — elle a été éprouvée en le cassant exprès.
4.19.36 — 21 août 2026
La liste des pseudos réservés se replie quand elle devient longue.
Évolutions
- Le panneau « Pseudos réservés » du chat affichait tous les comptes du réseau, sans aucune limite. Avec quelques dizaines de pseudos enregistrés, il aurait rempli toute la colonne.
- Au-delà de dix comptes, il ne montre désormais que ceux sur qui on peut vouloir agir tout de suite : un grade, un statut d'opérateur, ou une présence en ligne. Les autres passent derrière un « N autres pseudos réservés » qu'on déplie d'un clic.
- ⚠ En dessous de dix, rien ne change : la liste s'affiche entière. Un dépliant qui cache trois lignes coûte un clic pour rien.
- ⚠ Aucun compte n'est retiré — ils sont repliés, pas écartés. La liste complète continue de servir à savoir si votre propre pseudo est réservé, ce qui décide du bouton « S'identifier » ou « Réserver ce pseudo ».
Bugs corrigés
- ⚠⚠ Le panneau pouvait rester entièrement vide. Le classement des pseudos s'exécutait avant l'écart des entrées incomplètes : il suffisait d'une seule ligne mal formée pour que le classement échoue et que plus rien ne s'affiche. Le code se protégeait déjà de ces lignes, mais trop tard dans l'ordre des opérations. Aucun symptôme ne le montrait tant que la source reste saine ; c'est la campagne d'essai neuve qui l'a trouvé, en lui donnant exprès une liste abîmée.
Créations
- Une campagne d'essai pour ce panneau — il n'en avait aucune. Elle exécute la vraie fonction du fichier envoyé au navigateur plutôt que d'en vérifier une copie, et garde notamment qu'aucun compte ne disparaît du calcul quand il est replié.
Avertissements
- ⚠ Le badge « owner » de ce panneau désigne un rôle sur le réseau, tandis que le « ~ » de la liste des présents désigne le propriétaire du salon. Les deux portent la même couleur et se côtoient à l'écran. Le survol de chaque badge le précise désormais, faute de pouvoir le dire en trois lettres — une distinction visible reste à trancher.
- ⚠ Le badge « oper » indique un état de session, remis à zéro chaque nuit, et non un rôle permanent. Le survol le dit également.
4.19.35 — 21 août 2026
Le grade s'affiche devant le pseudo, dans la conversation du chat.
Évolutions
- Dans le fil du webchat, chaque pseudo est désormais précédé de son grade —
~,&,@,%ou+— dans la couleur qui lui correspond déjà dans la liste des présents. On voit d'un coup d'œil qui parle avec quel rôle, sans aller chercher dans la colonne de droite. - ⚠ Rien n'est recalculé pour cela : la liste des présents était déjà tenue à jour par le serveur (arrivées, départs, changements de mode et de pseudo). Une seconde règle de grade aurait divergé de la première au premier changement de mode.
- Les lignes d'historique, elles, n'auront jamais de grade : l'historique ne conserve que le pseudo. Un grade d'aujourd'hui affiché sur une ligne d'hier serait pire que pas de grade du tout.
Bugs corrigés
- ⚠⚠ Les grades du chat étaient écrits en dur dans le code du navigateur au lieu d'être lus dans ce que le serveur annonce à la connexion. Cela ne se voyait pas — le serveur annonce exactement ce qui était écrit — mais le jour où un grade change ou s'ajoute, le chat aurait affiché les autres de travers, sans rien signaler. Il lit désormais l'annonce du serveur, comme le fait déjà le client de référence du projet.
Créations
- Une campagne d'essai pour ces grades. Elle extrait la vraie fonction du fichier envoyé au navigateur et l'exécute, plutôt que d'en vérifier une copie réécrite : une copie ne prouverait que la copie. Elle éprouve un barème différent de celui d'Overtchat — c'est le seul cas où l'ancien défaut se voyait.
Erreurs
- ⚠ Deux vérifications de cette campagne annonçaient « ok » sans rien vérifier. Elles comparaient une valeur absente à une valeur absente, ce que le passage d'un langage à l'autre rendait indistinguable. Repérées seulement parce qu'un avertissement s'affichait à côté. Corrigées, et une garde refuse désormais toute comparaison dont une valeur manque.
- ⚠ Une vérification du site qui contrôle que chaque classe de style existe bien laissait passer une classe sur deux dans un cas précis. Elle restait verte même en supprimant la règle correspondante. Corrigée, puis éprouvée en cassant le style exprès.
4.19.34 — 20 août 2026
L'assistant d'installation prend les couleurs du site.
Évolutions
- Le panel du terminal affichait huit couleurs génériques, sans rapport avec le reste du projet. Il reprend désormais la palette exacte du panel web — le turquoise du réseau, les mêmes verts, ambres et rouges, les mêmes gris. Les deux écrans se reconnaissent au premier coup d'œil.
- ⚠ Un repli est prévu : sur un terminal qui n'annonce pas les couleurs étendues — console de secours, connexion distante sommaire, tâche automatique —, l'ancien jeu de huit couleurs reprend la main. Sans lui, l'affichage se remplirait de codes illisibles.
Créations
- Une campagne qui croise les deux sources. Les couleurs sont forcément recopiées — un script ne peut pas lire une feuille de style au démarrage — et une copie finit toujours par diverger. La campagne refuse qu'elle se périme : elle rougit dès qu'une teinte change d'un côté sans l'autre.
4.19.33 — 20 août 2026
Deux fichiers de configuration naissaient lisibles par tout le monde.
Bugs corrigés
- Deux fichiers d'état étaient créés sans protection, alors que les cinq autres du même dossier sont réservés à leur propriétaire. L'un d'eux ne contient rien de sensible aujourd'hui — mais il portera demain le propriétaire, le réseau et l'administrateur de chaque robot prêté. La protection se pose avant que le contenu la mérite.
- Un logiciel absent était annoncé comme une panne. Quand un composant optionnel n'est pas installé sur la machine, le programme disait « pose refusée » — ce qui envoie chercher un problème d'autorisations qui n'existe pas. Il l'explique désormais, sans erreur, et ne crée pas le dossier correspondant : un dossier vide ferait croire à une installation.
Avertissements
- ⚠ Ce contrôle a été fait à la demande de l'exploitant, après un large parcours des options. Les données étaient saines : tous les fichiers valides, rien de perdu, rien de corrompu. Ce sont trois défauts de forme qui ont été trouvés, pas une avarie.
4.19.32 — 20 août 2026
Critique
La surveillance installée ce matin n'aurait pas eu le droit de relancer le bot.
Bugs corrigés
- L'installateur pose enfin les autorisations système. Trois fichiers que le programme savait pourtant désinstaller n'étaient jamais installés : les autorisations qui permettent de redémarrer les services, leur équivalent pour le panel web, et la rotation des journaux du serveur.
- ⚠ Le premier est le plus grave, et sa propre documentation le disait déjà : sans lui, la surveillance livrée le matin même constate une panne sans pouvoir y remédier. Sur une installation neuve, elle voyait le bot mourir et n'avait pas le droit de le relancer — sans que rien ne le signale.
- La rotation manquante laissait par ailleurs les journaux du serveur grossir sans limite, ce qui est l'une des pistes d'une panne connue.
Évolutions
- Le fichier d'autorisations est contrôlé AVANT d'être installé, jamais après. C'est la seule pose de ce chantier qui puisse casser autre chose que le projet : un fichier fautif à cet endroit peut rendre l'élévation de privilèges inutilisable sur toute la machine. S'il ne passe pas son propre contrôle, il n'est pas posé — et les autres le sont quand même.
- La liste porte des dossiers, pas des fichiers : ajouter un fichier dans l'un d'eux est couvert sans que personne ait à s'en souvenir.
Avertissements
- ⚠ Les fichiers de configuration du serveur web restent à part, et volontairement : leurs cinq fichiers ont trois destinations différentes, et les activer demande un rechargement qui peut couper le site. Cela reste ouvert au registre.
4.19.31 — 20 août 2026
Reposer les contrôles d'intégrité devient un geste que l'on décide.
Créations
- Depuis la version précédente, la vérification d'intégrité refuse quand la référence manque, au lieu d'enregistrer ce qu'elle trouve. C'était le correctif — mais il laissait une question sans réponse, que le déplacement du fichier a rendue concrète en une minute : plus aucune référence n'existait, et rien ne permettait de repartir.
- Une entrée du menu permet donc de poser les références, délibérément. Elle annonce franchement ce qu'elle fait : elle adopte les fichiers tels qu'ils sont. À n'utiliser que sur une installation qu'on sait saine — sur une machine soupçonnée d'altération, elle graverait l'altération.
- ⚠ Ce n'est volontairement pas automatique : reposer tout seul serait exactement le défaut que la version précédente vient de corriger.
Modifications
- La liste des fichiers contrôlés n'existe plus qu'à un seul endroit, partagé par la vérification et par la pose. Elle était écrite en double, et c'est ainsi qu'un fichier se retrouvait contrôlé pour rien depuis des semaines : enregistré d'un côté, absent de la liste de l'autre.
4.19.30 — 20 août 2026
Critique
La mémoire de l'installation vivait dans un dossier que la machine efface à chaque redémarrage.
Bugs corrigés
- Le fichier qui se souvient de l'installation a été déplacé. Il vivait dans
/tmp, un emplacement vidé à chaque redémarrage de la machine et nettoyé automatiquement au bout de dix jours. Il était absent au moment de la correction. Or il ne contient pas seulement les empreintes de contrôle des fichiers de configuration : il porte aussi la trace que l'installation a eu lieu, la liste des dossiers à créer, la langue, le nom du projet et la liste des modules à déployer. Sa disparition faisait donc croire au programme qu'il n'avait jamais été installé. - La vérification d'intégrité validait ce qu'elle aurait dû dénoncer. Quand la référence manquait, elle enregistrait les fichiers tels qu'ils étaient, quels qu'ils soient, et les déclarait sains au passage suivant. Elle refuse désormais, et le dit. Une détection qui ne détecte pas est pire que pas de détection : elle rassure.
- Le résultat de la vérification n'arrivait jamais nulle part. Elle annonçait « tout va bien » même si les cinq fichiers étaient altérés. Le résultat remonte maintenant, et distingue trois cas : altéré, sans référence, conforme.
- Un sixième fichier était contrôlé pour rien. Son empreinte était soigneusement enregistrée à chaque changement, et jamais comparée à quoi que ce soit. Elle l'est.
Créations
- Une campagne de vérification pour ce mécanisme, qui n'en avait aucune. Elle exécute réellement le code et a été éprouvée en le cassant sur quatre points.
Avertissements
- ⚠ Les trois défauts de logique ont été corrigés en même temps que le déplacement, et il le fallait : un fichier qui ne disparaît plus les aurait figés au lieu de les révéler. Le mécanisme aurait paru sain simplement parce qu'il ne se réinitialisait plus.
4.19.29 — 20 août 2026
Une installation neuve laissait quatorze services au repos, sans que rien ne le dise.
Créations
- L'assistant d'installation pose désormais les services système. Il ne le faisait pas : le programme livrait quatorze définitions de services, et aucune n'était installée. Sur cette machine tout fonctionnait, parce qu'elles y avaient été posées à la main au fil des mois — mais sur une installation neuve, les sauvegardes ne tournaient pas, les opérateurs du panel ne s'appliquaient pas, les robots ne se posaient pas, et la surveillance du bot ne surveillait rien.
- Une sixième étape apparaît dans l'assistant, et elle se repasse autant de fois qu'on veut — après avoir ajouté un composant, ou posé un mot de passe qui manquait.
Évolutions
- On installe tout, on ne met en marche que ce qui peut marcher. Mettre en marche un service dont il manque un prérequis produirait un service en panne dès le premier jour, et un service en panne est un service qu'on apprend à ignorer. Chaque définition déclare elle-même ce qui lui est nécessaire ; l'assistant le lit, et dit ce qu'il laisse au repos et pourquoi.
- Les chemins et le compte d'exécution sont adaptés à l'installation réelle.
Avertissements
- ⚠ Ce qui reste : la pose n'a pas encore été constatée sur une machine neuve. Elle est vérifiée par une campagne qui l'exécute pour de vrai sur un faux système de fichiers — mais un essai n'est pas une installation.
- ⚠ Quatre autres familles de fichiers système restent dans le même cas : le programme sait les retirer, il ne sait toujours pas les poser.
4.19.28 — 20 août 2026
Le bot ne pouvait pas prévenir d'une panne qui l'empêchait justement de prévenir.
Évolutions
- L'envoi des courriels d'alerte reposait sur un seul mécanisme interne, et ce mécanisme s'arrête net quand le bot sature — c'est-à-dire exactement pendant la panne qu'il devrait annoncer. Un second chemin a été ajouté, déclenché par l'horloge et non par ce qui sature : toutes les heures, il expédie ce qui serait resté en attente.
- Quand ce second chemin rattrape réellement quelque chose, il l'écrit dans les journaux. Un filet de sécurité silencieux ne se vérifie pas, et un mécanisme qu'on ne peut pas vérifier finit par ne plus rien garantir.
Avertissements
- ⚠ Ce n'est qu'un filet. Le chemin fiable reste la surveillance extérieure installée la veille, qui vit hors du bot et ne partage aucune de ses pannes. Un bot assez atteint pour perdre ses minuteries peut l'être assez pour perdre son horloge : la fenêtre est réduite, pas fermée.
4.19.27 — 20 août 2026
Critique
La surveillance n'alertait qu'une seule fois, puis se taisait pour toujours.
Bugs corrigés
- Une panne qui revient ne prévenait plus personne. La veille extérieure sur le bot laisse une alerte en base et envoie un courriel. Mais l'alerte restait ouverte une fois la panne finie, et une alerte déjà ouverte ne redéclenche pas d'envoi : la deuxième panne, la troisième et toutes les suivantes se passaient en silence, jusqu'à ce qu'un administrateur pense à la ranger à la main. Les pannes des 18 et 19 août étaient précisément des pannes répétées.
- La surveillance signale désormais qu'elle est elle-même empêchée. Quand elle constate une panne sans pouvoir l'enregistrer ni l'annoncer — base injoignable —, elle le dit au système au lieu de se déclarer en bon état.
Évolutions
- Quand la cause d'une alerte a disparu, la surveillance referme l'alerte elle-même, en signant son geste. L'historique du panel distingue donc ce qu'une machine a refermé de ce qu'un administrateur a lu et acquitté.
Créations
- Une campagne de vérification pour ce mécanisme, éprouvée en cassant volontairement le code sur six points pour s'assurer qu'elle les voit.
Avertissements
- ⚠ Ce défaut n'a été trouvé ni par une relecture ni par une campagne : trois campagnes étaient au vert. Il est sorti d'un essai réel où le service a été coupé deux fois au lieu d'une.
4.19.26 — 19 août 2026
La page d'accueil annonçait quatre serveurs compatibles. Il y en a six.
Erreurs
- Le chiffre était resté en arrière. Deux serveurs ont été ajoutés depuis qu'il a été écrit, et personne ne l'a repris — alors que la page « Serveurs compatibles », à un clic de là, en annonçait bien six en toutes lettres. Deux pages du même site se contredisaient, et c'est la plus lue qui avait tort.
- Le tableau des services était recopié ligne par ligne, alors que la page des commandes dérive le sien de la même source depuis toujours. C'est exactement le défaut qu'un outil avait été écrit pour éliminer sur la page voisine — il subsistait ici.
Modifications
- Tout vient désormais de sa source : le nombre de serveurs, celui des services, le tableau des pseudo-clients, et les deux titres qui les écrivent en toutes lettres. Rien à remettre à jour au prochain ajout.
- ⚠ Une seule chose reste écrite : le verbe de l'exemple de commande, qui illustre sans rien décrire. Le nom du service, lui, vient de la source — pour qu'un service renommé ne laisse pas derrière lui un exemple qui ment.
4.19.25 — 19 août 2026
Critique
La panne qui privait le réseau de tous ses services est CONSTATÉE fermée : trois heures et quart de marche, sans un seul incident.
Évolutions
- Le défaut le plus grave du projet est refermé, et constaté — pas seulement corrigé. Quarante relevés toutes les cinq minutes, de 11 h 41 à 15 h 01 : aucun refus de minuteur, et une mémoire qui n'a pas varié d'un kilo-octet pendant les deux heures quarante-cinq dernières.
- Le chiffre qui tranche : la même mesure, sur la version malade, montrait cent soixante mégaoctets gagnés en trente et une minutes. Ici : moins d'un mégaoctet en trois heures et quart.
- ⚠ La durée comptait plus que la platitude. La fuite était exponentielle, donc invisible au début : une courbe plate pendant vingt minutes n'aurait rien prouvé. Les deux pannes de la veille se déclaraient à soixante-dix-sept et cent deux minutes — la veille a tenu cent quatre-vingt-quinze.
Avertissements
- ⚠⚠ Ce qui rendait ces pannes MUETTES n'est pas corrigé, et fait désormais l'objet d'un point à part. L'alerte du bot emprunte le même mécanisme que celui qui tombe en panne : elle se tait précisément quand il faudrait qu'elle parle. La surveillance extérieure qui répond à ce défaut est écrite et éprouvée, mais pas encore mise en service — c'est un geste d'exploitation.
- ⚠ Le plafond de taille des journaux, lui, n'agira qu'au prochain redémarrage du bot.
4.19.24 — 19 août 2026
Trois écarts du site, trouvés par un contrôle de coordination d'ensemble.
Erreurs
- ⚠⚠ Le point d'état public publiait plus que ce qu'il annonçait. Il servait aussi l'état réel des services, sans le délai d'attente qui existe justement pour ne pas signaler au visiteur une perturbation de moins d'une minute — une reconnexion, un redémarrage de service, un hoquet. Le mécanisme était contourné par la porte même qu'il devait protéger, et l'instant de départ de chaque perturbation était donné avec. Aucun consommateur ne s'en servait : la page d'accueil, seule appelante, ne lit que l'état publiable. Ces deux informations restent indispensables au cache, qui les relit d'un cycle à l'autre — elles vivent donc dans le fichier, plus dans la réponse.
- Un membre qui oubliait son mot de passe ne pouvait pas le retrouver. La page de réinitialisation existe depuis longtemps, mais aucune page du site n'y menait : ni le menu, ni le pied de page, ni l'inscription. Son seul lien vivait derrière le bouton « Administration », là où un membre ne va jamais — alors que le formulaire d'inscription annonce que l'adresse courriel « sert à retrouver l'accès en cas d'oubli ». Le lien est désormais là où la promesse est faite.
- Un commentaire du routeur en contredisait un autre, quinze lignes plus loin, sur la place d'une page dans le menu.
Créations
- Un contrôle sur le contenu de la réponse publique, et non plus seulement sur l'existence de la route. Le contrôle existant le disait lui-même : il gardait la position, jamais ce qui sortait. ⚠ Cassé exprès de deux façons avant d'être retenu.
4.19.23 — 19 août 2026
Le bandeau d'état du panel se renommait tout seul quelques secondes après l'ouverture de chaque page.
Erreurs
- La première pastille du bandeau affichait « IRCd », puis se changeait d'elle-même en « Overtchat-Hybrid » au premier rafraîchissement — quinze secondes plus tard, ou immédiatement en revenant sur l'onglet. Le bandeau s'élargissait au passage. C'était visible sur toutes les pages d'administration.
- La cause : la même table de noms courts était écrite deux fois dans le même fichier — une fois pour l'affichage initial, une fois pour le rafraîchissement — et les deux avaient divergé. Le nom du serveur en service manquait dans la seconde.
- ⚠ Aucun contrôle automatique ne lisait cette seconde table. C'est par là que le défaut est passé, et il y serait resté.
Modifications
- Il n'y a plus qu'une table, et le rafraîchissement la reçoit au lieu de la redire. C'est le procédé déjà employé ailleurs sur le site pour les libellés d'état.
Créations
- Un contrôle qui n'accepte pas deux listes. ⚠ Il ne compare pas les deux pour vérifier qu'elles concordent — il exige qu'il n'y en ait qu'une. Comparer les aurait laissées exister, et se serait contenté de crier le jour où elles divergent à nouveau.
- ⚠ Cassé exprès de deux façons avant d'être retenu, en vérifiant à chaque fois que la modification avait bien été appliquée.
4.19.22 — 19 août 2026
Un défaut de sécurité ouvert au registre : la vérification d'intégrité peut être remise à zéro par un simple redémarrage.
Erreurs
- La référence à laquelle les fichiers de configuration sont comparés vit dans un répertoire temporaire. Elle disparaît à chaque redémarrage de la machine — et elle avait déjà disparu au moment de la mesure.
- ⚠⚠ Ce qui se passe alors est pire que la perte : au contrôle suivant, l'outil adopte l'état en place quel qu'il soit, et le déclare comme référence. Une éventuelle modification devient donc la nouvelle normale, et le contrôle d'après l'annonce saine. Un contrôle qui ne détecte plus rien est pire qu'aucun contrôle : il rassure.
- Trois défauts voisins mesurés au passage : une empreinte est enregistrée sans que rien ne la relise jamais ; l'outil de vérification ne se vérifie pas lui-même ; et aucun contrôle automatique ne couvre ce mécanisme.
Avertissements
- ⚠ Rien n'est corrigé : le point est ouvert, avec ce qu'il faut pour le fermer et les pièges à éviter en le faisant. Le remède demande de choisir un emplacement durable, et surtout de ne pas récupérer l'ancienne référence — rien ne dirait qu'elle décrit un état sain.
4.19.21 — 19 août 2026
Le document de sécurité interne a été remesuré et corrigé : il décrivait par endroits un état qui n'était plus le sien.
Erreurs
- Quatorze écarts confirmés par la mesure, dans un document de sécurité qui n'est lu par aucun contrôle automatique et dérivait donc librement depuis qu'il a été écrit.
- Des listes et des comptes recopiés à la main. Ils étaient justes le jour où on les a écrits, et faux la semaine suivante. Ils ne sont plus recopiés : chaque endroit indique désormais la commande qui donne la valeur du jour.
- Un serveur retiré fin juillet y était encore décrit comme en service, à trois endroits, alors que le document savait ailleurs qu'il était arrêté.
- Une protection y était annoncée pour des composants qu'elle ne couvre pas. Le texte laissait entendre plus large que la réalité ; il dit maintenant exactement ce qui est couvert, et ce qui ne l'est pas.
- ⚠ Deux reproches y étaient devenus injustes. Le code avait été corrigé le 16 août et le document était resté au constat d'avant. Un reproche périmé coûte autant qu'un défaut caché : il fait chercher là où le travail est déjà fait, et il use la confiance accordée aux autres avertissements.
- Un chapitre entier décrivait une méthode de distribution abandonnée, et se contredisait lui-même quinze lignes plus bas.
Avertissements
- ⚠ Ce document a grossi de cent cinquante lignes au lieu de maigrir : à chaque correction, ce qui était affirmé à tort est conservé et daté, plutôt qu'effacé. C'est le choix du projet — on doit pouvoir relire ce qu'on a cru.
- ⚠ Il reste hors du site : il n'est servi par aucune page et n'entre pas dans l'archive distribuée. C'est ce qui permet d'y écrire franchement.
4.19.20 — 19 août 2026
La table des alertes ne regroupait pas les alertes répétées, contrairement à ce que son code affirmait depuis le premier jour.
Erreurs
- ⚠⚠ Chaque alerte répétée créait une ligne de plus, au lieu de faire monter un compteur. La règle d'unicité de la table portait sur la date d'acquittement, qui reste vide tant que l'alerte est ouverte — et deux valeurs vides ne sont jamais considérées comme identiques par la base. La règle ne s'appliquait donc jamais dans le seul cas où elle devait s'appliquer.
- Constaté par deux alertes identiques créées à vingt secondes d'écart, toutes deux ouvertes, chacune annonçant une seule occurrence.
- ⚠⚠ Et ce n'était pas qu'un compteur faux. Le mécanisme qui signale une erreur technique le fait dès la première fois, en s'appuyant explicitement sur ce regroupement pour ne pas devenir du bruit. Deux de ses déclencheurs mettent le message d'erreur dans l'identifiant de l'alerte : une base momentanément indisponible, avec des vérifications qui repassent toutes les cinq secondes, remplissait la table.
- Quatre commentaires du code décrivaient ce regroupement comme acquis. Ils décrivaient une intention, jamais un comportement. Les quatre sont rectifiés : ils disent maintenant ce qui se passait vraiment, et depuis quand.
Modifications
- La règle d'unicité porte désormais sur une colonne calculée par la base, qui vaut l'identifiant de la cause tant que l'alerte est ouverte et rien une fois qu'elle est rangée. Une seule alerte ouverte par cause, le compteur monte ; et l'historique des alertes rangées reste sans limite.
- Rien d'autre n'a changé. La date d'acquittement garde son sens : les requêtes du panel, du bot et des outils fonctionnent sans une ligne de changement. C'est la raison d'avoir écarté les autres solutions envisagées.
- Les installations existantes sont reprises : les doublons déjà présents sont repliés — comptes additionnés, première et dernière occurrence conservées, courriel déjà envoyé mémorisé — et non supprimés. L'historique déjà rangé n'est pas touché.
Créations
- Un contrôle automatique qui lève deux fois la même alerte et exige une seule ligne à deux occurrences, vérifie qu'un défaut qui revient lève bien une nouvelle alerte, et rejoue la reprise sur une base volontairement encombrée de doublons. ⚠ Il dérive le schéma et les requêtes de reprise du code lui-même : un contrôle qui porterait sa propre copie éprouverait sa copie.
- ⚠ Quatre garanties cassées exprès avant de le retenir. Deux des essais n'avaient en fait rien modifié — le contrôle semblait aveugle alors que c'était l'essai qui n'avait rien changé. Une mise à l'épreuve se vérifie avant d'être crue.
Avertissements
- ⚠ Le seuil « signaler au troisième échec » n'était pas touché : il compte ailleurs, en mémoire. Vérifié avant d'y toucher.
4.19.19 — 19 août 2026
Les journaux d'IriX ont enfin un plafond de taille — la troisième et dernière piste ouverte par la panne du 18 août.
Modifications
- Un journal qui dépasse 16 Mo est archivé sur-le-champ, sans attendre l'échéance du calendrier. Jusqu'ici la rotation ne connaissait que le jour : celle du 18 août ayant eu lieu à 9 h 43, la panne de 11 h 26 a pu écrire 1,5 Go qui n'ont été archivés que le lendemain.
- Le chiffre vient de mesures, pas d'une estimation : les quatorze archives conservées donnent une journée saine entre 39 Ko et 456 Ko, et le journal s'écrit à environ 1 Mo par jour. Les deux journées de panne pèsent 1,12 et 1,56 Go. 16 Mo se pose au large entre les deux — trente-cinq fois le pire jour normal, un centième d'une journée de panne.
- Le plafond s'applique même quand l'archivage est réglé sur « désactivé » : ce réglage veut dire « je ne veux pas d'archive quotidienne », jamais « laissez le disque se remplir ».
- Le journal de console est désormais couvert lui aussi. Il ne l'était nulle part — ni ici, ni dans la rotation du système. Il est vide aujourd'hui, mais il ne le resterait pas si l'on relançait le bot sans passer par le système.
- La veille extérieure signale à son tour un journal qui enfle au-delà de quatre fois ce plafond : à ce stade, ce n'est plus un journal gros, c'est la rotation qui ne tourne plus.
Erreurs
- ⚠⚠ Un écrêtage ne doit PAS compter comme l'archive de la période, et il allait le faire. La rotation note la date de son dernier passage ; si un écrêtage l'avait notée, l'archive du jour aurait été considérée comme faite et sautée. En réglage mensuel, un écrêtage le 3 mars aurait annulé l'archive de tout le mois. Corrigé avant d'être livré : l'écrêtage archive, mais ne déclare rien.
- Deux rotations dans la même seconde s'écrasaient l'une l'autre. Le nom de l'archive descend à la seconde, et la copie écrase sans rien dire : la première archive était perdue en silence, sans erreur, tout au vert. Le cas était improbable avec une seule rotation par jour ; le plafond le rendait atteignable. La seconde est maintenant avancée jusqu'à trouver un nom libre. ⚠ Pas un suffixe : la purge ne reconnaît qu'une forme de nom précise, et une archive qu'elle ne reconnaît pas ne serait jamais supprimée — on aurait échangé une perte de données contre un disque qui se remplit.
Créations
- Un banc pour la rotation, qui n'en avait aucun depuis sa mise en service en juillet — alors qu'elle tronque des fichiers et en supprime. Il éprouve les six garanties sur un bac à sable, jamais sur les vrais journaux.
- ⚠ Les quatre garanties ont été cassées exprès pour vérifier qu'il les voit. L'une des mutations n'avait en fait pas été appliquée : le banc semblait aveugle alors que c'était l'essai qui n'avait rien changé. Une mutation se vérifie avant d'être crue.
Avertissements
- ⚠ Le module est chargé au démarrage du bot : le plafond n'agira qu'au prochain redémarrage.
4.19.18 — 19 août 2026
Une veille extérieure surveille désormais IriX — écrite, éprouvée, mais pas encore mise en service.
Créations
- Une sonde qui vit HORS du bot. Toute la surveillance d'IriX était portée par ses propres minuteurs : quand ils manquent, elle se tait précisément au moment où l'on en a besoin. C'est ce qui a rendu les pannes du 18 août muettes. Cette sonde est déclenchée par le système, pas par le bot.
- Elle ne regarde que ce qu'un bot malade ne peut pas simuler : la présence du refus de minuteur dans le journal, la mémoire du processus, et un journal qui a cessé d'écrire. Les quatre indicateurs qui ont menti pendant les pannes — l'état du service, l'état du lien en base, la taille du journal et le port en écoute — sont écartés, et le fichier dit pourquoi.
- Elle sait relancer le bot quand c'est grave, au plus une fois par heure : sans ce frein, une panne qu'une relance ne guérit pas produirait une boucle de redémarrages, et le limiteur d'envoi étoufferait les alertes en silence.
- Les deux unités système correspondantes sont fournies, avec leur procédure d'installation.
Avertissements
- ⚠ Rien n'est activé. La sonde et ses unités sont dans le dépôt, éprouvées sur les quatre cas qu'elles doivent reconnaître, mais leur mise en service est un geste d'exploitation qui reste à faire.
- ⚠ Sans le droit de relancer le service, la sonde alerte quand même : elle constate et écrit, elle ne peut simplement pas guérir.
Erreurs
- Le regroupement des alertes en base ne fonctionne pas. Deux alertes de même cause créent deux lignes au lieu d'incrémenter un compteur : la clé d'unicité contient une colonne vide, et une valeur vide n'est jamais égale à une autre. Le nombre d'occurrences affiché vaut donc toujours un. ⚠ Le seuil « alerte au troisième échec » n'est pas touché : il compte ailleurs. Constaté en éprouvant la sonde, noté pour être traité à part.
4.19.17 — 19 août 2026
Critique
La panne qui a privé le réseau de tous ses services le 18 août avait une tout autre cause que celle qu'on lui prêtait — et elle allait se reproduire le jour même.
Erreurs
- ⚠⚠ La panne s'est produite TROIS fois, pas une. Les archives de journal en gardent trois épisodes distincts : un avant le 18 au matin, celui qui a été constaté de 11 h 26 à 16 h 40, et un troisième de 17 h 58 à 21 h 28 — que personne n'avait vu. Le troisième a commencé une heure et quart après le redémarrage censé être le remède, et il ne s'est arrêté que parce que la machine s'est éteinte.
- Le gel de l'environnement, longtemps accusé, n'y était pour rien. Le bot numérote ses minuteurs avec un compteur qui ne repart jamais de zéro, et ce numéro ne peut pas dépasser sept chiffres. Au dix-millionième, plus aucun minuteur ne peut être posé. Un gel retarde les minuteurs ; il n'en fabrique pas. Il fallait en avoir créé dix millions.
- Et c'est bien ce qui arrivait, en une heure et demie. Le balayage des identifications posait deux minuteurs à chaque tour au lieu d'un, et n'en retirait aucun : sa population doublait toutes les soixante secondes.
- Deux fautes se cachaient l'une l'autre : 1. la procédure croyait retirer le minuteur précédent, mais elle le cherchait dans la mauvaise liste — le bot en tient deux, une par unité de temps. Le retrait échouait sans bruit ; 2. le cycle replanifiait à la fin, alors que son propre corps l'avait déjà fait sur chacun de ses quatre chemins.
- ⚠⚠ Le commentaire du code affirmait le contraire, et il datait de la veille. Il disait « le double réarmement est sans danger, la procédure tue le minuteur précédent ». C'était faux ligne par ligne. Il a été remplacé par le récit de ce qui s'est réellement passé.
- La même faute de liste existait à dix endroits : aucune des procédures d'arrêt du bot n'arrêtait quoi que ce soit. Les dix sont corrigées.
Créations
- Un contrôle automatique garde les deux règles, et il les dérive du code au lieu de réciter une liste : tout minuteur doit être retiré de la liste où il a été posé, et un cycle ne doit replanifier qu'une fois.
- ⚠ Il a d'abord été faux, et c'est son propre garde-fou qui l'a dit. Sa première version ne lisait aucun cycle — elle affirmait pourtant que tout allait bien. Sans le contrôle « des cycles ont bien été lus », elle aurait accompagné la panne suivante en silence.
- ⚠ Les deux règles ont été cassées exprès avant d'être retenues.
Avertissements
- ⚠ Ce qui a rendu la panne muette n'est pas corrigé par cette version : l'alerte par courriel passe elle-même par un minuteur, donc elle se tait précisément quand les minuteurs manquent. Une surveillance extérieure au bot reste à poser.
4.19.16 — 19 août 2026
Le titre de l'écran de connexion à l'administration est plus grand, et il s'adapte désormais à toutes les largeurs d'écran sans laisser de trou.
Modifications
- Le titre « Administration » grossit d'environ moitié : de 26 à 38 pixels sur un écran d'ordinateur, et de 21 à 28 pixels sur le plus étroit des téléphones. Le sous-titre suit dans les mêmes proportions.
- Sa taille suit maintenant la largeur de l'écran en continu, au lieu de sauter d'un coup en dessous d'une largeur donnée. Il n'y a donc plus de format d'écran à prévoir : les futurs sont couverts d'avance.
- Le sous-titre voit son interlettrage légèrement resserré, ce qui lui rend la place que le grossissement lui prend.
Créations
- Un contrôle automatique garde désormais ce réglage. Il ne cherche pas la nouvelle écriture — il dérive l'ordre des règles de mise en forme et vérifie que la dernière qui s'applique au titre est bien celle qui suit l'écran en continu. Remettre un ancien palier par-dessus le ferait rougir, là où un contrôle plus naïf serait resté vert.
- Il garde aussi le repli destiné aux personnes qui demandent moins d'animations : ce repli doit ouvrir le titre en plus d'arrêter son mouvement, faute de quoi le titre resterait invisible pour elles.
- ⚠ Les deux contrôles ont été cassés exprès avant d'être retenus, pour vérifier qu'ils savent rougir. Un contrôle qui ne peut pas échouer ne garde rien.
Erreurs
- L'ancienne mise en forme laissait une catégorie entière de téléphones de côté. Elle ne changeait de taille qu'en dessous de 400 pixels de large ; les grands téléphones récents, de 401 à 430 pixels, recevaient donc la taille prévue pour un écran d'ordinateur, dans une carte bien plus étroite. Personne ne l'avait vu parce que rien ne débordait — c'était simplement mal proportionné.
- ⚠ Une note interne affirmait que les écrans de 390 pixels étaient touchés eux aussi. Mesure faite dans un vrai navigateur : c'est faux, ils recevaient bien la petite taille. La note a été corrigée. Le trou existait, mais pas là où on le croyait.
Avertissements
- ⚠ Le palier de mise en forme qui existait auparavant a été retiré, pas seulement laissé de côté : écrit après les nouvelles règles, il les aurait annulées sur les écrans étroits. Le remettre « par sécurité » rouvrirait exactement le défaut que cette version ferme.
4.19.15 — 17 août 2026
Critique
La panne silencieuse de la veille s'est reproduite le soir même — et elle est maintenant corrigée à la racine.
Erreurs
- ⚠⚠ Le réseau a de nouveau perdu tous ses services, deux heures après la première fois. Même enchaînement : le lien tombe, le bot se reconnecte en s'inventant un identifiant de serveur, le serveur refuse. Personne n'est prévenu. La panne a été trouvée en ouvrant la séance, pas par une alerte.
- La cause était plus grave que ce qu'on en savait. Le bot n'ignorait pas seulement l'identifiant inscrit dans sa configuration : il l'effaçait et écrivait le sien à la place. Voilà pourquoi rétablir la bonne valeur ne tenait pas — elle était réécrite à la tentative suivante.
- Trois défauts distincts se tenaient par la main, et les trois sont corrigés : 1. l'identifiant de la configuration est désormais transmis lors d'une reconnexion, au lieu d'être recalculé ; 2. tout échec de connexion libère les verrous posés pendant la tentative. Sans cela le bot se croyait connecté sur un lien mort et ne réessayait plus jamais — seul un redémarrage en sortait ; 3. un refus du serveur lève une alerte. L'ancienne ne couvrait que le cas où la connexion ne s'ouvrait pas ; ici elle s'ouvrait très bien, et c'est le serveur qui disait non.
- Le journal disait aussi trop peu. Il annonçait un identifiant attribué sans dire lequel il remplaçait. La ligne avait l'air d'une opération normale.
Erreurs — le site
- ⚠⚠ L'identification IRC depuis le site ne fonctionnait plus depuis un mois. Le visiteur qui demandait à s'identifier voyait « Demande transmise » indéfiniment, quoi que fasse le robot derrière. La page interrogeait une adresse qui lui répondait une page d'erreur au lieu de la réponse attendue, et le navigateur avalait l'échec sans rien dire.
- Le même défaut privait de sa redirection celui dont l'accès à un salon venait de s'ouvrir. L'accès s'ouvrait bel et bien ; le visiteur n'était simplement jamais conduit à son salon. Cette adresse-là n'avait jamais fonctionné depuis le jour où elle a été écrite.
- La cause est la même pour les deux : les deux adresses étaient déclarées trop bas dans le fichier d'entrée du site, après le contrôle qui répond « page inconnue » et s'arrête. Elles n'étaient donc jamais atteintes. Aucune erreur, aucune trace : une page bien formée répondait à la place.
- Réparé et vérifié en ligne. ⚠ Un contrôle automatique garde désormais cette règle. Il cherche dans le fichier toutes les adresses de ce genre et exige que chacune soit atteignable — y compris celles que les pages réclament. Le panel avait déjà ce contrôle ; le site ne l'avait pas.
Créations
- Un banc de vérification dédié à la reconnexion du lien de services. Il ne récite aucune liste : il cherche dans le code tous les endroits qui ouvrent une connexion et vérifie qu'aucun n'oublie l'identifiant. C'est exactement l'oubli qui a causé la panne, et une liste écrite à la main l'aurait laissé passer une fois de plus.
Évolutions
- Le banc a été mis à l'épreuve en cassant volontairement, une par une, les neuf choses qu'il prétend garder. Il en a d'abord manqué deux : il se contentait de retrouver des mots dans le code au lieu de l'exécuter. Corrigé, puis re-éprouvé. ⚠ Une limite est écrite noir sur blanc dans le banc : il ne remplace pas un essai contre une vraie base de données, et il le dit.
- Un essai a été mené sur le réseau réel : le serveur a été arrêté une fois, et le lien de services est remonté seul en douze secondes, avec le bon identifiant et sans redémarrer le bot. ⚠ Cet essai ne prouve pourtant pas tout, et c'est écrit au registre : le serveur s'est fermé d'une manière qui n'emprunte pas le chemin réparé. La panne réelle, elle, en emprunte un autre. Le point reste ouvert tant que ce chemin-là n'aura pas été vu à l'œuvre.
4.19.14 — 17 août 2026
Le nom du réseau se frappe à la machine sur toutes les pages — et une panne silencieuse a été trouvée en production.
Évolutions
- L'écran de connexion à l'administration porte un titre. « Administration » en grand, « Réservé aux administrateurs » en dessous — au-dessus du logo, car c'est ce qu'on doit lire en arrivant, avant même de savoir de quel réseau il s'agit. Le titre se dévoile de gauche à droite, la seconde ligne après la première. ⚠ Ce n'est pas la frappe à la machine de l'accueil, et c'est volontaire : une phrase de cette longueur aurait exigé une police à largeur fixe et minuscule pour tenir dans la carte.
- L'en-tête écrit le nom lettre à lettre, sur chaque page. La frappe y est plus rapide qu'à l'accueil et sans attente préalable : c'est ce qu'on lit en premier en arrivant, et une seconde d'animation à chaque clic deviendrait une gêne. ⚠ La place du nom est réservée dès le départ — sans cela, le menu sauterait vers la droite pendant toute l'animation.
Erreurs
- ⚠⚠ Le réseau est resté sans aucun service pendant une heure quarante-cinq, sans qu'une seule alerte parte. Après une coupure du lien, le bot s'est attribué un identifiant de serveur différent de celui que sa configuration impose ; le serveur a refusé, poliment et correctement, et le bot a réessayé indéfiniment avec le même mauvais identifiant. Rien ne cassait, rien ne rougissait : les cinq services étaient simplement absents pendant que tout le reste paraissait normal.
- Corriger la valeur n'a pas suffi : un verrou interne était resté posé et empêchait toute nouvelle tentative — le même défaut que celui corrigé le jour même sur le cycle des sujets. Il a fallu redémarrer le bot.
- Réparé le soir même, réseau complet rétabli et vérifié. ⚠ Le défaut, lui, reste ouvert : n'importe quelle coupure future y ramène. C'est le point le plus urgent du registre.
4.19.13 — 17 août 2026
Le plan du chantier des éditions décrivait un état vieux de six jours.
Erreurs
- Une fonction donnée comme point de départ d'une étape n'existe nulle part dans le projet. C'est l'écart le plus grave, et d'une autre nature que les autres : une date périmée se corrige en mesurant, une fonction fantôme fait bâtir sur du vide. L'étape concernée — filtrer les adresses et les secrets d'un rapport avant de l'envoyer à quelqu'un — paraissait donc largement livrée, alors que sa pièce maîtresse reste entièrement à écrire.
- Le document se contredisait lui-même : une question déclarée tranchée à un endroit était donnée comme ouverte à un autre, et bloquait une étape.
- Une liste de blocages entièrement périmée est conservée, barrée, plutôt que supprimée : chacune de ses lignes était vraie le 11 août, aucune ne l'est plus, et elle montre à quoi ressemble une condition qu'on n'a pas remesurée.
Évolutions
- ⚠ La leçon vaut plus que les corrections : un plan qui se trompe sur son propre état ne se suit pas, il s'invente. Le registre des chantiers s'applique déjà la règle de remesurer chaque point au moment où l'on y travaille ; ce document ne se l'appliquait pas, et six jours ont suffi.
4.19.12 — 17 août 2026
Le logo grandit, et le nom du réseau s'écrit à la machine.
Évolutions
- ⚠ Le nom passe en écriture à chasse fixe, et ce n'est pas décoratif : la frappe avance d'un cran par caractère, et un cran vaut la largeur d'un caractère. Dans une écriture proportionnelle, les crans se décalent des lettres et la dernière apparaît trop tôt ou reste coupée. La chasse fixe fait coïncider le cran et la lettre — et une machine à écrire l'est, de toute façon.
- Le nombre de lettres est calculé sur le nom du réseau, jamais écrit en dur : il se déréglerait au premier changement de nom.
Avertissements
- ⚠ Qui a réglé son appareil sur « moins d'animations » voit le nom entier et sans curseur — un trait qui clignote sans fin est exactement ce que ce réglage demande d'éviter.
- ⚠ Sur écran étroit, le nom réduit sa taille plutôt que de déborder.
4.19.11 — 17 août 2026
Plus aucun cycle du bot ne peut s'arrêter sans le dire.
Bugs corrigés
- Le cycle des sujets de salon ne pouvait pas être réparé sans redémarrer le bot. Il pose un verrou le temps de son passage ; une erreur en cours de route laissait ce verrou en place, et plus rien ne pouvait le relancer — ni lui-même, ni son planificateur. Verrou et replanification sont désormais rendus dans tous les cas.
- Cinq autres cycles protégés : la révocation des identifications abandonnées, le rattrapage des sujets, la purge du journal de trafic, l'évaluation des modèles de modération, et la publication automatique.
- ⚠ La publication automatique demandait un traitement différent, et le correctif habituel y aurait créé un défaut visible : elle ne doit volontairement PAS se replanifier sur un salon quitté ou dont la publication a été éteinte. Seul le travail est protégé, pas les conditions d'arrêt. Une exception : si le réglage lui-même devient illisible, on réessaie au tour suivant plutôt que de s'arrêter pour toujours.
4.19.10 — 17 août 2026
Une protection contre les suppressions ne pouvait pas s'exécuter.
Bugs corrigés
- La protection est rétablie, et sur deux fronts : la table doit exister, et une liste vide est désormais traitée comme un aveu d'ignorance plutôt que comme un fait. Un réseau sans aucun opérateur déclaré n'existe pas en pratique ; une base qui vient de tomber, elle, répond exactement cela. Le doute va du côté qui ne supprime rien.
- Trois vérifications « la table existe-t-elle ? » faisaient l'inverse de leur but. Écrites pour rendre un mécanisme silencieux quand une table manque, elles ne s'activaient jamais — et le traitement qui suivait, lui, déclenchait une alerte critique toutes les trente secondes. Sur une installation neuve, ces gardes produisaient précisément le bruit qu'elles devaient éviter.
Avertissements
- ⚠ Six cycles de moindre portée restent à traiter (nouveau point 36), dont un qui deviendrait irréparable sans redémarrer le bot. Ils sont recensés un par un, avec ce que chacun coûterait, et le remède est désormais éprouvé quatre fois.
- ⚠ Ces correctifs ne prennent effet qu'au prochain démarrage du bot.
4.19.9 — 17 août 2026
Le logo du site s'écrit à l'ouverture de la page d'accueil.
Créations
- Le logo animé de la page d'accueil, dessiné en SVG et animé en CSS — aucun script, aucune image à télécharger.
Évolutions
- ⚠ Il n'y a pas d'écran de chargement, et c'est un choix. L'idée initiale était un voile avec une barre allant de 0 à 100 % avant d'ouvrir la page. Une telle barre n'aurait rien mesuré : la page d'accueil s'affiche en quelques centaines de millisecondes, il n'y a rien à attendre. Elle aurait fabriqué le délai qu'elle prétend couvrir, et affiché une progression inventée — ce que ce projet refuse partout ailleurs. Le titre, les boutons et le bandeau d'état restent donc présents et cliquables dès la première image ; l'animation les accompagne au lieu de les masquer.
Avertissements
- ⚠ Qui a réglé son appareil sur « moins d'animations » voit le logo achevé, immédiatement : on retire le mouvement, jamais le contenu.
- ⚠ Sur écran étroit, le dessin passe au-dessus du nom — côte à côte, il lui volait la largeur et le nom du réseau se coupait.
4.19.8 — 17 août 2026
Trois points du registre fermés, et les contrôles qui les gardent en ont trouvé trois de plus.
Bugs corrigés
- Les encarts du panel se rendaient sans mise en forme — dont le bandeau d'alerte critique, affiché sur toutes les pages. Le panel et le site public emploient deux vocabulaires de style entièrement distincts, et le panel écrivait celui du site : l'avertissement le plus grave s'affichait comme un paragraphe ordinaire. Vingt et une écritures reprises dans huit fichiers.
- Une grille de trois colonnes n'en avait aucune. La règle correspondante n'existait pas dans la feuille du panel ; le bloc se rendait sur une seule colonne. Trouvé par le contrôle neuf, pas par l'œil.
- Un encart d'avertissement s'affichait sans sa couleur : il demandait une variante que la feuille ne connaît pas. Un frein d'utilisation avait donc l'apparence d'une information banale.
- Un lien du tableau de bord ne menait nulle part. Il annonçait une mise à jour disponible et rechargeait la page, sans un mot. Le panel désignait déjà la bonne destination ailleurs — il n'y avait qu'une divergence à supprimer.
- Un prêt de robot suspendu n'arrivait jamais à son terme. Le balayage horaire ne regardait que les prêts actifs : un prêt suspendu passé son échéance restait indéfiniment ni actif ni fini, sans une ligne au journal. Et lorsque la suspension venait d'une décision d'opérateur, le robot restait dans le salon.
L'alerte, éprouvée pour de vrai
- Une panne a été provoquée en production, avec accord, pour vérifier que l'alerte fonctionne de bout en bout — et elle fonctionne : trois échecs d'archivage à trente secondes d'intervalle, l'alerte au troisième exactement, la ligne au journal, l'enregistrement, le bandeau du panel, et le courriel reçu quatre minutes plus tard. Tout a été remis en place ensuite, et vérifié : aucun journal ni archive perdu.
- Une alarme qui ne pouvait pas sonner a été retirée. Elle surveillait une lecture qui ne signale jamais d'erreur : la reprise n'avait donc aucune chance de s'exécuter. L'avertissement existe déjà, plus près de la cause. ⚠ Du code qui prétend protéger est pire que pas de code : il fait croire le cas couvert.
- Un contrôle neuf empêche ce cas de revenir, et il s'éprouve lui-même sur des exemples fabriqués — un détecteur qui ne détecte rien a exactement l'allure d'un projet sain.
Avertissements
- ⚠⚠ La file d'installation des robots n'a aucun producteur (nouveau point 35). Le service qui pose les robots est en marche depuis le 9 août et tourne à vide : rien, dans tout le projet, ne sait déposer une demande. La moitié qui consomme avait été livrée et déclarée close sans que la moitié qui produit soit branchée. C'est une décision avant d'être du code — le parc doit-il croître tout seul ?
- ⚠ Le prêt suspendu reste à constater sur un cas réel arrivé à échéance.
- ⚠ Un piège du langage, rencontré trois fois dans la même séance : la balise de fermeture de PHP écrite dans un commentaire ferme quand même le fichier. Chaque fois en citant un exemple de code dans une explication.
4.19.7 — 17 août 2026
L'adresse des visiteurs du chat était fausse là où les services la lisent.
Bugs corrigés
- Le champ d'adresse annoncé aux services porte l'adresse réelle. L'adresse relayée était posée dans les champs textuels du client, jamais dans la structure réseau figée à la connexion — et c'est cette structure que lisait la fonction d'encodage. Elle lit désormais d'abord l'adresse que le serveur tient déjà pour vraie partout ailleurs : masques de bannissement, autorisations d'accès, plafond de connexions par adresse.
- Un bloc de commentaire de
nickprotect.havait perdu son préfixe, hérité d'une édition de fin de journée.
Modifications
Servers/overtchat-hybrid/src/s_serv.c— la fonction d'encodage de l'adresse.Servers/overtchat-hybrid/tests/test-forward.py— la campagne monte désormais un lien de services et lit ce qui y passe (7 constats → 12).
Avertissements
- ⚠ Les lignes déjà enregistrées restent fausses : c'est un historique, il n'est pas réécrit. Elles se lisent avec la date du correctif en tête.
- ⚠⚠ Une campagne d'essai du serveur était rouge, et son échec n'atteignait personne (point 34 du registre, ouvert et fermé le même jour). Trouvée en vérifiant l'absence de régression : 13 contrôles en échec sur 22, et déjà avant ce correctif — mesuré en recompilant la version précédente. Elle n'était simplement jamais lancée. Le réseau en service n'a jamais été concerné.
4.19.6 — 16 août 2026
Le registre des chantiers disait l'inverse de ce qu'il annonce.
Erreurs
- Son préambule était entièrement périmé. Il annonçait un point comme ouvert alors que le même fichier le déclare fermé, une section vide alors qu'elle ne l'était pas, et qu'un chantier ne devait pas s'ouvrir alors qu'il l'est sur décision. Le journal des revues successives a été retiré au profit d'un tri qui se dérive des titres.
- Deux points ouverts portaient un titre faux — l'un annonçait « rien n'est écrit » alors que la moitié du travail a été livrée le jour même, l'autre décrivait l'état du matin. Tous deux sont maintenant lisibles pour ce qu'ils sont.
- Quatre points fermés sont physiquement rangés sous « défauts ouverts ». Le document applique sa propre règle de rangement de façon inégale : c'est signalé en tête, avec la consigne de se fier au marqueur du titre et non à la section.
Avertissements
- Le tri complet des 33 points figure désormais en tête : 22 constatés fermés, un corrigé sans preuve, six réalisables par du code, cinq qui demandent un geste ou une décision de l'exploitant. ⚠ Il est daté et doit se remesurer, pas se recopier.
4.19.5 — 16 août 2026
La protection des pseudonymes ne pouvait pas s'armer ailleurs qu'ici.
Bugs corrigés
- Le fichier des pseudonymes protégés était déposé avec des droits que le serveur refuse. Il contient des empreintes de mots de passe, et le serveur refuse — délibérément — de charger un fichier lisible au-delà de son propriétaire. L'installateur le posait pourtant en lecture de groupe : la protection ne s'armait donc jamais, et le seul signe était une ligne d'erreur au démarrage. Invisible ici, où le fichier avait été corrigé à la main ; invisible ailleurs au début, le fichier livré étant vide.
- Huit endroits documentaient un format d'empreinte incomplet — dont le fichier livré et ses deux exemples, c'est-à-dire le gabarit même qu'on recopie. Une entrée écrite à la main d'après cette documentation est acceptée, mais avec une seule passe de calcul au lieu de cent mille : une protection cent mille fois moins coûteuse à casser, qui a toutes les apparences du bon fonctionnement. Un seul fichier du dépôt avait raison depuis le début.
Créations
- Trois contrôles ajoutés à
Bootstrap/tests/test-conf-modele.sh, tous dérivés : le serveur contrôle-t-il les droits, l'installateur pose-t-il le bon mode, et aucun document n'enseigne-t-il le format court. Éprouvés en les cassant.
Erreurs
- Le registre affirmait qu'un mot de passe qui ne correspond pas laisse le robot basculer « sans une ligne au journal ». Le serveur journalise bien le refus — c'est le robot qui reste muet. Regarder au mauvais endroit revenait à ne pas regarder.
- Un document du projet écrivait qu'un service écoutant sur
0.0.0.0l'est « IPv6 comprise ». C'est faux : cette écriture ne couvre que l'IPv4.
Avertissements
- Appliquer la protection d'un seul côté ne casse rien sur le moment, et c'est ce qui la rend dangereuse : la vérification n'a lieu qu'à la prise du pseudonyme, jamais sur une session déjà ouverte. Le défaut dormirait jusqu'au redémarrage suivant, c'est-à-dire le lendemain matin.
- La pose des mots de passe elle-même reste un geste humain. En revanche tout ce qui suit — écrire, recharger, reconnecter, vérifier — ne l'est pas, et la vérification est justement l'étape qu'on oublie.
4.19.4 — 16 août 2026
Le chat d'une installation neuve ne refusera plus ses propres visiteurs.
Modifications
Servers/overtchat-hybrid/conf/overtchat.conf.example— le réglage, et à côté ce qui le rend sûr : le port du chat n'écoute que la machine elle-même. Ce n'est pas la liste qui protège, c'est cela.
Créations
Bootstrap/tests/test-conf-modele.sh— six contrôles sur le modèle livré. Le principal ne demande pas « telle ligne est-elle là » mais « un serveur qui accepte des connexions de navigateur doit dire à qui il fait confiance » : l'exigence vaut aussi pour les réglages à venir. Éprouvé en le cassant deux fois.
Erreurs
- Le registre des chantiers affirmait ce défaut pour ce serveur-ci, où il était faux depuis douze jours, et le présentait comme un arbitrage à rendre. Il n'y avait rien à arbitrer : la correction manquait ailleurs. Le registre est repris, mesure par mesure.
Avertissements
- Le mensonge venait d'une colonne de la base. Pour un visiteur du chat, le serveur enregistre la bonne adresse dans un champ et
127.0.0.1dans un autre. Qui mesure depuis la base conclut que tout le monde partage une adresse. 26 lignes portent ce désaccord ; le point est ouvert au registre. - Le chat échappe entièrement au limiteur de rafales, et cela ne se corrige pas au même endroit : ce limiteur agit avant que l'adresse du visiteur soit connue. C'est permissif, non restrictif.
- Aucun refus pour cause de plafond n'a jamais eu lieu sur ce serveur, cinq journaux vérifiés. Le chat n'a pas encore connu deux visiteurs distincts en même temps.
4.19.3 — 16 août 2026
Le panel dit quand le contrôle de ville est éteint.
Modifications
Web/pages/chat.php— l'encart, et le pourquoi de son coût : lire l'état demande d'indexer les 123 906 communes, mesuré à 145 ms. Un contrôle « allégé » écrit à côté aurait créé une seconde vérité sur la même règle, qui aurait divergé au premier changement de seuil.Web/inc/asv.php— la promesse fausse est remplacée par ce qui est vrai, et par les quatre raisons mesurées de ne pas brancher le journal.Web/tests/test-asv.php— deux contrôles nouveaux, dérivés : une page du panneau doit lire cet état, et aucune page publique ne doit le révéler. Les deux ont été éprouvés en les cassant volontairement.
Avertissements
Deux défauts ont été constatés en chemin et inscrits au registre des chantiers, sans être corrigés ici :
- Dix-huit encarts du panneau se rendent sans mise en forme, dont le bandeau d'alerte critique présent sur toutes ses pages : ils emploient une classe qui n'existe que dans la feuille de style du site public. Le contrôle censé l'attraper examine les deux feuilles réunies, et ne peut donc pas le voir.
- Le lien vers la mise à jour, au tableau de bord, ne mène nulle part : la page se recharge sans rien dire.
4.19.2 — 16 août 2026
Le contrôle de ville du chat fonctionne enfin ailleurs qu'ici.
Modifications
Web/inc/distrib.php— la liste des villes part désormais dans l'archive du site. Elle est entrée dans la liste qui sert à la fois à composer l'archive et à décider de la refabriquer : un fichier ajouté à la seule archive aurait été emporté mais jamais rafraîchi, et les installations suivantes auraient reçu une liste figée sans que rien ne le signale.Web/public/index.php— un commentaire affirmait que la ville publiée vient toujours de la liste ; la ligne qu'il annonçait disait le contraire lorsque la liste manque. Il dit maintenant ce que le code fait.
Bugs corrigés
- Le contrôle de ville était éteint en silence sur toute installation tierce. Sans la liste, la vérification ne se fait pas — c'est un choix assumé, une liste absente étant une panne d'exploitation et non une fraude — et le texte saisi part au
realname. Ce mode dégradé, prévu comme l'exception, était l'état normal partout ailleurs qu'ici. - Le banc qui devait l'attraper était aveugle.
Web/tests/test-distrib.phpporte un contrôle nommé « tout ce que le site lit hors deWeb/part dans l'archive », et il était vert. Il ne reconnaissait qu'une façon d'écrire un chemin, quand le module du chat en emploie une autre. Les deux sont désormais reconnues, et le contrôle a été éprouvé en le cassant volontairement : il rougit maintenant, là où il restait vert.
Avertissements
- L'archive du site passe de 1,22 à 1,79 Mio (+46 %). Aucune limite de taille ni de délai n'est approchée.
- Réinstaller remplace la liste. Un exploitant qui aurait reconstitué la sienne avec d'autres pays la verrait écrasée au prochain passage par le menu d'installation du site. La protéger empêcherait aussi toute mise à jour de la liste : le point est ouvert au registre des chantiers, il demande un arbitrage.
4.19.1 — 16 août 2026
Le chat s'ouvre dans son propre onglet, et refuse d'en ouvrir deux.
Modifications
Web/inc/site.php— le menu et le pied passent par la même fonction pour ce lien : deux écritures, une seule vérité.Web/public/assets/chat.js— le verrou d'unicité.
Avertissements
- ⚠⚠ Le verrou expire, et c'est ce qui compte. Un onglet fermé brutalement ne prévient personne. Un drapeau posé une fois survivrait à qui l'a posé et lui interdirait de revenir définitivement : on pose donc un signe de vie, renouvelé toutes les 5 secondes et périmé au bout de 15.
- ⚠ Ce n'est pas une garde, c'est un confort. Le stockage du navigateur est cloisonné par profil : deux navigateurs, une fenêtre privée ou deux machines ne se voient pas. Cela évite le double-clic et l'onglet oublié, pas un abus voulu. Le seul plafond réel est celui du serveur.
- ⚠ Un lien, et non une fenêtre ouverte par script : le moment où le chat sait quoi ouvrir est postérieur à la vérification d'âge, donc hors du geste de l'utilisateur — où tout navigateur bloque une ouverture de fenêtre.
4.19.0 — 16 août 2026
Le chat vous avertit quand on vous cite.
Créations
Web/tests/test-chat-mention.php— 34 constats, qui exécutent la fonction avecnode. La réécrire en PHP éprouverait la copie, pas ce qui tourne chez le visiteur.
Modifications
Web/public/assets/chat.js—meCite()détecte aux frontières de mot et sans la casse. Les deux comptent : IRC ne distingue pas Paul de paul, et sans frontières un pseudo court sonnerait sur « salut », « alors », « canal ». On apprendrait en une soirée à ignorer le signal.Web/public/assets/site.css— la classe de citation est la seule ligne du fil qui porte un fond : les huit autres types ne jouent que sur la couleur du texte, et les cinq teintes disponibles y sont déjà toutes prises. L'animation respecteprefers-reduced-motion.
Bugs corrigés
- ⚠ La comparaison « ce message vient-il de moi » se faisait avec la casse. Si le serveur renvoie votre pseudo dans une casse différente de celle de la connexion, votre propre message s'affichait comme venant de quelqu'un d'autre — et, avec la nouveauté du jour, vous vous seriez averti vous-même.
Avertissements
- ⚠⚠ Aucune expression régulière n'est construite avec le pseudonyme, et c'est le point de conception principal. Un pseudo IRC peut contenir des crochets, une barre verticale, des accolades, un accent circonflexe, une barre oblique inverse ou un accent grave — tous spéciaux dans une expression régulière. Un motif mal échappé ne lèverait aucune erreur : il cesserait simplement de mordre, et la personne ne serait plus jamais avertie sans que rien ne le signale.
- ⚠ Trois cas ne déclenchent volontairement aucune alerte : vos propres messages, les services (leurs réponses citent systématiquement le destinataire — sonner à chaque identification reviendrait à ne plus sonner), et le rejeu de l'historique à la reconnexion.
- ⚠ Le banc n'éprouve pas où la détection est branchée : cela demande un navigateur et deux clients. Le point 27 de
Markdown/CHANTIERS.mdreste ouvert jusqu'à ce constat.
4.18 8 versions · 16 août 2026 7 additions 3 improvements 15 changes 12 bugs fixed 2 mistakes 8 warnings
4.18.7 — 16 août 2026
Le seul contrôle d'intégrité du projet refusait des archives saines pendant cinq minutes après chaque déploiement.
Bugs corrigés
Web/inc/distrib.php— le cache du manifeste compare désormais les dates des fichiers servis, et non le seul âge du cache. L'économie reste entière : une cinquantaine defilemtimeau lieu d'autant dehash_file.
Modifications
Web/tests/test-distrib.php— un constat qui vérifie que chaque empreinte publiée correspond au fichier réellement servi. Il ne mesure pas le cache mais sa conséquence : un cache réparé autrement le satisfera tout autant. Éprouvé par mutation — l'ancien comportement rétabli, il rougit et désigne nommémentsite.
Erreurs
- ⚠ Le docblock du manifeste renvoyait à
safe_encrypt verifyau présent, fonction supprimée le 29/07/2026. C'est vraisemblablement cette phrase qui a engendré celle de la page de téléchargement, laquelle promet encore que « chaque composant est vérifié avant d'être posé » — ce qui reste faux. Le docblock dit maintenant ce que le manifeste garantit réellement, et renvoie au point 26 du registre. - ⚠ La ligne « Version courante » de ce document était restée à 4.18.5 pour un dépôt en 4.18.6, le jour même où elle se décrit comme ayant déjà menti.
4.18.6 — 16 août 2026
Six outils étaient installés chez vous sans pouvoir être mis à jour.
Bugs corrigés
Tools/bancs.sh,desinstaller.sh,edition.sh,faire-archive-hybrid.sh,villes-importer.shettests/test-desinstaller.shsont désormais servis.Robots/overop/overop.tcletoverop.conf.exempleaussi — sans quoi le prêt de robot était ininstallable hors de cette machine.
Modifications
Web/inc/distrib.php— les six entrées manquantes. ⚠ La liste reste explicite : distribuer un script demeure une décision fichier par fichier, et un script déposé dansTools/ne devient pas public du seul fait d'y être.Web/tests/test-distrib.php— deux constats croisés. Le premier dérive du disque la liste des scripts emportés par l'archive ; le second dérive du script d'installation les sources qu'il va télécharger. Chacun exige que la cible figure à l'inventaire réel. Éprouvé par mutation — quatre mutations, quatre détectées, dont les deux qui comptent : un script neuf déposé dansTools/, et une source neuve déclarée dans l'installateur.- ⚠ Ces constats interrogent l'inventaire réel, pas le texte du module. La première version cherchait les chemins dans le source et accusait 27 fichiers parfaitement servis : les modules d'IriX y sont distribués par un motif générique, donc leur chemin n'y figure nulle part en toutes lettres.
Avertissements
- ⚠ Un fichier ne peut pas être à la fois installé et introuvable. Pour écarter un script de la distribution, il faut aussi l'écarter de l'archive : les deux décisions vont ensemble, et c'est ce que le nouveau constat impose.
4.18.5 — 16 août 2026
Le chat du site était inaccessible à tout le monde depuis la 4.18.0. Un nom de champ, et un seul.
Bugs corrigés
- Le webchat refusait l'entrée à tout visiteur (
Web/public/assets/chat.js). Constaté en service sur le site public, puis reconstaté corrigé.
Modifications
Web/public/assets/chat.js— le jeton part sous le nom que le serveur lit.Web/tests/test-asv.php— trois constats qui croisent les deux côtés : le nom attendu est dérivé decsrf_check()dansWeb/inc/auth.php, les noms employés sont relevés danschat.js, et ils doivent coïncider. Aucun des deux n'est écrit en dur dans le banc.
Avertissements
- ⚠ Cinq constats de ce banc étaient au vert pendant toute la panne. Ils vérifient que la route contient les bons appels — pas qu'elle réponde. Un banc qui lit du texte source ne remplace pas une page ouverte dans un navigateur.
- ⚠ Le compte de « douze points » de la 4.18.4 ci-dessous est faux : il y en a treize. Le branchement de
IriX/cmds/irix-chanq.tcl(file-illisible), livré par le même commit, ne figure dans aucune des énumérations.
4.18.4 — 16 août 2026
L'alerte passe de 4 à 12 points branchés — et deux endroits où elle ne DOIT pas crier.
Modifications
IriX/tests/test-alerte.tcl— 39 vérifications, dont un constat qui compte les modules appelants : un module d'alerte avec un seul point d'appel ne ferme pas un trou « à la jointure », il en crée un. 3 mutations, 3 attrapées.
Avertissements
⚠⚠ CINQUIÈME OCCURRENCE DU MÊME PIÈGE DE BANC dans la séance. Le constat « l'alerte n'est pas branchée sur set_error » s'écrivait set_error.*?alerte:: — et cherchait donc jusqu'au prochain alerte:: n'importe où dans les 12 000 lignes suivantes. Il rougissait sur du code juste. Le motif est désormais borné au corps de la procédure.
Un motif qui ne dit pas où il s'arrête ne mesure pas ce qu'on croit.
⚠ La contre-épreuve des mutations a d'abord échoué sur un bac à sable incomplet — Tools/ n'y était pas copié, et le banc y cherche alerte-courriel.php. Même piège que test-doublons le 14/08.
⚠ Rien n'est constaté pour ces huit branchements. Aucun n'a encore levé d'alerte réelle : ils sont écrits, éprouvés au banc, et jamais vus agir. Le point 24 reste ouvert.
4.18.3 — 16 août 2026
Une tentative de lien qui n'aboutit pas se voit enfin — et l'alerte critique est CONSTATÉE de bout en bout.
Bugs corrigés
traiter_actionsnote désormais ce qu'il attend ;observerconclut au cycle suivant — c'est le seul endroit qui puisse le savoir.- ⚠ On ne conclut rien avant un cycle complet : juger trop tôt ferait déclarer en échec un lien qui monte encore. Même prudence que la péremption de l'observation.
- ⚠ Une réussite remet le compteur à zéro : sinon trois échecs espacés de réussites finiraient par barrer un pair qui marche, et
action_verdictrefuserait « 3 échecs de suite » sur un lien sain. - ⚠
alerte::echecet nonerreur: une tentative isolée peut rater pour une raison passagère. C'est sa répétition qui dit « ce lien ne montera jamais ».
Avertissements
⚠ VERSION a été montée sans que ce journal soit écrit, et c'est test-update.php qui l'a attrapé — quatre constats rouges. Le défaut est déjà nommé dans l'historique du dépôt (« le commit précédent l'annonçait, encore ») ; il vient d'être refait. Monter VERSION et écrire sa section sont un seul geste, pas deux.
⚠ Deux pièges mesurés pour la suite du branchement, et ils sont dans le point 24 : les catch autour d'un db_exec ont une branche morte, et alerte::echec est inerte sur ce qui tourne une fois par heure.
4.18.2 — 16 août 2026
L'alerte devient VISIBLE : bandeau, page, acquittement, courriel.
Créations
Web/inc/alerte.php— lecture, compte par niveau, acquittement, pastille de menu, bandeau.Web/pages/alertes.php— les ouvertes, les rangées, et ce que la page ne peut pas dire.Tools/alerte-courriel.php— l'envoi, sur le montage deTools/alerte-pseudo.php.::soc::alerte::poster_courrielset son cycle, dansirix-alerte.tcl.
Modifications
Web/inc/layout.php— le bandeau sur toutes les pages, l'entrée de menu avec sa pastille.Web/public/admin.php— l'actionalerte_acquitter, au niveau op.Web/inc/routes.php,Web/tests/test-routes.php— la route et son talon.IriX/tests/test-alerte.tcl— 34 vérifications.
Évolutions
⚠⚠ LE COURRIEL NE PART PAS DE lever, et c'est la décision qui compte. exec php est synchrone et ouvre une connexion SMTP ; lever peut être appelée depuis n'importe quelle boucle. Un envoi placé là bloquerait la boucle d'événements d'Eggdrop le temps du SMTP — le bot cesserait de répondre au réseau pour annoncer qu'il a un problème. Un balayage borné (3 par passage, toutes les 5 min) poste ce qui attend, comme nickexpire.
⚠ mail_at est posé par le SCRIPT, pas par le bot après coup : entre l'envoi et la pose, un plantage ferait renvoyer le même courriel à chaque passage — et une alerte qui se répète toutes les minutes dans une boîte est le plus sûr moyen d'apprendre à filtrer ce réseau.
⚠ Seules les crit font un bandeau, et seules les crit partent par courriel. Les warn vivent sur leur page, signalées par la pastille du menu. Un bandeau qui s'affiche pour un avertissement finit par se contourner du regard, et le jour où il porte une vraie panne, personne ne le lit.
⚠ Ranger n'efface pas : acquit_at est posé, la ligne reste avec son compte et ses dates. La clé UNIQUE portant sur (cle, acquit_at), un défaut qui revient lève une nouvelle alerte au lieu de rouvrir l'ancienne en silence.
⚠ La page dit ce qu'elle ne peut pas dire. Un encart explique qu'une page vide ne signifie pas que tout va bien : le bot ne signale que ce que le code défaillant lui dit. Sans cet encart, cette page deviendrait la nouvelle section 🔴 vide du registre — rassurante et fausse.
Bugs corrigés
Tools/alerte-courriel.phplisait$r['ok']alors quesmtp_send()rend une liste[ok, message]. Tout envoi réussi aurait été compté comme un échec, et le courriel serait reparti à chaque passage. Vérifié dansmailer.php:104plutôt que supposé.- Un caractère chinois (
非) s'était glissé dans le texte du bandeau, à la place de « non ».
Avertissements — trois pièges de banc dans la même séance
⚠⚠ Le motif plus large que la chose, QUATRE fois aujourd'hui. Trois fois le mot cherché existait dans un commentaire (csrf_check, asv_ages, bind time — ce dernier dans la note qui explique pourquoi on n'en emploie pas) ; la quatrième, exec se trouvait au milieu de db_exec ". Chercher un mot, c'est aussi le trouver dans ce qui en parle — et au milieu d'un identifiant.
⚠⚠ Un piège propre à Tcl, à connaître : la gourmandise de toute l'expression est fixée par son premier quantificateur. Un [^\n]* gourmand en tête rend le (.*?) suivant gourmand aussi — l'extraction du corps d'une procédure filait jusqu'au bout du fichier et emportait les suivantes. Le constat rougissait sur du code juste.
⚠ Et j'ai d'abord imputé cela aux fins de ligne CRLF, avec une explication détaillée écrite dans le banc. Il n'y avait aucun CRLF — mesuré ensuite. L'explication fausse a été retirée. Ce n'est pas Tcl qui trompe, c'est de conclure avant de mesurer.
⚠ Un garde-fou a évité un vert-à-vide : le constat « lever ne lance aucun exec » était vert sur un corps vide. Un second garde-fou vérifie désormais que l'extraction s'arrête — un corps qui ferait la moitié du fichier serait « vrai pour une mauvaise raison ».
4.18.1 — 16 août 2026
L'alerte critique — côté bot. Ce qui casse en service, et qui le dit.
Créations
IriX/cmds/irix-alerte.tcl— table<bot>_alertes,lever,echec(répétition),erreur(technique),ouvertes.IriX/tests/test-alerte.tcl— 26 vérifications, 7 mutations, 7 attrapées.
Évolutions
⚠ Les DEUX journaux, toujours. ::soc::log écrit dans IriX-sql.log, putlog dans IriX.log, et ils ne portent pas les mêmes lignes. Le projet s'est déjà fait prendre en cherchant la trace d'une purge dans le mauvais fichier et en concluant qu'elle n'avait pas tourné.
⚠ Si la base refuse, l'alerte n'est pas perdue : les journaux l'ont déjà. Une alerte qui disparaîtrait parce que la base est tombée serait perdue au pire moment — la base qui tombe est le genre d'incident qu'on veut voir.
⚠ La clé UNIQUE porte sur (cle, acquit_at) : un défaut qui revient après avoir été acquitté lève une nouvelle alerte au lieu de rouvrir l'ancienne en silence. On veut voir qu'il est revenu.
⚠ Les trois jointures sont franchies dans le même commit — le source dans IriX-sql.tcl, et les deux manifestes de Bootstrap/overtchat-setup.sh. C'est ce qui a manqué à irix-edition.tcl le 14/08 : le dépôt marchait, une installation neuve serait morte au chargement. test-modules-charges.tcl le vérifie — 25 modules, trois croisements.
Bugs corrigés
- Un
putlog "module chargé"avait été écrit au niveau du fichier, juste sous le commentaire qui l'interdit. Retiré. La preuve qu'un module est chargé ne s'écrit pas dans le module — c'esttest-modules-charges.tclqui la donne.
Avertissements
⚠⚠ CE MODULE NE DÉTECTE RIEN DE LUI-MÊME. Il est appelé par le code qui sait qu'il vient d'échouer. Un mécanisme qui n'appelle pas alerte::echec restera aussi muet qu'avant — poser ce module ne protège pas du motif « à la jointure », il en crée un de plus. Un seul appelant existe à ce jour.
⚠ Rien n'est encore visible. Le bandeau du panel, la page de lecture, l'acquittement et le courriel restent à écrire : pour l'instant, une alerte va dans les journaux et dans la base, et personne ne la voit sans requête.
⚠ Non constaté : IriX tourne l'ancien code tant qu'il n'a pas rechargé.
4.18.0 — 16 août 2026
L'ASV est BRANCHÉ : formulaire, contrôle serveur, publication au choix, et la charte réécrite.
Créations
- La route
?p=asv·Web/public/index.php— POST, jeton anti-CSRF, plafond par adresse, validation, composition durealname.
Modifications
Web/site/chat.php— âge (menu 16→99), sexe (les cinq réponses), ville, et la case « Afficher mon ASV aux autres », décochée.Web/public/assets/chat.js— appelle la route AVANT d'ouvrir le WebSocket, et envoie lerealnamereçu du serveur.Web/site/charte.php— trois passages réécrits (voir plus bas).Web/tests/test-asv.php— 65 constats, dont 13 sur la route et le formulaire. 14 mutations au total, 14 attrapées.
Évolutions
⚠⚠ LE CONTRÔLE PROTÈGE LE FORMULAIRE, PAS LE PORT. Le webchat ouvre un WebSocket directement vers le serveur IRC : aucun PHP ne se trouve sur ce chemin. Le JavaScript appelle donc ?p=asv avant de connecter, et n'ouvre rien si la route refuse. Mais qui ouvre le WebSocket lui-même, ou se connecte avec mIRC, ne passe pas par là. C'est cohérent avec l'arbitrage retenu — « webchat obligatoire, IRC facultatif » — et c'est une limite connue, pas une faille cachée.
⚠ Le menu, les required et le JavaScript ne gardent RIEN : ils se contournent en trois secondes avec les outils du navigateur. Ils évitent un aller-retour. La décision est prise par la route, et nulle part ailleurs.
⚠ Le realname est composé PAR LE SERVEUR, à partir des valeurs validées — la ville est celle du fichier, jamais celle qui a été tapée. Le navigateur ne fait que le transmettre. S'il le composait, on pourrait y écrire n'importe quoi, et ce champ est lu au /WHOIS par tout le réseau.
⚠ Une panne de la vérification NE LAISSE PAS ENTRER — l'inverse du choix fait pour la liste de villes absente, et pour une raison : là, c'est une donnée d'installation qui manque ; ici, c'est le contrôle lui-même qui n'a pas répondu, et l'on ne sait donc rien de l'âge.
⚠ Seul un CONTOURNEMENT compte pour le plafond. Une ville mal orthographiée est une faute de frappe : la compter mènerait à barrer quelqu'un qui cherche sa commune, exactement l'inverse du but.
Bugs corrigés
asv_rate_block()cherchait l'adresse dansdetail;audit_log()la range dans sa colonneip. Le compte serait resté à zéro et le plafond n'aurait jamais bloqué personne — sans que rien de visible ne casse.
Avertissements
⚠⚠ DEUX MUTATIONS ONT ÉTÉ RATÉES, POUR LA MÊME RAISON, DANS LE MÊME BANC. Mes constats cherchaient csrf_check() et asv_ages() n'importe où dans le fichier — et ces textes existent aussi dans les commentaires que j'y avais écrits. Commenter l'appel en // csrf_check(); laissait le constat vert.
Chercher un mot, c'est aussi le trouver dans ce qui en parle. C'est le défaut « motif plus large que la chose », déjà recensé — et refait deux fois ici. Les deux constats sont désormais ancrés (^\s*csrf_check\(\); en début de ligne, foreach\s*\(\s*asv_ages\(\) pour la boucle).
⚠ Rien n'est constaté en service. Le formulaire a été rendu hors navigateur — 84 âges de 16 à 99, aucun 13 ni 15, les cinq sexes, case décochée — mais personne n'a encore ouvert le chat et tapé une ville. Le compte claude du panel a un mot de passe haché, et le webchat demande un vrai navigateur.
⚠ L'ASV n'est pas encore stocké pour les opérateurs : il vit le temps de la connexion, dans le realname. Le tableau de la charte le dit ainsi, et il dit vrai — mais la modération n'y a donc accès que si la personne publie.
4.17 11 versions · 15 août 2026 → 16 août 2026 13 additions 4 improvements 14 changes 7 bugs fixed 6 warnings
4.17.10 — 16 août 2026
Le socle de l'ASV — Âge, Sexe, Ville. Le module, la liste des villes, le banc. Rien n'est encore branché sur le chat.
Créations
Web/inc/asv.php— âges, sexes, normalisation et recherche de ville, validation, détection de contournement, composition durealname, plafond par adresse.Tools/villes-importer.sh— constitueConfig/villes.txtdepuis GeoNames.Config/villes.txt— 123 897 entrées, 1,8 Mo. France, Belgique, Suisse, Luxembourg et Québec.Web/tests/test-asv.php— 52 constats, 8 mutations, 8 attrapées.
Évolutions
⚠⚠ CE MÉCANISME N'EMPÊCHE AUCUN MINEUR D'ENTRER, et il faut le dire. Un âge déclaré n'est pas vérifiable : un enfant de douze ans choisit « 25 » et passe. Ce module pose une règle, il ne protège personne à lui seul.
Ce qui protège, c'est la modération des privés et sa catégorie minorite. ⚠ Elle devient PLUS utile, pas moins : elle est désormais le filet qui rattrape ceux qui ont menti au formulaire. Ne pas la retirer sous prétexte que les mineurs sont « interdits ».
⚠ Le chat ne dépendra jamais d'Internet. L'import est un geste d'installation joué une fois ; asv.php ne lit ensuite que le fichier local. Une API tierce en panne aurait fermé le chat, ce qui est inacceptable pour un contrôle de ville.
⚠ Une liste absente LAISSE ENTRER — seul endroit du module où le défaut prudent ouvre au lieu de fermer. Une liste manquante est une panne d'exploitation, pas une entrée frauduleuse : refuser tous les visiteurs pour un fichier absent transformerait un oubli d'installation en coupure de service. Le prix de ce choix est qu'il doit se VOIR, d'où asv_villes_etat().
⚠ Le script refuse d'écrire en dessous de 20 000 villes. Un import tronqué par une coupure réseau produirait une liste qui refuse des villes en ayant l'air de marcher — pire qu'un fichier absent, que l'on sait au moins nommer.
⚠ Licence CC BY 4.0 : les données GeoNames imposent de citer la source. L'en-tête du fichier la porte et doit y rester. Aucun conflit avec le MIT — ce sont des données, pas du code.
Bugs corrigés — tous trouvés en regardant les VILLES, jamais les comptes
⚠⚠ Bruxelles, Anvers et Genève étaient ABSENTES d'une liste de 92 613 entrées. GeoNames nomme chaque lieu dans sa langue locale ou en anglais — « Brussels », « Antwerpen », « Geneva » — et le nom français vit dans la colonne des variantes. Un Belge tapant « Bruxelles » aurait été refusé, sur un réseau francophone, par une liste qui avait l'air complète.
⚠⚠ Puis « Paris » est devenu « París ». Les variantes ajoutées, le nom affiché devenait le premier venu dans l'ordre alphabétique : « Le Havre » → « Lé Hâvre », « Anvers » → « Anvèrs ». Le fichier porte désormais un rang, et un nom principal l'emporte toujours sur une variante.
⚠⚠ Une seconde règle a été essayée puis RETIRÉE — « à rang égal, la forme accentuée gagne ». Elle corrigeait « Geneve » → « Genève » et cassait Anvers : « Anvèrs » est aussi une variante accentuée, et c'est une faute d'orthographe. Aucune heuristique locale ne distingue un accent juste d'un accent faux. On préfère un accent manquant à un accent faux — « Geneve » se lit, « Anvèrs » est une erreur que le réseau publierait au WHOIS de quelqu'un.
⚠ awk écrivait avec > au lieu de >>, et il est relancé pour chaque pays : le fichier était tronqué à chaque appel, et seul le dernier pays aurait survécu — un import « réussi » et presque vide.
⚠ unzip n'est pas installé sur la Debian de production. Le script emploie python3 et son module zipfile à défaut, et dit lequel il utilise.
Avertissements
⚠ Rien n'est branché sur le chat. Le formulaire, chat.js, le stockage et la charte restent à écrire. Le module est éprouvé, il n'est pas encore employé — c'est exactement le motif « à la jointure » que ce projet a payé cinq fois.
⚠ La charte disait alors le CONTRAIRE — ce n'est plus vrai. Remesuré le 25/08/2026 : la phrase « dire son âge n'est pas une faute » n'existe plus dans Web/site/charte.php, qui traite désormais l'âge dans sa section dédiée et cite elle-même cette contradiction. ⚠ Le renvoi portait un numéro de ligne sur un fichier vivant, et il désignait aujourd'hui un tableau de durées de conservation : nommer, jamais numéroter. Reste vrai : pseudos-interdits.example (dans Servers/overtchat-hybrid/conf/) porte que « le réseau accueille des mineurs ». Tant qu'elles ne sont pas réécrites, le site promet une chose et le formulaire en imposera une autre.
⚠ Deux mutations sur huit ont d'abord été ratées, et chacune disait autre chose. L'une était un vrai trou du banc — rien n'éprouvait la règle principal/variante, et la casser laissait tout vert. L'autre montrait que le code résiste par deux gardes indépendantes, dont chacune suffit : la mutation n'en cassait qu'une. Une mutation qui ne rougit pas ne prouve pas que le code tient.
4.17.9 — 16 août 2026
« Prêt de robot » devient un groupe de menu, un Eggdrop par ligne.
Créations
eggdrop_nav_entrees()·Web/inc/botreg.php— une vue d'ensemble en tête, puis une entrée par robot portant sa présence réelle, périmée à 300 s : un robot sans nouvelles redevient « Inconnu », jamais « Hors ligne ». Motif d'anope_nav_entrees(), repris et non réinventé.
Modifications
Web/inc/layout.php— le groupe est placé entreAnopeet le groupe réseau, d'oùrobotsa été retiré.Web/pages/robots.php— le robot désigné par?c=est mis en avant.Web/tests/test-routes.php— talon pour le nouveau groupe.Web/tests/test-botreg.php— trois constats revus ou ajoutés (voir plus bas).
Évolutions
⚠⚠ LA CLÉ DE DÉCLINAISON EST c, COMME ANOPE — et ce n'est pas un détail. nav_actif() ne compare que le paramètre c (liste blanche de layout.php). Une cible en robots&b=… n'y serait jamais discriminée : les cinq entrées s'allumeraient ensemble, et le menu montrerait cinq endroits où l'on ne peut être qu'une fois. Réutiliser c évite d'élargir cette liste, et une seule clé de déclinaison dans tout le menu vaut mieux que deux. Un banc le garde désormais.
⚠ Cache statique dans eggdrop_nav_entrees(), comme anope_clients_presence() : le menu est rendu deux fois par page — barre latérale et menu replié — et sans lui, toute page du panel paierait deux requêtes de plus.
⚠ Un robot désactivé garde son entrée, avec sa pastille propre. Le faire disparaître ferait croire qu'il n'existe plus alors qu'il est mis de côté — et l'on ne pourrait plus cliquer pour le réactiver.
⚠ Ce menu ne dit RIEN du botnet, délibérément : « lié » y désigne le lien DCC entre Eggdrop, qui vit dans une autre table et a sa propre page. Un robot peut tourner sans être lié, et c'est l'état par défaut. Mêler les deux dans une seule pastille donnerait un état que personne ne saurait relire.
⚠ Le clic mène quelque part. Sans la mise en avant, les cinq entrées mèneraient à une page rigoureusement identique — un menu qui promet cinq destinations et n'en offre qu'une est pire qu'une entrée unique, parce qu'on le croit. Un ?c= inconnu le dit (« ce robot n'est plus déclaré au parc ») plutôt que d'afficher la page sans un mot.
⚠ La comparaison est insensible à la casse — la base compare sans, PHP avec — et le nom affiché est toujours celui de la base, jamais celui reçu : un ?c= forgé ne peut rien écrire à l'écran. Constaté sur trois cas, dont overop-h et un nom inexistant.
Bugs corrigés
⚠⚠ UN BANC QUI CHERCHAIT UNE CHAÎNE LITTÉRALE, ET QUI SERAIT TOMBÉ POUR UNE RAISON FAUSSE. test-botreg.php vérifiait que layout.php contient le texte 'robots' => [. L'entrée étant devenue un groupe construit par une fonction, la chaîne a quitté layout.php sans que le menu perde quoi que ce soit — le banc aurait rougi sur un code parfaitement juste. Il dérive désormais l'entrée de la fonction qui la produit.
Un banc qui cherche du texte à l'endroit où il croit qu'il est garde la forme du code, pas ce qu'il fait. C'est la même famille que les cinq façons connues qu'un banc a de mentir.
Avertissements
⚠ Trouvé par un agent d'exploration lancé en parallèle, et je serais passé dessus : le constat textuel ci-dessus comme la contrainte sur la clé c. Les deux auraient été découverts après coup, l'un par un banc rouge inexplicable, l'autre par un menu qui s'allume en entier.
4.17.8 — 16 août 2026
Le suivi en direct d'une demande de botnet, et le cadre du tableau de bord complété.
Créations
botnet_suivi()·Web/inc/botnet.php— trois états, et les confondre était le défaut :
| État | Ce qu'on affiche | Rafraîchit ? |
|---|---|---|
| en cours | « demande en cours, IriX la traite en moins de 60 s » | oui, toutes les 5 s |
| bloqué | « la demande n'est pas consommée — c'est IriX qu'il faut regarder » | non |
| en erreur | bannière rouge, motif et compte d'échecs | — |
Web/tests/test-botnet-suivi.php— 20 constats, 5 mutations, 5 attrapées.
Modifications
botnet_peers()rendaction_age. ⚠ Sans lui,last_error— qui n'est jamais effacé tant qu'une action ne réussit pas — afficherait une erreur d'il y a trois jours comme une panne du moment, et la bannière rouge deviendrait un meuble.Web/pages/dashboard.php— le cadre porte désormais le botnet, ce qui attend une décision (demandes de salon, avis de travaux, mise à jour), la version et l'édition.
Évolutions
⚠⚠ LE RAFRAÎCHISSEMENT S'ARRÊTE, et c'est le point le plus important. Au-delà de trois cycles, on cesse de recharger et l'on dit que personne ne répond. Une page qui tourne indéfiniment devant un bot mort affiche « en cours » pour l'éternité — c'est le même mensonge que l'état périmé, que cette page traite déjà en le rendant INCONNU plutôt que « pas lié ». « Je n'ai pas de nouvelles » n'est pas « c'est en cours ».
⚠ Le seuil vaut trois cycles et non un : la machine gèle avec la veille de Windows (point 15), et un seul cycle crierait au moindre retard.
⚠ Un âge inconnu rend « en cours », jamais « bloqué ». Un pair jamais traité ne dit pas depuis quand il attend : le déclarer bloqué serait une accusation sans mesure.
⚠ Le compteur de rechargements est borné et remis à zéro dès qu'il n'y a plus d'attente. Sans cette remise à zéro, la demande suivante ne se rafraîchirait pas — un correctif qui ne marche qu'une fois est pire qu'aucun, parce qu'on croit l'avoir.
⚠ Le miroir PHP ↔ Tcl est désormais gardé : le banc dérive OBS_PAS du module et le compare à BOTNET_CYCLE, et fait de même pour la péremption d'observation en la dérivant des deux fichiers. S'ils divergent, le panel promet un délai que le bot ne tient pas — et l'on croira à une panne pour la raison exacte qui a motivé ce correctif.
Bugs corrigés
- Le cadre lisait
update_cache_lire()['disponible'], qui n'existe pas (la clé estavailable). ⚠ Et surtout : une version publiée non vide n'est pas une mise à jour disponible — elle peut être égale ou antérieure à l'installée. C'est exactement l'erreur du 11/08/2026, où j'avais conclu que le panel proposait une mise à jour vers une version plus ancienne. Seulupdate_verdict()compare, et lui seul tranche. - Deux appels à des fonctions inexistantes attrapés avant tout rendu :
botreg_duree_texte()(c'estbotnet_duree()) etapp_version()(c'est la constanteAPP_VERSION). Les deux auraient tué la page.
Avertissements
⚠ Le cadre passe de 658 à 734 ms. Toutes les sources ajoutées restent sur la machine : update_verifier() — qui interroge le site — est délibérément écartée au profit du cache. Un tableau de bord qui dépend du réseau met dix secondes à s'afficher le jour où le réseau tombe, c'est-à-dire le jour où on l'ouvre.
⚠ Le rechargement automatique n'est pas constaté. Le banc garde la DÉCISION — rafraîchir ou non ; que le navigateur recharge bien au bout de cinq secondes et s'arrête à la borne ne se voit que dans un vrai navigateur.
4.17.7 — 16 août 2026
Le tableau de bord porte un cadre de vue générale, à droite.
Créations
statut_synthese()·Web/inc/statut.php— la vue générale, dérivée destatut_tout(). Elle n'invente aucune mesure : le tableau de bord et la page Statut disent donc forcément la même chose.Web/tests/test-statut-synthese.php— 19 constats, 6 mutations, 6 attrapées.- La grille
.avec-cote·app.css— contenu + colonne latérale de 320 px, repli en une colonne sous 1100 px.
Modifications
Web/pages/dashboard.php— la page passe en deux colonnes, le cadre à droite.
Évolutions
⚠⚠ AUCUNE TROISIÈME SOURCE D'ÉTAT. Le tableau de bord lisait stack_status(), la page Statut lit statut_tout() : deux sources coexistaient déjà. En ajouter une troisième pour ce cadre aurait reproduit à l'identique la charge d'un robot, écrite à trois endroits et payée trois fois (4.16.29 → 4.16.32) — chacune juste de son côté, et la troisième trouvée seulement en RENDANT la page. La synthèse dérive donc, elle ne mesure pas.
⚠⚠ POURQUOI LA PRODUCTION ET LES ESSAIS SONT SÉPARÉS. Six composants sur neuf sont arrêtés en permanence — serveurs d'essai, Anope non installé — et c'est normal. Au même rang que la production, ils donneraient un cadre où six lignes crient tous les jours ; un cadre qui crie toujours cesse d'être lu, exactement comme une étiquette « critique » posée sur ce qui ne l'est pas. Le verdict d'ensemble ne regarde donc que la production, et le champ production qui le permet existait déjà.
⚠ Les anomalies, elles, remontent des deux familles : un port d'essai tenu par un inconnu mérite d'être vu — il ne doit simplement pas faire dire que le réseau va mal. C'est l'anomalie qu'on filtre, pas son origine.
⚠ Seuls les messages err et warn remontent. Les info sont justes et détaillés sur la page Statut ; dans un cadre de synthèse ils noieraient l'écart qu'on vient y chercher. « On garde l'écart, pas le constat. »
Avertissements
⚠ Le cadre coûte ~300 ms — statut_synthese() interroge systemctl et ss pour neuf composants, sur la page la plus ouverte du panel. Mesuré : 328 ms au premier appel, 284 au second, sans aucun cache. Le coût est assumé, pas masqué : une valeur mise en cache devient une seconde vérité, avec sa propre péremption. C'est le prix de l'OBSERVÉ contre le DÉCLARÉ.
⚠ minmax(0, 1fr) et non 1fr, dans la grille. Une piste en 1fr a pour taille minimale la largeur de son contenu le plus large : un tableau un peu long, et la page déborde horizontalement. Invisible sur grand écran, et ne se voit qu'au doigt.
⚠ Rendu hors navigateur : 27 437 octets, aucune notice, <div> équilibrés à 144/144. ⚠ La première mesure en annonçait 17 — toutes imputables à l'INSTRUMENT, qui écrivait avant d'ouvrir la session. Soupçonner l'outil de mesure avant le code.
⚠ Pas encore vu dans un vrai navigateur — le compte claude du panel a un mot de passe haché. Le rendu prouve que la page se construit ; il ne prouve pas qu'elle est belle ni lisible au doigt.
4.17.6 — 16 août 2026
🔴 LE TROU DE 4.17.5 EN CACHAIT UN SECOND : le bot REFUSAIT toute action du panel, en la prenant pour un doublon d'elle-même.
Bugs corrigés
action_verdictprend un paramètreen_traitement(0 par défaut, donc aucun appelant existant ne change). À 1, il lève cette seule garde ; toutes les autres s'appliquent d'autant plus que l'état a pu changer entre la pose et l'exécution — pair désactivé, devenu lié, trop d'échecs.traiter_actionsl'appelle avec 1.
Modifications
IriX/tests/test-botnet.tcl— six constats ajoutés, 69 vérifications, et les deux sens tenus : en traitement l'action passe, hors traitement elle bloque toujours. Les trois autres gardes sont éprouvées en traitement, là où on pourrait croire le drapeau permissif. 3 mutations, 3 attrapées.
⚠⚠ LE BANC ÉTAIT DÉJÀ VERT SUR CE POINT, et c'est la leçon de la version. Il vérifiait « une action déjà programmée bloque » — règle juste, posée à la mauvaise question. Un banc ne rougit pas sur une règle correcte appliquée au mauvais endroit : cela ne se voit qu'en regardant agir.
⚠ Le sixième constat est celui qui compte le plus : il lit le corps réel de traiter_actions et vérifie que l'appel porte bien le drapeau. Sans lui, retirer le 1 remettrait le défaut à l'identique en laissant les cinq autres verts — « garder la porte en regardant la serrure », déjà attrapé sur test-bindtime.tcl le 14/08. La mutation M2 le confirme : elle n'est vue que par lui.
Avertissements
⚠ Déployé sans rechargement, délibérément — même motif que les 14 et 15/08 : le passage horaire de 11:00 porte le contrôle des prêts, et le retour d'IriX prend 70 à 95 s. Le code est en place ; IriX tourne encore l'ancien en mémoire jusqu'au prochain rechargement.
⚠ Ce correctif n'est donc PAS constaté, et il ne peut pas l'être avant ce rechargement. Le constat à obtenir : cliquer « Lier », puis voir dans l'activité du botnet un attempt — et non plus un refused.
4.17.5 — 16 août 2026
🔴 SIX actions du panel étaient MORTES — toute la page Botnet, et le dialecte des liens ULine.
Bugs corrigés
- Les six actions sont déclarées dans
ACTION_LEVELS. Les niveaux ont été tranchés par SerVuS, jamais devinés :botnet,botnet_enableetbotnet_reseten admin — actes d'exploitation réversibles, même famille quesocket;botnet_addetbotnet_delen owner — désigner la machine à laquelle le bot parlera est de la configuration d'infrastructure, commeoper_saveetprotection_save.protoen admin, par stricte analogie avecsocket, son voisin de page et d'objet.
Créations
Web/tests/test-panel-actions.php— le croisement qui aurait attrapé ce trou, et qui attrapera le prochain. Il dérive trois listes des fichiers et n'en énumère aucune : les entrées d'ACTION_LEVELS, lescasedu switch, et ce que les pages postent réellement. Il les croise dans les trois sens. 10 constats, 6 mutations, 6 attrapées — dont la reproduction du trou d'origine et celle duprotoque personne n'avait vu.
⚠ Ce que le banc NE fait PAS : il ne lit rien de ce que fait une action, ni du niveau qui lui est donné. Une action déclarée au mauvais niveau le satisfait pleinement. Il constate qu'elle est joignable, rien de plus — comme test-bindtime.tcl et test-modules-charges.tcl, c'est un point de passage obligé, pas une preuve.
⚠ Son quatrième constat garde le portier lui-même : sans lui, les trois croisements resteraient verts en gardant une porte qui n'existe plus. C'est le défaut attrapé le 14/08 sur test-bindtime.tcl — « garder la porte en regardant la serrure » —, repris et non réappris.
Avertissements
⚠ Ce correctif n'est PAS constaté. Le code est déployé, le banc est vert, les mutations mordent — mais personne n'a encore vu un bouton de la page Botnet faire ce qu'il annonce. Le compte claude du panel a un mot de passe haché, donc inutilisable : le constat appartient à SerVuS. Tant qu'il n'a pas eu lieu, le point reste ouvert au registre, et c'est la règle.
4.17.4 — 15 août 2026
✅ Le point 2 est CLOS. Une information a traversé le lien de botnet, les deux extrémités tracées.
4.17.3 — 15 août 2026
L'écho n'est pas revenu : le transport n'était écrit que d'un seul côté.
Modifications
Robots/overop/overop.tcl—::overop::on_ping(répond) et::overop::on_pong(ne répond pas), avec leursunbindpréalables comme les trois binds voisins : un.rehashre-source ce fichier.IriX/tests/test-botnet-echo.tcl— un §4bis qui dérive lesbind botdes deux sources et croise les verbes dans les deux sens. 5 mutations neuves, 5 attrapées, dont celle qui reproduit le défaut de ce soir.
4.17.2 — 15 août 2026
Le botnet avait 802 lignes et aucun verbe : rien ne pouvait circuler sur le lien. Il en a deux, et un banc qui garde la porte.
Créations
IriX/tests/test-botnet-echo.tcl— 26 constats, 7 mutations, 7 attrapées.
4.17.1 — 15 août 2026
Le salon gardien #!Bots! est en service : les cinq Eggdrop y siègent, tous en +B. Ce qui bloquait n'était ni le robot ni sa configuration.
Modifications
- Septième dérogation
!#!Bots!, posée à côté de!#!Services!— son pair, autorisé pour la même raison. Appliquée parreload(SIGHUP) : aucune connexion rompue. Le serveur a confirmé « 11 exceptions ». - Les quatre
overop.confportentMODE $botnick +iBetchannel add #!Bots!. ⚠ Cette partie avait fonctionné du premier coup : les robots étaient en+ixBdès leur redémarrage.
4.17.0 — 15 août 2026
Ouverture de la branche 4.17. La 4.16 se ferme sur une série de versions tournant toutes autour du même défaut : du code juste que personne ne joignait. Cette première version de la branche ferme le quatrième cas, et pose le banc qui garde la jointure pour les suivants. ⚠ Le compte des versions par branche est calculé par la page ?p=versions à partir des rubriques ci-dessous — il n'est écrit à la main nulle part, et surtout pas ici.
Créations
IriX/tests/test-modules-charges.tcl— le banc qui garde la jointure. Il dérive les trois listes (les.tcldecmds/, lessourcede l'entrée, les deux manifestes) et n'en énumère aucune : un module écrit demain entre seul dans les trois croisements. 8 mutations, toutes attrapées.
Modifications
IriX/cmds/IriX-sql.tcl— section 6quaterdecies, lesourcemanquant.Bootstrap/overtchat-setup.sh—irix-edition.tclporté dansgit.irix.filesetgit.irix.modes.sql.modules.
4.16 75 versions · 9 août 2026 → 14 août 2026 59 additions 43 improvements 108 changes 22 bugs fixed 2 removals 3 checks 18 mistakes 44 warnings
4.16.74 — 14 août 2026
Le chantier des éditions est ouvert, son socle est posé — et quatre passes de mutation ont été nécessaires pour comprendre ce qui protégeait vraiment.
Créations — Phase 1 du chantier des éditions
Config/config.json→project.edition. ⚠ Ce fichier est déjà exclu de la surveillance de mise à jour : l'amont ne l'écrase jamais, ce qui en fait le seul bon endroit pour un état propre à l'installation.Web/inc/edition.php,IriX/cmds/irix-edition.tcl,Tools/edition.sh— un lecteur par langage, et trois seulement. « Un composant qui DÉDUIT son édition finira par se tromper. »Web/tests/test-edition.php— 19 constats, qui croisent les trois.IriX/tests/_edition-lire.tcl— l'outil que le banc appelle. Tiret bas en tête pour que le lanceur ne le prenne pas pour une campagne muette.
4.16.73 — 14 août 2026
Le journal des prêts entre en service — et il aurait posé deux lignes pour une seule fin.
Modifications
MANDATON/MANDATOFFpassent l'auteur et la raison àbasculer. Sans eux, le journal notait « automatique » pour un geste que quelqu'un avait décidé, et l'on ne distinguait plus une reprise à la main du balayage horaire.MANDATFINpasse l'auteur àtermineret ne journalise plus lui-même.
4.16.72 — 14 août 2026
« 66 commandes à renommer » était faux — et c'est en le mesurant avant de le faire qu'on s'en est aperçu.
Modifications
Web/inc/commandes.php—cmd_rangs()déclareoperateur(3) etproprietaire(5) ;opest retiré, plus aucune commande ne le portait.- Les deux clés qui ne sont pas des grades SQL disent enfin ce qu'elles sont :
ircops« vérifié auprès du serveur, jamais par un grade en base », etowner (Eggdrop)« flagndu userfile, sans rapport aveccsowner». Leur description mentait plus discrètement que le rouge.
Bugs corrigés
test-commandes.phpétait rouge depuis 15:41 — le seul échec sur 69 bancs, et il l'était avant la séance. 15 commandes portaient un grade que la table des libellés ne connaissait pas. Il ne cassait rien en service : cette table libelle et trie, elle ne garde aucune porte.
4.16.71 — 14 août 2026
Le journal des prêts ne gardait presque rien — et c'est une suspension partie sous nos yeux qui l'a montré.
Créations
Web/inc/mandat.php— le journal des prêts et l'état de chacun, vus du panel. Aucune écriture : le journal s'écrit côté bot, et là seulement.Web/tests/test-mandat-journal.php— 18 constats, six mutations attrapées. Il dérive les actes et l'ENUMresultdu source Tcl et les croise avec les libellés de la page. Sans lui, un acte ajouté côté bot serait enregistré, visible dans « Toutes », et introuvable au filtre.IriX/tests/test-bindtime.tcl— 8 constats, cinq mutations attrapées. Toutbind timedoit déclarer son rattrapage sur une ligne# RATTRAPAGE:.
Modifications
irix-mandat.tcl— le journal s'écrit dansbasculeretterminer, les deux portes par lesquelles un prêt change d'état, plusinstaller,retireret les deux constats d'absence. Aux portes, et non chez les appelants : les y laisser aurait donné autant de rédactions que de chemins. ⚠ Les refus sont journalisés aussi.paretpourquoisont optionnels — un paramètre obligatoire aurait imposé de réécrire tous les appelants, et c'est ainsi qu'on oublie le seul qui comptait.- Neuf actes :
accord·fin·suspension·reprise·bascule·absence·retour·entree·sortie. ⚠entreeetsortiedisent qu'un ordre est parti, jamais que le robot est entré ou sorti. Web/pages/robots.php— deux sections neuves, avec un filtreadistinct de celui des demandes (r) : partagé, filtrer l'un aurait vidé l'autre.IriX-binds.tcl— chaquebind timedéclare son rattrapage. Le point 15 est tranché par l'option (c), l'assumer : le gel coûte un retard, jamais une donnée, et les trois travaux du passage horaire comparent du temps.test-mandat.tcl— 199 constats. Le talon debasculersuit la vraie signature et garde ce qu'on lui passe : l'accepter sans le garder aurait fait passer au vert un constat qui ne lit rien.
4.16.70 — 14 août 2026
Le scan quotidien a tourné pour la première fois — et personne ne l'a provoqué.
⚠ Ce qui n'est pas encore éprouvé
La passe n'avait rien d'échu à retirer : les DELETE n'ont donc pas été éprouvés en charge. Au plus tôt le 08/09/2026, quand chat_hist dépassera 30 jours, vérifier que hist: purge — N ligne(s) retirée(s) apparaît dans IriX-sql.log.
Modifications
Markdown/CHANTIERS.md— point 16 sorti des défauts ouverts et porté dans les travaux, avec son constat. Il ne reste qu'un seul défaut ouvert : le 15. Son affirmation « déployé sans rechargement, IriX tourne l'ancien code » a été datée : elle était vraie à 14:43 et fausse à 17:13.Markdown/IRIX.mdetMarkdown/DATABASE.md— les deux annonçaient au futur ce qui est arrivé. ⚠ DATABASE.md gardait « chaque nuit » comme cible : la remise à zéro a lieu à la première occasion du jour, soit le démarrage du bot au réveil de la machine, pas minuit.- Point 15 — sa piste (b) « rattraper au réveil » n'est plus une hypothèse. Elle ne couvre que le passage quotidien : le passage horaire reste perdu, et le gel n'est pas corrigé. Le point reste ouvert.
4.16.69 — 14 août 2026
Le registre passé en revue point par point — et deux défauts qui duraient depuis des semaines sans que rien ne les signale.
Créations
- Rattrapage du scan quotidien dans
IriX-sql.tcl—daily_rattrapage,daily_due,daily_derniere,daily_marquer, etdaily_corpsextrait dubind time. Motif de::soc::logrottransposé : unutimerqui se réarme, une garde sur le jour calendaire, une mémoire en base (daily_last_rundanssoc_settings). Trois jours manqués ne donnent qu'une reprise. - Contrôle des tableaux dans
Web/tests/test-markdown.php— une suite de lignes en « | » doit rendre un<table>, et un seul. Compte dérivé du source, aucun nombre en dur. - Repli PHP par WSL dans
Tools/git-hooks/pre-commit.
Modifications
require_gradeparle le vocabulaire du réseau :op→operateur,owner→proprietaire,ircops→netadmin. Sans accent ni tiret — ce sont des clés comparées parlsearch.admin,useretvoicene changent pas.Web/inc/commandes.phpa suivi.IRIX.md,DATABASE.md,RESEAU.md,GRADES.md: corrigés de ce que la mesure a démenti.
Suppressions
- La déauthentification quotidienne de
daily_corps.::soc::auth::scanfait ce travail toutes les 60 secondes, avec une garde de démarrage que le geste retiré n'avait pas, et en consultant le registre du lien.
Bugs corrigés
- Un tableau pouvait disparaître du site en silence. Retirer un séparateur
|---|---|ne casse aucune paire de balises : le tableau ne naît pas, sa ligne retombe en paragraphe, et ses barres s'affichent au lecteur. Le banc restait vert. Trouvé par mutation, et il a attrapé son auteur le jour même. - Tout PHP commité depuis le poste Windows passait sans contrôle de syntaxe : le hook renonçait faute de
php. Il passe désormais par WSL, et le dit. syncownerallait être renommé à tort — son « owner » est le flagnd'Eggdrop, pas un grade SQL. Attrapé partest-grades.php.
Évolutions
18555et8123identifiés :go2rtc(module WebRTC) et Home Assistant, tous deux dans un conteneur ennetwork_mode: host— leurs ports ne sont pas redirigés, ils sont ceux de la machine, IPv6 publique comprise.- Le point 1 (amorce de l'IA) et le point 5 (lot 3) étaient fermés et annonçaient du travail : reconstatés, puis marqués clos.
⚠ Avertissements
- Écrit n'est pas en service. Le rattrapage et les grades renommés sont sur le disque de la prod, pas en mémoire : le bot tourne encore avec l'ancien code. Ils n'entrent en vigueur qu'à son redémarrage, et c'est là seulement que les constats pourront se faire.
- Le gel de WSL n'est pas corrigé (point 15). La veille de Windows fait perdre des passages horaires ; le croisement montre que le projet compare partout du temps et non des passages, donc le gel coûte des passages, pas des données.
- Le point 10 attend un geste de l'exploitant — un mot de passe par pseudonyme, qui ne peut pas être automatisé. La procédure est vérifiée et son ordre écrit.
4.16.68 — 13 août 2026
Les fichiers de sauvegarde ne se servent plus — et la règle évidente aurait été sans effet.
Le motif, éprouvé dans les deux sens
⚠ Une règle qui bloque trop casse le site, et c'est une faute autant qu'une règle qui ne bloque rien. Le banc éprouve donc les deux : neuf noms qu'elle doit refuser — dont le fichier qui a réellement fuité — et dix qu'elle doit laisser passer, y compris /.well-known/acme-challenge/…, sans quoi le renouvellement du certificat tomberait.
Créations
Web/tests/test-apache-sauvegardes.php— 30 constats. Il vérifie aussi, par dérivation du disque, qu'aucun fichier de sauvegarde ne traîne aujourd'hui dans la racine servie : la règle est une seconde barrière, pas la première.
4.16.67 — 13 août 2026
Le code du panel a été téléchargeable depuis Internet, et un conseil envoyait chercher une chose déjà faite.
Modifications
Markdown/SECURITY.md— la leçon des fichiers de sauvegarde, et la nuance IPv6.Tools/panel-account.php— conseil conditionnel.Web/tests/test-panel-account.php— 15 constats.
4.16.66 — 13 août 2026
Le désinstalleur appelait la sauvegarde avec une option qui n'existe pas.
Modifications
Tools/desinstaller.sh—--with-db.Tools/tests/test-desinstaller.sh— 29 constats, 7 mutations toutes détectées, dont le vrai bug remis à l'identique.
4.16.65 — 13 août 2026
Créer un compte faisait taper le mot de passe deux fois, puis mourait sur une trace SQL.
Créations
Web/tests/test-panel-account.php— il lance la vraie commande avec une adresse dérivée de la base, jamais recopiée, et vérifie qu'elle refuse avant de demander le mot de passe. ⚠ Il ne fournit d'ailleurs aucun mot de passe sur son entrée : si l'outil en demandait un, il ne pourrait pas aboutir. ⚠ Et il compte les comptes avant/après — aucun n'est créé.
4.16.64 — 13 août 2026
Un désinstalleur complet, protégé par le mot de passe administrateur — demandé par SerVuS.
Créations
Tools/desinstaller.shTools/tests/test-desinstaller.sh— 26 constats, 6 mutations toutes détectées. Les essais montent de faux arbres dans un répertoire jetable ; aucun ne touche à l'installation réelle.
4.16.63 — 13 août 2026
Passe d'anomalies : deux pages d'installation annonçaient comme absent ce qui tourne tous les jours.
Modifications
Markdown/INSTALL.md,Markdown/ARCHITECTURE.md— l'état réel, plus la commande qui le dérive au lieu de le lire.Markdown/WEB.md— le tableau des niveaux du panel distingue désormais la clé (inchangée) du nom rendu (4.16.61).Web/public/assets/chat.js— « Helpeur » dans les boutons de grade.
4.16.62 — 13 août 2026
Les grades de salon portent le vocabulaire — un seul mot changeait.
Modifications
Web/inc/chanaccess.php—halfops'affiche « Helpeur ».Web/tests/test-chanaccess.php— 48 constats, 5 mutations toutes détectées.
4.16.61 — 13 août 2026
Les niveaux du panel portent le vocabulaire du réseau — première étape de l'unification des grades.
Modifications
Web/inc/auth.php—level_name()rend le vocabulaire.Web/tests/test-grades.php— 29 constats, 6 mutations toutes détectées. Les constats ne portent pas que sur les cinq valeurs rondes : ils gardent aussi les seuils (un>=changé en>ferait glisser chaque niveau d'un cran sans qu'aucun libellé ne change), l'ordre des rangs et leur unicité.
4.16.60 — 13 août 2026
Le correctif précédent annonçait un succès qui n'existait pas : il relisait avec l'outil dont il doutait.
Modifications
IriX/cmds/IriX-sql.tcl— trace inconditionnelle des deux lectures et du refus.IriX/tests/test-floodjoin.tcl— 22 constats, 12 mutations toutes détectées.
4.16.59 — 13 août 2026
Le bot bannissait le serveur des services de leur propre salon, à chaque démarrage.
Créations
IriX/tests/test-floodjoin.tcl— 18 constats, 9 mutations toutes détectées.
4.16.58 — 13 août 2026
Effacer une mémoire d'absence demandait une preuve, et n'en demandait aucune.
Modifications
IriX/cmds/irix-mandat.tcl— preuve positive avant tout effacement de mémoire.IriX/cmds/IriX-sql.tcl—botregetbotnetinitialisés au démarrage.IriX/tests/test-appels.tcl— le croisement dérivé desdb_init.IriX/tests/test-mandat.tcl— 195 constats ; avectest-appels.tcl, 17 mutations toutes détectées.
4.16.57 — 13 août 2026
La suspension des prêts était muette quand tout va bien — le défaut de la 4.16.53, refait le jour même.
Modifications
IriX/cmds/irix-mandat.tcl— une trace de vie au niveau le plus bas, une fois par heure, quand il n'y a rien à défaire.IriX/tests/test-mandat.tcl— 192 constats, 14 mutations toutes détectées ; retirer la trace fait rougir le banc.
4.16.56 — 13 août 2026
Le schéma des prêts ne s'initialisait qu'à la main, et aucune migration ne pouvait donc l'atteindre.
Modifications
IriX/cmds/IriX-sql.tcl—::soc::mandat::db_initappelée dansstart_system, aprèsload_config. ⚠ Jamais au niveau du fichier : un appel posé ausources'exécute avant la configuration, et c'est le défaut qui a produit 171 erreurs SQL à chaque démarrage depuis le 27/07/2026.IriX/tests/test-mandat.tcl— 191 constats, 13 mutations toutes détectées.
4.16.55 — 13 août 2026
Un prêt que personne ne sert finit par se suspendre — après 24 heures, et seulement après.
Créations
::soc::mandat::suspendre_non_servis, appelée au passage horaire après le signalement — l'ordre compte : suspendre d'abord sortirait le prêt des actifs, et le dernier avertissement ne partirait jamais.::soc::mandat::_absence_ecrire, qui n'accepte que les deux littéraux SQL utiles — ce qui n'est pas prévu se refuse, il n'a pas à s'échapper.::soc::mandat::_observation_vivante, la garde du reflet vide, partagée par les deux chemins.- Colonne
absent_depuissur la table des prêts, posée par unALTERdédié : unCREATE TABLE IF NOT EXISTSne s'exécute pas sur une table déjà là, et la colonne n'aurait existé que sur les installations neuves.
Modifications
IriX/tests/test-mandat.tcl— 189 constats, dont 32 neufs, et 12 mutations toutes détectées.
4.16.54 — 12 août 2026
« Il n'y est pas » était faux : la procédure regardait quelqu'un d'autre.
4.16.53 — 12 août 2026
Le contrôle des prêts dit maintenant qu'il est passé, même quand tout va bien.
4.16.52 — 12 août 2026
Un prêt accordé que personne ne sert se dit maintenant aux opérateurs.
Créations
::soc::mandat::non_serviset::soc::mandat::signaler_non_servis, appelées au passage horaire après la bascule de charge — l'ordre compte : signaler avant elle dénoncerait un prêt qu'elle s'apprête à corriger.
4.16.51 — 12 août 2026
Un opérateur du réseau n'est pas expulsé par les bans automatiques — constaté dans les deux sens.
4.16.50 — 12 août 2026
La bascule de charge a basculé pour de vrai — et le salon n'a pas été servi.
⚠ Avertissements
- Le statut du point 2 de
Markdown/CHANTIERS.mdattend l'arbitrage de l'exploitant : la bascule a tenu toutes ses promesses, mais le salon n'a pas été servi. Les deux lectures sont écrites côte à côte dans le carnet plutôt que tranchées d'autorité. - L'essai a été nettoyé par le chemin normal — le prêt terminé, l'ordre de sortie émis, le salon désactivé chez le robot, et le tout relu en base plutôt que supposé.
4.16.49 — 12 août 2026
Un motif de protection qui visait à côté depuis le premier jour.
Créations
Servers/overtchat-hybrid/tests/test-nickpolicy.c— septième campagne du serveur. Elle n'éprouve pas un mécanisme mais le fichier qu'on livre, et les deux ne se remplacent pas : le mécanisme fonctionnait parfaitement le jour où la mesure a montré que presque rien n'était gardé.
Elle garde les deux sens — que les services soient réservés, et que les robots ne le soient jamais. 16 constats, et deux mutations qui la font rougir : retirer un service de la liste, et élargir le motif en over*.
Modifications
Servers/overtchat-hybrid/conf/pseudos-interdits.example— quatre pseudonymes de services ajoutés, et la raison écrite sur place ;Servers/overtchat-hybrid/tests/run-tests.sh— la campagne y est inscrite le jour où elle est écrite. Le lanceur énumère à la main : une campagne qui n'y figure pas ne tourne jamais, et laisse croire que le sujet est couvert.
✅ Et la campagne entière a été relancée pour le vérifier : les dix-sept passent, la nouvelle comprise, à sa place et comptée par le lanceur. Éprouver un banc à la main prouve qu'il fonctionne, pas qu'il tournera — et c'est la seconde qui protège.
⚠ Avertissements
- Ce lot ne couvre que les pseudo-clients du lien de services. Les robots et IriX se connectent en clients : les inscrire dans cette liste leur interdirait de se connecter. Leur protection passe par
pseudos-proteges.conf, qui demande un mot de passe par pseudonyme — le mécanisme est écrit et éprouvé, mais les mots de passe ne se posent pas automatiquement. VoirMarkdown/CHANTIERS.md. - Le fichier de politique vit hors du dépôt, dans la configuration du serveur en service. Mettre à jour le modèle ne met pas à jour une installation : il faut y reporter le changement, puis recharger.
4.16.48 — 12 août 2026
La bascule de charge — point 2 du carnet, ouvert depuis le 09/08.
Erreurs
⚠⚠ ::soc::mandat::basculer EXISTAIT DÉJÀ, avec la signature {chan etat} — c'est elle qui suspend ou réactive un prêt, et IriX-sql.tcl l'appelle. Ma procédure portait le même nom : en Tcl, la seconde définition écrase la première sans un mot, et la commande de suspension aurait cessé de fonctionner sans que rien ne le signale.
Trouvé par le banc, au tout premier lancement, avant tout déploiement. Renommée bascule_charge. C'est le pendant du travers déjà nommé dans le carnet : on y guette la procédure qui n'existe pas, celle qui existe DÉJÀ coûte tout autant. Vérifier qu'un nom est libre avant de l'écrire — grep "proc <nom>" suffit.
Évolutions
IriX/tests/test-bascule.tcl— 32 constats, dont le premier est la garde du HUP. ⚠ Son fauxdb_selfiltre comme la base le fait : l'exclusion du robot tombé vit dans une clause SQL, et un décor qui rend tout le parc ne pourrait pas l'éprouver.- 61 bancs au vert, 3547 constats.
- 9 mutations, toutes détectées — dont celle qui vide la garde du HUP.
⚠ Une mutation a survécu au premier essai : le constat cherchait le nom de la procédure dans le balayage horaire, or ce nom figure aussi dans la garde info commands. Il cherche désormais l'appel.
Avertissements
⚠ Écrite et éprouvée, PAS ENCORE CONSTATÉE EN RÉEL. Il y faut un robot réellement tombé pendant plus de 30 minutes, puis un passage horaire. Tant que ce n'est pas fait, ce point reste ouvert dans CHANTIERS.md — « écrit et éprouvé » n'est pas « en service », c'est la règle du carnet.
4.16.47 — 12 août 2026
Les cahiers rattrapent la journée. Six documents relus contre ce qui a changé — et trois portaient des affirmations devenues fausses.
Modifications
ROADMAP.md— ⚠ le point le plus faux du lot. Il annonçait encore « l'unité reste à installer », « la phrase secrète n'existe pas » et « aucune sauvegarde n'a jamais été produite sur cette installation ». Les trois étaient vrais le 11/08 au matin, et faux le lendemain : unité installée et active, minuteur rattrapé tout seul au démarrage, phrase secrète ouvrant les quatre archives, archive restaurée pour de vrai, et copie hors machine depuis la 4.16.44. Ne reste que la recopie de la phrase hors de la machine.IRIX.md—!banpermajouté au tableau des commandes, avec ses trois gardes et le refus de toute durée.DATABASE.md— nouvelle section sur la casse, à côté de celle qui traitait déjà l'accent-insensibilité : c'est le même piège une lettre plus loin. La collation_cicompare sans la casse, le code avec — et la règle qui en découle : une garde d'existence quiSELECTla colonne doit adopter ce qu'elle lit, pas seulement tester sa vacuité.SECURITY.md— les deux incidents de secret du 12/08, dont aucun ne venait d'un secret écrit volontairement : une vieille copie oubliée sur un partage réseau, et un filtre bâti sur le nom de la clé (set pass…) là où la directive s'appelledbpass. Plus la chaîne de renouvellement du mot de passe de la base, et les deux fichiers qui le portent.EDITIONS.md,PRET-ROBOT.md— les comptes de bancs écrits à la main sont retirés et renvoient au lanceur. Un chiffre à la main ne survit pas à la séance qui l'écrit ; celui-ci datait de trois séances.
Évolutions
CHANTIERS.md: six points revus dans la journée, trois fermés par constat — le webchat (3), le message d'accueil (6) et l'exemption des opérateurs (8).- 60 bancs au vert, 3515 constats.
4.16.46 — 12 août 2026
La rotation distante — du code qui supprime, sur le disque de quelqu'un d'autre.
Créations
- La rotation distante, dans
copier_hors_machine, pour les deux voies — un chemin monté comme le FTP. Réglable pargarder=dans la configuration.
⚠ Le distant garde 30 par défaut, le local 7. C'est voulu : le distant est la copie de survie, sur un disque qui ne sert qu'à ça ; le local partage sa place avec le projet lui-même.
Évolutions
Web/tests/test-backup.php: 85 → 103 constats.- 60 bancs au vert, 3515 constats.
- 13 mutations, toutes détectées.
⚠ Trois mutations ont été retirées, et on dit pourquoi plutôt que de les laisser passer pour « survécues » — ce qui ferait croire le banc aveugle :
- le tri sans
LC_ALL=Cn'est pas détectable de façon portable ; le résultat dépendrait de la langue de la machine qui lance le banc ; - les deux gardes de l'ignorance se recouvrent, et le compte est figé avant elles : trois verrous imbriqués qu'aucune mutation simple ne franchit ;
-type f: sans lui,findliste le répertoire, maisrm -fsans-rrefuse de l'effacer. La garde reste — un répertoire dans la liste consomme un tour de boucle — mais elle n'est pas observable par une destruction.
4.16.45 — 12 août 2026
tls_verifier — le certificat de la box, et pourquoi ce choix se déclare.
Évolutions
Web/tests/test-backup.php: 79 → 85 constats, dont les trois qui gardent ce réglage : le défaut vérifie,nonajoute-kaux deux appels, et une valeur inconnue ne l'ajoute pas.- 60 bancs au vert, 3495 constats.
Avertissements
⚠ Le montage du disque a été essayé d'abord, et abandonné sur mesure. Le noyau WSL2 ne connaît que 9p : mount -t drvfs sur un UNC échoue, cifs est absent, un lecteur réseau Windows (F:) reste invisible depuis WSL et depuis tout processus hors session — y compris par l'interop PowerShell, donc y compris sous systemd, qui est justement le contexte de la sauvegarde. Le FTP est la seule voie qui tienne sans intervention à chaque démarrage.
4.16.44 — 12 août 2026
La sauvegarde quitte enfin la machine.
Créations
copier_hors_machinedansTools/backup-overtchat.sh— appelée après la production ET la vérification de l'archive locale : copier une archive illisible ne servirait à rien.
Deux voies, et la plus simple d'abord :
| Voie | Ce qu'il faut |
|---|---|
chemin=/mnt/z/… | Le disque connecté en lecteur réseau côté Windows — ce que BACKUP.md recommande déjà. Aucun identifiant n'a à vivre dans un fichier |
url=ftp://… | Rien à installer : curl est déjà là. Identifiants dans un fichier 600, hors dépôt |
Si les deux sont donnés, le chemin gagne : moins de pièces mobiles, et aucun secret à manipuler.
Évolutions
Web/tests/test-backup.php: 42 → 79 constats, avec un fauxcurlet uncptruqué : on exécute la fonction, on ne la relit pas. C'est le seul moyen de savoir ce qui partirait vraiment sur le réseau — et surtout ce qui ne partirait pas.- 60 bancs au vert, 3491 constats.
- 10 mutations, toutes détectées, dont celle qui crée le répertoire absent et celle qui retire l'appel depuis
do_backup.
⚠ Deux mutations ont survécu au premier essai, et les deux pour la même raison : le banc cherchait la présence d'un motif là où il y a deux appels curl — l'envoi et la relecture de la taille. Muter le premier laissait le second intact. Il compte désormais. Et la troisième survivante a révélé un trou franc : aucun constat n'éprouvait une copie tronquée par la voie chemin, un vrai cp copiant toujours tout. D'où le cp truqué.
4.16.43 — 12 août 2026
Le défaut annoncé n'existait pas — et le constat en réel l'a montré après que je l'eus « corrigé ». Un point du registre invalidé, un doublon supprimé, et un vrai défaut trouvé en chemin.
Bugs corrigés
⚠ Un vrai défaut a été trouvé en consolidant, et lui existait bel et bien. Le test qui vivait dans on_mode coupait au format seul — « dernier mot, entier d'au moins neuf chiffres ». Une limite de salon en est un :
Absurde comme limite, parfaitement valide comme mode. _sans_ts ne coupe que ce qui est en surplus de ce que les modes consomment : +l ayant consommé son paramètre, il n'y a pas de surplus, et la limite reste.
Évolutions
- Un seul retrait de l'horodatage, au point de passage unique (
record_mode). Il y en avait deux depuis le matin — et deux copies d'un même calcul divergent, c'est la règle de ce carnet. IriX/tests/test-modtrace.tcléprouve désormais le chemin S2S de bout en bout (on_mode), dont le cas+l 1786521110qui était faux.- 60 bancs au vert, 3456 constats. 6 mutations sur
modtrace, toutes détectées.
Erreurs
⚠ Le registre a porté ce point pendant un jour sans qu'il soit mesuré. Il était vraisemblable — le serveur envoie bien l'horodatage, record_mode recopie bien ce qui suit les modes — et faux, parce que les deux ne se rencontrent jamais. Une chaîne dont chaque maillon est vrai n'est pas une chaîne qui existe.
⚠ Et j'ai écrit le correctif avant l'essai. Le banc était vert, les mutations détectées : rien de tout cela ne pouvait dire que le chemin n'était pas emprunté. Seul l'essai en réel le pouvait.
4.16.42 — 12 août 2026
!banperm — le ban permanent, sur tout le réseau. Demandé par SerVuS le jour même.
Créations
::soc::ban::perm(IriX-sql.tcl), liée à!banpermenpubet exposée sur la console DCC sous.banperm.
Deux points tranchés par SerVuS :
- réservé au grade
admin— soitadmin,owneretircops. Le grade Admin/Owner d'Eggdrop reste l'autorité principale : c'est le statut de celui qui a fait lehello; - posé immédiatement sur tous les salons enregistrés, ET inscrit en
channel='*'— les deux, pour qu'il survive aux redémarrages et vaille sur les salons à venir.
⚠ channel='*' n'est pas une convention nouvelle : ::soc::ban::delete la lit déjà, et la page des réglages de salon annonce que « les bans du réseau (channel = '*') s'appliquent aussi ».
⚠ Aucune durée n'est acceptée, et c'est le sens du mot : expires reste NULL. Offrir un !banperm … 2h serait un contresens, et une seconde façon de poser un ban temporaire.
Évolutions
IriX/tests/test-banperm.tcl— 32 constats, dont le croisement des binds : le banc vérifie que la commande est réellement liée, enpubcomme en console. Quatre fois sur ce projet, la procédure était juste et personne ne l'appelait.- 60 bancs au vert, 3451 constats.
- 9 mutations, toutes détectées.
✅ Et un banc existant a fait son travail sans qu'on le lui demande. test-grades.php a rougi sur « aucune commande liée n'est passée sous silence » : la commande était liée, le site ne la documentait pas. Une commande ouverte qu'aucune page n'annonce est précisément ce que ce banc existe pour empêcher. Déclarée dans Web/inc/commandes.php — et le banc a dérivé du code le grade exigé pour le comparer à celui de la page, sans qu'on ait à le lui dire.
Erreurs
⚠⚠ Une CINQUIÈME issue de mutation a été trouvée, et elle mentait comme les quatre autres : « MUTÉE AILLEURS ». Le carnet en connaissait quatre — survécue, détectée, plantée, non appliquée. Deux mutations ont d'abord été annoncées « SURVÉCUE » : le motif if {![string match "*!*@*" $mask]} existe aussi dans ::soc::ban::add, cent lignes plus haut, et c'est elle qui était mutée. Le fichier changeait bien — le garde-fou « le fichier n'a pas changé » ne voyait donc rien — et le script concluait « le banc ne détecte pas », alors que la procédure visée n'avait pas été touchée.
Vérifier qu'un fichier a changé ne suffit pas : il faut vérifier que la BONNE zone a changé. La mutation est désormais bornée à la portée de la procédure éprouvée.
Avertissements
⚠ La nomenclature des grades reste incohérente dans le projet, et ce point n'est pas ouvert par cette version — il est seulement constaté. Quatre vocabulaires coexistent : require_grade (user…ircops), overtchat-setup.sh (owner/admin/coadmin/xop et op/halfop/voice), les colonnes (cs*), et celui de l'exploitant (Net-admin, Chef-de-bot, Helpeur…). coadmin n'existe dans rien de ce qui décide : ni colonne, ni lecture, ni écriture. L'ajouter à la seule liste require_grade en ferait un « niveau fantôme » — le défaut documenté au 20/07/2026 pour halfop et csadmin.
4.16.41 — 12 août 2026
Deux heures d'écart et un nombre de dix chiffres. Les deux derniers points que le carnet gardait ouverts sans qu'ils demandent une décision.
Bugs corrigés
Web/inc/travaux.php— chargeidentity.php, qui pose le fuseau du système. L'avis se date à l'heure locale en ligne de commande comme sur le site.IriX/cmds/irix-modtrace.tcl—_sans_tsretire l'horodatage du burst de l'affichage des modes.
Créations
IriX/tests/test-modtrace.tcl— 27 constats. Le carnet notait depuis le 11/08 qu'aucun banc Tcl ne couvraitmodtrace, alors que c'est lui qui remplit l'onglet Activité.
Évolutions
_ciblesest désormais bâtie sur_apparier, qui rend l'appariement et le nombre de paramètres consommés. Compter dans une seconde procédure aurait fait deux lectures des mêmes trois tables de modes — et la seule question aurait été de savoir quand elles divergeraient.- 59 bancs au vert, 3419 constats (58 et 3392 avant).
- 6 mutations sur
modtrace, toutes détectées — dont celle qui retire l'appel à_sans_tssans toucher à la procédure. C'est le trou à la jointure, payé quatre fois sur le chantier des robots.
4.16.40 — 12 août 2026
Sur IRC, #Accueil est #accueil — le robot le savait, la base aussi, et le bot non. Un défaut trouvé en écrivant le banc qui devait seulement vérifier que deux compteurs étaient d'accord.
Bugs corrigés
irix-botreg.tcl—salons_attendusetstat_ecartcomparent désormais les noms de salon sans égard à la casse (lsearch -exact -nocase), aux quatre endroits concernés.chargessuit sans y toucher : il compte parsalons_attendus, et le dit.irix-mandat.tcl—accorderadopte la casse de la base (set chan $connu) avant d'écrire le mandat.Web/inc/botreq.php—botreq_deposeradopte la casse de la base avant d'écrire la demande.
Créations
Web/tests/test-charge.php— le banc que le carnet réclamait depuis le 11/08 : il croise les deux implémentations de la charge. Ingrédients (les deux tables,etat = 'actif', le dédoublonnage), casse, et chemins d'écriture — plus un croisement de comportement sur les données réelles, recoupant le SQL avec un compte direct fait en PHP.
⚠ Il mesure la collation au lieu de la supposer : le jour où elle deviendrait sensible à la casse, c'est lui qui le dirait le premier.
⚠ Et il annonce ce que les données du jour ne permettent pas de distinguer — sans recouvrement entre les deux tables, le croisement n'éprouve pas le dédoublonnage, et un vert s'y lirait comme un satisfecit.
IriX/tests/test-mandat-accorder.tcl— 17 constats sur la procédure qui écrit le prêt. Elle n'était gardée par rien :test-mandat.tclcompte 116 constats et la remplace par un faux pour observer son appelant. Le trou n'était pas à la jointure cette fois — il était dans la procédure.
Évolutions
- 58 bancs au vert, 3392 constats (56 et 3346 avant).
- 20 mutations passées sur les trois corrections, toutes détectées. ⚠ L'une d'elles a survécu au premier essai : le banc cherchait la présence d'un
-nocaselà où il en fallait deux, un par source. Il compte désormais. C'est la mutation qui a trouvé la faiblesse, pas la relecture.
Avertissements
- ⚠ Les lignes déjà écrites ne sont pas réparées. La correction empêche d'en créer de nouvelles et rattrape la comparaison ; elle ne réécrit aucune ligne existante. Au 12/08 aucune ne diverge —
botreq,mandatetopmybotportent toutes la casse canonique. - ⚠ Le chemin du site n'est éprouvé que statiquement.
botreq_deposerécrit en base : le banc vérifie que la correction est en place, pas qu'elle s'exécute. Le pendant côté bot, lui, est éprouvé sur décor.
4.16.39 — 11 août 2026
La sauvegarde existe, se restaure — et la restauration a trouvé qu'elle oubliait le serveur du projet.
Créations
_exclusions_serveurs— les serveurs tiers sont désormais dérivés de ce que git ne suit pas, jamais énumérés. ⚠ Une liste écrite à la main aurait laissé passer le prochain serveur tiers ajouté : c'est le travers que ce projet paie le plus souvent. Repli sur l'exclusion large si git est indisponible — mieux vaut une archive amputée qu'une archive de 130 Mo.
Modifications
Web/tests/test-backup.php— 46 constats. ⚠ Le banc exécute la dérivation sur un décor fabriqué (un dépôt git temporaire avec un serveur suivi et un non suivi) au lieu de relire le bloc statique : depuis cette version, les motifs quetarreçoit ne sont plus tous écrits dans le script.Markdown/BACKUP.md— les userfiles des robots, trou qui n'était signalé nulle part.
Erreurs
⚠ Mon banc a crié sur du code juste, et il avait raison de crier. En lisant le bloc EXCLUDES=(…) statique, il ne voyait plus les exclusions ajoutées à l'exécution — donc moins de motifs que tar n'en recevra. Il accusait le script de ne plus exclure Servers/ircu, qu'il exclut pourtant. Il comparait le code à une image périmée de lui-même.
⚠ Et mon premier correctif de banc ne prouvait rien : il passait $R, qui est un préfixe fictif (Service-Overtchat) et non un chemin, puis le vrai clone — dont git ne répond pas à travers un montage Windows. Dans les deux cas la dérivation rendait le vide, et les constats passaient sans rien mesurer. D'où le décor fabriqué.
4.16.38 — 11 août 2026
Le chantier des quatre éditions est préparé — et il ne doit pas s'ouvrir maintenant.
Créations
Markdown/EDITIONS.md— l'inventaire mesuré, les quatre éditions détaillées, cinq questions à trancher avant d'écrire une ligne, la licence, l'hébergement, le portage Windows.
Avertissements
⚠⚠ Le point le plus dur n'est pas technique. Le projet est sous licence MIT : « vous pouvez le copier, le modifier, le redistribuer et vous en servir, y compris commercialement ». N'importe qui peut donc retirer une limitation et redistribuer. Une édition payante fondée sur du MIT vend un service — hébergement, mises à jour, support —, pas un logiciel. Les deux autres voies (changer de licence, garder un dépôt fermé) sont décrites, avec ce qu'elles coûtent.
⚠ Windows : l'obstacle est l'installateur, pas le serveur. Le serveur emploie epoll avec un repli poll(2) — la boucle d'événements est déjà derrière une abstraction, donc le portage est ciblé sur event.c et la couche socket. Les 10 429 lignes de bash de l'installateur, elles, seraient à réécrire entièrement.
⚠ Une édition, c'est aussi une campagne de bancs. Aujourd'hui : 56 bancs, 3 342 constats, sur une configuration. Sans une campagne par édition, trois sur quatre casseront sans que personne le voie — personne ne les installe tous les jours.
⚠⚠ Et le chantier ne doit pas démarrer tant que les huit points du registre sont ouverts, dont la sauvegarde qui n'a jamais produit d'archive. Un projet qu'on découpe en quatre multiplie par quatre ce qu'il a de bancal. Les défauts trouvés aujourd'hui ne se sont vus qu'en faisant tourner le projet ; quatre éditions, ce sont quatre choses à faire tourner.
4.16.37 — 11 août 2026
Un SQUIT ne nous concerne que s'il nous désigne. Et le coupable n'était pas celui que j'avais nommé.
Créations
::soc::ulines::auto::squit_nous_vise— compare la cible à notre nom de serveur et à notre SID. ⚠ Les deux : certains serveurs SQUITent par nom, d'autres par identifiant, et n'en reconnaître qu'une forme laisserait IriX accroché à un lien que le serveur vient de couper. ⚠ Comparaison insensible à la casse, et par égalité — un nom qui contient le nôtre n'est pas le nôtre.IriX/tests/test-squit.tcl— 12 constats, 4 mutations, dont celle qui remet l'ancien code.
Avertissements
⚠ On TIENT quand le SQUIT ne nous vise pas, et le risque est assumé. Si le serveur nous coupait vraiment, il fermerait aussi le socket et l'eof s'en chargerait. Se déconnecter par excès de prudence, en revanche, coupe un lien qui allait très bien — c'est le défaut qu'on vient de fermer.
4.16.36 — 11 août 2026
L'installateur pose le SID d'Anope tout seul — la dernière des quatre valeurs qu'il fabriquait au lieu de les lire.
Créations
_anope_link_sid— ancré sur le nom du bloc, comme le mot de passe. ⚠ Le bloc d'IriX en réserve un autre et vient en premier dans le fichier : prendre « le premiersidvenu » donnerait à Anope l'identifiant du bot, c'est-à-dire deux serveurs pour un même SID.
Modifications
Bootstrap/tests/test-anope-lien.sh— 35 constats, 5 mutations. ⚠ La commandesedest extraite du script, jamais recopiée dans le banc : une copie aurait divergé le jour où l'originale change, et le banc aurait continué d'éprouver l'ancienne.
Avertissements
⚠⚠ Un SQUIT d'un ULine emporte le lien de l'AUTRE ULine, et c'est systématique. Un arrêt propre d'Anope fait tomber IriX, qui revient seul en une vingtaine de secondes. Ce n'est pas un accident d'essai : c'est ce qui a rendu les tentatives d'Anope si coûteuses, puisque Restart=on-failure le relançait toutes les dix secondes et que chaque tour emportait IriX.
⚠ CETTE VERSION A ACCUSÉ LE SERVEUR — À TORT. La cause était dans IriX, et le correctif est en 4.16.37 : la branche
SQUITdu dispatcher se déconnectait sur tout SQUIT passant sur le lien, sans regarder sa cible. Le serveur, lui, faisait son travail. Ce paragraphe est conservé tel qu'il a été écrit ; le suivant dit ce qu'il en était.
⚠ Anope est arrêté et disabled, à la demande de SerVuS : il sert à éprouver l'installation, la configuration et le lancement — pas à tourner. Le réseau reste servi par OverNick, OverTchat, OverBot, OverHub et OverWeb.
4.16.35 — 11 août 2026
Le panel disait « non déclaré » de sept services qui tournaient, et affichait ses heures avec deux heures de retard. Deux défauts signalés par SerVuS dans la demi-heure qui a suivi le premier lien d'Anope — deux choses qu'aucun banc ne regardait, et qu'aucune relecture n'aurait montrées.
Créations
anope_conf_lignes_de()— la lecture récursive, avec ses quatre gardes.
Modifications
Web/inc/identity.php— pose le fuseau du système, avant toute date.Web/tests/test-anope.php— 96 constats, 3 mutations.Web/tests/test-json.php— le fuseau de PHP contre celui du système, et la dérive des deux horloges.
Erreurs
⚠⚠ ini_get('date.timezone') NE DIT PAS si quelqu'un a choisi. Un premier jet s'y fiait pour ne pas écraser un réglage d'exploitant — et ne changeait donc rien du tout : la fonction rend "UTC", la valeur compilée dans PHP, alors qu'aucun php.ini de cette machine ne déclare quoi que ce soit. Mesuré par grep, après avoir constaté que la correction n'avait aucun effet. Le piège est le même que celui de date_default_timezone_get(), que le commentaire dénonçait deux lignes plus bas.
⚠ Et deux constats neufs ont échoué sur du code juste, pour la même raison qu'hier : un motif trop large. Ils cherchaient le mot dehors dans les lignes rendues — or ../dehors.conf, le nom même de l'include refusé, contient ce mot. On cherche désormais name = "dehors".
⚠ Un constat dont la cible n'existe pas ne prouve rien. Le premier jet visait ../suite.conf, un chemin qui ne menait à aucun fichier : la lecture le sautait faute de cible, garde ou pas, et le constat restait vert sur un code sans protection. La mutation qui retirait les deux gardes de chemin a donc survécu. Le décor pose maintenant une vraie cible un cran au-dessus.
4.16.34 — 11 août 2026
Le burst des bans n'envoyait pas l'horodatage du salon — et c'est ce qui fermait le lien vers Anope.
Modifications
Servers/overtchat-hybrid/src/s_serv.c—burst_channelajoutechan->creationtime, le même horodatage que leSJOINquelques lignes plus haut. ⚠ Celui du SALON, pas celui du ban : c'est l'horodatage du salon qui arbitre les modes ; la date de pose ne dit rien à l'autre bout.
Avertissements
⚠ IriX reçoit le même burst, et son record_mode prend tout ce qui suit la cible comme paramètres de mode. L'appariement reste juste — _cibles consomme un paramètre par mode et ignore le surplus —, mais l'horodatage apparaîtra dans le texte journalisé d'un +b reçu au burst. À constater à la prochaine reconnexion d'IriX, et à corriger si l'onglet Activité en souffre. Aucun banc Tcl ne couvre modtrace.
⚠ Les bans serveur ne survivent pas à un redémarrage, et rien ne les retire au SQUIT. Mesuré en lisant ban.c : aucune persistance disque, et ban_remove n'est appelée que par un retrait manuel d'opérateur. Un service qui tombe laisse donc ses Q-lines jusqu'au prochain redémarrage du serveur — quatre l'ont été ici (OperServ, MemoServ, HostServ, Global), posées douze fois chacune par un Anope qui bouclait sur Restart=on-failure. Elles sont parties avec ce redémarrage. Le défaut de fond reste ouvert : sur un réseau qui ne redémarre pas, elles resteraient pour toujours.
4.16.33 — 11 août 2026
Le prêt de robot va d'un bout à l'autre — constaté. Et le port d'Anope était fabriqué, une heure après avoir corrigé le nom et le mot de passe.
Créations
_anope_srv_port— le port du listenerserversonly, lu. ⚠ Le bloclistenporte sonportavant sesoptions: on accumule le bloc et on ne décide qu'à l'accolade fermante. Lire le port dès qu'on le voit rendrait celui du premierlistendu fichier — 6667, les clients.
Modifications
Bootstrap/tests/test-anope-lien.sh— 26 constats, 5 mutations. Le décor porte maintenant les trois listeners dans l'ordre réel, celui des clients en premier : c'est le seul agencement où l'erreur se voit.
Erreurs
⚠ La trace du mandat a été cherchée dans le mauvais journal. ::soc::log n'écrit pas dans IriX/runtime/IriX.log mais dans IriX/cmds/IriX-sql.log. Le premier ne montrait aucune ligne mandat : +o alors que le MODE était bien parti — de quoi conclure à un mécanisme muet, ou pire, à un appel vers une procédure inexistante. Elle existe, et elle avait écrit. Le registre nomme déjà ce piège : « les journaux ne sont pas là où on les cherche ».
4.16.32 — 11 août 2026
Le site annonçait 80 places libres. Une était occupée depuis deux heures.
Modifications
Web/inc/botreg.php— la charge réunit les deux tables. ⚠ LeNOT INévite qu'un salon cité par les deux compte double. ⚠ Sans aucune des deux tables, la charge resteNULL— inconnue, pas nulle :botreg_placesécarte alors le robot au lieu de lui prêter toutes ses places.Web/tests/test-botreg.php— 129 constats, 4 mutations.
Créations
botreg_charge_sql()— l'expression SQL extraite, pure donc éprouvable. Elle était noyée dansbotreg_robots(), qui interroge la base et ne peut être appelée sans elle : la logique du compte n'était couverte par aucun constat, dans un banc qui en porte cent vingt.
Avertissements
⚠ Trois copies restent trois copies. Elles sont désormais d'accord, et rien ne les empêche de diverger à nouveau : deux sont en Tcl, une en PHP, et aucun banc ne les croise. Le banc du site vérifie déjà la péremption d'observation contre le module Tcl — le même geste vaudrait ici.
4.16.31 — 11 août 2026
La page Anope donne enfin la commande à taper — et un banc vérifie qu'elle existe encore.
⚠ Une page qui donne une commande doit être éprouvée comme du code
Une commande renommée, et cette page envoie l'exploitant sur « Option inconnue » — sans que rien ne le signale, puisque le texte reste parfaitement lisible. Le banc lit la commande dans la page et la cherche dans le script : à trois endroits, le dispatcher d'arguments, _cli_commande, et l'écran d'aide.
⚠ Il ne compare pas deux chaînes écrites à la main. Une constante recopiée dans le banc aurait divergé exactement comme le texte qu'elle prétend garder.
Modifications
Web/pages/anope.php— la commande, et ce qu'elle propose désormais seule.Web/tests/test-anope.php— 84 constats (78 avant), 2 mutations.
Erreurs
⚠ Le premier jet de ce banc laissait passer la mutation qu'il visait. Le constat sur l'écran d'aide cherchait la commande n'importe où après le mot USAGE, en mode /s : le motif traversait les dix mille lignes du script et retombait sur les occurrences du dispatcher. Retirer la commande de l'aide laissait donc le constat au vert. La sous-chaîne n'est pas une preuve — le banc extrait maintenant le bloc, puis cherche dedans.
⚠ Et une mesure trop large a fait accuser le panel à tort. Le rendu hors navigateur, qui sert à éprouver les pages, extrait le texte par strip_tags — lequel ignore l'attribut hidden. Une pastille masquée « v4.16.27 disponible » est ainsi ressortie comme si elle était à l'écran, et a été prise pour un défaut : le panel aurait annoncé une mise à jour vers une version plus ancienne que l'installée. Il n'en affichait rien, et update_verdict faisait exactement son travail. L'outil de mesure retire désormais ce qui est masqué avant de lire.
4.16.30 — 11 août 2026
Anope ne pouvait plus être configuré, et le nom qu'on allait lui donner n'existait nulle part. Trois défauts trouvés avant son premier démarrage.
Créations
anope-config— une commande, pour un geste qui n'en demandait pas moins de cinq. Elle écrit la configuration si elle manque et ne touche à rien si elle est là. ⚠ Elle pose des questions : l'écran d'aide la range à part des commandes utilisables depuis une tâche planifiée._anope_srv_conf,_anope_link_noms,_anope_link_pass— la lecture du bloclink. ⚠ Le registre des serveurs ne suffisait pas : son champconfigvautnullet la configuration en service vit hors du dépôt._service_configure_si_besoin— le rattrapage. Anope seul, par constat et non par principe : c'est le seul des trois services dont on ait vérifié qu'il refuse de démarrer sans configuration.Bootstrap/tests/test-anope-lien.sh— 22 constats, 3 mutations.
Modifications
IriX/cmds/irix-botreg.tcl—chargescompte désormais parsalons_attendus. Un robot ne tenant que des prêts s'annonçait à0/20et pouvait se voir confier vingt salons de plus. Tranché par SerVuS : un prêt occupe une place du parc. ⚠ Le dédoublonnage n'est pas un détail : deuxCOUNT(*)additionnés compteraient deux fois un salon que les deux tables citent, et rempliraient le parc plus vite qu'il ne se remplit.Tools/bancs.sh— les bancsbashsont découverts.
Erreurs
⚠ Une mutation a survécu au premier jet du banc, et elle avait raison. Le constat qui gardait l'arrêt à l'accolade fermante ne prouvait rien : tant que le bloc visé porte un mot de passe, la lecture sort dessus et la garde ne sert jamais. Il fallait un bloc link sans mot de passe, suivi d'un bloc oper qui en porte un — alors l'absence de garde se voit, et le lien hérite du secret d'un opérateur.
Le cas manquait au décor, pas au code. Sans la passe de mutation, ce banc serait resté vert en ne mesurant rien — c'est le fil du 10/08, appliqué cette fois à un banc écrit le jour même.
4.16.29 — 11 août 2026
Le salon prêté n'est plus signalé « en trop » — un robot à sa place ne produit plus d'erreur toutes les cinq minutes.
Modifications
IriX/cmds/irix-botreg.tcl—salons_attendusréunit les deux sources. ⚠ Deux requêtes, pas unUNION: les deux tables peuvent porter des collations différentes selon qu'elles sont nées d'une migration ou du Tcl, et unUNIONlèverait 1271 sur la divergence. Chaque source sous son proprecatch, pour qu'un déploiement partiel rende encore l'autre.IriX/tests/test-botreg-proto.tcl— huit constats neufs, dont celui de la jointure. Vérifiés contre l'ancien code : six échouent, le banc attrape donc bien le défaut.
Avertissements
⚠ ::soc::botreg::charges garde le même angle mort, et ce n'est pas corrigé ici. Elle compte la charge d'un robot sur ${t}_botreg seul : un robot qui ne tiendrait que des prêts s'annonce à 0/20 et pourrait se voir confier vingt salons de plus. Sans effet aujourd'hui — un seul prêt, aucun enregistrement OPMYBOT —, mais c'est une décision de conception à prendre : un prêt occupe-t-il une place du parc ? En attente d'arbitrage.
Erreurs
⚠ Le piège des listes Tcl, refait pour la troisième fois — et pour la deuxième fois dans le banc qui l'annonce. Trois constats neufs comparaient la liste rendue par salons_attendus à #alpha #beta ; une liste dont le premier élément commence par un dièse se représente {#alpha} #beta. Les trois ont échoué sur du code juste.
Le connaître ne suffit pas : l'avertissement était écrit dans ce fichier, à quelques lignes. D'où verifie_salons, qui compare longueur puis chaque salon par lsearch -exact — une procédure qui rend le geste faux impossible, plutôt qu'un commentaire de plus.
4.16.28 — 11 août 2026
Le robot prêté reçoit enfin son op — et la garde qui empêche de le donner à un usurpateur.
Créations
::soc::mandat::oper_si_prete— six refus, chacun fermant une porte distincte : pas de mandat, mandat fini, un autre robot que le mandataire, IriX absent, IriX présent mais pas op, robot parti entre son annonce et l'op.
Modifications
IriX/tests/test-mandat.tcl— 116 constats, 7 mutations toutes détectées, dont celle qui compte : n'importe quel robot recevrait l'op.
Erreurs
⚠ Une mutation survivante a révélé un bouchon trop grossier. Le décor du banc faisait rendre la même liste à botonchan et botisop : la mutation qui retire le contrôle d'op survivait donc, le contrôle de présence filtrant déjà. Un bouchon plus permissif que la réalité ne prouve rien — et IriX peut parfaitement siéger sans être opérateur, c'est même l'état normal après un netsplit. Les deux états sont désormais distincts, et le cas a son constat.
⚠ Et le piège des listes Tcl, refait dans le banc qui l'annonce. Un constat comparait la liste rendue à #accueil ; une liste dont le premier élément commence par un dièse se représente {#accueil}, Tcl protégeant le caractère qui ouvrirait un commentaire. Comparer [lindex $p 0], jamais la liste rendue telle quelle.
4.16.27 — 11 août 2026
Le premier prêt de robot du projet qui aboutit — et le défaut qui l'empêchait depuis toujours, au bout du chemin le plus visible.
Modifications
IriX/cmds/irix-mandat.tcl—consommerjournalise puis envoie, dans cet ordre : un accord dont on perdrait la trace serait pire qu'un robot en retard.
⚠ Quand l'ordre ne part pas, le mandat TIENT — c'est un droit, et il est écrit. Mais la demande porte alors l'échec de l'arrivée, en nommant ce qui reste vrai : « le droit tient, faire entrer le robot à la main ». Annoncer « done » laisserait le demandeur devant un salon vide.
IriX/tests/test-mandat.tcl— 102 constats, 6 mutations toutes détectées, dont le défaut d'origine et son inverse : envoyer l'ordre alors que l'accord vient d'être refusé.
Avertissements
⚠ Le prêt d'essai est ACTIF pour 24 h — OverOp-H siège sur #accueil jusqu'au 12/08 13:44. Il s'éteindra seul ; MANDATFIN #accueil le termine plus tôt.
⚠ Le robot n'est pas opérateur du salon. Le mandat lui accorde kick,ban,voice, mais l'op se pose par autoop, qui n'est pas armé sur #accueil. Le droit et le pouvoir sont deux choses, et ce lot n'a prouvé que le premier.
4.16.26 — 11 août 2026
Sur les cinq symboles qui s'affichaient en clair sur la page publique, trois étaient corrects — c'est la mesure qui accusait à tort.
Modifications
Web/inc/markdown.php— le motif du gras.Web/tests/test-markdown.php— 104 constats, dont le gras sur le vrai contenu, l'italique imbriqué, et les deux gardes d'espace.
Erreurs
⚠ Un constat neuf n'éprouvait pas ce qu'il croyait. Écrit pour tenir la garde d'espace ouvrante, il portait sur « ** texte ** » — blancs des deux côtés, un cas que la garde fermante refuse déjà seule. La mutation correspondante survivait, et le constat passait au vert sans rien tenir. Pour éprouver une garde, il faut le cas où elle est SEULE à jouer.
⚠ Et une mutation survivante ne prouve pas toujours un trou. Celle qui rendait le contenu du gras gourmand (+? → +) survit aussi — mesurée sur six cas, elle rend exactement le même HTML : \*(?!\*) interdit déjà de traverser un **. Elle est équivalente, aucun constat ne peut la détecter, et en fabriquer un reviendrait à éprouver la lettre du code plutôt que ce qu'il fait. Les compter ensemble aurait annoncé deux trous là où il n'y en avait qu'un.
4.16.25 — 11 août 2026
Le réglage autobans ne commandait rien, et personne ne s'en était aperçu parce qu'il n'avait jamais été ouvert.
Modifications
IriX/cmds/IriX-sql.tcl— le chemin en double retiré, les deux gardes posées avant la lecture de la table : après, on aurait déjà posé le+bau moment de découvrir qu'il fallait épargner la personne.Web/inc/chanreglages.php—autobansdans les trois listes qui doivent s'accorder.Web/site/salonadmin.php— la case, et ce qu'elle ne fait pas.
⚠ La page dit deux choses qu'un propriétaire ne peut pas deviner : les bans du réseau (channel = '*') s'appliquent aussi, et décocher n'enlève pas les +b déjà posés. Là non plus ce n'est pas un oubli — un +l est un plafond calculé que le robot doit défaire, un +b est une sanction que quelqu'un a voulue.
Web/tests/test-chanreglages.php— 205 constats, 8 mutations toutes détectées.
Erreurs
⚠ Huit mutations ont d'abord été rapportées « PLANTÉE » — c'est-à-dire aucune mesure. Le bac à sable ne portait que trois fichiers de Web/inc/, et chanreglages.php en charge six par cascade. Le rapport avait l'allure d'un résultat. Un banc qui ne démarre pas ne dit rien, et il faut le distinguer d'un banc qui passe — c'est la quatrième issue des scripts de mutation, et elle vient de servir une fois de plus.
Avertissements
⚠ Reste à constater : cocher la case sur un salon et vérifier les deux moitiés — qu'un masque visé est bien expulsé, et surtout qu'un opérateur du réseau ne l'est pas.
4.16.24 — 11 août 2026
Un opérateur du réseau enfermé dehors par son propre ban. SerVuS s'est banni lui-même sur #!Overtchat! pour éprouver la chaîne des bans, et s'est retrouvé incapable de parler sur le salon — donc incapable d'y lancer la commande qui l'aurait débanni.
Créations
Servers/overtchat-hybrid/tests/test-oper-outrepasse.py— 22 vérifications, 5 mutations toutes détectées.
⚠ Elle garde les deux familles à la fois. Vérifier seulement que l'opérateur passe outre un ban laisserait vivre la version « l'opérateur peut tout », qui est un autre défaut — et celui-là se paierait sur des membres qui croient à une promesse. Deux des cinq mutations gardent précisément ce défaut-là.
Modifications
Servers/overtchat-hybrid/src/channel.c—channel_can_joinetchannel_can_send.
⚠ Le contrôle établit d'abord ce qui s'appliquerait, avant de décider. Répartir un « si opérateur, sortir » dans chaque branche aurait deux défauts : la notice ne saurait plus dire laquelle des restrictions joue, et la prochaine restriction ajoutée oublierait l'exemption sans que rien ne le signale.
Servers/overtchat-hybrid/tests/run-tests.sh— seize campagnes. ⚠ La liste est tenue à la main et le fichier le dit lui-même ; les numéros ont dû être repris un par un,Tools/bancs.shdérivant d'eux le nombre annoncé.
Avertissements
✅ EN SERVICE depuis 12h50, avec l'accord de SerVuS. Le réseau est revenu entier : huit unités actives, les cinq pseudo-clients réintroduits, les quatre robots présents, dix connectés en base, et le serveur répond son 001.
⚠ L'ancien binaire est conservé en bin/overtchatd.avant-4.16.24 — le retour arrière tient en un mv et un restart.
⚠ Deux pièges pendant la pose, tous deux déjà nommés au carnet. On n'écrase pas un binaire en cours d'exécution : on copie à côté puis on mv, qui est atomique, jamais install qui tronque. Et sudo exige le suffixe .service — sans lui, la commande a demandé un mot de passe et est restée suspendue, le binaire déjà remplacé et le service pas encore redémarré. Les connaître ne suffit pas à ne pas les faire.
⚠ Reste à constater sur le vrai réseau : se rebannir, vérifier qu'on parle toujours et que la notice arrive.
⚠ Une mesure a failli être prise pour bonne alors qu'elle n'avait pas eu lieu : un cp écrit en ligne dans PowerShell a perdu ses variables sans erreur, si bien que la seizième campagne n'a pas tourné — et le lanceur a quand même affiché « toutes les campagnes passent ». Une mesure qui n'a pas eu lieu n'est pas une mesure réussie, et c'est la troisième fois que ce projet le paie.
4.16.23 — 11 août 2026
La première pose de robot qui va d'un bout à l'autre — et le quatrième défaut du chantier, qui attendait trois semaines qu'un hello soit donné.
Modifications
Tools/overop-pool.php— le robot est déclaré au parc avecorigin='auto', une valeur qui existait dans le schéma depuis l'origine sans que personne ne l'écrive : elle distingue au panel ce que le pool a posé de ce qu'un exploitant a déclaré.
⚠ Sans rien écraser si la ligne existe déjà. Un robot déclaré à la main porte peut-être un max_chans choisi ou un enabled='non' volontaire ; les remplacer par les valeurs par défaut défairait une décision d'exploitation. C'est le travers du seed « INSERT IGNORE » de juillet.
⚠ Et une déclaration ratée n'écrit pas « failed » : le robot est posé et actif, dire le contraire pousserait à le reposer. C'est le détail de « done » qui porte la réserve.
Web/tests/test-botpool.php— neuf constats de plus (49 en tout).
✅ CONSTATÉ : OverOp-T a été rattrapé à la main, sa demande étant déjà close, et il est passé online tout seul au BOTSTAT suivant. Le parc annonce quatre robots et 80 places.
4.16.22 — 11 août 2026
La protection des pseudonymes promettait à un visiteur ce qu'elle ne pouvait pas faire. Sur un réseau parlant P10, elle lui écrivait « le pseudo vous sera retiré dans 60 secondes », puis « vous êtes désormais Invite12345 » — et ne renommait personne.
Créations
- Deux aides dans
irix-proto.tcl:sait_sur, qui demande sans lever, etsignaler_absence, qui journalise une seule fois par dialecte et par fonction.
⚠ Ce « une seule fois » n'est pas du confort. La garde passe une fois par visiteur non identifié : écrire à chaque passage remplirait le journal du même constat et noierait tout le reste.
IriX/tests/test-proto-absence.tcl— 38 constats, 9 mutations toutes détectées, dont celle qui compte : déplacer le contrôle APRÈS la notice rétablit le défaut mot pour mot, et le banc le voit.
Modifications
irix-nickguard.tcl— sur un lien qui ne sait pas renommer, la garde retombe sur son comportement désarmé. L'avertissement part quand même : il informe le visiteur que le pseudonyme est enregistré, ce qui le concerne, et ne lui promet plus rien. Aucune minuterie n'est posée.
⚠ L'ordre est tout le correctif. Le contrôle est avant la notice, dans les deux procédures.
irix-operjoin.tcl— même chose pour l'entrée dans les salons d'opérateurs et pour le mode qui les réserve. ⚠ Le contrôle y précède même la requête SQL : interroger la base pour lever ensuite sur chaque salon coûterait une requête pour rien.
Avertissements
⚠ Ce lot corrige le silence, pas l'échec. Sur un réseau P10, la protection des pseudonymes reste un avertissement sans suite, et les salons d'opérateurs ne sont pas réservés. C'est ce que la table des capacités disait déjà au panel ; c'est désormais aussi ce que dit le journal, et ce que le visiteur ne s'entend plus promettre.
4.16.21 — 11 août 2026
Une page qui pilotait un service envoyait sans jamais savoir ce qui revenait. La colonne raw_reply existait depuis l'origine du schéma et n'était ni écrite ni lue : un SVSNICK refusé, un pseudonyme inconnu, un mode invalide — le panel affichait « sent » avec la même sérénité qu'une commande ait abouti ou qu'elle ait été rejetée.
Créations
IriX/tests/test-ulcmd-retour.tcl— 44 constats, 11 mutations toutes détectées. Les procédures sont extraites du fichier servi, jamais recopiées.
Modifications
IriX/cmds/IriX-sql.tcl— cinq procédures de capture, et les deux accroches.
⚠ Un piège de Tcl évité de justesse. Le premier jet déclarait ses constantes par variable reponse_fenetre. Ce fichier n'ouvre aucun namespace eval — ses procédures sont déclarées par leur nom qualifié —, si bien que ce variable aurait posé ::reponse_fenetre, dans le namespace global. Les procédures auraient lu une variable inexistante et la fenêtre aurait valu la chaîne vide. C'est la forme set au nom complet qu'emploie déjà tout le sous-système ; un constat du banc l'exige désormais.
Web/pages/ulines.php— colonne « Retour » dans la file des commandes. La mention de proximité est écartée de l'aperçu, où elle serait identique partout, et conservée dans l'infobulle, où l'on lit vraiment le détail.
Avertissements
⚠ Le tampon vit en mémoire jusqu'à la fermeture. Un redémarrage du bot pendant la fenêtre perd la capture en cours : la commande reste « sent » sans retour — c'est-à-dire exactement l'état d'avant. Rien n'est dégradé.
⚠ Reste à constater sur un vrai lien. La capture n'a été éprouvée que hors réseau. Il y faut une commande qui provoque une réponse — par exemple !ulcmdq <lien> WHOIS Inexistant depuis IRC —, puis la colonne « Retour » de ?p=ulines.
4.16.20 — 11 août 2026
Il n'existait aucune sauvegarde de cette installation. Le mécanisme est écrit depuis juillet, documenté sur deux cent trente lignes, éprouvé — et il n'avait jamais tourné une seule fois.
Créations
Config/systemd/overtchat-backup.{service,timer}— un passage par jour à 4 h, avec la base.
| Choix de l'unité | Contre quoi |
|---|---|
Persistent=true | ⚠⚠ La machine est un poste de bureau : elle ne tourne pas à 4 h. Sans cette ligne le minuteur ne partirait jamais, et cela ne se verrait pas — il serait « active » pendant que le service n'a jamais tourné |
Aucun SuccessExitStatus | Les deux autres minuteurs du projet en portent un, à raison. Ici, une sauvegarde ratée comptée pour un succès ne se découvrirait qu'en restaurant |
PrivateTmp=true | Le dump SQL transite en clair par un répertoire temporaire. L'archive, elle, n'est jamais écrite en clair — gpg chiffre à la volée |
Web/tests/test-backup.php— 42 constats, 9 mutations toutes détectées. Il éprouve les motifs d'exclusion contre des chemins témoins, comme tar les appliquerait. ⚠ Un premier jet ne testait que les préfixes et accusait le script de ne pas exclure le dépôt git : sans--anchored, un motif tar matche aussi un suffixe de composants. C'était le contrôle qui avait tort.
Modifications
Tools/backup-overtchat.sh— les exclusions d'Anope, la cible de restauration, et trois durcissements :
⚠ --with-db échoue au lieu d'avertir. Mot de passe introuvable, mysqldump absent, dump refusé, dump vide : ces quatre cas étaient de simples avertissements, l'archive se créait, le script rendait 0, et l'on croyait avoir sauvegardé la base. Sur un passage automatique que personne ne lit, c'est une confirmation mensongère. Le durcissement ne vaut que pour l'option : sans elle, rien ne change.
⚠ Le mot de passe MySQL se lit dans IriX.json, là où le nom de la base et le compte l'étaient déjà. Le script en lisait deux sur trois et exigeait le troisième en variable d'environnement — si bien que --with-db ne marchait qu'à la main. Il n'est jamais exporté globalement, seulement passé en préfixe de mysqldump.
⚠ Un seuil d'alerte à 25 Mo. Il n'échoue pas — une grosse archive reste valide — mais il nomme les trois plus gros répertoires. C'est le même raisonnement que le signalement des bancs muets de la 4.16.19 : le vrai correctif d'un défaut silencieux n'est pas le correctif, c'est de rendre le prochain bruyant.
Markdown/BACKUP.md,ROADMAP.md,CHANTIERS.md,ARCHITECTURE.md,INSTALL.md— la nouvelle unité, et les deux défauts.
Avertissements
⚠⚠ Rien n'est encore sauvegardé, et il faut deux gestes pour que ça le soit. D'abord poser la phrase secrète, et la recopier ailleurs : sans elle, les archives sont irrécupérables — y compris celle qui contiendrait le fichier. Un mot de passe ne se pose jamais automatiquement, c'est une règle de ce projet. Ensuite installer l'unité. Les deux commandes sont dans Markdown/BACKUP.md.
Tant que ce n'est pas fait, une perte disque emporte la base, les configurations hors dépôt et Components/Service/anope/conf.
4.16.19 — 11 août 2026
L'outil qui éprouve était le seul que personne n'éprouvait. Le lanceur de bancs annonçait un total faux de 242 constats, et il le faisait depuis des semaines sans que rien ne le signale.
Créations
Web/tests/test-bancs.php— le banc du lanceur, 23 constats et 5 mutations toutes détectées. ⚠ Il exécute la fonction extraite du fichier réel, il ne la réécrit pas en PHP : une copie du motif serait une seconde liste des mêmes règles, et elles divergeraient au premier correctif.
⚠ Son premier jet analysait les bancs eux-mêmes, ligne par ligne, pour vérifier que leur résumé est lisible. Mesuré : deux faux positifs immédiats — test-anope.php écrit le sien dans un ternaire sur trois lignes, et test-protection.php porte une ligne d'échec dont le premier nombre n'est pas le compte. Abandonné. La couverture est tenue à l'exécution, par le signalement ci-dessus, qui ne peut pas accuser à tort.
Modifications
Tools/bancs.sh— les deux familles de format, et le signalement des bancs dont aucun constat n'a été lu.Markdown/CHANTIERS.md,Markdown/ROADMAP.md— revue du 11/08, ci-dessous.
Suppressions
- La table des dix-neuf bancs de
ROADMAP.md. Elle en décrivait dix-neuf quand il y en avait cinquante et un, avec des comptes du 02/08 dont la plupart étaient faux neuf jours plus tard. Elle prévenait elle-même, deux lignes plus haut, qu'elle avait perdu onze entrées et qu'il ne fallait pas la lire. Une liste qui prévient qu'elle ment reste une liste qui ment.
Erreurs
Trois affirmations d'état périmées, trouvées en mesurant plutôt qu'en relisant. Aucune n'était une faute : toutes disaient vrai le jour où elles ont été écrites.
| Où | Ce qui était écrit | Ce qui est mesuré le 11/08 |
|---|---|---|
CHANTIERS.md, point 5 | « l'état d'origine (non) a été remis » pour autolimit | oui sur quatre salons, cochés depuis le panel le 10/08 à 19h25 — sept heures après que la phrase eut été écrite |
CHANTIERS.md, point 3 | chat_hist porte 7 lignes | 30 |
ROADMAP.md, phase 4 | trois manques annoncés | les trois sont comblés — courriel de décision (05/08), webchat, garde-fous du panel |
✅ Et le point 5 y gagne un constat qu'il attendait : « constater qu'un propriétaire coche une case et voit l'effet sur son salon » était sa dernière condition hors autobans. C'est fait — du panel, sur quatre vrais salons, et le journal du bot porte le MODE +l 3 correspondant sur chacun.
Avertissements
⚠ autolimit armé sur #accueil met un +l permanent sur le salon d'accueil du réseau. Il se recalcule à chaque entrée et chaque sortie, donc il ne ferme la porte à personne — mais il ne se recalcule que par IriX. Le bot absent, la dernière valeur reste posée. Ce n'est pas une raison de retirer le réglage, c'en est une de compter ce +l parmi ce qu'une panne d'IriX emporte avec elle.
⚠ ${t}_bans est toujours vide, et c'est le dernier verrou d'autobans : un !newban depuis IRC suffit à le lever.
4.16.18 — 10 août 2026
Une septième case de mode, réservée aux opérateurs du réseau. Signalé par SerVuS : il voulait poser +O sur #!Services! et la page ne le proposait pas.
Avertissements
⚠ Une mutation a survécu, et elle était la plus grave : retirer le rôle de l'appel fait à la validation. Tous les constats appelaient la fonction directement, jamais la décision qui s'en sert — ils restaient donc verts pendant qu'un opérateur n'aurait plus jamais pu poser +O. C'est le travers que ce fichier documente déjà pour le verrou des modes, et il a resservi sur la ligne d'à côté.
⚠ Deux constats ont par ailleurs échoué sur du code juste : des variables lues avant leur définition, et une classe [^)]* qui butait sur la parenthèse d'un transtypage.
4.16.17 — 10 août 2026
Le panel au doigt, et quatre pages qui débordaient. Suite de la 4.16.16, après avoir vérifié les quinze pages au lieu des deux déjà regardées.
4.16.16 — 10 août 2026
Les formulaires du site deviennent utilisables au doigt. Signalé par SerVuS : « je pensais pouvoir cocher les cases depuis mon téléphone, mais c'est pas pratique. »
Avertissements
⚠ !important est indispensable ici, et c'est le seul endroit de cette feuille où il l'est : ces champs portent leurs dimensions en attribut style, qui l'emporte sur toute règle externe. Sans lui, la règle est écrasée et ne sert à rien tout en paraissant présente — c'est le genre de correctif qu'on croit acquis parce qu'on le lit dans la feuille. Une mutation le vérifie.
⚠ La règle vise le doigt, pas seulement une largeur. Une tablette au stylet n'a pas le même besoin qu'un téléphone tenu à une main.
4.16.15 — 10 août 2026
Les routes du site public sont enfin croisées avec les pages qu'elles désignent. Le panel avait ce contrôle depuis longtemps ; le site, non — et une route qui désigne un fichier absent ne se voit qu'en cliquant.
Modifications
Web/tests/test-nav-site.php— le croisement, dans les deux sens, plus celui du menu : une entrée qui pointerait vers une route inexistante mènerait le visiteur sur une erreur depuis la barre de navigation, le pire endroit pour en trouver une.
Avertissements
⚠ Deux exceptions sont volontaires, et le banc exige qu'elles le restent. La page d'erreur n'a pas de route — c'est elle qui répond quand aucune ne correspond. Et le chat n'est routé que si le webchat est proposé : sans cela, une installation qui n'a pas ouvert son listener servirait une page annonçant son propre échec. ⚠ Son absence retombe alors sur l'accueil plutôt que sur une erreur, parce que l'adresse a existé et traîne dans les favoris.
⚠ La tolérance accordée au chat est elle-même surveillée. Sans ce garde-fou, elle masquerait une vraie route morte le jour où le chat cesserait d'être conditionnel — une exception qu'on n'éprouve plus devient un trou.
4.16.14 — 10 août 2026
L'accueil du panel montre les Eggdrop posés sur la machine, et l'état de leur console. Demandé par SerVuS.
Modifications
Web/inc/sys.php— le relevé, et la lecture du port de console.
⚠ L'inventaire vient de systemd, pas du disque. Le site tourne sous un compte qui ne peut pas lire les répertoires des robots posés automatiquement — ils sont créés en 0750. Un relevé fondé sur le disque aurait vu les anciens et manqué tous les nouveaux : le pire des inventaires, celui qui paraît complet.
⚠ Les robots qui attendent leur hello y figurent aussi. Ils tournent dans une unité transitoire, pas encore sous leur unité définitive : ne regarder que celle-ci les aurait tus, et un robot posé puis oublié ne se signale nulle part ailleurs.
Web/pages/admin.php— le tableau. Une console n'est dite ouverte que si le port répond : lelistende la configuration ne dit que l'intention.
Bugs corrigés
| Symptôme | Cause | Portée |
|---|---|---|
| La console d'IriX était annoncée fermée sur un port qui répond très bien | Eggdrop accepte deux formes — listen 3333 et listen 127.0.0.1 3333 —, et le motif lisait le premier nombre venu : il rendait 127 | ⚠ L'écart ne se voit pas au dépôt : la configuration de la machine est ignorée par git, parce qu'elle lui est propre. Lire le fichier versionné aurait donné raison au motif fautif |
Avertissements
⚠ Le banc du panel a rattrapé une classe inventée dans mon propre tableau — badge bad, qui figure déjà parmi les sept noms trouvés le 02/08/2026. Le vocabulaire du panel est clos, et il ne se devine pas.
⚠ Et j'ai d'abord écrit la grille du SITE dans une page du PANEL. Les deux feuilles ont des vocabulaires proches et ne se prêtent rien : c'est exactement le défaut corrigé ce matin, refait dans l'autre sens une heure plus tard.
⚠ Un constat non discriminant laisse survivre une mutation. Celui qui éprouvait listen-addr n'employait que la forme guillemetée du projet — or c'est elle qui bloque tout motif, quel qu'il soit. Le cas qui tranche est l'adresse nue, et il a fallu l'ajouter pour que la porte soit tenue.
4.16.13 — 10 août 2026
Le site et l'installateur annoncent désormais les mêmes serveurs, et le banc l'exige. Vérification demandée par SerVuS : les six serveurs sont-ils bien affichés, marqués, et posables ?
Modifications
Web/tests/test-compat.php— le croisement, dans les deux sens, plus la concordance des versions. ⚠ Elle n'est exigée que sur les versions précises : la page annonce « 6.x » pour UnrealIRCd, qui est une famille et non un numéro.
⚠ La page dit p10, l'installateur dit ircu : ce sont le protocole et le logiciel qui le parle. La correspondance ne se devine pas — elle est déclarée, et un contrôle exige qu'elle couvre tous les serveurs, de sorte qu'un ajout au site sans entrée fasse rougir le banc.
Avertissements
⚠ Une sous-chaîne n'est pas une preuve, et c'est la troisième fois. Le contrôle du serveur maison cherchait overtchat-hybrid ; la mutation qui renommait le répertoire en overtchat-hybrid-absent y a survécu, puisque le second contient le premier. Même piège que le sélecteur CSS et que la boucle cherchée dans tout un fichier. Ancrer, ou poser une limite de mot.
4.16.12 — 10 août 2026
Une installation neuve ne recevait ni sa version, ni son journal. Trouvé en vérifiant, à la demande de SerVuS, que le projet s'installe encore correctement après les corrections de la journée.
Modifications
Web/inc/distrib.php— la liste des fichiers de racine que le site emporte, et leur surveillance. ⚠ Elle est close et courte :Markdown/entier n'a rien à partir — ce sont les cahiers de travail du projet, pas des fichiers dont le site a besoin pour fonctionner.
Créations
Web/tests/test-distrib.php— 17 constats. ⚠ Il dérive ce que le site lit hors deWeb/au lieu de recopier une liste : une page qui lira un fichier de plus fera rougir le banc, au lieu d'être découverte par un nouvel administrateur. 6 mutations, 6 détectées.
✅ Vérifié sur une extraction réelle : version, journal, registre et installateur sont là, et aucun fichier sensible ne part.
4.16.11 — 10 août 2026
Les colonnes citées par le code sont désormais croisées avec celles qui existent. C'est le défaut le plus répété du projet : cinq colonnes nommées de mémoire le 07/08, aucune n'existait ; deux de plus le 09/08 sur les tables de l'IA ; une de plus le 10/08 en écrivant un simple contrôle.
Créations
Web/tests/test-colonnes.php— il relève le schéma réel, lit les sources, et croise. Résultat du jour : 299 requêtes examinées sur 54 tables, aucune colonne absente.
⚠ Il renonce plutôt que de deviner : une liste qui porte un décompte, un alias ou une jointure est sautée en entier. Un faux positif coûte plus cher qu'un manque — il fait douter de tout le reste du rapport.
Avertissements
⚠ Sa première version rendait « aucune colonne suspecte » après avoir examiné ZÉRO requête. Le nom de table n'est jamais écrit en clair dans ce projet, et le motif ne reconnaissait donc rien. Le rapport se lisait comme un satisfecit. Un audit qui n'examine rien doit rougir, pas conclure — c'est la même leçon que la mutation qui ne s'applique pas.
⚠ Et le garde-fou compte PAR FAMILLE, pas en total. Une mutation a cassé le seul motif du site : le banc est resté vert, celui du robot fournissant encore assez de requêtes pour satisfaire un seuil global. Une moitié d'audit qui se tait vaut un audit qui ment.
⚠ Une mutation a dû être écartée comme invalide : elle neutralisait le constat final du banc lui-même. Aucun banc ne résiste à ce qu'on le mute pour qu'il mente — ce n'était pas un trou, c'était une mauvaise question.
4.16.10 — 10 août 2026
La pose automatique d'un robot ne pouvait pas aboutir. La première jamais tentée l'a montré en une minute, après des semaines où tout était « écrit et éprouvé ».
Modifications
Tools/overop-pool.php— la pose se fait désormais en deux temps, avec le geste humain au milieu.
Premier passage : le robot est posé, lancé, et la demande passe « en cours » avec ce qu'on attend d'elle. ⚠ Ce qui prouve la pose, c'est que le robot tourne — pas qu'un fichier soit là : un fichier de PID survit à un processus mort.
Passages suivants : dès que le hello a eu lieu, le robot passe sous systemd et la demande est close. ⚠ Tant qu'il n'a pas eu lieu, rien n'est déclaré en échec : il ne s'est rien passé de fautif.
⚠ Et le robot est remis debout s'il est tombé entre deux passages. Il n'est pas encore sous systemd : rien ne le relance, et le hello de l'exploitant tomberait dans le vide sans que personne sache pourquoi.
Avertissements
⚠ Le hello ne s'automatise pas, et ce n'est pas une limite technique. Il désigne un propriétaire. Dans ce projet, les comptes ne se posent jamais tout seuls — la règle vaut ici comme ailleurs.
⚠ Quatre poses ont été nécessaires pour trois causes. Chacune était cachée derrière la précédente : tant que la première bloquait, les deux autres ne pouvaient pas se montrer. Un mécanisme qu'on n'a jamais fait tourner en entier n'a pas un défaut, il en a une pile — et vingt-quatre contrôles au vert n'en disent rien.
4.16.9 — 10 août 2026
Le panel annonçait un port de liaison qui n'existe pas sur ce serveur. Le 7000 était celui d'UnrealIRCd ; Overtchat-Hybrid porte le sien sur 6900 et n'ouvre rien sur 7000. Mesuré ce jour-là : il n'est pas dans les ports en écoute de la machine, quand 6667, 6697, 6900 et 8000 y sont tous.
Modifications
Web/pages/admin.php,Web/pages/serveur.php— le 7000 cède la place au WebSocket du chat, servi par l'un comme par l'autre serveur. ⚠ Le port est lu dans la constante, jamais recopié : il se règle dans la configuration, et une valeur en dur s'en détacherait au premier changement.
Web/tests/test-statut.php— les trois listes sont désormais croisées, plutôt que la seule qui avait été corrigée en premier. ⚠ Le contrôle ignore les commentaires : les trois fichiers expliquent justement pourquoi ce port a été retiré, et rougir dessus obligerait à effacer l'explication pour faire passer le banc — le pire des remèdes. Une mutation vérifie cette tolérance, en exigeant que le banc reste vert.
Évolutions
Les 28 onglets du panel ont été rendus un par un, hors navigateur, un processus par page. Résultat : aucune notice, aucune page nue, aucun processus tombé. C'est ce rendu qui a mis le port en évidence.
⚠ Le premier passage accusait deux pages à tort. Un set_error_handler est appelé même pour ce que @ supprime : c'est à lui de consulter error_reporting(). La sonde de ports porte son @ depuis longtemps, documenté sur vingt lignes. Le défaut était dans la mesure, pas dans le code mesuré.
4.16.8 — 10 août 2026
Sept endroits du site s'affichaient sans leur mise en forme. Les classes employées existaient — mais dans app.css, la feuille du panel. Le site public ne charge que site.css : ces éléments se rendaient nus, sans erreur, sans une ligne au journal. On ne les voit qu'en regardant.
Modifications
Web/public/assets/site.css— quatre règles qui manquaient. ⚠ La couleur de la carte d'avertissement vient de la variable du site, pas de la valeur en dur que le panel emploie.
Web/site/compatibilite.php,installation.php— deux corrigées dans la page, pas dans la feuille : les classes du site existaient déjà sous un autre nom. ⚠ Le vocabulaire CSS du site est CLOS : on n'y ajoute une règle que si rien ne fait déjà l'usage.
Web/site/commandes.php— une classe retirée, pas ajoutée. Au panel, c'est elle qui porte le rembourrage d'une carte ; ici la carte le porte déjà. La définir aurait doublé la marge intérieure. ⚠ Une classe manquante ne se comble pas par réflexe : il faut regarder ce qu'elle ferait.
Créations
Web/tests/test-vues-site.php— 15 constats.test-vues.phpposait ces questions pour le panel ; personne ne les posait pour le site, celui que des visiteurs regardent. Les pages y sont découvertes, jamais énumérées. 8 mutations, 8 détectées.
Avertissements
⚠ Un ?> écrit dans un commentaire // ferme le bloc PHP. Le banc s'est affiché en clair au lieu de s'exécuter, parce qu'un commentaire citait la balise fermante. C'est le cousin exact de l'accolade isolée dans un commentaire Tcl, qui compte pour l'équilibrage. Écrire la balise en toutes lettres.
4.16.7 — 10 août 2026
La limite de places automatique est ouverte au propriétaire d'un salon. Tranché par SerVuS. Le robot garde deux places libres au-dessus du nombre de personnes présentes, et refait le calcul à chaque entrée et à chaque sortie.
Bugs corrigés
| Symptôme | Cause | Portée |
|---|---|---|
| Éteindre la limite ne la retirait jamais : le salon restait plafonné à sa dernière valeur, et il aurait fallu un opérateur pour libérer les places | do_autolimit sort aussitôt quand le réglage ne vaut pas oui. Rien n'envoyait le -l, et le panel n'écrit qu'en base : il ne parle pas au robot | Le réglage aurait été un piège. C'est le travers déjà corrigé pour les modes de salon — décocher doit retirer vraiment — retrouvé ici par l'autre porte |
| Cocher ne posait rien tant que le robot n'avait pas encore lu le salon | La pose exigeait un changement de valeur. Sur un cache vide, les deux lectures rendent la même chose : aucune transition n'est vue | Trouvé en éprouvant pour de vrai, pas en relisant. Le propriétaire aurait coché et n'aurait rien vu — exactement ce qu'on cherchait à éviter |
⚠ Trouvé en relisant le code AVANT d'ouvrir, pas après. Une case qui s'arme mais ne se désarme pas est pire qu'une case absente : le propriétaire croit avoir tout remis à zéro.
Modifications
IriX/cmds/IriX-sql.tcl—undo_autolimit, et les deux chemins qui y mènent. Celui de la commande!autoset, et surtout celui du panel : le robot relit sa configuration toutes les 30 secondes, et c'est là qu'il faut voir qu'un réglage vient de s'éteindre. ⚠ L'ancienne valeur ne se lit qu'avant de vider le cache — après, il n'y a plus que la nouvelle. ⚠ Un cache déjà vide rend la nouvelle valeur : le pire cas est donc un retrait manqué, jamais un retrait intempestif.
⚠ Et la POSE suit le même chemin, pour la même raison. Le calcul n'était branché qu'à l'entrée et à la sortie d'une personne : cocher la case ne faisait donc rien de visible tant que le salon ne bougeait pas. Le propriétaire regardait, ne voyait aucune limite, et concluait que le réglage ne marchait pas. Un réglage sans effet visible est un réglage qu'on croit cassé — et c'est ce qu'on allait faire constater.
⚠ La pose ne regarde que la NOUVELLE valeur, pas la transition — et c'est l'essai réel qui l'a imposé. Exiger un changement la faisait manquer chaque fois que le robot n'avait pas encore lu le salon : les deux lectures rendent alors la même valeur, on lit « oui → oui », et rien ne part. Le retrait, lui, garde la transition : sans elle, il enverrait un -l à chaque relecture de tout salon non réglé.
Web/inc/chanreglages.php— ⚠ la QUATRIÈME liste des mêmes clés a disparu. Après la liste close, les libellés et les défauts, la requête de lecture énumérait elle aussi ses colonnes à la main. Ouvrir un réglage sans qu'elle suive l'aurait rendu invisible : la page aurait affiché éternellement sa valeur par défaut pendant que la base disaitoui. C'est le défaut du 09/08/2026, à un fichier près — et il attendait dans la ligne d'à côté. Les colonnes sont désormais dérivées.
Web/site/salonadmin.php— la section « Les places de ce salon », et ce qu'elle dit au propriétaire : le nombre est calculé, et remettre sur non retire la limite.
Évolutions
⚠ Le banc de relecture éprouvait une COPIE. Il portait scan_config « recopiée telle quelle », pour ne pas charger 11 800 lignes qui exigent un Eggdrop. Une copie ne reste juste que le temps où personne ne touche à l'original : la procédure a gagné le retrait de la limite, la copie ne l'avait pas, et le banc serait resté vert en éprouvant du code qui n'est plus servi. Il découpe maintenant la vraie procédure dans le fichier — info complete en trouve la fin, c'est Tcl qui compte les accolades.
Deux croisements de plus, chacun contre un maillon qui manquait : un réglage ouvert doit avoir un champ de saisie dans la page, et la requête de lecture doit dériver de la liste close.
Avertissements
⚠ autobans reste fermé, et pas pour la même raison. Ce n'est pas le réglage qui gêne : c'est que la table des bans est vide. L'ouvrir aujourd'hui offrirait une case sans le moindre effet — exactement le travers corrigé pour les grades. Il attend qu'un opérateur pose un premier ban.
⚠ Trois mutations ont d'abord SURVÉCU, et chacune disait vrai. Un contrôle cherchait la clé n'importe où dans la page : le libellé suffisait à le satisfaire alors que la saisie avait disparu. Un autre cherchait la boucle dans tout le fichier, où une seconde boucle identique répondait pour la première — le piège du sélecteur CSS, à un fichier près. Le troisième venait du banc : son simulateur rendait l'ancienne valeur quel que soit l'endroit d'où on l'appelait, donc l'ordre des deux gestes lui était indifférent. Les trois contrôles ont été refaits, et les neuf mutations sont détectées.
4.16.6 — 10 août 2026
Cette page affichait ses propres symboles de mise en forme. Quarante-six passages du journal montraient des astérisques au lieu d'être en italique, dix accents graves traînaient au milieu du texte, un tableau portait une colonne fantôme, et la forme des ordres échangés entre robots se lisait à plat, ordre et accusé mêlés sur une seule ligne.
Modifications
Web/inc/markdown.php— quatre manques comblés.
L'italique n'était pas connu : « un compte » s'affichait avec ses astérisques. ⚠ Il ne suffit pas d'apparier deux astérisques : 867 lignes du journal en portent un, et l'immense majorité ne sont pas de l'italique mais des jokers de noms de fichiers — ui_*, overop@*. Les apparier au hasard ferait disparaître tout ce qui les sépare. Les deux astérisques doivent donc toucher du texte.
Les blocs de code n'étaient pas connus. ⚠ Ils se traitent avant le saut des lignes vides, sinon un bloc qui en contient voit ses lignes se coller les unes aux autres.
Le double accent grave — la façon de citer un accent grave littéral — s'appariait de travers et en laissait quatre visibles dans une cellule.
Enfin, le code cité est désormais mis à l'abri des autres règles au lieu d'être seulement traité en premier. ⚠ La nuance a son importance : une fois la balise écrite, les règles suivantes travaillaient encore sur son contenu, et un astérisque cité dans une commande ouvrait un italique.
Web/site/versions.php— le style des balises neuves. ⚠ Le<code>d'un bloc héritait sinon du cadre du code intra-ligne : une bordure par ligne, et un fond dans un fond.
Le sommaire affichait par ailleurs le titre brut : un titre citant un chemin y montrait ses accents graves, alors que le titre lui-même, plus bas dans la page, était rendu correctement. ⚠ Il est désormais dépouillé en passant par le rendu, et non en énumérant les syntaxes à retirer : une seconde liste se périmerait à chaque syntaxe ajoutée au moteur.
Web/inc/site.php— le menu « Installer » ne reste plus déplié. On choisissait « Serveurs compatibles », la page s'affichait, et le panneau restait ouvert par-dessus le haut du contenu. Il portaitopendès que la page courante appartenait au groupe.
⚠ Le repère de position n'est pas perdu, et c'est ce qui permettait de le retirer : le groupe reste marqué active, et le style le colore déjà en couleur d'accent — fermé ou non. Le commentaire du code défendait open par la crainte inverse ; la feuille de style y répondait déjà.
Créations
Web/tests/test-nav-site.php— 21 contrôles sur la barre du site public, qu'aucun banc ne couvrait. ⚠ L'un d'eux exige la règle de style du groupe actif : si elle disparaissait, refermer le menu deviendrait une vraie perte d'information, et plus personne ne saurait pourquoi.
Bugs corrigés
| Symptôme | Cause | Portée |
|---|---|---|
| Un tableau du journal affichait quatre colonnes sous un en-tête qui en compte trois, et deux accents graves flottaient au milieu | Le découpage des cellules coupait sur tout tube, y compris celui cité dans du code — `base\|<insulte>` | Le même défaut que celui corrigé la veille pour le tube échappé, mais par l'autre porte : ici, aucune faute d'écriture n'était visible dans le fichier |
Avertissements
⚠ Le banc était vert, et il l'est resté pendant que la page affichait tout cela. Il éprouvait le moteur sur les syntaxes qu'il connaissait déjà, pas sur ce que les fichiers servis contiennent réellement. Les contrôles ajoutés portent désormais sur le vrai contenu : aucun accent grave, aucun astérisque, aucun tilde ne doit rester visible hors du code, et chaque ligne de tableau doit compter autant de cellules que son en-tête.
⚠ Un contrôle trop large est aussi un défaut. Celui qui interdisait les tildes est passé au rouge le jour où le code a été mis à l'abri — c'est-à-dire le jour où le moteur a cessé de mettre en forme ce qu'un auteur cite volontairement. Le journal écrit `~~texte~~` pour décrire le barré : l'y laisser est le bon rendu.
4.16.5 — 9 août 2026
Le filtre de modération coupait tous les mots accentués en deux. Il découpait « découvre » en « couvre », « réseau » en « seau », « agréable » en « agr » et « able ». Un filtre censé reconnaître des propos déplacés en français, qui ne voyait jamais un mot accentué en entier.
Créations
IriX/tests/test-ia-tokens.tcl— 28 contrôles sur le découpage des mots, et 4 essais de sabotage, tous détectés. Cette partie du filtre n'était éprouvée par aucun banc : c'est ainsi que le défaut a tenu.
Modifications
IriX/cmds/IriX-sql-IA.tcl— les accents sont désormais ramenés à leur lettre simple avant le découpage. « agréable » et « agreable » donnent le même mot appris, ce qui est voulu : les gens écrivent sans accents, et deux entrées pour un mot diviseraient son compte par deux.
Bugs corrigés
- Le premier vrai trafic a été mesuré de bout en bout, et la chaîne tient : le filtre reçoit les messages, les juge, et apprend enfin ses premiers mots. Le blocage annoncé depuis trois semaines est levé.
- L'historique des salons s'écrit également — sept messages, sept lignes gardées.
Avertissements
- ⚠ Le vocabulaire appris pendant ces essais a été effacé, deux fois. Le filtre doit apprendre de vrais visiteurs, pas de messages écrits pour le tester. Le compteur est donc remis à zéro volontairement : ce n'est pas une panne, c'est l'état voulu tant que personne n'est venu parler.
- ⚠ Les alphabets non latins restent découpés. Limite assumée : le réseau est francophone.
Erreurs
- Trois essais de sabotage ont été rapportés « survécus » alors qu'ils ne s'étaient pas appliqués du tout. C'est la deuxième fois dans la journée. L'outil vérifie désormais qu'il a bien modifié le fichier, et s'arrête en erreur sinon.
4.16.4 — 9 août 2026
Le chat effaçait votre conversation en se reconnectant. Quand la connexion tombait, il affichait « Connexion interrompue par le réseau — rien de ce que vous avez écrit n'est perdu », puis se rebranchait deux secondes plus tard en vidant l'écran. Le message se démentait lui-même, et le visiteur perdait le fil de ce qu'il lisait pour une coupure dont il n'était pas la cause.
Modifications
Web/public/assets/chat.js— une reconnexion n'est plus traitée comme une connexion neuve. Les lignes déjà affichées, les onglets et les conversations privées restent. Ne repart que ce qui est devenu faux : la liste des présents, le sujet et les modes, que le serveur redonne aussitôt.- Le chat dit qu'il est revenu — « Reconnecté » — et rappelle du même coup que l'on n'est plus identifié. Sans cette ligne, l'avertissement de coupure restait le dernier message affiché et l'on croyait la panne en cours.
- Le visiteur n'est plus ramené de force sur le salon d'origine : s'il lisait une conversation privée ou un autre onglet, il y reste.
Évolutions
- La reconnexion automatique a été constatée dans un vrai navigateur, ce qu'aucun banc ne peut faire : il faut une page, une vraie connexion et une vraie coupure. Coupure à 13 h 47 min 01 s, reconnexion à 13 h 47 min 03 s — les deux secondes annoncées. Les deux salons ouverts ont été retrouvés, et le serveur a bien vu revenir la connexion.
- La garde de l'historique a été constatée du même coup : sans identification, le chat affiche « Identifiez-vous pour relire l'historique de ce salon ».
Erreurs
- En lisant le code, un second défaut avait été déduit : la liste des salons à retrouver paraissait effacée avant d'être utilisée. La mesure a montré le contraire — les deux salons revenaient. La ligne incriminée appartenait à une autre fonction. Une lecture rapide ne vaut pas une mesure, y compris quand elle accuse.
4.16.3 — 9 août 2026
Le message d'accueil du serveur pouvait promettre une protection retirée. À la connexion, il annonce que les messages privés traversent un filtre automatique. C'est vrai — sauf si un opérateur venait de couper ce filtre par une commande tapée dans son client. Le message, lui, continuait de l'affirmer, avec l'autorité que donne un texte officiel.
Créations
Config/systemd/overtchat-motd.{service,timer}— le message d'accueil est confronté à l'état réel du filtre toutes les cinq minutes, quel que soit le chemin par lequel cet état a changé.
Bugs corrigés
- Un troisième chemin échappait à tout. Le message était déjà réécrit au démarrage du serveur et après un rechargement demandé au système — les deux seuls moments prévus. Mais un opérateur peut recharger la configuration depuis son client, et ce chemin-là ne prévenait personne. Le même défaut avait été corrigé le 2 août pour l'autre porte ; celle-ci était restée ouverte.
Évolutions
- On constate désormais l'état plutôt que d'espérer avoir intercepté tous les événements qui le changent. C'est le raisonnement déjà retenu pour les opérateurs du panel : un passage régulier ferme aussi les chemins qu'on n'a pas prévus.
- Rien n'est réécrit sans raison : le générateur compare le texte composé à celui en place et ne touche à rien s'ils sont identiques. Un passage coûte un huitième de seconde.
- Le banc du message d'accueil passe à 43 contrôles et 6 essais de sabotage, tous détectés. Le rattrapage a été prouvé de bout en bout : le fichier a été volontairement remplacé par une ligne d'essai, puis retrouvé identique après un passage.
- Un tube dans un tableau ne coupe plus la case en deux. Écrire une commande dans un tableau de la page Versions faisait apparaître une colonne fantôme, dont le titre était un bout de la commande. Découvert en écrivant la ligne d'installation ci-dessus — elle s'affichait de travers.
Erreurs
- La feuille de route annonçait ce défaut comme entier. Il était corrigé à moitié depuis une semaine, et personne n'avait mis la case à jour. C'est en allant vérifier la case qu'on a trouvé la porte encore ouverte.
- Un essai de sabotage annoncé « survécu » ne l'avait pas été : le sabotage ne s'était pas appliqué du tout, et le rapport donnait ce silence pour un verdict. Un essai qui n'a pas eu lieu n'est pas un essai réussi.
Avertissements
- ⚠ L'unité reste à installer : cela demande des droits que l'automatisme n'a pas. Tant qu'elle ne tourne pas, le message d'accueil dépend toujours des deux seuls chemins précédents.
4.16.2 — 9 août 2026
Le propriétaire d'un salon choisit désormais les modes de son salon, dans l'onglet Réglages : messages de l'extérieur, sujet réservé aux opérateurs, salon modéré, salon discret, réservé aux pseudonymes enregistrés, actions refusées. Six cases à cocher, et le robot applique.
Modifications
Web/inc/chanreglages.php— les modes du salon rejoignent la liste des réglages ouverts, sous une forme qui n'accepte que des cases. Décocher retire vraiment le mode : l'enregistrement dit au robot ce qu'il faut poser et ce qu'il faut enlever, en une fois. Un salon dont les modes ont été posés par un opérateur reste verrouillé, et la page le dit.Web/site/salonadmin.php— les six cases, ce que chacune fait en clair, et l'avertissement quand elles sont en lecture seule.Markdown/WEB.md— le passage qui affirmait ces réglages fermés était faux depuis le jour même ; il est corrigé et détaille les précautions.
Bugs corrigés
- Un défaut trouvé dans le banc, pas dans le code. La garde qui empêche d'effacer les modes posés par un opérateur était écrite au milieu de la fonction d'enregistrement. La neutraliser laissait le banc vert : les contrôles portaient sur la fonction qui détecte, jamais sur la décision qui l'écoute. La décision a été sortie à part, et un contrôle vérifie maintenant qu'elle est bien appelée — pas seulement écrite.
Évolutions
- Le banc des réglages de salon passe à 144 contrôles et 8 essais de sabotage, tous détectés.
Avertissements
- ⚠ Personne n'a encore coché une case sur un vrai salon. Le banc prouve la mécanique ; il ne peut pas prouver qu'un propriétaire voit le mode apparaître. Cela demande un navigateur et un salon réel.
4.16.1 — 9 août 2026
La page qui affiche les carnets ne savait pas les lire. Le moteur Markdown du site ignorait deux syntaxes que les deux fichiers publics emploient. Les chevrons des citations s'affichaient en clair — jusqu'au milieu d'une phrase quand la citation faisait deux lignes — et les tildes du texte barré restaient là où un point périmé aurait dû être rayé. Le défaut était visible par n'importe quel visiteur de la page Versions.
Créations
Web/tests/test-markdown.php— 39 constats sur le moteur de rendu, et 5 mutations qui prouvent qu'il rougit. Il éprouve aussi les vrais fichiers servis par la page, pas seulement des cas d'école : ce sont eux qui ont révélé le défaut.
Modifications
Web/inc/markdown.php— les citations>deviennent des<blockquote>. Leur contenu est rendu par un appel récursif, sans quoi une citation perdrait ses listes, ses tableaux et son gras. Le sommaire du bloc est jeté : un titre écrit dans une citation n'a pas à figurer dans la table des matières de la page. Le barré~~texte~~devient<del>.Web/site/versions.php— le style des deux balises neuves. Le vocabulaire CSS du site est clos ; une balise ajoutée au moteur sans style s'affiche au défaut du navigateur, c'est-à-dire de travers.Markdown/CHANTIERS.md— seconde revue du 9 août.
Bugs corrigés
- Les citations n'étaient pas rendues du tout. 11 lignes citées dans le registre des chantiers, 17 dans ce journal : leur chevron partait dans le texte affiché. Un paragraphe suivi d'une citation avalait la citation entière.
- 12 tildes de texte barré restaient visibles sur les deux fichiers.
Erreurs
- Le premier constat sur le style de la page cherchait
.md blockquotesans son accolade. Or la sous-règle.md blockquote p:first-childcontient déjà cette chaîne : le constat restait vert alors que la règle principale avait disparu. C'est la mutation qui l'a attrapé, pas la relecture.
Avertissements
- Le registre des chantiers a livré un sixième point périmé : l'historique de modération d'un salon existait déjà, et affichait déjà. Le registre visait la table
IriX_modq, qui est bien vide — mais l'écran ne lit pas cette table.
4.16.0 — 9 août 2026
Cinq chantiers passés dans l'ordre, et trois d'entre eux disaient faux. Le registre des chantiers annonçait des manques qui n'existaient plus : les messages privés du chat étaient faits depuis des semaines, les garde-fous de l'installation automatique étaient écrits, et le rôle qui « masquait » la propriété a été corrigé plutôt que documenté. Ce registre ne se contente donc pas de trop dire — il sous-dit aussi, et il se mesure comme on mesure l'état d'un serveur.
Créations
Tools/overop-pool.php+Config/systemd/overtchat-botpool.{service,timer}— l'exécutant du prêt de robot. Le bot demandait dans le vide : il déposait ses demandes dans une file que personne ne lisait. Ce service la lit et pose le robot — répertoire, configuration, démarrage. Un seul par passage, le minuteur repasse toutes les cinq minutes : poser toute la file d'un coup ferait d'un compteur emballé une flotte de robots en une seconde.Web/inc/chathist.php,Web/sql/020-chat-hist.sql,Web/tests/test-chathist.php— l'historique des salons du chat. En rejoignant un salon, on voit ce qui s'y est dit avant d'arriver. Gardé trente jours, puis effacé.IriX/tests/test-ia-amorce.tcletWeb/tests/test-botpool.php— deux bancs d'essai pour les deux points les plus délicats du jour.
Évolutions
- Le webchat se rebranche tout seul après une coupure réseau. Cinq tentatives espacées de 2 à 30 secondes, puis abandon annoncé — un silence laisserait croire que ça essaie encore. Les salons rejoints sont retrouvés. ⚠ Sans ré-identification : le mot de passe ne survit pas à la connexion qui l'a reçu, et cela reste vrai.
- L'historique se relit par compte, jamais anonymement. L'identification est exigée partout, même sur un salon ouvert à tous : un historique rendu à quiconque passe deviendrait une archive du réseau, relisible sans laisser de nom. Sur un salon réservé, être identifié ne suffit pas — il faut y avoir un rôle, sans quoi la réserve ne vaudrait que pour le direct.
- Les robots de prêt annoncent ce qu'ils servent (
BOTSTAT, toutes les cinq minutes). Le bot déduisait leur charge de sa seule base ; un fichier divergent la laissait affirmer qu'un robot tient des salons qu'il a quittés. Seul l'écart laisse une trace : trois robots bavards écriraient 864 lignes par jour pour ne rien dire. - Le propriétaire d'un salon le reste, même opérateur du réseau. Il ne voyait jamais le bouton « Demander un robot » de son propre salon.
- Le propriétaire arme lui-même les grades de son salon. Ils étaient posables partout et ne s'appliquaient nulle part — un réglage décoratif.
Bugs corrigés
- La modération automatique ne pouvait pas commencer à apprendre. Sans vocabulaire connu, elle jugeait chaque message « pas assez sûr » et s'arrêtait là — sans jamais rien retenir. Elle apprend désormais des messages que le filtre de mots vient de laisser passer, et s'arrête d'elle-même dès qu'elle en sait assez.
- Un réglage de salon ne demande aucun redémarrage : le bot relit tout seul en trois secondes. La consigne inverse coûtait 75 secondes de coupure à chaque fois, pour rien.
- Une purge d'historique écrite mais jamais appelée. Le code était juste et ne tournait pas ; la table aurait grossi sans fin.
Avertissements
- ⚠ L'apprentissage de la modération n'a encore rien appris : il attend une vraie conversation sur un salon surveillé. Tant que personne ne parle, ce zéro ne prouve rien — ni que la correction marche, ni qu'elle échoue.
- ⚠ L'installation automatique n'a jamais posé de vrai robot. Le service tourne, la file est vide, il n'a donc rien eu à faire.
- ⚠ La reconnexion du chat et l'affichage de l'historique restent à constater dans un vrai navigateur : aucun banc ne peut les éprouver.
- ⚠ Les conversations privées ne sont pas dans l'historique, et n'y seront pas : le serveur ne les transmet à personne d'autre.
4.15 1 version · 7 août 2026 5 additions 2 improvements 3 bugs fixed 1 removal 4 mistakes 4 warnings
4.15.0 — 7 août 2026
Ce que les documents affirmaient, et ce que la mesure a dit. Onze lots ce jour-là. Six ont produit du code ; cinq n'ont produit qu'un constat — le défaut annoncé n'existait plus, ou pas comme il était décrit. PROJET.md, ROADMAP.md et IRIX.md portaient un écart de niveau sur !banall depuis trois semaines, et une décision d'exploitation attendait dessus pour rien. Le carnet donnait deux tables pour mortes alors qu'elles sont conservées à dessein et attendues au ROADMAP. Les supprimer aurait détruit du travail en cours.
Créations
IriX/cmds/irix-partyline.tcl— la console DCC d'IriX. Elle n'écrit aucune commande : elle EXPOSE les quatre-vingts existantes.putnoticesait désormais écrire vers une console quand::soc::dcc_idxest posé, un pont pose ce contexte, adapte la signature{hand idx text}→{nick host hand chan text}, et le RETIRE — y compris quand la commande lève. Le salon, qu'une console n'a pas, se donne en premier mot. Trois commandes s'y ajoutent que l'IRC ne peut pas donner :.bots(déclaré contre constaté),.compte(base SQL contre userfile Eggdrop),.lien(état du botnet).Web/inc/chanreglages.phpetWeb/pages/eggdrop.php— le lot 3 du prêt de robot, et la page des Eggdrop au panel.users.auth_uid— quelle CONNEXION s'est identifiée.OverOp-QetOverOp-S, décidés au §14 dePRET-ROBOT.mdet jamais posés jusqu'ici : répertoires, configurations, ports 3342 et 3343, déclarés au registre, observés par le bot, et sous systemd. Le parc annonce enfin trois robots et soixante places.- Bancs :
test-partyline.tcl(18 constats),test-autoconfig-relu.tcl(13),test-chanreglages.php(68).test-auth.tclpasse de 29 à 43.
Suppressions
- Le mode
+G— dix emplacements. Déclaré, posable, annoncé en 004, 005 et PROTOCTL, et lu par personne : aucunif (… & CMODE_CENSOR)n'existait, et aucune liste de mots côté serveur. La modération réelle passe parantimotd'IriX, qui ne consulte pas ce mode. ⚠ Deux des dix emplacements étaient des chaînesCHANMODESécrites en dur — ungrepsur+Gne pouvait pas les voir ; c'estVERSION.mdqui a mis sur leur piste, en précisant « annoncés en 005 ». Les bits libérés ne sont pas réattribués.
Évolutions
- L'identification appartient à une connexion, plus à un pseudonyme.
auth_uidretient l'UID identifié ;::soc::uid_du_lienle cherche dans le registre du dispatcher. Trois précautions, chacune contre le défaut inverse : l'écriture d'auth_uidest séparée de celle d'auth(groupées, unUPDATEsur base non migrée échouerait en entier et lecatchl'avalerait) ; unauth_uidvide fait retomber sur le test par pseudonyme ; la révocation efface aussi l'UID. IriX-sql-fixes.tcldevientIriX-svc.tcl(A-14). Il ne portait plus une seule rustine : 351 lignes, huit procédures::soc::svc::, dontscan_actions, le cycle de 30 s qui sert le panel.
Bugs corrigés
- Les écrans d'aide doublaient les sanctions dans la file. Trois rafales — 8, 24 et 7 lignes — sortaient par
putspeed_x, c'est-à-direputquick, la file HAUTE priorité, sur un bot dont le métier est de sanctionner vite. Les 42NOTICEqui contournaientputnoticey reviennent ;putnoticesen envoie N en un appel. - Un réglage posé depuis le site restait sans effet.
::soc::auto::cachen'était vidé que par!autoset: la page de salon écrivait en base, et le bot gardait l'ancienne valeur jusqu'au rechargement de ses scripts.::soc::auto::scan_configcompareupdated_atau cycle et relit — le premier passage NOTE sans invalider, sinon le cache se viderait à chaque démarrage. - Reprendre un pseudonyme dans les 4 s donnait l'identification du partant. Le différé de révocation testait le nom ; il suit maintenant la connexion.
Erreurs
Constatées dans la documentation, pas dans le code.
- L'écart
!banall/!unbanall/!kickalln'a jamais existé. Trois documents affirmaient « déclarésircops, codésadmin».IriX-table.tclles déclare niveau 6, et le niveau 6 ESTadmin—ircopsvaut 10. Et${t}_commandsn'est de toute façon jamais lue : le contrôle d'accès est en dur dans le Tcl. Une déclaration que rien ne consulte ne peut pas être « en écart » avec le code. - Le défaut 17 est clos : le SID annoncé vient bien de
server_sid. Constaté sur le lien en service —server_sidvaut003, les cinq pseudo-clients portent003AAAAAAà003AAAAAE, quand les clients ordinaires portent10A…, le SID du serveur. - Le carnet donnait pour manquants le template systemd d'
overop@et l'écrivain debotreg_pooshy.seen_at: les deux existaient déjà. - Le
sedde pose d'OverOp-Havait réécrit sa propre documentation ens/OverOp-H/OverOp-H/g. La pose de Q et S vise les lignes de réglage.
Avertissements
- ⚠
ia_tokensvaut 0, et ce n'est pas une panne : c'est un cercle vicieux. Sans token,::soc::ia::scorerend{0.0 0}; le score passe sous le seuil, et la brancheelsen'entraîne que si$sig >= $min_tokens— or$sigvaut 0. Le modèle ne peut pas démarrer seul. Sa seule amorce esttrain_from_sanction, appelée quand le filtre de mots sanctionne — chaîne vérifiée complète. Elle n'avait rien à apprendre parce qu'antimotn'était actif que sur#Csadmin, salon d'administration. Il l'est désormais sur#accueilet#membres. ⚠ Ne pas injecter de jetons d'essai : du vocabulaire inventé fausserait durablement tous les scores. - ⚠ Le rôle
ircopmasque le rôleproprietaire. Un opérateur réseau, même propriétaire d'un salon, ne verra jamais le bouton « Demander un robot », qui exigerole === 'proprietaire'. Le chemin a été éprouvé avec un compte d'essai non-opérateur ; il fonctionne, mais il reste invisible à qui est IRCop. - ⚠ Un
restart irixmet 75 secondes à ramener les neuf connectés, pas 25. Le lien S2S doit se refaire ET réintroduire les cinq pseudo-clients. - ⚠
::soc::logécrit dansIriX-sql.log, pas dansjournalctl. Chercher une trace::soc::logparjournalctlne rend rien — et ce vide se lit comme « le mécanisme ne tourne pas ». Ce seul piège a produit trois conclusions fausses le même jour, dont un recul sur du code qui fonctionnait.
4.14 1 version · 5 août 2026 1 addition 5 warnings
4.14.0 — 5 août 2026
Du code qui affirme, et rien qui exécute. Sept défauts fermés ce jour-là, et ils sont tous de la même famille : une colonne sans écrivain, un verbe jamais routé, un appel à une procédure qui n'existe pas, un commentaire qui décrit un effet absent. Aucun ne se signalait, et les bancs passaient — ils éprouvent des procédures, pas des chaînes, et ces trous étaient tous aux jointures, là où un module suppose qu'un autre fait le travail.
Le panel garde trace des avertissements d'expiration
Tools/alerte-pseudo.php chargeait config.php et mailer.php, jamais db.php. Or mail_log() s'ouvre sur une garde function_exists('qx'), prévue pour le cas « table absente » — elle avalait aussi « base jamais chargée ».
Le courriel partait, l'outil rendait 0, le bot posait expire_alerte, et le panel n'en gardait aucune trace. Le jour où un titulaire dit n'avoir pas été prévenu, c'est cette ligne qu'on cherche.
Invisible autrement qu'en provoquant l'envoi : status=sent dans journalctl -u postfix, et rien dans l'onglet Courriel.
Créations
IriX/tests/test-appels.tcl · IriX/tests/test-chanq-robots.tcl · Web/tests/test-clientip.php · Web/tests/test-audit.php · Web/inc/audit.php · Tools/chanq-mail.php · Config/systemd/overop@.service (template, trois instances) · Config/systemd/overtchat-chanq-mail.{service,timer} · Web/sql/018-opmybot-multibot.sql · Web/sql/019-web-audit.sql
Avertissements
OverOp-QetOverOp-Ssont décidés (§14), pas posés. Un seul robot existe ;- l'expiration des pseudos n'a aucun sujet : un compte en base, sans adresse ;
- trois décisions d'exploitation restent ouvertes — mettre la modération en service, trancher le niveau de
!banall/!unbanall/!kickall, statuer surIriX-sql-fixes.tcl; - l'IPv6 n'a toujours pas été sondée depuis un réseau extérieur.
4.13 1 version · 4 août 2026 2 bugs fixed 3 warnings
4.13.0 — 4 août 2026
Un droit qui ne valait que sur le réseau vaut désormais par salon — et quatre mécanismes qu'on croyait en service ne tournaient pas. Le fil de la journée n'est pas le lot demandé : c'est le nombre de choses qui paraissaient fonctionner. Une campagne écrite mais jamais lancée, un banc qui tombait un jour sur sept, un autoop qui n'a jamais rien posé, une identification qui ne tombait pas. Aucune ne se signalait ; toutes se sont vues en provoquant l'effet.
Bugs corrigés
test-std.tcltombait tous les mardis : sa regex cherchaitMarsans limite de mot, et « Mardi » le contient. Le code avait raison. Un banc qui tombe selon le jour de la semaine est pire qu'un banc absent — on apprend à ignorer son échec.bancs.shannonçait « neuf campagnes » alors qu'il y en a quinze : le nombre est désormais dérivé du lanceur.
Avertissements
- ⚠ Le réglage
automode_useret la listeoper_chanvivent en base, hors dépôt : une base recréée les perd. - ⚠ Poser un grade sur la page ne change rien sur le réseau tant que le salon n'a pas
automode_userarmé — et la page le DIT désormais, dans les deux sens. - ⚠ Il reste un cas où
authsurvit à une déconnexion : une reconnexion en moins de quatre secondes sans se ré-identifier. Le fermer demande de raisonner sur l'UID de session, pas sur le pseudonyme.
4.12 1 version · 3 août 2026 not broken down
4.12.0 — 3 août 2026
Le prêt de robot va jusqu'au bout, et trois défauts ne se sont montrés qu'en production. Les bancs prouvent une décision ; ils ne prouvent ni qu'un ordre traverse le réseau, ni qu'une migration s'applique, ni qu'une page s'affiche. Chacun des trois lots de cette version a été démenti au moins une fois par le réel après avoir été vert au banc — et c'est la partie utile de la journée.
4.11 3 versions · 1er août 2026 → 2 août 2026 13 additions 10 improvements 18 bugs fixed 6 checks 10 mistakes 5 warnings
4.11.2 — 2 août 2026
Huit lots, une seule cause. Un fait écrit à deux endroits, l'un mis à jour, l'autre pas — et rien qui le signale. Une route de menu, un tableau de compatibilité, un catalogue d'installation, cent vingt-quatre grades, une phrase cherchée dans un journal : à chaque fois deux listes du même fait, dont une seule avait suivi. Rien ne cassait, c'est ce qui rend ce défaut long à voir.
Créations
Web/inc/routes.php— la table des pages du panel, sortie d'admin.phpoù aucun banc ne pouvait la lire. Déplacer la liste n'est pas cosmétique : c'est ce qui rend le contrôle possible.Web/inc/commandes-anope.php— les 249 commandes d'Anope, extraites et non écrites : le nom tapé vient descommand { service; name }de sa configuration, la description desSetDesc(_("…"))de ses modules, la traduction de son fichier français. Extracteurs dansTools/anope-commandes.pyetTools/anope-commandes-php.py.- Quatre bancs :
test-routes.php(22),test-grades.php(18),test-commandes.php(14), et 60 vérifications neuves danstest-compat.php. Web/tests/test-vues.php(17) — la question d'après celle detest-routes.php: une fois la page atteinte, s'affiche-t-elle ? Il vérifie que chaque page routée appelle le gabarit, et que chaque classe qu'elle écrit en dur existe dans une feuille de style. Les appels sont cherchés par les jetons de PHP, jamais parstrpos: le nom d'une fonction apparaît aussi dans les commentaires, et une recherche de texte y verrait un appel qui n'existe pas — le genre de repère qui passe au vert sur un défaut intact.Web/tests/test-motd.php(34) — le message d'accueil dit-il ce que le serveur fait ? Les deux fonctions pures du générateur, extraites du fichier et jamais incluses — l'inclure écrirait le MOTD de production —, le modèle réel, et l'unité systemd versionnée. Trois repères tiennent le fond plutôt que la forme : la branche filtrée annonce le filtre, la branche nue ne l'annonce PAS, etAPPELsurvit dans les deux.IriX/tests/test-doublons.tcl(30) — deux règles de chargement qu'aucune erreur ne signale : aucune procédure définie deux fois parmi les dix-huit modules, et aucune procédure sur un namespace pas encore déclaré. L'ordre de chargement est dérivé dessourcedu point d'entrée. Il compare aussi les deux écritures du schéma deweb_authqetmodq— colonnes et valeurs d'ENUM.Web/tests/test-ulines.php(34) — ce qu'un lien ULine accepte selon son état.socket_refusal()n'était éprouvée par rien, alors que c'est elle qui grise les boutons ET qui fonde le refus côté serveur.
Bugs corrigés
- La page « Protection » du panel renvoyait au tableau de bord. Trois listes décident qu'une page existe — l'entrée de menu, la route, le fichier — et elle en avait deux sur trois. Rien n'échouait : le lien s'affichait, une page s'ouvrait, et ce n'était pas la bonne. Le repli se nomme désormais, à l'écran et au journal ; un repli muet est ce qui a rendu ce défaut invisible une journée.
- La même page, une fois atteinte, s'affichait toute nue.
admin.phpne fait qu'uninclude: il ne pose NI l'en-tête NI le pied. Chaque page produit son propre<!doctype>, son<link>versapp.csset son ossature en appelantrender_header()etrender_footer()— « Protection » n'appelait ni l'un ni l'autre. Fond blanc, cartes disparues, tout en texte brut, et rien au journal. C'est le troisième maillon de la même chaîne, et il se casse aussi silencieusement que les deux premiers. - Deux autres pages n'appelaient pas
render_footer()—connexionsetopers. Moins voyant, pas anodin : le script qui rafraîchit le bandeau d'état vit dans le pied, donc leurs pastilles restaient figées sur la valeur du chargement. Un panel de supervision qui montre un lien tombé comme encore actif est pire qu'un panel muet. - Onze classes CSS n'existaient dans aucune feuille. Sept sur « Protection » —
page-head,lead,switch-row,grid-2,btn-primary,btn-warn,table—, plus unbadge badlà où le vocabulaire ditbadge err; et trois ailleurs :table-wrappourtbl-wrap,row,tbl. Une classe inconnue ne produit aucune erreur : l'élément se rend, sans le style attendu. - La page Compatibilité annonçait quatre serveurs et en montrait six. Le premier tableau bouclait sur la table, les trois grilles du bas récitaient un
$DIALECTESfigé à quatre. Colonnes, largeurs, titre, sommaire et description de référencement sont maintenant dérivés. Les largeurs écrites à 17 % la pièce faisaient 102 % à six colonnes, et la grille sortait de son cadre. - L'installateur ne proposait pas Bahamut, dont le site annonçait pourtant qu'IriX le parle. Vingt points d'accroche, dont les DEUX catalogues — celui qui crée
servers.jsonet celui qui complète un fichier existant, sans lequel une installation en service ne l'apprendrait jamais. - La page Commandes annonçait fermé ce que le code laisse ouvert. Dix écarts :
hello,passdu premier lancement,auth,help,!help,!infoet!statusétaient données pour « user » alors qu'elles ne testent RIEN ;syncownerexige le flagnd'Eggdrop, pas un grade de salon ; et deux commandes manquaient —approve, par laquelle un IRCop valide une réinitialisation de mot de passe du site, etVERIFY, que le site DEMANDE de taper pour finir une inscription. - La table des protocoles d'Anope ignorait
bahamutdepuis sa naissance : un lien bahamut y retombait sur « inconnu ». - Le MOTD promettait un filtre que le rechargement venait de couper.
conf_load()rappellemsgfilter_load()à chaque REHASH, mais le générateur n'était accroché qu'à l'ExecStartPost— le démarrage. Viderfiltre-messages.confpuis recharger laissait le message d'accueil affirmer à chaque connexion que les messages privés sont protégés. Ce n'est pas une ligne périmée : c'est la promesse sur laquelle quelqu'un décide de ce qu'il écrit. Second point d'accroche à l'ExecReload, avec un mode qui attend la ligne de journal du rechargement en cours — le HUP est asynchrone — et sans repli sur le fichier de motifs, qui après un rechargement raté dirait ce que le serveur aurait dû charger. - Réparer un lien ULine coupait les autres. L'alerte « des liens sont rompus » nommait les liens en panne, puis offrait un bouton unique qui passait en
reloadTOUS les sockets activés — orreloaddéconnecte et reconnecte deux secondes plus tard. C'est l'incident du 31/07 qui avait coupé la production (point 16 dePROJET.md). L'alerte porte maintenant un bouton par lien rompu, et le drapeau global n'agit plus que sur les liens qui ne sont pas connectés. Il programmeconnectet nonreload: le panel REFUSAIT déjà unreloadsur un lien non établi pendant que le drapeau en posait un — deux logiques contradictoires pour le même geste. - Quatre procédures d'IriX étaient définies deux fois, le point ouvert n'en annonçait que deux.
IriX-sql.tclsourceIriX-table.tclà sa ligne 30 puis redéfinit plus bas :svc::db_init,auto::db_initetauth::db_initne s'exécutaient jamais, pas plus que la copie de::soc::sql_escdansIriX-sql-IA.tcl. Rien ne cassait — on corrigeait le schéma dans le fichier mort, on redémarrait, et rien ne changeait. Lasvc::db_initmorte décrivait d'ailleurs un schéma périmé (sansroleniaction_pending) et créaitmodq/web_authq, dont le schéma qui fait autorité est celui des migrationsWeb/sql/. Retiré, avec la même pierre tombale que pouria::db_initle 19/07.
Évolutions
- Anope devient un groupe du menu, avec trois états par pseudo-client : Online (vu dans
${t}_online, c'est le réseau qui répond), Offline (absent et cohérent), Warline (il devrait être là et n'y est pas). Sans le troisième, un service tombé s'écrirait comme un service volontairement coupé, et l'on ne regarderait pas. - La page Commandes se choisit son service — un menu à deux niveaux, IriX et Anope. On ne consulte jamais « toutes les commandes » : on cherche ce que sait faire OverNick, ou ce que ChanServ attend.
- La pastille du menu ne relance plus un
psà chaque page.pid_of()liste tous les processus de la machine et les filtre en PHP : 12 ms, payés à chaque clic pour une pastille qui ne change qu'aux démarrages. Relais de 20 secondes en session, effacé paranope_ctl()— sans quoi démarrer Anope laisserait le menu montrer le contraire, et l'on referait l'action en croyant qu'elle a échoué. Mesuré : 30 ms la première fois, 0,04 ms ensuite. test-grades.phplit les sources d'IriX et en dérive la garde exigée, commande par commande, plutôt que de comparer à des grades recopiés dans son propre code. Les commandes qui gardent leur porte autrement — session lue à la main, flag Eggdrop, WHOIS — sont déclarées en exceptions, et le banc vérifie que chacune est encore fondée.
Erreurs
- Un banc vert ne prouve rien s'il compare à une liste recopiée. Le repère « les cinq dialectes sont couverts » de
test-anopea été mis à jour EN MÊME TEMPS que la table qu'il contrôlait : il est resté vert pendant que la table mentait. Il lit désormais les dialectes dansirix-proto.tcl, à leur source. test-irix.pyrendait 26 sur 27 depuis le 30/07, et ce n'était pas un défaut. Le contrôle cherchait la phrase « EOS reçu » ; ce jour-là, la détection de fin de burst avait été refaite pour reconnaître leEBd'ircu et le message était devenu « fin de burst reçue (EOS) ». Le burst se closait parfaitement. Un banc qui atteste un fait en cherchant une PHRASE mesure la stabilité du vocabulaire, pas celle du code : il lit maintenant l'étatsock_statepublié par le banc Tcl. 27 sur 27.- Une mesure prise au mauvais endroit est une mesure fausse. Le coût du menu Anope a d'abord été annoncé à 22 ms, mesuré depuis
/mnt/coù le moindreis_filecoûte cent fois son prix. Sur le disque de production, la valeur était tout autre. - Un
\bdans une chaîne Python non brute donne un BACKSPACE, pas le motif d'expression régulière. Une heure perdue sur un extracteur qui ne trouvait plus rien : le fichier contenait l'octet 0x08. - Le tableau des grades se disait rangé « du plus faible au plus fort » et listait
useravantpublic: les deux portaient le même numéro. Invisible tant que l'un ne servait qu'aux services et l'autre qu'au robot. - La table des bancs de
ROADMAP.mden listait treize, datés du 31/07, alors qu'il y en a vingt-quatre. Reprise, séparée entre ceux qui se lancent seuls et ceux qui exigent un serveur en face, et elle dit maintenant comment se recompter sans elle.
Avertissements
!infoet!statussont ouverts à toute personne présente sur le salon, compteurs de comptes et de salons compris. C'est l'état du code, désormais documenté comme tel — pas une décision prise ici.- Le certificat de Bahamut est généré à l'installation, en
-batchet seulement s'il manque. Sansircd.crt, ce serveur n'ouvre aucun port, pas même en clair, et rien dans son message ne désigne la cause.
Vérifié
- Neuf bancs PHP : compat 260, statut 85, anope 78, update 50, protection 34, chatmod 23, routes 22, grades 18, commandes 14. Quatre bancs Tcl autonomes : proto 501, needop 32, sessions 30, nickexpire 26.
test-irix.py: 27 sur 27, éprouvé par deux mutations — la variable d'état renommée, puis le serveur privé de sonEOSet recompilé (7 sur 22, le lien ne monte plus).test-grades.phpéprouvé par neuf mutations, toutes mordues. Deux premières tentatives n'ont rien prouvé : la mutation ne s'était pas appliquée.- Page Commandes rendue hors navigateur dans trois vues et deux tris, et servie en production.
4.11.1 — 1er août 2026
Le robot du réseau réclamait l'op à personne. Un correctif de la 4.11.0 lui avait fait perdre le sien ; celui-ci le lui rend, et fait taire la demande qui tournait à vide.
Bugs corrigés
- 120 fois la même ligne, une par minute. Depuis 15h08, le journal portait « Besoin d'op sur #!Services! - Mode réclamé : +o » sans que rien ne réponde. Ce message était écrit sur le salon ; or les messages que le dispatcher route portent un service en cible, celui-là portait un salon. Il partait dans le vide.
- Deux défauts, pas un. Le message était inutile — et il aurait été dangereux s'il avait été utile : accorder l'op sur la foi d'une phrase lue sur un salon, c'est l'accorder à quiconque sait la recopier. La demande naît désormais dans le code du bot, pour son propre pseudonyme, et rien de ce qui vient du dehors ne peut la déclencher.
- Pourquoi il avait perdu l'op : depuis la 4.11.0, les cinq pseudo-clients créent le salon de service au moment du lien, et le robot, qui le rejoint ensuite, entre sur un salon qui existe déjà — un client ordinaire n'y est pas opérateur. Rendre l'op aux services lui avait pris le sien.
- Les trois autres besoins étaient logés à la même enseigne : invitation, clé, limite écrivaient eux aussi sur le salon. L'invitation passe désormais par un service ; la clé n'est plus imposée au salon — la poser d'autorité reviendrait à changer la clé des autres pour se laisser entrer — et la limite ne nous appartient pas : on le dit, et on n'entre pas.
Évolutions
- Le mécanisme se tait quand il échoue : trois essais, puis une demi-heure de silence — annoncée, datée, et la reprise l'est aussi. Un mécanisme qui renonce sans le dire est indiscernable d'un mécanisme en panne.
- Le lien employé est choisi sur la présence du robot, non sur « le premier debout » : deux liens peuvent mener à deux réseaux, et un mode posé du mauvais côté viserait un salon qui n'existe pas là-bas.
Erreurs
botisircopsne dit pas ce que son nom promet. Elle ne teste pas si le robot est opérateur IRC : elle lit le grade de son pseudonyme dans la table des utilisateurs. Le robot n'y étant pas inscrit, elle répondait « non » quel que soit son état réel — c'est ce qui envoyait la branche de repli à chaque appel. Signalée depuis longtemps au journal des défauts (H-3), sans que la cause ait été nommée. Elle subsiste ailleurs, avec le même malentendu.
Vérifié
- Mesuré avant et après, en production : 134 lignes « Besoin d'op » dans la journée, 0 depuis le rechargement. Et dans l'autre sens — l'effet voulu est là :
MODE #!Services! +o IriXémis par OverTchat, puis « op obtenu après 1 tentative(s) », le serveur ayant renvoyé le mode. IriX/tests/test-needop.tcl, neuf : 32 vérifications hors lien sur le code réel. Sept mutations les font tomber.
4.11.0 — 1er août 2026
Les services cessent d'être expulsables, et le sixième dialecte parle. Deux chantiers sans rapport apparent, réunis par la même leçon : ce qui protège doit être vérifiable de l'extérieur, et ce qu'on croit générique porte presque toujours l'hypothèse d'un serveur précis.
Créations
- Protection des services et des robots —
src/protection.cdans Overtchat-Hybrid. Les trois gardes du serveur — expulsion (m_channel.c), déconnexion (m_oper.c), bannissement réseau (ban.c) — posent désormais une seule question,protection_shields(). Un robot est protégé s'il porte le mode+Bet figure dans la liste écrite par le panel : le mode se pose soi-même, il ne saurait valoir immunité. conf/protection.conf, déclaré par une directiveprotection = …et tenu à part de la configuration principale : le panel doit pouvoir l'écrire sans jamais toucher au fichier qui porte les mots de passe. Deux interrupteurs indépendants,servicesetrobots. Fichier absent ou valeur incomprise ⇒ protection ACTIVE — un réglage illisible ne doit pas désarmer une garde.tests/test-robots.py— douze constats sur la protection.- Le dialecte
bahamut(irix-proto.tcl), écrit d'après les sources du serveur : il n'a aucune documentation de protocole. IriX/tests/lien-bahamut-bot.tcletIriX/tests/essai-bahamut.py— le vrai code du bot contre un vrai Bahamut, jugé par un client témoin.- Le suivi d'un identifiant qui change — primitive de dialecte
id_apres_renommage, et::soc::ulines::auto::reclef_utilisateur, qui reclasse en un seul endroit tout ce qu'IriX tient d'une personne.
Évolutions
- Six dialectes décodables :
bahamutrejointunreal,och,hybrid,p10etinspircd. Chacun n'y est entré qu'après un lien monté par le bot lui-même contre le serveur réel — jamais sur la foi d'un banc hors lien. - Le panel règle la protection et dit lorsque le serveur ne l'applique pas encore, plutôt que d'afficher un réglage sans effet.
- Le bot se déclare robot :
::soc::modes_du_botlui pose+iB. Il tenait le salon de service sans aucune protection — un opérateur reste expulsable par un autre. - Le burst de salon d'UnrealIRCd est enfin lu (
SJOIN), et l'injection reprend l'horodatage du salon annoncé par le serveur.
Bugs corrigés
- Les cinq pseudo-clients entraient sur
#!Services!sans l'op, depuis toujours. Eggdrop se connecte d'abord comme client et crée le salon ; le lien serveur monte dix secondes plus tard, et sesSJOINportent un horodatage plus récent — la règle du TS écarte alors les préfixes demandés. Invisible jusque-là parce qu'un remplacement du serveur vide le salon. Ce qui l'avait caché :SJOINn'était traduit en aucun verbe connu du dispatcher, si bien que le burst de salon n'était jamais lu en production. - Un renommage périmait les registres en silence sur un dialecte où l'identifiant est le pseudonyme. Ils ne répondaient pas « faux » mais « inconnu », pendant que les anciennes clés s'accumulaient.
- Le verbe
BURSTen désignait trois sous Bahamut : l'ouverture du burst du serveur, sa fermeture — c'est l'argument qui les sépare — et, par la traduction deSJOIN, le burst d'un salon. Le lien montait puis mourait au délai.
Erreurs
- Un talon de banc rendait un lien sourd. Le talon générique rend une chaîne vide, le vrai code écrit
if {[::soc::svc::cmd_common …]}, et Tcl refuse. L'erreur survient dans un gestionnairefileevent— que Tcl supprime dans ce cas : le lien restait ouvert et ne lisait plus rien après le premier message d'un témoin, pendant que le constat « aucune erreur Tcl » répondait 0. On en a conclu pendant une heure que le serveur ne propageait pas les changements de pseudo ; un sniffer branché sur le même lien a montré qu'il les propageait très bien. SVSNICKsur son propre pseudo-client ne prouve rien : le serveur route la commande vers celui qui possède le client, c'est-à-dire nous. La ligne revient telle qu'elle est partie.- Bahamut refuse en silence les connexions trop rapprochées — trois depuis une même adresse en quinze secondes, et le refus se fait à l'
accept, sans rien journaliser. Un témoin jamais entré se lit alors comme un défaut de propagation.
Avertissements
- On ne rétablit pas l'op des services depuis l'extérieur. Un
MODE +ooooolancé depuis un compte netadmin est appliqué, puis IriX expulse son auteur (« Abus d'une désynchronisation ») et l'op ne tient pas. Seul un redémarrage d'IriX corrige. - Six robots sont déclarés dans la liste du panel ; un seul en avait besoin, le bot lui-même. Les cinq pseudo-clients sont couverts par l'interrupteur
services, pas par celui des robots. - Le défaut EOS de
tests/test-irix.pyreste ouvert : 26 constats sur 27, et il préexistait à ces changements.
4.10 1 version · 31 juillet 2026 3 additions 4 improvements 6 bugs fixed 1 removal 2 mistakes 2 warnings
4.10.0 — 31 juillet 2026
Le projet cesse de supposer qu'il est le seul, et qu'il s'appellera toujours pareil. Neuf lots depuis la 4.9.3, qui ont tous la même racine : des noms et des chemins écrits en dur du temps où il n'existait qu'une installation, la mienne. Le numéro mineur et non correctif le dit — rien n'est cassé, mais l'installateur, le serveur et une dizaine de fichiers ne se comportent plus de la même façon chez quelqu'un d'autre.
Créations
- Avis de travaux —
Web/inc/travaux.phpetTools/travaux.php: un bandeau sur les pages publiques et une pastille au panel pendant qu'on modifie le site. Distinct de la page de maintenance Apache, qui répond à la place du site ; ici le site est servi, on prévient seulement qu'il bouge. L'état vit dansConfig/travaux.json, un fichier et non une table — la base fait partie de ce qui peut être en travaux. Deux actions au panel, niveau admin. - Contrôle du manifeste au
pre-commit— le hook compare lessourcedeIriX-sql.tclaux deux listes de l'installateur et refuse le commit en cas d'écart. - Purge de l'état de mise à jour —
_upd_state_purge_exclusretire deupdate_state.jsonce que le balayage refuserait aujourd'hui.
Évolutions
- Le nom de l'installation se choisit au premier lancement —
--projet=,OVERTCHAT_PROJET, ou la question de l'assistant. Résolu avant$BASE_DIRet les vingt chemins figés enreadonlyqui en dérivent, d'où la relance du script plutôt qu'une correction de variables déjà écrites. « Service-Overtchat » et « Overtchat » sont refusés, pour le répertoire comme pour le nom public du réseau : ils nomment le réseau et le serveur d'origine. Une installation déjà en place ne voit rien changer. - Le domaine du site est confronté au réel avant l'installation : DNS puis HTTP, avec confirmation explicite si quelque chose répond déjà. Un constat, pas un verdict — l'installateur reste utilisable hors ligne.
- Plus aucun fichier ne suppose le nom de l'installation. Trois scripts déduisent leur racine de leur propre place (
readlink -fd'abord), les trois unités systemd la reçoivent à l'installation —install-service.shsubstitue chemins et compte de service —, le hook Let's Encrypt passe par l'environnement. - Overtchat-Hybrid passe en 2.0.0, et son jeton de protocole devient
OCH-. Il annonçaitOVH-1.0.0depuis le commit qui l'a créé, alors qu'il a reçu le WebSocket, le filtre de messages privés, la limitation de débit, les salons interdits et le lien TLS. Majeur parce que le WebSocket et le filtre changent ce que ce serveur est ;OCH-parce que « OVH » est la marque d'un hébergeur et que ce jeton part à chaque connexion, dans le 002 et le 004 — c'est aussi le nom que ce dialecte porte déjà dansirix-proto.tcl.
Suppressions
- Le chemin ULine hérité, en entier — 790 lignes d'
IriX-sql.tcl:detect_conf,sync_init, les sixsync::*,load_config,load_config_sql,save_config_sql,do_ulines_scan,db_ulines_scan_check, le drapeauulines_scan, et les commandes!ulineconf,!ulinesync,!ulineset. Elles visaientunrealircd.conf, que la production n'a plus depuis la bascule du 28/07 surovertchat.conf: elles échouaient à chaque appel, et le scan de démarrage balayait$HOMEpour rien. Restentlog_cmd,require_ircopet!ulinestatus, appelés par le chemin vivant.
Bugs corrigés
_write_default_configbâtissait ses chemins sur$HOMEet non$TARGET_HOME: soussudo, l'arborescence décrite partait dans~root.- Une fonction qui affiche un écran ne peut pas rendre sa valeur par
$( )— l'assistant se relançait avec un--projet=contenant son propre affichage, et la question revenait indéfiniment. Toute boucle de question compte désormais ses tours. irix-nickexpire.tcletirix-chatalerte.tclmanquaient àgit.irix.files: sourcés sans garde, une installation neuve serait morte au chargement. Quatrième divergence du manifeste en dix jours — d'où le contrôle au hook.Config/travaux.json, créé le matin même, n'avait pas été ajouté aux exclusions de la mise à jour : 404 permanent, vingt lignes sous le commentaire qui décrit ce piège..gitattributesne couvrait que douze extensions sur dix-huit :git statusannonçait des modifications fantômes surchat.jsetsite.css. Index renormalisé,.batdu côté CRLF avec les.ps1.API.mddocumentait?p=chat-compte, une route qui n'existe pas — elle s'appelle?p=reservation, en POST seulement.
Erreurs
Config/irix.jsonannonçait la version du projet sous une clé nomméeirix.version, dans un fichier nomméirix.json. Elle a porté 4.6.6, puis 4.9.3 quand elle a été « alignée » — ce qui n'a fait que rendre l'erreur plus crédible. Elle porte celle du module, 6.3.ARCHITECTURE.mdrecopiait un numéro de version en tête — 4.6.0 quandVERSIONdisait 4.9.3 — dans un document qui reproche ailleurs exactement cela aux fichiers de configuration.
Avertissements
- Les trois unités systemd déjà installées dans
/etc/systemd/system/gardent les chemins qu'elles avaient : seuls les gabarits du dépôt sont corrigés. 186 poignées de main TLS avortées dans la journée du 31/07✅ Élucidé et corrigé le même soir. Ce n'était ni un scanner ni une attaque : c'est le panel qui sonde son propre serveur.port_open()ouvre une connexion TCP, constate que quelque chose écoute, referme — et sur le port TLS, le serveur avait commencé sa poignée de main. La fonction est appelée pour les quatre ports à chaque battement de?p=status, plusieurs fois par minute dès qu'un onglet du panel est ouvert. La répartition horaire le disait : 40 à 9 h et 38 à 13 h, 2 à 15 h quand personne ne regardait.UNEXPECTED_EOF_WHILE_READINGetSHUTDOWN_WHILE_IN_INITdescendent en DEBUG — un pair qui raccroche avant d'avoir rien dit n'est pas un événement. Mesuré avant/après sur cinq sondes : 5 lignes, puis 0. Une vraie anomalie reste visible : unGET /sur le port TLS journalise toujours « http request » en INFO.
4.9 4 versions · 31 juillet 2026 15 additions 14 improvements 12 bugs fixed 8 checks 2 mistakes 10 warnings
4.9.3 — 31 juillet 2026
Appeler à l'aide ne dépend plus du client qu'on utilise, et le message d'accueil cesse d'être un texte figé. La 4.9.2 avait donné un bouton aux visiteurs du site ; restaient ceux qui se connectent avec un vrai client IRC, c'est-à-dire ceux dont le réseau ne sait rien.
Créations
APPEL— commande de service, ouverte à tous. Le pendant, pour les clients IRC, du bouton du chat. Sur les 82 commandes du réseau, aucune ne permettait de demander un opérateur : le filtre de contenu du serveur protège des messages qu'on reçoit, mais protéger n'est pas écouter. Elle est offerte par les CINQ services — quelqu'un qui a besoin d'aide ne doit pas avoir à deviner lequel l'écoute — et écrit dans la même table que le site, donc le module d'annonce et le panel la traitent sans rien savoir de sa provenance.Tools/motd-generer.phpet son modèleircd.motd.tpl— le message d'accueil composé depuis l'état RÉEL du filtre, lu dans le journal du serveur (« N motif(s) de filtre chargé(s) ») et non dans le fichier de motifs, qui peut avoir changé sans rechargement.IriX/tests/essai-appel.py— éprouve la commande depuis un vrai client connecté au port utilisateur.- Un bouton de réconciliation sur la page Statut :
installedremis d'accord avec le disque, sauvegarde horodatée, trace nominative.
Évolutions
- Le message d'accueil ne contenait qu'une ligne — « Bienvenue sur le réseau Overtchat. », 36 octets. Le MOTD riche du dépôt est celui d'UnrealIRCd : il ne sert plus personne depuis la bascule du 28/07. Le nouveau tient en un écran et met l'appel en premier, avant la liste des services : personne ne fait défiler un MOTD pour chercher du secours.
- Trois textes disaient « signalez un abus » sans dire comment — la charte, la page Contact, le MOTD. C'était honnête tant qu'aucun moyen n'existait ; les taire ensuite revenait à donner une consigne inapplicable.
ExecStartPostsur l'unité du serveur, préfixé de-: un message d'accueil périmé est un désagrément, un réseau qui refuse de démarrer est une panne.- La page des commandes liste
APPEL, en public et en commun.
Bugs corrigés
- Un commentaire entre deux branches d'un
switchTcl rendaitAPPELmuette. Le corps d'unswitchest une LISTE de paires motif/script : un#y devient un motif, et la ligne suivante un script. Le journal disait « invalid command name "—" » — le tiret cadratin lu comme une commande — et le client n'obtenait aucune réponse. Le fichier passait pourtant la vérification de syntaxe : il était complet, juste faux. runningétait comparé alors qu'aucun fichier ne peut le tenir à jour. Le message s'affichait sous presque chaque composant, en permanence, sans rien apprendre — au point d'être signalé comme une anomalie du panel. Une information qu'on voit toujours devient le bruit qui masque les autres.Runtime/version.jsonétait suivi par git alors que le panel le réécrit à chaque vérification : le clone de production devenait modifié dès le premier contrôle, et le déploiement suivant a effectivement échoué — merge abandonné, puis « Everything up-to-date » au push. Ignoré,.exampleversionné.- Le bouton d'appel était hors écran : poussé en pied de colonne, il se trouvait à y=1050 sur une fenêtre de 900. Il fallait faire défiler pour demander de l'aide.
Erreurs
- Deux bancs ont d'abord échoué sur leurs PROPRES attentes, pas sur le code : l'un cherchait « opérateur a été prévenu » quand la réponse disait « operateur a ete prevenu » ; l'autre rejouait avec le même pseudo, si bien que la garde de débit refusait le premier appel. Le bon comportement lu comme une panne, deux fois. Un banc qui impose une orthographe mesure une chaîne de caractères, pas un comportement.
Vérifié
APPELéprouvée contre la production depuis un vrai client, sur trois services (OverTchat, OverNick, OverHub) — ce qui vérifie au passage qu'elle est bien commune à tous les rôles. L'annonce arrive sur le salon d'administration en une vingtaine de secondes.- Le bouton du chat cliqué depuis un navigateur : de la souris jusqu'à l'annonce aux opérateurs, avec le bon pseudo et le bon salon.
- Redémarrage réel du serveur :
ExecStartPostdéclenché (status=0), script idempotent — « déjà à jour, rien à écrire » —, 6 connectés revenus, lien ULineactiveet vérifié, MOTD reçu en 52 lignes. - Les deux branches du modèle, y compris celle qu'on ne peut pas voir en production : filtre inactif.
Avertissements
- Le générateur ne s'exécute qu'au démarrage du serveur. C'est le bon moment — le nombre de motifs ne change pas autrement — mais un fichier de motifs vidé sans redémarrage laissera le MOTD affirmer une protection retirée jusqu'au prochain.
- Le filtre lu est celui du SERVEUR, pas celui du site : le premier vaut pour tous les clients, le second ne protège que le chat du navigateur. Les confondre ferait annoncer une protection à qui n'en bénéficie pas.
4.9.2 — 31 juillet 2026
Le chat porte ses règles, et donne enfin de quoi appeler quelqu'un. Un visiteur ordinaire n'avait aucun moyen de signaler un abus : la charte lui disait de « prévenir un opérateur » sans dire par quoi, et le menu de modération est réservé aux gradés — c'est-à-dire à tout le monde sauf à celui qui subit.
Créations
- Trois cadres dans la colonne de gauche du chat : les règles, un avertissement sur les messages privés, un bouton d'appel. Repliés par défaut, présents en permanence.
charte_conduite()etcharte_interdits()— la source unique des règles. La charte et le chat n'en sont plus que deux rendus.chatmod_appel()et la route?p=chat-appel— un appel humain, distinct de l'alerte automatique.Config/apache/maintenance.html— la page servie quand le site ne répond plus, à la place du 503 d'usine d'Apache.
Évolutions
- Le module d'annonce du bot distingue un appel d'une alerte : « appel — X demande un opérateur sur #salon » au lieu de « message reçu par X vers #salon (appel) », qui décrivait un message là où il n'y en a pas.
- Un appel toutes les trois minutes par pseudo, et le refus le dit.
- Le guide : quatre renvois « voir §9 » devenus des liens nommés.
Bugs corrigés
- L'avertissement sur les privés ne ment plus quand le filtre est coupé. Il l'est par défaut ; un cadre l'affirmant sans condition aurait menti à toute installation qui ne l'a pas activé.
Erreurs
- Le site public est resté injoignable une quinzaine de minutes, par ma faute : un
pkill -f 'php -S 127.0.0.1:80'destiné à un serveur d'essai a aussi tuéphp -S 127.0.0.1:8080, celui qui SERT. Le motif était un préfixe, et80préfixe8080. Remis en marche parWeb/start.sh start. C'est le troisième incident de ce dépôt causé par unpkill -ftrop large — les deux précédents avaient tué le shell appelant. Filtrer par PID, ou parpgrep -x.
Vérifié
- Chaîne d'appel éprouvée contre la production : l'appel s'écrit, le bot le relève et l'annonce sur le salon d'administration en dix-neuf secondes, le second appel est refusé par la garde de débit, un GET sur la route rend 405 et un POST sans jeton 400. Les deux alertes d'essai ont été classées.
- Page de maintenance : aucune ressource externe, tient dans l'écran en 1280×800 comme en 375 px, aucun texte sous 11 px.
Avertissements
- La page de maintenance n'est pas encore installée. Elle demande une copie sous
/var/wwwet un rechargement d'Apache, tous deux en root — voir l'en-tête deConfig/apache/irix-ssl.conf.
4.9.1 — 31 juillet 2026
Un guide d'installation pour qui n'a jamais monté de serveur IRC. La page existante est une page de référence : elle suppose qu'on sait ce qu'est un démon, un lien serveur-à-serveur, un paquet de développement. Celle-ci suppose l'inverse, et dit la même chose dans l'ordre où on la rencontre.
Créations
Web/site/guide.php— onze sections, trois schémas, et surtout ce qu'on doit voir après chaque commande. Sans le retour attendu, on ne sait pas si l'étape a réussi, et on enchaîne en emportant l'erreur avec soi.- Un groupe déroulant dans la barre du site — « Installer » réunit le guide, la vue d'ensemble, le téléchargement, les serveurs compatibles et les versions. Bâti sur
<details>, comme le menu replié : il s'ouvre au clavier, sans une ligne de JavaScript, et s'ouvre tout seul quand la page courante est dedans.
Évolutions
- La barre passe de onze entrées à huit plus un groupe. Deux pages qui n'y tenaient pas — « Serveurs compatibles » et le guide — deviennent atteignables autrement que par un lien au milieu d'un texte.
- Le guide nomme trois choses que l'installateur ne fait pas : le serveur MySQL, le compte du panel, et le mot de passe au premier lancement. Les taire produit exactement le genre de blocage qu'on ne sait pas nommer.
- L'accueil mène au guide, dans le bandeau comme au bas de page. Son bouton s'appelait déjà « Guide d'installation détaillé » et menait à la page de référence, qui n'en est pas un ; le libellé cesse de mentir. Le lien « Voir sur GitHub » voisin, qui répondait 404, cède la place au téléchargement.
Bugs corrigés
myoriginvalait le domaine du FAI, et la file de courriel se remplissait toute seule._postfix_configureposaitmyorigin= domaine de l'adresse d'expédition ; avec une adresse chez un fournisseur, la machine prétendait êtrefree.fr. Le courrier local versrootdevenaitroot@free.fr, jugé externe, envoyé sur Internet — et l'aliasroot:posé deux lignes plus bas n'était jamais consulté, les alias ne s'appliquant qu'aux adresses locales. Le garde-fou était court-circuité par le réglage censé le rendre utile. Relevé sur l'installation d'origine : 240 messages en file, un par échec desudo— Debian activemail_badpass—, chacun suivi de son avis de non-remise.myoriginvaut désormais le domaine du site.- Les cinq liens GitHub de la page d'installation menaient à une erreur — page du dépôt, archive zip, fichier « raw », tickets, licence. Le bouton « Télécharger l'archive » tombait sur un 404 à l'étape la plus décourageante qui soit. Seul le protocole git répond sur ce dépôt ; les adresses web non.
Vérifié
- Rendu réel contrôlé au navigateur : les trois schémas se dessinent et héritent des couleurs du site, aucun texte ne déborde de son cadre, le déroulant reste invisible et n'intercepte aucun clic tant qu'il est fermé.
- En 375 px : le groupe se retire de la barre au profit du menu replié, la page ne défile jamais horizontalement, les sept blocs de commandes défilent dans leur cadre sans jamais dépasser la fenêtre, aucun texte n'est sous 12 px et aucune cible tactile sous 32 px.
Avertissements
- « La page ne déborde pas » ne veut pas dire « la page est lisible ». Le premier contrôle mobile ne mesurait que les largeurs, et il était vert : les trois schémas tenaient dans la fenêtre, en s'y réduisant à une échelle de 0,38. Leur texte arrivait à 4,5 px. Il a fallu mesurer la taille rendue, et non la largeur, pour voir ce qu'un coup d'œil aurait vu tout de suite. Les schémas gardent désormais une largeur minimale et leur cadre défile, comme le font déjà les tableaux — défiler pour lire vaut mieux que voir sans lire.
4.9.0 — 31 juillet 2026
La mise à jour cesse d'être un geste manuel, et l'installateur redevient exécutable. Le module de mise à jour existait depuis longtemps — empreintes, sauvegarde, retour arrière — et n'était joignable que par une entrée de menu, donc par quelqu'un devant un clavier. En allant l'ouvrir, on a trouvé pire : le script distribué ne démarrait plus du tout.
Créations
Web/inc/update.php— le service de mise à jour du site, distinct dedistrib.php. Celui-ci répond à « donne-moi ce fichier », celui-là à « suis-je à jour, et qu'est-ce qui a changé ? ». Deux questions qui partagent une racine et rien d'autre./update— une seule requête pour décider : numéro publié, empreinte attendue du script, où le prendre, et l'explicatif tiré de ce journal.- Sept commandes dans l'installateur :
check,update,upgrade,status,history,rollback,version. Aucune n'attend de saisie, et les codes de retour sont ceux qu'attend une tâche planifiée. Web/tests/test-update.php— 50 vérifications.Tools/git-hooks/pre-commit— refuse un fichier que son interpréteur ne sait pas analyser :bash -npour les scripts shell,php -lpour le site et le panel. Il vérifie la version MISE EN SCÈNE et non celle du disque : ce sont deux fichiers différents dès qu'on a mis en scène une partie de ses modifications, et c'est justement là qu'on a le plus besoin du garde-fou. À activer une fois par clone —git config core.hooksPath Tools/git-hooks.
Évolutions
- Le panel annonce les nouvelles versions par une pastille, à côté de celle des demandes de salon. La question part sur le réseau au plus une fois toutes les six heures : le battement du panel, lui, part toutes les quinze secondes depuis chaque page ouverte.
Runtime/version.jsonsert enfin à quelque chose. Il portait déjà les trois champs qu'il fallait et n'était alimenté par rien.- La file d'attente de Postfix se pilote depuis le panel — relancer sans sudo, vider avec. Deux actions distinctes plutôt qu'une avec un paramètre : le niveau exigé se lit sur le nom, et un POST forgé ne peut pas transformer l'une en l'autre.
- Le tableau des liens dit si le serveur du dialecte est installé.
Bugs corrigés
- Trois apostrophes rendaient l'installateur inexécutable. Le JSON par défaut est un argument de
jqentre apostrophes simples ; un commentaire ajouté la veille en portait trois, la chaîne se refermait, et bash lisait le JSON comme du code.bash -nrefusait le fichier entier. Tout téléchargement depuis le 30/07 recevait un script qui sortait sans exécuter une ligne. - La page Statut cherchait deux binaires là où ils ne sont pas. UnrealIRCd est sous
Components/Serveur/bin/, jamais sousServers/; etServers/overtchat-hybridn'est que l'arbre des sources — le serveur EN PRODUCTION s'affichait « binaire absent » pendant qu'il tenait le réseau. - Un port tenu par un autre serveur n'est plus une anomalie. Deux serveurs ne peuvent pas écouter le même port ; que celui qui ne sert pas soit arrêté est la condition du bon fonctionnement. Seul un port ouvert sans que rien n'y corresponde en reste une.
- Le fichier
VERSIONn'était surveillé par rien — sans extension, il échappait au scan, et ne figurait pas dans la liste noyau. Le script se remplaçait, redémarrait, et relisait l'ancien numéro. - Les deux extracteurs de version cherchaient un motif disparu à la 4.0.0 et rendaient une chaîne vide depuis, l'affichage retombant sur une comparaison d'empreintes qui ressemble à une comparaison de versions.
Avertissements
- La règle sudoers n'est pas installée tant qu'on ne l'a pas posée à la main :
sudo install -m 440 Config/sudoers.d/overtchat-services /etc/sudoers.d/. Sans elle, « Vider la file » échoue en disant quoi faire. Celle en service sur la machine est antérieure aux lignes Anope. /updateet/dl/VERSIONne répondent qu'une fois le site déployé. D'ici là,overtchat-setup.sh versionrépond « injoignable » et la pastille du panel reste éteinte — ce qui est le comportement voulu face à une absence de réponse, mais ne prouve rien tant que le déploiement n'est pas fait.- Rien n'est annoncé dans le chat. Le mécanisme existe et fonctionnerait, mais une nouvelle version de l'installateur ne concerne pas les gens qui discutent. Un message répété à un public qui n'y peut rien est du bruit.
- Le hook ne s'active pas tout seul.
core.hooksPathest une configuration locale à chaque clone — et c'est heureux : un dépôt qui imposerait l'exécution d'un script à qui le clone serait un vecteur d'exécution de code. À poser dans le clone WSL comme dans celui de travail. bash -nn'attrape que la SYNTAXE. Il a vu les apostrophes du 30/07, mais il laisse passer unif [ 1 ; then—[est une commande, pas de la grammaire, et la faute n'apparaît qu'à l'exécution. Le hook écarte une classe de pannes, pas les pannes.phpn'est pas installé sur le poste Windows. Le hook y saute la vérification des fichiers PHP et l'ANNONCE — sauter en silence laisserait croire qu'ils ont été contrôlés. Les fichiers PHP du dépôt sont vérifiables depuis WSL, où php 8.4 est présent. ⚠ Le compte écrit ici était faux du double au 25/08/2026 ;git ls-files '*.php' | wc -lle donne.
4.8 1 version · 30 juillet 2026 4 additions 4 improvements 3 bugs fixed 6 warnings
4.8.0 — 30 juillet 2026
Les conversations privées : un endroit pour elles, et de quoi les surveiller sans les lire. Un message privé n'avait pas de fenêtre — il s'affichait dans le salon qu'on regardait et disparaissait au changement d'onglet. Il n'était surtout modéré nulle part, et l'exploration a montré pourquoi : le serveur ne le donne à personne.
Créations
Servers/overtchat-hybrid/src/msgfilter.c— filtre de contenu des messages privés, dans le serveur. Le seul point du réseau qu'on ne contourne pas en changeant de client.Web/inc/chatmod.php— la même analyse côté site, qui fait autorité sur ce qui est enregistré.Web/pages/chat.php— panel : mise en service, journal des alertes, règles visibles.Web/sql/014-chat-prive.sql,IriX/cmds/irix-chatalerte.tcl,Web/tests/test-chatmod.php,tests/test-filtre.py,conf/filtre-messages.example.
Évolutions
- Un onglet par conversation dans le chat, avec compteur de non-lus et fermeture — un salon se rejoint, une conversation s'ouvre. Les services gardent l'onglet « Activité serveur » : leurs réponses ne sont pas une conversation, et les en séparer éloignerait la question de sa réponse.
- La gravité est une somme, non une liste de mots. « J'ai 13 ans » ne vaut rien seul, « envoie-moi une photo » non plus ; ensemble, avec un renfort de combinaison, ils dépassent tous les seuils.
- À l'émission le message est retenu, à la réception il est masqué — affichable d'un clic. L'effacer priverait la personne de ce qu'on lui a écrit, et cela lui appartient.
- L'avis aux opérateurs ne porte jamais le contenu : un salon d'administration est lu par plusieurs personnes et journalisé. Le contenu ne va qu'au service, qui l'enregistre derrière une authentification.
Bugs corrigés
- La conversion leet détruisait la détection d'âge : « 13 ans » devenait « 1e ans ». La règle qui porte tout le dispositif ne voyait plus rien. Le banc l'a trouvé du premier coup ; à l'œil, la ligne semblait inoffensive.
site_reglage_setrend[ok, message]et ne lève pas : le panel aurait annoncé « en service » sur un échec d'écriture.- L'avertissement « aucun salon d'administration » se répétait toutes les vingt secondes — 4 320 lignes par jour pour la même chose.
Avertissements
- Le filtre serveur est inactif tant qu'aucun fichier de motifs n'est déclaré. C'est l'état d'un serveur neuf, et il faut le vouloir pour en sortir. Il est EN SERVICE sur ce réseau depuis le 30/07/2026, 35 motifs.
- Les alertes sont annoncées sur
#!Services!, par deux chemins qui ne se doublent pas : le SERVEUR annonce ses propres refus au moment où il les prononce (réglageFILTER_CHANNEL), et le BOT annonce celles venues du chat du site à son relevé, sous vingt secondes (chanadminen base). Ni l'un ni l'autre ne porte le contenu du message. Le salon est en+O: ces avis ne sont lus que par les opérateurs. #!Services!a dû être AJOUTÉ àIriX_channelspour cela : il n'y figurait pas, unUPDATE … SET chanadmin='oui'n'aurait donc rien posé, et le bot — qui tire de cette table la liste des salons qu'il rejoint — n'était pas sur le salon où on lui demandait d'écrire.- La file d'attente des copies d'alerte vit en mémoire : un arrêt du serveur la perd. Le refus lui-même, qui est ce qui protège quelqu'un, a déjà eu lieu et figure au journal — ce qui se perdrait est la trace consultable, pas la protection.
- Les modes
+G(censure), de salon comme d'utilisateur, restent déclarés, posables, annoncés en 005 — et lus par personne. Ce filtre ne les branche pas : il s'applique à tout le monde ou à personne. tests/test-irix.pyéchoue sur « IriX a reçu notre EOS et clos le burst », et cet échec est ANTÉRIEUR à cette version — vérifié en recompilant le code précédent.
4.7 1 version · 30 juillet 2026 6 additions 3 improvements 4 bugs fixed 3 warnings
4.7.0 — 30 juillet 2026
Une réservation de pseudo qui s'éteint, et un chat qui sait la proposer. Un pseudo réservé l'était pour toujours : le réseau finissait par manquer de pseudos que personne n'utilisait. Il s'éteint désormais après six mois sans identification — mais jamais sans que son titulaire ait été averti, ce qui s'est révélé être la partie la plus délicate à écrire.
Créations
IriX/cmds/irix-nickexpire.tcl— le balayage d'expiration, appelé une fois par jour. Avertissement au cinquième mois, suppression au sixième.IriX/tests/test-nickexpire.tcl— 26 vérifications, éprouvées par six mutations. Ce module supprime des comptes : c'est la partie du projet où un banc vaut le plus cher.IriX/tests/test-sessions.tcl— 30 vérifications sur le lien dont parle chaque écriture de session.Tools/alerte-pseudo.php— l'avertissement par courriel. Son code de sortie décide : sans envoi réussi, rien n'est supprimé.Web/inc/nickservice.php— qui tient les pseudonymes ici, OverNick ou NickServ. Détection, et réglagenick_servicequi l'emporte.Web/inc/reservation.php— l'ouverture d'un compte de site adossé à un pseudo réservé à l'instant.
Évolutions
- La réservation depuis le chat. Le bouton devient « Réserver ce pseudo » quand le pseudo n'est pas enregistré, et le formulaire crée d'un geste la réservation ET le compte du site. La preuve n'est pas un code recopié mais le mot de passe du pseudo — le visiteur est connecté dessus à cet instant.
- Colonne « Réservation » et bouton No-Expire au panel, avec l'échéance en clair : jamais, exempté, sans adresse, ou le nombre de jours restants.
REGISTERgarde l'adresse qu'il annonce, et dit ce qu'il engage.
Bugs corrigés
- Le nettoyage horaire fermait des sessions vivantes. Il juge sur les salons du bot ; un lien serveur-à-serveur voit tout le monde, y compris qui n'y est pas. À la première heure ronde, ces sessions étaient closes « orphelines » alors que ces gens étaient là — et sans
LIMIT, toutes celles du pseudonyme, sur tous les liens. - Personne ne fermait les sessions d'un lien tombé : elles restaient ouvertes jusqu'au redémarrage suivant.
- Six réponses WHO/WHOIS écrivaient dans la session d'un homonyme connecté sur un autre lien.
svc_config.namen'est pas le rôle : la lecture du pseudo-client cherchaitname = 'nick', ne trouvait jamais rien et retombait sur un repli — juste ici par coïncidence, faux dès qu'un service est renommé.
Avertissements
- L'envoi SMTP n'a jamais été éprouvé avec une vraie adresse. Tant qu'il échoue, aucune réservation n'est supprimée : c'est le bon sens de l'échec, mais la fonction reste inerte jusqu'à sa première vérification.
- Les pseudos sans adresse ne sont jamais supprimés automatiquement — on ne peut pas les avertir. Le panel les signale pour décision humaine.
- Le bouton du chat n'a pas pu être vu à l'œuvre : le tunnel WebSocket n'est pas joignable depuis l'environnement de vérification. Ce qui est vérifié : la page sert la bonne configuration, le fichier déployé contient bien la logique, et l'ouverture de compte refuse le GET comme le POST sans jeton.
4.6 14 versions · 28 juillet 2026 → 30 juillet 2026 12 additions 55 improvements 66 bugs fixed 6 removals 13 checks 15 mistakes 36 warnings
4.6.13 — 30 juillet 2026
Quatre dialectes, quatre liens, et tout ce que trois liens simultanés ont révélé. La version précédente fermait le lot 7 sur un lien p10 qui sert. Celle-ci monte les trois autres, ajoute au panel une page qui compare le déclaré au réel — et paie le prix de la nouveauté : la moitié de ce qui suit est une correction de choses qu'un seul lien n'avait jamais mises en défaut.
Évolutions
- Un socket par dialecte, chacun vérifié contre un vrai serveur. ircd-Hybrid 8.2.47 a été configuré et lancé pour l'occasion ;
unreala été éprouvé par bascule temporaire, faute de pouvoir coexister avec la production.
| Socket | Dialecte | Serveur | État |
|---|---|---|---|
| 1 — Overtchat | och | Overtchat-Hybrid, 127.0.0.1:6900 | production |
| 3 — Hybrid-essai | hybrid | ircd-Hybrid 8.2.47, 127.0.0.1:7202 | essai |
| 4 — ircu-essai | p10 | ircu 2.10.12.19, 127.0.0.1:7102 | essai |
| 5 — Unreal-essai | unreal | Overtchat-Hybrid, 127.0.0.1:6900 | éprouvé, puis désactivé |
- Le dialecte
hybrida monté du premier coup, opérateur du salon compris : le correctifEOBde la veille, écrit sans serveur en face, était le bon. C'est le serveur lui-même qui a résisté — sansmodules.conf, ircd-Hybrid ne charge AUCUN module, ne connaît donc ni PASS, ni CAPAB, ni SERVER, ne répond rien, et referme au bout de trente secondes sur « Registration timed out » sans jamais dire qu'il n'a pas compris. - La clé de
${t}_onlinepasse à(socket_id, uid). Un UID n'est unique que DANS SON LIEN, et deux réseaux choisissent leurs identifiants de serveur chacun de leur côté. ${t}_sessionsporte une colonnesocket_id. Entre réseaux liés simultanément, l'homonymie n'est pas un cas limite : c'est la règle.- Dix-sept fichiers
.mdrecalés sur l'état réel du projet. - Le site public dit enfin sur quoi ce programme s'installe. Jusqu'ici, la page d'installation supposait le serveur maison ; elle renvoie désormais vers une page qui compare les quatre, fonction par fonction et protection par protection. Son tableau des capacités est lu dans la base du bot, celle qu'il republie à chaque démarrage — avec la provenance affichée, et un instantané daté en repli quand la base ne répond pas. Une page de compatibilité qui vieillit sans le dire est pire que pas de page du tout : quelqu'un installe sur la foi d'une ligne périmée.
Créations
| Fichier | Rôle |
|---|---|
Web/inc/statut.php | La logique de la page « Statut serveurs » : lecture des déclarations, observation de la machine, et une fonction pure de verdict |
Web/pages/statut.php | La page elle-même — lecture seule, cinq verdicts, messages d'erreur / avertissement / information |
Web/tests/test-statut.php | 52 vérifications sans base, sans fichier et sans réseau |
Web/inc/compat.php | Les quatre serveurs, ce que chaque protocole permet, et ce que la sécurité y gagne ou y perd |
Web/site/compatibilite.php | La page publique correspondante — ?p=compatibilite, quatre tableaux, une croix pour l'impossible et une flèche pour le reste |
Web/tests/test-compat.php | 169 vérifications, dont celle qui compte : un refus doit être motivé, jamais une case barrée sans raison |
IriX/cmds/irix-proto.tcl → sid_de_uid | Le serveur d'origine d'un client, dont la forme dépend du dialecte |
Bugs corrigés
- Aucune session n'était plus ouverte à l'arrivée d'un client.
::soc::online::on_uidappelaitsession_openavec$vhost, variable supprimée le matin même en passant la lecture au dialecte. Tcl levait « no such variable », lecatchl'avalait. Une régression introduite et refermée le même jour, mais qui dit tout : uncatchsans journal est un endroit où les défauts s'installent — celui-ci en journalise désormais l'échec. - L'installateur ne téléchargeait pas
irix-proto.tcl, queIriX-sql.tclsource sans garde depuis le lot 3 : une installation neuve serait morte au chargement. Le site le distribuait pourtant ; c'est la liste embarquée dansBootstrap/overtchat-setup.shqui l'avait oublié. Troisième divergence de ce manifeste en un mois — rien ne le compare automatiquement auxsourceréellement écrits. - Le serveur d'origine d'un client était faux d'un caractère sur un lien p10 :
serveur_deprenait trois caractères en dur, la forme d'UnrealIRCd, et attribuait « AqA » à un client du serveur « Aq ». - Le tampon de la table des connectés confondait deux liens : indexé par UID seul, comme les
DELETEet lesUPDATEpartiels qui l'accompagnent. Le départ d'un client effaçait la ligne d'un homonyme d'ailleurs. purge_socketvidait le tampon entier : la chute d'un lien d'essai jetait au passage les changements en attente de la production.session_closefermait la session du premier homonyme trouvé, tous liens confondus, et le rattrapage d'adresse écrivait celle de l'un dans la session de l'autre.- La page de statut elle-même a rendu trois faux verdicts à son premier affichage :
ROOTest défini en dur sur l'installation qui sert, et déduire la racine du chemin du fichier faisait voir « non installé » sous deux serveurs qui tournent.
Erreurs
- Un commentaire qui contredisait son propre fichier : la section p10 affirmait encore que
decodablesne contenait pasp10, deux mille lignes plus bas que la ligne qui l'y inscrivait. - Quatre affirmations fausses dans la couche de protocole, relevées en revérifiant chaque référence contre les sources :
SJ/SVSNICK dans la table des jetons d'un serveur qui n'a ni l'un ni l'autre, le mode+rde P10 donné pour inexistant, le+Rde salon aussi, et la table des modes d'ircd-Hybrid amputée dew— un+wdemandé était donc écarté avec un motif faux. - Les comptes de la documentation étaient faux depuis le lot 3 : quinze modules Tcl annoncés au lieu de seize, quatorze documents au lieu de quinze, et
PROTOCOLES.md— le document des huit lots — n'était indexé nulle part. BACKUP.mdjustifiait l'exclusion deServers/par « versionnés dans le dépôt ». Ils ne le sont pas : les configurations des deux serveurs d'essai n'existent que sur le disque de cette machine.- Deux défauts des bancs eux-mêmes : un constat qui cherchait « 501 » dans une sortie contenant son propre libellé, et un client témoin nommé en dur qui faisait échouer tout second essai enchaîné.
Vérifié
332 vérifications hors lien côté Tcl, 52 côté PHP, et surtout des preuves par l'effet, sur les liens réels :
- une session réellement écrite à l'arrivée d'un client, lue pendant qu'il est connecté — après la déconnexion, on ne verrait que le
quitd'unUPDATE, sans savoir si l'ouverture a eu lieu ; - trois clients du même pseudonyme sur les trois réseaux, chacun sous son lien et avec les champs de son dialecte, et le départ de l'un qui n'emporte rien chez les autres ;
- sur ircu comme sur ircd-Hybrid, un client ordinaire voit les cinq pseudo-clients opérateurs de
#!Services!— le@vient du serveur, pas de notre journal.
Chaque correction a été mise en défaut avant d'être crue : le défaut remis en place, aucune session n'est écrite (490 → 490) ; restauré, les deux s'ouvrent. Un banc qui reste vert sous mutation ne mesure rien.
Avertissements
- Les sockets 1 et 5 ne peuvent pas être montés ensemble : le serveur n'a qu'un bloc de lien pour ce nom, et vérifie le SID annoncé.
- Les serveurs d'essai vivent hors du dépôt et hors des sauvegardes.
Servers/*est gitignoré saufovertchat-hybrid/. - Les sessions antérieures à cette version portent
socket_id = 0, qui se lit « lien inconnu » : cette table est un historique, elle n'est pas vidée au démarrage. — levé le jour même : la fonction, ses compteurs et la gardeonline_list()ne filtre pas sursocket_idonline_oper_present()prennent un lien facultatif, la page Connectés gagne un sélecteur et un badge d'origine. Deux défauts plus graves sont sortis de là : un tableau d'arguments SQL écrasé au lieu d'être complété, et_oper_presentcôté bot qui s'arrêtait au premier homonyme — un pseudonyme sans+osur un lien d'essai faisait refuser l'action d'un opérateur bien réel de la production, une fois sur deux, sans motif lisible.- p10 n'a encore servi que des pseudo-clients non rattachés en base.
4.6.12 — 30 juillet 2026
Le lien p10 ne servait à rien, et le banc disait que tout allait bien. La veille au soir, 241 vérifications passaient pendant qu'ircu refusait cinq modes, annulait cinq fois l'op et laissait la sonde sans réponse. Six écarts, tous nommés par le serveur dans des lignes qu'IriX jetait dans son default. Ce qui ferme le lot 7 n'est pas le code : c'est le lien qui sert, et un client témoin qui le confirme.
Évolutions
- Les modes de service se traduisent par RÔLE, pas par lettre. Recopier les lettres d'un serveur à l'autre donne des modes acceptés et faux :
qest PROTECTED sous UnrealIRCd et HIDEIDLE sous ircd-Hybrid,ds'y écritD, etkest SKILL chez lui quand il est CHSERV sous ircu.+iSdevient donc+iken p10,+isur ircd-Hybrid — qui n'a AUCUN mode de service —, et ce qui est écarté est dit dans le journal, jamais perdu en silence. - Quatre primitives de plus dans la façade :
modes_service,est_introduction,lire_burst_salon,decoder_ip. Etlire_clientrend cinq champs de plus (ident, hôte, hôte affiché, adresse, nom réel). ::soc::online::on_uidne lit plus par index en dur. Il remplit la table des connectés du panel et lisait aux positions d'UnrealIRCd : sur un lien d'un autre dialecte, les colonnesuid,ident,host,vhostetipauraient été fausses, lecatchde l'appelant avalant tout. Il passe parlire_client, etdecode_ipdélègue àdecoder_ipdu dialecte.p10entre dans::soc::proto::decodables— la liste que le lot 7 avait créée précisément pour empêcher de l'y mettre trop tôt. Les quatre dialectes sont désormais utilisables, et la table des capacités en publie douze fonctions chacun, soit 48 lignes.
Créations
| Fichier | Rôle |
|---|---|
IriX/tests/lien-p10.tcl | Monte un vrai lien contre l'ircu de Servers/ircu avec les procédures réelles, extraites de IriX-sql.tcl — pas un simulateur |
IriX/tests/essai-p10.py | Fait juger ce lien par un client témoin connecté au port utilisateur : dix constats, dont le @ devant les cinq services dans son NAMES |
Bugs corrigés
- Les numériques de réponse n'étaient pas des verbes.
decoupercherchait un verbe connu en second mot ;318n'en étant pas un, « Aq 318 … » se lisait sans préfixe avec « AQ » pour commande. Aucune branche311/318/401du dispatcher n'était atteignable : la sonde de présence ne POUVAIT pas aboutir, quelle qu'eût été la forme du WHOIS envoyé. - Le dialecte était résolu APRÈS le SID, dont la forme est justement une affaire de dialecte. Les deux gardes interrogeaient donc le dialecte de repli, et un socket p10 sans SID en base recevait un « 002 » d'UnrealIRCd. Le lien montait quand même — ircu lit les deux premiers caractères et prend le reste pour de la capacité — puis tuait les cinq pseudo-clients : « Unknown numeric nick ». Invisible en production, où la variable gardait la valeur d'une connexion précédente.
- L'op se prenait par
JpuisM +o, et ircu annulait les cinq :ms_joindéope systématiquement, et unMvenant d'un client non opérateur est renvoyé en déopant sa source. C'estC(CREATE) qui donne l'op — et les cinq services doivent partager le TS de l'injection, faute de quoi seul le premier l'obtient et les quatre autres déclenchent un avis de désynchronisation. - La sonde WHOIS nommait un serveur :
ms_whoistraite son premier argument comme tel dès qu'il y en a deux, d'où le « 402 :Server has disconnected ». - L'adresse restait
AAAAAA:client_entrelisait un champ que personne ne remplit. Elle encode maintenant l'adresse brute, et ne touche jamais au champip64, dont le nom ne dit pas pour quel serveur il a été encodé. - Un lien
hybridn'aurait jamais reconnu la fin de son burst :EOBmanquait à la liste des verbes de fin. Même défaut que celui d'EBpour ircu, corrigé la veille — relevé en relecture, avant qu'un serveur ne le montre. - L'installateur ne téléchargeait pas
irix-proto.tcl, queIriX-sql.tclsource sans garde depuis le lot 3 : une installation neuve serait morte au chargement. Le site le distribuait pourtant — c'est la liste embarquée dansBootstrap/overtchat-setup.shqui l'avait oublié.
Erreurs
- Un commentaire qui contredisait son propre fichier : la section p10 affirmait encore que «
decodablesne contient PAS p10 » et que « le panel refuse de basculer un lien vers ce dialecte », deux mille lignes plus bas que la ligne qui l'y inscrivait. - Trois affirmations fausses, relevées en revérifiant chaque référence contre les sources :
SJ/SVSNICK figurait dans la table des jetons d'un serveur qui n'a ni l'un ni l'autre — et_est_verbel'acceptait —, le mode+rde P10 était donné pour inexistant alors que c'estFLAG_ACCOUNTdont seul le retrait est impossible, et le+Rde salon existe aussi. Une quatrième était incomplète : la table des modes d'ircd-Hybrid omettaitw, si bien qu'un+wdemandé était écarté avec un motif faux. - Deux défauts des bancs eux-mêmes, trouvés en les faisant tourner : un constat qui cherchait « 501 » dans une sortie contenant son propre libellé « modes refusés (501) » — donc toujours rouge —, et un témoin nommé « Temoin » en dur, qui faisait échouer tout second essai enchaîné sans dire pourquoi.
Vérifié
327 vérifications hors lien, 0 échec, et dix constats sur un lien réel. Chacun des deux bancs a été mis en défaut par mutation du code — remettre J suivi de M +o fait tomber l'op à 0 sur 5, retirer la traduction ramène les 501, la sonde à deux arguments empêche l'état « active ». Un banc qui reste vert sous mutation ne mesure rien.
Les quatre dialectes ont parlé à un vrai serveur, chacun par son socket :
| Socket | Dialecte | Serveur | État |
|---|---|---|---|
| 1 — Overtchat | och | Overtchat-Hybrid, 127.0.0.1:6900 | production, active + verified |
| 3 — Hybrid-essai | hybrid | ircd-Hybrid 8.2.47, 127.0.0.1:7202 | essai, active + verified |
| 4 — ircu-essai | p10 | ircu 2.10.12.19, 127.0.0.1:7102 | essai, active + verified |
| 5 — Unreal-essai | unreal | Overtchat-Hybrid, 127.0.0.1:6900 | éprouvé par bascule, désactivé au repos |
Sur ircu comme sur ircd-Hybrid, un client ordinaire voit les cinq pseudo-clients opérateurs de #!Services! — le @ vient du serveur, pas de notre journal.
Avertissements
- Les sockets 1 et 5 ne peuvent pas être montés ensemble : Overtchat-Hybrid n'a qu'un bloc de lien pour « IriX.overtchat.fr », et il vérifie que le SID annoncé est celui qu'il a configuré. Le socket 5 reste donc désactivé au repos.
- Les deux serveurs d'essai vivent hors du dépôt.
Servers/*est gitignoré saufovertchat-hybrid/: les configurations d'ircu et d'ircd-Hybrid, y compris les réglages qu'il a fallu leur faire, n'existent que sur le disque de cette machine. - p10 n'a encore servi que des services non rattachés en base : sur le socket 4,
svc_confign'en porte aucun, si bien que l'injection passe par la branche de repli qui litIriX-src.conf.
4.6.11 — 30 juillet 2026
Le décodeur appartient enfin au dialecte. Il était écrit en dur dans le tronc commun, et supposait trois choses vraies de tous les serveurs rencontrés jusqu'ici : un deux-points en tête de préfixe, des verbes en toutes lettres, un identifiant d'une seule forme. P10 rompt les trois. C'est la seconde moitié du lot 7, et le seul endroit où ce lot touche le chemin qui sert.
Évolutions
- Cinq lectures rejoignent la couche :
decouper,generer_uid,identifiant_valide,encoder_ip,lire_client. Le tronc commun n'a plus une seule branche par serveur — la règle du §3, « par délégation, jamais par condition en ligne », est tenue. decouperrend le verbe en forme longue, ce qui a évité de réécrire le dispatcher : sonswitchreste en toutes lettres face à un serveur qui n'envoie que des jetons d'une lettre. Aucune de ses branches n'a changé.- Reconnaître un préfixe sans deux-points se fait sur le SECOND mot : le jeton
PAest aussi un numérique de serveur valide, et se fier au premier ferait lire « PA :secret » comme un préfixe. lire_clientcompte depuis la fin en P10 — les modes y sont facultatifs. Compter depuis la gauche donnerait le numérique pour des modes une fois sur deux.
Bugs corrigés
- Le banc de non-régression ne mesurait pas la normalisation des verbes. En retirant le
string toupperdedecouper, il restait vert : ses neuf lignes d'essai portaient toutes un verbe déjà en majuscules. Deux lignes à verbe minuscule et une vérification directe ont été ajoutées.
Vérifié
241 vérifications, 0 échec. La seule qui compte vraiment sur ce chemin : l'ancien corps du dispatcher est recopié dans le banc et comparé au nouveau sur onze lignes réellement vues sur le lien de production. Idem pour l'ancien générateur d'UID sur sept valeurs dont les bornes de base 36, et pour l'ancien encodage d'adresse, replis compris.
Avertissements
Ces trois avertissements ont été levés le jour même, en 4.6.12 — ils sont laissés tels quels : ils disent ce qu'on savait ne pas savoir, et c'est ce qui a rendu la suite possible.
p10n'est toujours pas dansdecodables, et c'est délibéré : rien de ce décodeur n'a rencontré un vrai serveur ircu. Un banc prouve ce qu'on compose et ce qu'on découpe, pas qu'un lien monte. L'inscription attend un socket d'essai, le burst lu et un message échangé.- IriX ne relira ces fichiers qu'à son prochain rechargement. Jusque-là, la production tourne sur le code d'avant.
- Restent le burst de salon
B, dont la lecture n'est pas écrite, et le calcul de l'IP en base64 d'ircu là où la fiche du service est construite —encoder_ipsait le faire, il reste à l'y brancher.
4.6.10 — 30 juillet 2026
Un encodeur P10, et la notion qui empêche de s'en servir trop tôt. Le dialecte p10 est écrit : 24 primitives pour ircu 2.10.12.19. Mais P10 n'est pas un dialecte de plus — c'est un autre protocole —, et le décodeur d'IriX n'en lit pas un mot. C'est le lot 7, à moitié.
Créations
::soc::proto::p10— ~340 lignes, sur les sources compilées le jour même.::soc::proto::decodables,decodable,utilisable— et la colonneutilisablepubliée en base, lue parproto_utilisables()côté panel.
Évolutions
- Écrit ne veut plus dire utilisable.
dialectesse déduit des namespaces qui portent des primitives : c'est une question d'encodeur.decodablesest une liste tenue à la main, à dessein — elle dit ce que le décodeur sait lire, ce qui ne se déduit d'aucun namespace. Le panel refuse la bascule vers un dialecte non utilisable, et dit pourquoi. - Six primitives ne sont pas définies pour p10, et c'est le résultat du lot : ni
renommer, nifaire_entrer, nifaire_sortir, nichanger_hote, nichanger_ident, nireserver_aux_operateurs. C'est ce qui empêcheirix-operjoinetirix-nickguardde croire qu'ils protègent quelque chose sur ce serveur. Une septième,marquer_identifie, refuse la dépose :ACpose un compte, et seule la déconnexion l'efface.
Bugs corrigés
- Une vérification du banc mesurait l'inverse de ce qu'elle annonçait. « Un dialecte non écrit retombe sur unreal » employait
p10comme exemple — orp10est écrit depuis ce jour. Le repère porte désormais sur un dialecte franchement imaginaire.
Vérifié
201 vérifications hors lien, 0 échec — 52 ajoutées, chaque ligne comparée octet à octet aux formes du serveur, refus compris. Deux mutations pour éprouver le banc : un deux-points ajouté en tête d'une ligne P10 en fait tomber 1, le + retiré d'une G-line en fait tomber 3.
Trois pièges relevés dans les sources, qu'aucune documentation ne donne : les modes de la ligne N emportent leur espace ou disparaissent entièrement, le statut d'opérateur ne voyage pas dans le J — il faut deux lignes —, et la cible d'un I est un pseudonyme là où tout le reste emploie des numériques.
Avertissements
- Le décodeur n'est pas fait, et c'est l'essentiel du travail restant : découpe de ligne sans deux-points, identifiants base64 sensibles à la casse, table des verbes en réception. Sans lui, un lien
p10monterait et ne transporterait rien. - L'encodage des IP en base64 d'ircu manque aussi côté émission :
client_entreécritAAAAAA, la valeur qu'ircu emploie lui-même pour une adresse inconnue. - Tant qu'IriX n'a pas redémarré, le panel voit
hybridetp10comme non écrits — la table des capacités est republiée au démarrage. C'est le comportement sûr : aucun des deux n'est proposé entre-temps.
4.6.9 — 30 juillet 2026
IriX sait parler à un second serveur. Le dialecte hybrid est écrit : 29 primitives pour ircd-Hybrid 8.2.47, chacune fondée sur une ligne de ses sources. C'est le lot 6 de PROTOCOLES.md, celui dont le préalable n'était pas du code mais une machine.
Créations
::soc::proto::hybrid— ~330 lignes. Chaque primitive porte en commentaire le fichier et la ligne dont sa forme est tirée. Rien n'est déduit du « TS6 en général », qui n'existe pas : chaque implémentation a ses écarts, et ce sont eux qui font tomber un lien.
Évolutions
- Presque rien ne se délègue à
unreal, contrairement àoch. Les deux serveurs ne partagent que les commandes les plus banales, et jusqu'à celles-là la source diffère. Une délégation aurait donné un dialecte qui a l'air de marcher et déraille au premier cas particulier. - Le handshake n'est pas le TS6 « classique » : le SID voyage dans
SERVERetPASSne porte que le mot de passe.CAPABn'annonce qu'EOB— une capacité annoncée est une promesse de lire, et il ne faut pas réclamer ce qu'on ne décode pas. - Le TS à zéro désactive le contrôle des commandes de service : le serveur écrit
if (ts && ts != target->tsinfo) return. C'est la porte qu'il laisse ouverte, et c'est elle qui permet aux primitives de garder la signature de la façade, laquelle ne transporte pas cet horodatage. MODEplutôt queTMODE:TMODEcontrôle le TS du salon, qu'on n'a pas, et un TS inventé ferait échouer la commande en silence.MODEa unSERVER_HANDLERqui n'exige rien de la source.changer_identn'est pas défini, et c'est le travail : ircd-Hybrid n'a aucun équivalent deCHGIDENT. La façade lève une erreur nommant le dialecte, plutôt que d'émettre une ligne qui ne ferait rien.
Vérifié
149 vérifications hors lien, 0 échec — 49 ajoutées pour ce dialecte, chaque ligne comparée octet à octet à ce que le code du serveur dit attendre, refus compris. Le banc a été éprouvé par deux mutations : l'ordre des champs du UID inversé en fait tomber 2, le TS de SVSKILL retiré en fait tomber 1.
Avertissements
- Aucun lien n'a été monté. Un banc hors lien ne dit rien de la réaction du serveur, seulement de ce que nous composons. L'épreuve se fera sur un socket déclaré au panel — jamais sur celui qui sert.
- Un point du dialecte n'a pas été établi par lecture : le TS de salon d'
INVITE, laissé à 0 faute d'être transporté par la façade. Rien dans le code lu ne dit qu'un zéro y vaut « ne pas vérifier », contrairement aux commandes de service. C'est le seul endroit à éprouver avant de s'y fier. - Le panel proposera désormais
hybriddans le choix de dialecte d'un lien, puisque les dialectes « écrits » sont déduits des namespaces qui portent des primitives. Écrit ne veut pas dire éprouvé.
4.6.8 — 30 juillet 2026
Trois serveurs et un logiciel de services, installés pour de bon. Le projet raisonnait depuis des semaines sur des serveurs qu'il n'avait jamais compilés. PROTOCOLES.md en portait la trace : six questions sans réponse, et une table de capacités où neuf lignes sur onze disaient « non — non confirmé, aucun binaire installé pour le vérifier ». Ils sont installés. Huit de ces neuf « non » étaient faux.
Évolutions
- Cinq sources épinglées, en un seul endroit — en tête de
overtchat-setup.sh. Les numéros vivaient à trois : le JSON des serveurs, celui des services, et un--branch v1.10.1au milieu d'une fonction. Relevés le 30/07/2026 par code HTTP, taille et tags d'API, pas recopiés. _sources_syncaligne les JSON déjà écrits. Sans elle l'épinglage n'aurait valu que pour une installation neuve : ces fichiers ne sont pas suivis par git, et les_initne réécrivent jamais un fichier existant.- Le site lit les versions au lieu de les recopier —
composants_liste()extrait les constantes du script. La page annonçait « v3.5.2 » face à un dépôt en 4.6.7 ; c'était la troisième fois qu'un numéro écrit en dur mentait.
Bugs corrigés
- Un
install_dirnul, et 876 Mo compilés dans un dossier nommé « null ». Leservices.jsonen service vient d'un schéma antérieur qui n'avait pas ce champ. Rien ne le vérifiait :mkdir,tar,cmakeetmakeont travaillé sur un chemin relatif, dans le dépôt lui-même._dir_exploitablerefuse désormais un chemin vide, « null » ou relatif ;_svc_repair_dirsrépare le fichier. - Deux binaires que personne ne cherchait sous leur vrai nom. Anope 2.1 produit
bin/anopeet nonbin/services: l'installation échouait sur « binaire introuvable » après une compilation réussie, puis le rollback effaçait tout. Overtchat-Hybrid produitbin/overtchatd, absent lui aussi de la liste. - Deux
source_urlmorts : une page HTML pour ircu, un compte GitHub abandonné pour Overtchat-Hybrid — dont les sources sont dans le projet. - Trois paquets exigés pour rien.
_install_hybridréclamait autoconf, automake et libtool avant même de regarder les sources, qui portent leurconfigure. Sur une machine sans élévation, l'échec était définitif.
Erreurs
J'ai écrit dans un commit que l'archive d'un tag GitHub d'ircu2 n'embarquait pas de configure. C'était une supposition présentée comme un fait ; elle est fausse, et le commit 6b34d04 la rectifie. J'ai aussi annoncé que le nom horodaté du binaire d'ircu allait faire échouer _srv_finalize : make install crée lui-même le lien.
Avertissements
services.confd'Anope n'est pas écrit._anope_configurelit le mot de passe du lien au clavier, et ce secret n'a pas transité par cette session. La configuration reste à faire.- Aucun de ces trois serveurs n'a été démarré. Ils sont compilés et installés ; qu'ils montent un lien avec IriX reste à éprouver — c'est l'objet des lots 6 et 7.
- Eggdrop est épinglé sur une version candidate (1.10.2rc1), par décision explicite. La dernière version publiée est la 1.10.1, et IriX tourne dessus.
4.6.7 — 30 juillet 2026
Le panel Anope savait allumer sept pseudo-clients, pas dire à quel serveur ils parlent. Anope ne devine pas le dialecte de son lien : un bloc module le désigne, et un module faux ne produit aucune erreur franche — Anope démarre, puis le lien échoue au burst. Le panel pilotait les sept pseudo-clients sans jamais regarder ce bloc-là. C'est le lot 8 de PROTOCOLES.md, et le dernier atteignable sans installer de serveur tiers.
Créations
Web/tests/test-anope.php— le premier banc PHP du projet, 62 vérifications sur desservices.confde synthèse. Anope n'est installé sur aucune machine d'ici : il n'y a pas de fichier réel à lire, pas de lien à monter, aucune observation possible en service. Une preuve hors installation était donc la seule disponible, et elle a décidé de la forme du code.
Évolutions
- La décision est une fonction pure —
anope_protocole_verdict(lignes, dialecte). Tout ce qui choisit est dedans ; ce qui l'entoure ne fait que lire un fichier et une table. Enfouie dans la lecture, cette décision n'aurait pu être éprouvée d'aucune manière. - Le dialecte n'est pas un choix de cette page : il vient de la colonne
protodu lien ULine, et le POST ne le porte pas. Un formulaire qui l'accepterait permettrait de configurer Anope pour un serveur qui n'est pas celui d'en face — exactement la panne que ce lot doit rendre impossible. - Cinq verdicts qui ne se confondent pas : conforme, à activer, non déclaré, divergent, sans objet. Le divergent est le coûteux — un module de protocole étranger actif — et il a sa propre couleur.
- P10 refuse, et le dit : Anope n'embarque aucun module P10, ni en 2.0 ni en 2.1. Ce n'est pas une configuration à corriger, c'est un logiciel de services à changer — srvx, X3 ou GNUWorld. Le refus tient même quand un module de protocole est actif, puisque c'est justement le cas où Anope tourne sur un réseau qu'il ne sait pas servir.
- Une seule écriture, jamais deux. Éteindre le module étranger et allumer le bon se fait en mémoire puis s'écrit en une fois : aucun état intermédiaire du fichier ne porte deux protocoles actifs, ou aucun.
Vérifié
62 vérifications hors installation, dont l'aller-retour complet de la bascule et celle qui compte le plus : après application, le mot de passe du lien et tout le reste du fichier sont intacts — le panel commente et décommente, il ne réécrit pas.
Et le banc a été éprouvé lui-même, par deux mutations du code : l'ordre des opérations inversé fait tomber 1 vérification, le choix du nom figé sur le premier candidat en fait tomber 4. Un banc qui reste vert sous mutation ne mesure rien — c'est la leçon du 29/07, appliquée avant d'annoncer un résultat.
Avertissements
Ce qui n'est pas prouvé : qu'Anope, ce module chargé, monte le lien. Il faudra l'installer pour le savoir. La liste des noms de modules de protocole reconnus n'a été lue dans aucune installation — elle peut être incomplète, et un nom qu'elle ignore passera pour un module ordinaire. C'est le sens prudent : le panel signale ce qu'il reconnaît et se tait sur le reste.
4.6.6 — 29 juillet 2026
Le lien de production dit enfin à quoi il parle. Il annonçait unreal ; il a en face Overtchat-Hybrid. Les deux dialectes émettent la même chose sur tout ce qu'IriX utilise — mais pas les mêmes possibilités, et c'est ce que le panel affichait de travers. C'est le lot 5 de PROTOCOLES.md.
Évolutions
- Dialecte
och, qui hérite d'unrealpar délégation explicite, une procédure par primitive. Plus verbeux qu'un relais automatique, et voulu : une primitive ajoutée àunrealn'apparaîtra pas ici toute seule, elle demandera le geste de vérifier qu'Overtchat-Hybrid la comprend. Un héritage muet promettrait, au nom de ce serveur, tout ce qu'on écrirait pour l'autre. - Le routage par lien, annoncé au lot 4 comme non fait : 46 compositions passent désormais par
::soc::proto::pour <lien>. La colonneprotopilote donc la composition, et plus seulement l'acceptation du lien. Pas de « lien courant » global : un point d'entrée oublié aurait composé dans le dialecte d'un autre lien, sans un mot. - Le lien de production est déclaré
och.
Bugs corrigés
- Une composition d'
UIDécrite en clair subsistait dansIriX-sql-fixes.tcl, oubliée par le lot 3 : son argument passait à la ligne, et le relevé des sites ne cherchait que les appels tenant sur une seule. irix-proto.tclne se chargeait que si quelqu'un avait préparé le terrain : il définissait des procédures dans des namespaces déclarés ailleurs. La campagnetest-irix.py, qui le source seul, l'a révélé en refusant de créer le premier dialecteoch. Le fichier déclare maintenant ce qu'il emploie — sans effet en production, indispensable partout ailleurs.
Vérifié
100 vérifications hors lien — dont, primitive par primitive, que och rend exactement les mêmes lignes qu'unreal sur tout ce qu'IriX émet. 26 contre un vrai serveur. Et la mesure qui autorisait la bascule : le burst d'avant et celui d'après, 13 lignes identiques octet pour octet, puis les 17 vérifications de bout en bout rejouées sous le nouveau dialecte.
4.6.5 — 29 juillet 2026
Une session comptait les salons rejoints, pas les connexions. L'onglet Connexions du panel promet « qui est venu, quand, d'où, et quand il est reparti » ; il montrait en réalité une ligne par entrée dans un salon où le bot siège. Seize pour IriX en deux heures.
Bugs corrigés
- Une arrivée, une ligne. La session s'ouvrait sur le bind
JOINd'Eggdrop et se fermait surPART— donc en quittant un salon, alors que la personne est toujours sur le réseau. L'ouverture suit désormais l'arrivée sur le réseau (online::on_uid), qui la voit une seule fois et complètement : ident, hôte, hôte masqué, adresse et serveur d'origine sont tous dans la commandeUID. La fermeture suit le départ, sur le même chemin — le seul qui voie partir tout le monde, là où le bindQUITne voit que les clients partageant un salon avec le bot. - Le burst ne compte pas comme une arrivée. Il réannonce tout le réseau à chaque relien : sans distinction, chaque reconnexion aurait daté d'aujourd'hui l'arrivée de gens présents depuis des jours.
- 229 sessions restées ouvertes, dont certaines du 25/07 : personne n'écrit la fin quand le bot s'arrête entre-temps. Elles sont closes au démarrage, comme le sont déjà les sockets et les authentifications.
- Cinq
putlogde débogage partaient à chaque déconnexion depuis des semaines — le point M-1 dePROJET.md, ouvert de longue date. Retirés.
Vérifié
Un client connecté, deux salons rejoints, puis départ : une seule ligne, portant son hôte masqué, son adresse et son serveur, ouverte à l'arrivée et fermée au départ. Les 229 fantômes clos au démarrage, contrôlés en base — event_type et motif à l'appui, pour s'assurer que c'était bien cette correction qui avait agi et non autre chose.
4.6.4 — 29 juillet 2026
Le panel proposait des commandes sans savoir si le serveur en face les comprend. Il n'avait aucun moyen de le savoir : rien ne disait quel dialecte parle un lien, ni ce que ce dialecte permet. C'est le lot 4 de PROTOCOLES.md.
Évolutions
- Colonne
protosur les liens ULine (unreal,och,hybrid,p10; défautunreal, qui est ce que parlent tous les liens existants). Elle est lue à la connexion et contrôlée : un dialecte non écrit fait refuser le lien avant l'ouverture de la socket, avec la liste de ce qui est disponible. Sans ce contrôle, l'erreur serait tombée à la première commande — donc après le handshake, avec un lien établi, des pseudo-clients annoncés et un panel affichant « actif ». - Table des capacités : ce que chaque dialecte sait faire, décrit dans la façade et publié en base au démarrage. Le panel la lit ; il ne la recopie pas. Deux tables à tenir d'accord divergent au premier ajout, et c'est toujours celle qu'on affiche qui a tort.
- Page Liens ULine honnête : le dialecte de chaque lien s'affiche et se change ; les dialectes décrits mais pas encore écrits sont proposés et désactivés, ce qui répond à « pourquoi ce choix manque-t-il ? » sans ouvrir le code. Le tableau des capacités donne le motif au survol de chaque
partielet de chaquenon.
Bugs corrigés
- « Hôte masqué » et « Adresse » vides dans l'onglet Connexions. Mesuré : sur 479 sessions, 138 portaient un hôte masqué et une seule une adresse. Ce n'était pas une perte de donnée — le lien reçoit ces champs dans chaque commande
UIDet les écrit fidèlement dansonline. C'estsession_openqui ne les a jamais eus : son unique appelant est le bindJOINd'Eggdrop, qui ne connaît quenick!ident@host, et la colonnevhostne figurait même pas dans sonINSERT. Elle les reprend désormais deonline, et le cycle rattrape les sessions ouvertes plus vite que lui — un client qui rejoint un salon dans la seconde de son arrivée devance le rafraîchissement de 30 s.
Vérifié
89 vérifications hors lien (dont tout refus porte son motif : un grisage muet au panel serait un demi-service). En production : migration appliquée sur les deux liens, 44 capacités publiées, refus d'un dialecte non écrit constaté sur le lien d'essai, et une session neuve portant enfin son hôte masqué et son adresse.
Avertissements
- Les primitives ne routent pas encore par lien. La colonne décide aujourd'hui de l'acceptation du lien, pas du langage employé dessus — faute d'un second dialecte à distinguer. Passer l'identifiant jusqu'aux primitives est le premier geste du lot 5, et rien ici ne prétend le contraire.
- Une session est toujours ouverte par entrée en salon, non par arrivée sur le réseau : un client qui rejoint trois salons où le bot siège produit trois lignes, et l'onglet Connexions les montre toutes. Constaté en mesurant (16 lignes pour
IriXen deux heures) ; non traité ici, parce que c'est un changement de ce que « session » veut dire.
4.6.3 — 29 juillet 2026
Trente formes de protocole écrites en clair sur trente sites d'appel. Ajouter un serveur revenait à les retrouver tous, et à espérer n'en avoir oublié aucun. Elles vivent désormais dans IriX/cmds/irix-proto.tcl, derrière une façade qui choisit le dialecte — un seul est écrit, celui d'UnrealIRCd 6, que parle aussi Overtchat-Hybrid. C'est le lot 3 de PROTOCOLES.md, celui qui était annoncé comme le plus dangereux.
Créations
IriX/cmds/irix-proto.tcl— 33 primitives, une façade, un dialecte. Sourcé avant tout ce qui l'appelle, et ne définissant que des procédures : ni configuration lue ni journal écrit au chargement, comme les autres modules.
Évolutions
- Trois règles, chacune tirée d'un défaut déjà payé ici. La façade ne devine pas : le dialecte est déclaré, jamais détecté. Une primitive absente lève une erreur au lieu de rendre une chaîne vide — la commande qui n'existe pas doit se voir davantage que celle qui existe. Et la façade compose sans écrire : elle rend une liste de lignes, que
::soc::ulines::auto::emettrepasse àraw, seul point d'écriture. ::soc::svc::sendremplacé par::soc::svc::envoyer: le premier prenait une ligne déjà écrite en clair par l'appelant, c'est-à-dire l'endroit exact où le dialecte se répandait.- Une exception assumée : le handshake est composé par la façade mais écrit par
puts. Sa première ligne porte le mot de passe du lien, etrawjournalise tout ce qu'il émet.
Bugs corrigés
- Six commandes de service devenues muettes. Le branchement, fait par script, a écrit
\nlittéral là où il fallait un backslash en fin de ligne. Tcl y voit un argument valant un saut de ligne :emettreen recevait trois au lieu de deux, l'erreur était avalée par lecatchdu dispatcher, etKILL,SAJOIN,SAPART,SVSNICK,CHGHOST,CHGIDENTne partaient plus — sans un mot, ni au journal, ni à l'opérateur. Les G-lines fonctionnaient, leurs deux enveloppes ayant été corrigées à la main : la panne était partielle, donc plus difficile à voir. - Le banc ne pouvait pas le voir : il vérifiait la façade sans jamais appeler les enveloppes qui l'appellent. Neuf d'entre elles y entrent désormais, avec un vrai canal et relecture de la ligne écrite.
tests/irix-link.tclne chargeait pas la nouvelle couche : les appels tombaient sur les talons automatiques du banc, le handshake partait vide, et la campagne échouait sur un « EOF pendant burst » qui ne désignait pas sa cause.
Vérifié
78 vérifications hors lien — chaque ligne comparée octet à octet à celle du code d'avant, chaînes relevées avant extraction. 26 de plus font tourner le vrai code d'IriX contre un vrai serveur : handshake, burst, cinq UID injectés, sonde WHOIS, SVSJOIN, SVSMODE, SVSNICK, CHGHOST. 17 en production, sanctions et commandes de service comprises.
Et la mesure qui tranche : les 45 formes réellement émises depuis le redémarrage ont été confrontées aux 90 formes relevées dans le journal avant l'extraction — aucune nouvelle, aucune modifiée.
Avertissements
- Un banc qui teste la couche du dessous ne dit rien de celle du dessus. C'est ce qui a laissé passer les six commandes muettes, et cela vaut pour tout ce qui sera écrit au-dessus de cette façade.
- Une épreuve lancée trop tôt accuse le code à tort. Après un redémarrage d'IriX, le lien passe
activeavant que les cinq pseudo-clients soient injectés : une campagne lancée dans cet intervalle reçoit401 No such nick/channelet conclut à une panne. Attendre la présence des cinq.
4.6.2 — 29 juillet 2026
Les avis du serveur se choisissent par catégorie. Jusqu'ici, tout opérateur en +s recevait les 45 avis du serveur : chaque arrivée de client, chaque incident de lien, chaque anomalie technique. Sur un réseau qui grossit, l'avis qui compte finit noyé dans celui qui ne concerne personne — et un modérateur qui ne peut ni relancer un lien ni recharger la configuration lisait quand même tout ce qui s'y rapporte.
Créations
Servers/overtchat-hybrid/tests/test-snomask.py— dixième campagne du harnais, 17 vérifications contre le vrai binaire. Chaque vérification a son inverse : constater qu'un avis arrive ne prouve rien tant qu'on n'a pas constaté qu'un autre n'arrive pas. Éprouvée en neutralisant le filtre, qui fait bien échouer les deux vérifications décisives.
Évolutions
- Six catégories d'avis, et un masque par connexion — pas par client : un avis serveur ne va qu'aux opérateurs locaux, un masque n'aurait aucun sens de l'autre côté d'un lien.
sendto_realops()exige désormais sa catégorie, et les 45 appels ont été mis à jour. Elle aurait pu être facultative, avec un défaut « tout le monde la voit » : chaque avis ajouté ensuite aurait glissé dans ce défaut sans que personne s'en aperçoive, et le masque se serait vidé de son sens à mesure que le serveur grandit. Ici le compilateur refuse un appel sans catégorie.MODE <pseudo> +s <lettres>pour se régler en jeu : une liste nue remplace le masque,+cajoute une catégorie,-cla retire. L'argument n'est consommé que s'il est un masque valide de bout en bout — sans cette réserve,MODE moi +s +iavalerait le+iau lieu de le poser.- Le numérique
008est enfin émis. Il était déclaré, avec son format, et n'avait jamais servi — unRPL_SNOMASKque rien n'envoyait. snomaskdans le blocoper: le masque par défaut se déclare par compte. C'est la granularité par grade, etTools/opers-sync.shla dérive du grade du panel selon une règle simple — on reçoit ce sur quoi on peut agir.globalreçoit sanctions, connexions et opérateurs ;ircopsanctions et connexions ;moderateurles sanctions seules.- Rien n'est écrit pour
netadminetadmin, délibérément : un bloc sans directive reçoit tout, y compris les catégories qui n'existent pas encore. Leur figer un masque aujourd'hui leur ferait manquer, en silence, le premier avis d'une catégorie ajoutée demain.
Bugs corrigés
Tools/opers-sync.shpouvait bloquer la synchronisation des opérateurs. Une directive inconnue ne produit pas un avertissement mais fait échouer le chargement entier de la configuration. Le dépôt se met à jour d'ungit pull, le binaire demande une recompilation : entre les deux, ce script — qui tourne toutes les 30 secondes — aurait écrit unsnomaskque le serveur en service ne comprend pas, et chaque enregistrement du panel serait resté sans effet, avec un panel continuant d'annoncer des succès. Le script vérifie donc que le binaire porte la directive, se replie sans elle sinon, et le dit. Constaté à l'œuvre avant le déploiement : le repli s'est déclenché et s'est annoncé.
Vérifié
Les dix campagnes du harnais passent, soit 297 vérifications contre le vrai binaire — dont celle qui fait tourner le code Tcl réel d'IriX contre le serveur. Compilation sans un seul avertissement.
En production le 29/07 à 16:33 : binaire remplacé, overtchatd redémarré, lien ULine rétabli de lui-même et cinq pseudo-clients réinjectés.
Puis 8 vérifications sur le serveur en service : le même avis de connexion franchit le masque complet et ne franchit plus « +s k », tandis qu'une G-line posée par IriX atteint bien l'opérateur réglé sur les sanctions — ce qui éprouve du même coup les commandes du chantier précédent. Bannissement d'essai retiré, STATS g vérifié vide ensuite.
Une première version de cette vérification ouvrait trois connexions et concluait à un filtre défaillant. La production limite à trois connexions par adresse, IriX comprise : le client témoin était refusé, et l'avis attendu n'avait jamais eu lieu d'être émis. Le journal du serveur, qui reçoit tout indépendamment des masques, a tranché en une ligne.
La granularité par grade, éprouvée de bout en bout. Un compte ClaudeMod de grade moderateur a été créé au panel pour cela : le grade seul lui donne snomask "k", écrit dans son bloc par Tools/opers-sync.sh et accepté au rechargement. Sept vérifications en production, sans qu'il règle quoi que ce soit : il ne reçoit pas la connexion d'un client, il reçoit la sanction, et il peut ensuite élargir son masque lui-même — le défaut par grade est un point de départ, pas une clôture. Le journal du serveur confirme que le client témoin s'était bien connecté, sans quoi le « il ne le voit pas » n'aurait rien prouvé.
Avertissements
- Ce correctif demande une recompilation ET un redémarrage. Contrairement à IriX, un rechargement à chaud ne remplace pas un binaire, et le redémarrage déconnecte les clients.
- Le masque ne s'applique qu'aux avis, pas aux confirmations. L'auteur d'une commande reçoit toujours la réponse à sa propre action : ce n'est pas un avis serveur et cela ne passe pas par le masque. La première version de la campagne de test s'y est laissé prendre et croyait voir un filtre défaillant.
- Le journal du serveur reçoit tout, quel que soit le masque de qui est connecté : c'est la trace d'exploitation, elle ne dépend pas du public.
4.6.1 — 29 juillet 2026
Quinze commits, et presque tous le même défaut : un programme qui annonce un succès qu'il n'a pas obtenu. Le panel affichait « IriX activé » sans avoir testé le démarrage ; l'installateur déclarait Eggdrop, Anope et overtchatd installés alors qu'aucun des trois ne pouvait démarrer ; le hook TLS mourait avant le serveur en service ; IriX confirmait des sanctions qu'il n'émettait pas ; et le serveur laissait poser un bannissement universel en répondant « Erroneous Nickname » à tout le réseau. La journée n'a pas ajouté de fonctions : elle a rendu vrai ce que le projet affirmait déjà.
Créations
Markdown/PROTOCOLES.md— cartographie préalable au chantier « un IriX pour quatre serveurs » (UnrealIRCd, ircd-Hybrid, ircu, Overtchat-Hybrid) : 27 formes de protocole recensées avec fichier, ligne et rôle, un point d'insertion unique pour une future couche d'abstraction, et huit lots de travail ordonnés par rapport valeur/risque. Quatre niveaux de certitude, jamais mélangés : ce qui reste à confirmer est regroupé en §8 plutôt que dilué dans le texte.- Panel Anope (
Web/inc/anope.php,Web/pages/anope.php,Config/systemd/anope.service) — état de l'installation, cycle de vie de l'unité et activation des pseudo-clients. Anope n'ayant ni table ni file dans la base, les deux seuls leviers sont sonservices.conf— un blocmodulecommenté ou décommenté, le reste laissé intact, mot de passe du lien compris — et son unité systemd, appelée par sudo avec des commandes écrites en toutes lettres. Anope est optionnel : son absence est le cas nominal, et la page le dit calmement au lieu d'afficher des boutons qui échoueraient. IriX/tests/test-proto.tcl— banc hors lien : chaque primitive de protocole est appelée pour de bon et la ligne produite comparée octet à octet à celle attendue. Ni socket, ni base, ni Eggdrop ; 39 vérifications en une seconde. C'est l'amorce du lot 2 dePROTOCOLES.md.IriX/tests/epreuve-sanctions.py— épreuve sur le réseau en service : 17 vérifications qui provoquent l'effet et l'observent ailleurs. Aucune ne lit une confirmation.
Évolutions
- Les sanctions réseau d'IriX existent pour de bon. Bannissement (
TKL), changement d'identité (CHGHOST,CHGIDENT), sortie forcée (SVSPART), déconnexion et renommage ne vivaient que sur le chemin ULine hérité, que rien n'ouvrait. Neuf primitives les portent désormais sur le lien qui sert (IriX-sql.tcl, section 6bis-C4), avec douze commandes IRCop sur le service de rôlehub:GLINE,ZLINE,UNGLINE,UNZLINE,GLINELIST,ZLINELIST,KILL,SAJOIN,SAPART,CHGHOST,CHGIDENT,SVSNICK. Durées à la grammaire du serveur (30s,2h,7d; sans suffixe, en minutes). Toutes rendent 1 si la ligne est partie, 0 sinon, et aucune ne confirme d'elle-même. - Convention de source arrêtée : une émission est sourcée par l'UID d'un pseudo-client, jamais par un SID de serveur. Les deux passent le contrôle du serveur, mais un SID ne dit pas quel service a agi dans les avis aux opérateurs.
- Le déploiement d'IriX depuis le panel produit enfin une instance qui démarre.
_irix_configurecollecte l'identité en la reprenant deConfig/identity.jsonet deWeb/inc/config.php— le bot doit annoncer le même réseau que le site et écrire dans la base que le site lit. Le mot de passe SQL va dans leIriX.jsonde l'instance en 600, seul fichier qui en a besoin._irix_ecrire_confgénère une vraie configuration Eggdrop, jamais écrasée si elle existe déjà. - L'installateur distribué est désormais le script, plus un binaire.
shcne compile pas : il chiffre le script et le repasse à bash comme argument unique, or le noyau plafonne un argument à 131 072 octets et le script en fait 286 250. Le binaire se produisait sans erreur puis sortait sur « Argument list too long » sans exécuter une ligne. Les cléssetup,setup-devet l'ancien nomovertchat-setuppointent tous le.sh;CORE_WATCHED,git.setupetimportsuivent. Tools/identite-config.shconnaît le serveur en service. Il ne confrontaitConfig/identity.jsonqu'à UnrealIRCd, dont le répertoire n'existe plus, et sautait toute la moitié « serveur » en silence. Il lit maintenantovertchat.conf, dont la syntaxe diffère (blocsme { … }etadmin { … }), et rappelle qu'overtchatd doit recharger sa configuration.- Tout l'affichage du panel Bash passe par des primitives
_ui_*—printf '%-32s'rembourre en octets, donc chaque accent décalait une colonne, et les séquences de couleur comptent dans${#chaîne}sans occuper de colonne. Les entrées du menu sont regroupées par thème sans être renumérotées : regrouper aide qui découvre, renuméroter trahit qui s'en sert déjà.
Suppressions
- Trois installateurs concurrents, dont un seul démarre.
Builder/ne s'exécutait plus depuis des mois pour quatre raisons indépendantes (unsource ../installer/en minuscule qui passe sous Windows et échoue sous Linux, unsourcesur un binaire ELF, un MAKEFILE décrivant une arborescence inexistante, un clone vers un dépôt qui n'est plus le remote).Installer/est supplanté parBootstrap/overtchat-setup.sh: douze de ses quatorze fichiers avaient zéro référence, et sonuninstall.shéchouait à sa quatrième ligne, juste avant unrm -rfsur une variable non définie. Projet/01-04-2026/— aucune référence hors du journal, quatre binaires ELF versionnés dont deux identiques par MD5 à des copies actives.Components/Service/lib/Tcl/Stable/— présentée comme la source distribuée des modules IriX, elle avait quatre modules en moins et quatre fichiers en retard. Le projet le savait déjà :distrib.phpréacheminait délibérément toute demande versIriX/cmds/. Le manifeste réclame désormais les modules là où ils vivent.IriX-std.tclreste seul sousComponents/, faute d'homologue.- Onze fichiers de configuration que plus aucun code ne lisait —
Config/{config-base,paths,folders,schema,defaults}.jsondécrivaient l'installateur supprimé,Runtime/{env,database}.shsourçaient un binaire sorti du suivi git. Deux candidats ont été écartés après vérification, contre l'avis de l'audit : ils étaient référencés par du code vivant. - Le chemin ULine hérité d'IriX — 41 procédures, 1 140 lignes (
IriX-sql.tclpasse de 10 473 à 9 333). Sont restésrequire_ircop(~30 appels, tout le contrôle IRCop du projet),log_cmdet la synchronisationsync::*: ils ne dépendaient pas du socket. Markdown/{DOCKER,README}.md, forks périmés de leurs homonymes à la racine, qu'ils contredisaient.
Bugs corrigés
Serveur.
- Un champ de décalage sur
TKL, et plus personne ne pouvait se connecter.ms_tklne lisait que la disposition compacte du masque, alors qu'UnrealIRCd 6 le scinde en<user> <hôte>. Au burst, Anope réserve ses sept pseudonymes parTKL + Q * NickServ …: le masque était lu enparv[3], soit*— un Q-line sur*était posé et le serveur répondait « Erroneous Nickname » à tout le monde. Les deux dispositions sont maintenant reconnues au nombre d'arguments. (Correctif compilé et mis en service le 29/07 à 14:47 ; un rechargement à chaud ne remplace pas un binaire.) - Un retrait de bannissement qui échouait en silence.
TKL - G * <hôte>faisait chercher le masque*, introuvable ;ban_remove()échouait sans rien dire pendant qu'OperServ annonçait « deleted from the SQLINE list ». Tout bannissement posé par les services devenait permanent. L'échec est désormais annoncé aux opérateurs. - Un masque
*ou*@*est refusé à l'ajout. Rien ne l'arrêtait.
IriX.
TKLinversait user et hôte —TKL + G <hôte> <user>. Invisible tant que le serveur ne lisait queparv[3]: un/gline vilain@mauvais.frbannissait toutmauvais.fret enregistraitvilaincomme auteur. Les deux correctifs devaient être posés ensemble.!ulinestatusannonçait « DÉCONNECTÉ » en permanence, y compris avec des liens parfaitement établis : il lisait les drapeaux du chemin mort. Il interroge désormais<bot>_ulines_sockets.- Un masque trop large n'était refusé nulle part sur le trajet des services :
ban_mask_too_broadne s'applique pas auxTKL. La règle des quatre caractères significatifs est doublée côté IriX.
Installateur et panel.
- Eggdrop s'installait sans ses modules.
make eggdrop || makes'arrêtait au premier succès, etmake eggdropne construit que le binaire. Sansmodules/, IriX échouait à son premierbind msg,msgétant fourni par le moduleserver— longtemps après que l'installation ait été déclarée réussie. Séquence corrigée, et l'absence de modules fait désormais échouer l'installation. - Anope se compilait sans configuration.
conf/services.conf, sans lequel Anope refuse de démarrer, n'était écrit par aucune étape._anope_configurepart du modèle livré par la version compilée plutôt que d'écrire une conf de zéro : les directives changent d'une version majeure à l'autre. - Le panel déployait un IriX qu'aucun programme ne pouvait lancer :
_irix_startexécutaittclsh, alors qu'IriX est un jeu de scripts qu'Eggdrop héberge — 23bind, 246putlog, 25botnick. L'exécution s'arrêtait à la sixième ligne du premier module. irix-operjoin.tclmanquait au manifeste alors queIriX-sql.tclle source et l'appelle à neuf endroits. Une instance déployée depuis le panel recevait seize fichiers sur dix-sept, et Eggdrop s'arrête au premiersourceintrouvable.- Sept confirmations mensongères au panel, toutes bâties sur le même oubli : la valeur de retour n'était pas lue. « IriX activé » sans test du démarrage, deux
killnon vérifiés, « Mise à jour terminée » sur une erreur de syntaxe Tcl, « ✔ Aucune erreur » quandjqéchouait. - La mise à jour écrasait l'identité du réseau : le scan ramassait
Config/identity.json, propre à chaque installation, donc toujours « en attente », puis remplacé par les valeurs amont — nom du réseau, domaine et adresses de courriel disparaissaient avec un « MIS À JOUR » en vert. _server_updatepouvait détruire une installation ET sa sauvegarde :cp -an'était pas testé avant lerm -rfqui suit.- Le retour arrière ne restaurait qu'une fraction des fichiers : l'horodatage de session était calculé par fichier, créant autant de répertoires de session que de secondes écoulées. Il annonçait pourtant « ✔ N fichier(s) restauré(s) » et rendait 0 dans tous les cas.
- « Vérifier SHA-256 » répondait INVALIDE à tous les coups côté serveurs : la comparaison portait sur la chaîne « null ». Chaque appel marquait un serveur sain en défaut.
- L'archive du site s'installait sans contrôle d'intégrité dès que le manifeste était injoignable, et pouvait réécrire
Bootstrap/etConfig/. _panel_logslisait dans$HOME/Service-Overtchat— donc~rootsous sudo. Il annonçait « log absent » sur une installation dont les journaux se remplissaient normalement.--debugn'était reconnu qu'en première position, alors que c'est--root --debugqu'on tape quand l'installation en root échoue ; et une option inconnue n'était qu'un avertissement, si bien qu'une faute de frappe sur--rootlançait une installation sans élévation.- Deux migrations SQL portaient le numéro 010 : l'ordre était décidé par l'alphabet, pas par le numéro, alors que 011 et 012 font
ALTER TABLEsur une table créée par 010.apply.shrefuse désormais une numérotation ambiguë. make -j"$(nproc)"devientmake -jsinprocest absent — soit autant de jobs que de règles. Repli surgetconfpuis 1, borné à 16.
Exploitation.
- Le renouvellement du certificat s'arrêtait avant le serveur en service. Le hook Let's Encrypt déposait le certificat pour UnrealIRCd puis pour Overtchat-Hybrid ; sous
set -euo pipefail, l'échec du premier bloc — le binaire ayant été retiré — faisait sortir le script avant le second, le seul qui compte. La panne ne serait apparue qu'à l'expiration, sous la forme d'un réseau injoignable en TLS. - Le Dockerfile emportait le mot de passe MySQL dans l'image. Il copiait
IriX/runtime/en entier : absent d'un clone frais, où le build cassait, mais présent hors suivi sur une machine de développement, où le secret partait dans l'image. Le.dockerignorelaissait par ailleurs entrerConfig/access.json. - Une installation neuve d'overtchatd ne démarrait pas :
contrib/install-service.shn'installait aucun des quatre fichiers de politique dontovertchat.conf.exampledéclare les chemins, et dontsrc/conf.cfait une erreur fatale. Son contrôle de configuration était de surcroît lancé hors du préfixe, donc ne portait pas sur ce que le service allait charger. - La mise à jour guettait
Bootstrap/installirix, fichier absent du dépôt, de toute installation et du disque : chaque vérification demandait une URL inexistante et le rapport était rouge en permanence, noyant les pannes réelles.
Documentation.
- Douze fichiers de
Markdown/décrivaient un dépôt qui n'existe plus — arborescence d'avant le nettoyage, serveur hors service, procédures qui envoyaient dans le mur (webchat viawebsocket.conf,git cloneproduisant~/Overtchatquand tout code en dur~/Service-Overtchat).SECURITY.mdprésentait comme ouverte une alerte déjà traitée, en citant des numéros de ligne devenus vides : une alerte permanente et fausse finit par ne plus être lue. - Numéros de version désalignés :
Config/config.jsonetRuntime/version.jsonannonçaient 3.5.2,Config/irix.json4.0.0, quandVERSIONdisait 4.6.0. Et le logo du panel proclamait « V3.X.X », faute de s'afficher avant la lecture deVERSION. LICENSEportait l'ancien compte GitHub (Servus33), quandREADME.mdetConfig/identity.jsondisentSerVuS033.
Erreurs
- Un diagnostic posé le matin, corrigé l'après-midi. Il a été annoncé que les G-lines d'IriX « bannissaient plus large que demandé » à cause de l'inversion user/hôte. C'était faux dans ses conséquences : IriX n'émettait aucune G-line, le code étant sur le chemin mort. Le correctif reste juste, mais il portait sur du code inerte. Le correctif du serveur, lui, était entièrement fondé — c'est Anope qui posait le Q-line sur
*. - Une prémisse trop large. Le retrait du chemin hérité était demandé jusqu'à ce qu'il ne reste « aucune référence à
::soc::uline::». Trois sous-systèmes bien vivants logent dans ce namespace ; les en déloger aurait été un renommage sans rapport avec le code mort, à risque réel. - Un commit dont le message ne dit pas tout.
7a885d4annonce le correctifTKLet livre aussi le panel Anope complet — 1 139 lignes de PHP, une unité systemd et une règle sudoers. Le journal le rattrape ici.
Avertissements
GLINELISTetZLINELISTne montrent que les sanctions posées par les services. Un opérateur qui pose une G-line en direct n'y figure pas. Un panel qui présenterait ces tables comme « les bannissements du réseau » mentirait :STATSreste la seule source complète.- Le seed du panel est un
INSERT IGNORE: sur une base déjà peuplée, les lignesulineconnectetulinedisconnectsubsistent dans<bot>_commandset devront être retirées à la main si le panel les affiche encore. - Le serveur peut refuser après coup — pseudonyme occupé, hôte invalide. Les commandes d'IriX n'annoncent donc jamais plus que « la commande est partie ».
- Le panel Anope ne relit pas les blocs
uline,operet le module de protocole : ils dépendent du serveur IRC retenu et restent à la charge de l'exploitant. La page le dit plutôt que de laisser croire que tout est réglé. IriX-std.tcl(mode Standard, sans SQL) reste distribué sans équivalent maintenu dans l'arborescence active. À éprouver, ou à retirer du choix d'installation.
4.6.0 — 28 juillet 2026
Overtchat-Hybrid sert le réseau. Le serveur écrit pour ce projet a remplacé UnrealIRCd en production le 28/07/2026 à 14h16, après un essai en cohabitation sans coupure et une bascule de quelques secondes. Le démarrage automatique a suivi : overtchatd est enabled, unrealircd est disabled.
Évolutions
- WebSocket (
src/websocket.c,src/sha1.c) — le chat du site parle IRC à travers un WebSocket. Le serveur ne connaissait pas ce protocole : basculer sans lui aurait coupé le point d'entrée public du réseau. Poignée de main RFC 6455, cadrage en lecture et en écriture, ping/pong, contrôle d'origine. - Salons interdits (
src/chanprotect.c) — reprend la politique de création sur demande qu'UnrealIRCd tenait pardeny channel. Différence délibérée : les exceptions l'emportent où qu'elles soient écrites, là où UnrealIRCd fait dépendre le résultat de l'ordre des blocs. - Limitation de débit —
FLOOD_MESSAGESetFLOOD_PERIODétaient documentés et lus par personne. Ils s'appliquent enfin. - Onglet Connexions au panel — historique des arrivées et des départs, avec adresse réelle, hôte masqué, durée et motif de fin.
- 280 vérifications sur neuf campagnes, contre le vrai binaire et de vraies sockets.
Bugs corrigés
- Un lien serveur en TLS ne pouvait pas s'établir. Deux défauts distincts, invisibles en clair : la vérification de chaîne interrompait la poignée de main malgré un commentaire affirmant le contraire, et le handshake IRC n'était jamais émis sur un lien sortant chiffré — le pair attendait un
PASSqui ne venait pas. - Aucun anti-flood. 300 messages en rafale arrivaient entiers à leur destinataire, 500
WHOISproduisaient 1000 réponses. Désormais 10 sur 300 passent, soit la limite annoncée. - Le serveur démarrait sans ses fichiers de politique quand il était lancé hors de son préfixe : erreur fatale au démarrage, avertissement au
REHASH. - IriX lisait l'adresse au mauvais rang de la commande
UID— l'index 11 au lieu de 10, c'est-à-dire le premier mot du realname. Une seule des 333 sessions enregistrées portait une adresse plausible. - Le préflight de bascule refusait une configuration qu'il déclarait valide, faute de pouvoir écrire son journal dans
/tmpsous un autre utilisateur. irix.confétait en0644— mot de passe MySQL en clair sur une machine en DMZ.- Un contrôle de la campagne des protections ne testait rien : il s'authentifiait sous un opérateur inexistant.
- Une fenêtre PowerShell clignotait toutes les deux minutes sur le bureau : la tâche de maintien WSL passe désormais par un lanceur
wscriptsans console.
Erreurs
- Trois options de configuration étaient acceptées et lues par personne :
tls-no-verify,flood-exemptetwebsocket. Elles annonçaient des réglages inexistants — le pire des cas, puisqu'on croit avoir décidé quelque chose. La première est retirée, les deux autres sont implémentées. - Le symptôme de lien muet documenté le 27/07 était faux. L'écart entre
LINKSetLUSERSest l'effet normal deHIDE_ULINES. - Le SID recommandé était dangereux :
010appartient à l'espace où IriX puise les SID de ses sockets. Le serveur porte10A.
Avertissements
- Les services ont été muets vingt-cinq minutes après la bascule, entre 14h24 et 14h52. Cause : une reconnexion du lien demandée à chaud pour réinjecter les pseudo-clients. IriX a ouvert un second socket sans fermer le premier, le serveur a refusé (« déjà présent »), et les deux états ont divergé. Seul un redémarrage d'IriX les a remis d'accord. Ne pas relancer un lien ULine à chaud : modifier la configuration des services, puis redémarrer IriX.
- Les mots de passe des blocs
oper{}etlink{}restent en clair : le serveur sait lire une empreinte mais refuse franchement de la vérifier. - IriX régénère le bloc
link{}d'UnrealIRCd depuis la base et ne sait pas écrire celui d'Overtchat-Hybrid : ce bloc se maintient à la main.
4.5 2 versions · 27 juillet 2026 → 28 juillet 2026 4 additions 6 improvements 7 changes 4 bugs fixed 5 mistakes 9 warnings
4.5.7 — 28 juillet 2026
Version qui lève les blocages de la bascule vers Overtchat-Hybrid. La configuration de production est écrite et éprouvée en cohabitation ; le certificat TLS n'était pas le problème qu'on croyait ; celui qui l'était n'avait pas été vu.
Créations
Servers/overtchat-hybrid/src/chanprotect.cetinclude/chanprotect.h— salons interdits. Le serveur n'avait aucun équivalent dudeny channeld'UnrealIRCd, qui fait respecter la création de salons sur demande depuis le 22/07. Vérifié en essai avant d'être écrit : un client quelconque créait n'importe quel salon. Basculer en l'état aurait rouvert la création à tout le monde, en silence, pendant que le MOTD et le site renvoyaient toujours vers le formulaire.Servers/overtchat-hybrid/conf/salons-interdits.example— le socle, reprenant la politique en vigueur : six salons ouverts, tout le reste sur demande.~/overtchatd/conf/overtchat.conf— configuration de production, en0600. Hors dépôt, comme il se doit.
Modifications
Tools/ircd-bascule.sh— l'essai en cohabitation ne demande plussudo(il ne touche ni à systemd, ni à un port privilégié), n'écoute plus que sur la boucle locale (la machine est en DMZ,ufwinactive), lance le serveur depuis son préfixe, et pose la configuration d'essai en0600comme celle dont elle reprend les mots de passe.Tools/unrealircd-letsencrypt.sh— le hook de renouvellement sert désormais les deux serveurs. Pendant la bascule ils se relaient ; un hook qui n'en connaîtrait qu'un laisserait l'autre avec un certificat figé au jour de son installation.Servers/overtchat-hybrid/tests/test-protection.py— campagne des salons interdits : ordre des lignes sans effet, exceptions insensibles à la casse, exemption des opérateurs, tenue de la politique après unREHASHsans le fichier, refus de démarrer sans lui.DEPLOIEMENT.md,README.mddu serveur,ROADMAP.md,SECURITY.md,OVERTCHAT-HYBRID.md.
Bugs corrigés
- Le serveur démarrait sans ses fichiers de politique. Un
banned-nicksou unbanned-channelsdéclaré mais introuvable ne produisait qu'un avertissement, au milieu de lignes rassurantes — « configuration chargée » comprise. L'essai du matin a tourné sans aucun de ses 80 pseudonymes interdits, et rien ne permettait de s'en apercevoir. C'est désormais une erreur fatale au démarrage, et toujours un simple avertissement auREHASH, où la liste déjà chargée tient encore. - Un contrôle de la campagne des protections ne testait rien. Celui qui vérifie qu'un fichier de comptes lisible par tous ne désarme pas la protection s'authentifiait sous
oper admin, qui n'existe pas dans la configuration de test : leREHASHqu'il croyait déclencher était refusé, et il passait parce que la liste chargée au démarrage tenait encore. irix.confétait en0644sur l'installation hôte — mot de passe MySQL en clair, machine en DMZ, donc lisible par tout compte local.SECURITY.mddemandait de le vérifier depuis le 21/07 ; c'est fait, et corrigé.
Erreurs
- Le nom du bloc
link{}n'est pas une constante. La documentation affirmait qu'il devait valoirservices.overtchat.fr— c'était le nom d'une ligne d'essai, généralisé à tort. Il doit porter exactement leuline_namede la ligne d'IriX_ulines_socketsutilisée. - Le symptôme de lien muet documenté le 27/07 était faux.
LINKSne montrant qu'un serveur là oùLUSERSen compte deux est l'effet normal deHIDE_ULINES yes, visible aussi quand tout fonctionne. La seule vérification qui prouve quelque chose est d'interroger un service. - Le SID recommandé était dangereux.
010appartient à l'espace0XXoù IriX puise les SID de ses sockets, en n'excluant que000et001: le serveur pouvait se faire attribuer le sien par les services, et voir ses UID rejetés en silence. Le serveur porte10A.
Avertissements
- Le certificat est partagé avec UnrealIRCd. La configuration d'Overtchat-Hybrid pointe le fichier déposé pour UnrealIRCd plutôt que d'en garder une copie — une copie vieillirait sans que rien ne le signale. Le hook étendu doit être recopié dans
/etc/letsencrypt/renewal-hooks/deploy/, ce qui demanderoot. - Les mots de passe de la configuration sont en clair. Le serveur sait lire une empreinte
$algo$…mais refuse franchement de la vérifier : le mécanisme n'est pas implémenté. Régression assumée par rapport à l'argon2 d'UnrealIRCd, le temps que le hachage arrive. IriX.jsonetirix.confexistent aussi dans la copie Windows, sousOneDrive— donc synchronisés chez un tiers, où les droits POSIX ne signifient rien.- IriX régénère le bloc
link{}d'UnrealIRCd depuis la base et ne sait pas écrire celui d'Overtchat-Hybrid : après la bascule, ce bloc se maintiendra à la main.
4.5.6 — 27 juillet 2026
Version de consolidation, centrée sur Overtchat-Hybrid, le serveur IRC écrit pour le réseau. Il passe en test bêta : compilé, éprouvé et essayé en cohabitation avec la production, sans la remplacer. Le numéro saute de 4.0.0 à 4.5.6 pour couvrir d'un seul tenant l'ensemble des textes du projet — journal, charte, documentation Docker et messages du serveur —, jusqu'ici mis à jour séparément et déjà désaccordés entre eux.
Créations
| Fichier | Rôle |
|---|---|
Servers/overtchat-hybrid/src/nickprotect.c | Pseudonymes protégés par mot de passe et liste de pseudonymes interdits |
Servers/overtchat-hybrid/include/nickprotect.h | Interface du module, et pourquoi il ne remplace pas les services |
Servers/overtchat-hybrid/conf/charte.example | Charte du réseau, servie par /RULES |
Servers/overtchat-hybrid/conf/pseudos-interdits.example | 80 motifs : insultes, injures haineuses, usurpations d'autorité |
Servers/overtchat-hybrid/conf/pseudos-proteges.example | Format du fichier de comptes et droits exigés |
Servers/overtchat-hybrid/tests/test-commandes.py | Sondes, annuaire, outillage d'opérateur, SVS*, TKL, rechargement |
Servers/overtchat-hybrid/tests/test-protection.py | Pseudonymes interdits et protégés |
Tools/wsl-keepalive-check.ps1 | Contrôle périodique du maintien de la distro WSL |
DOCKER.md | Documentation Docker, jusque-là présente sur la machine sans être versionnée |
Évolutions
- Les pseudonymes composés. Un
/nickn'efface plus le pseudonyme de connexion : il le garde devant, séparé d'une barre.SerVuSqui demandetestdevientSerVuS|test. La variante se remplace au changement suivant plutôt que de s'empiler, et/nick merend le pseudonyme nu. La base n'est pas mémorisée mais dérivée du pseudonyme courant : un champ aurait dû être tenu à jour après unSVSNICK, après un renommage par collision et à l'enregistrement, soit autant d'occasions de diverger de ce qui est réellement porté. - Les pseudonymes interdits. Une liste de politique, relue au
REHASH, distincte des Q-lines qui sont des actes de modération. Les motifs fournis sont volontairement resserrés :*con*attraperait Concombre, Constance et Marconi. - Les pseudonymes protégés. Un pseudonyme déclaré n'est accordé qu'à qui présente son mot de passe à la connexion, par
PASS. Le refus est immédiat pour tous les autres : l'usurpateur ne le porte jamais, pas même une seconde. Empreintes SHA-256 salées, sel tiré degetentropy(), comparaison à temps constant, fichier refusé s'il est lisible au-delà de son propriétaire. QLINEetUNQLINEexistent. Voir ci-dessous : elles n'existaient pas.- Le serveur a une charte, servie par
/RULES, qui répondait « aucun règlement publié ». - La couverture de tests double. 146 vérifications sur quatre campagnes, 243 sur six.
Bugs corrigés
| Symptôme | Cause | Portée |
|---|---|---|
| Une Z-line posée sans durée bannissait le motif au lieu de l'adresse | La durée facultative se lit en tête et était reconnue au seul fait de commencer par un chiffre — or un masque de Z-line est une IP, qui commence toujours par un chiffre. ZLINE 203.0.113.50 :spam posait un bannissement sur spam | Sécurité. L'adresse restait libre et l'opérateur recevait une confirmation qui ressemblait à un succès |
| Les Q-lines n'interdisaient rien | ban_check_nick() était écrite, déclarée, compilée — et appelée nulle part. Aucune commande QLINE n'existait par ailleurs | Sécurité. Le README les annonçait comme fonctionnelles ; un pseudonyme injurieux s'enregistrait sans obstacle |
REHASH journalisait bind : Address already in use à chaque port | Le rechargement créait un second objet listener là où le premier tenait déjà le port | Le bruit n'était que le symptôme : un bloc listen{} supprimé restait servi jusqu'au redémarrage, et la liste enflait d'un doublon par rechargement |
| Le préflight de bascule laissait passer les clés de masquage du dépôt | Il cherchait CHANGEZ en majuscules ; les clés du modèle sont en minuscules | Sécurité. Feu vert donné avec les clés publiques en service : le masquage d'hôtes redevenait réversible par quiconque a lu le dépôt |
make test échouait sur tout clone frais | tests/run-tests.sh était enregistré sans le bit exécutable | Des tests qu'on ne peut pas lancer ne protègent personne |
Un /nick <insulte> aboutissait sous la forme base|<insulte> | Le contrôle ne portait que sur le pseudonyme composé, jamais sur la variante demandée | Trouvé par la campagne, pas par relecture. Même défaut pour /nick <pseudonyme d'un tiers>, qui donnait Autre|SerVuS |
Modifications
Tools/ircd-bascule.sh— préflight insensible à la casse, décompte des valeurs restantes, troncature annoncée plutôt que silencieuse. Deux pièges deset -euo pipefailtraités :grepsort en 1 quand il ne trouve rien, c'est-à-dire dans le cas favorable, etheaden milieu de tuyau provoque un SIGPIPE fatal.docker/dctx.ps1—dwsletdcwvisent le daemon natif parDOCKER_HOSTexplicite. Le contexte SSHwslest abandonné : il aboutissait à/run/docker.sock, donc à Docker Desktop, l'inverse de sa promesse.DOCKER.md— le passage affirmant que l'ordre duPATHsuffit à viser le bon daemon est corrigé : il ne suffit pas, l'intégration WSL de Docker Desktop procède par substitution de socket.
Erreurs
- L'intégration WSL de Docker Desktop a été activée puis abandonnée. Elle occupait
/run/docker.sockdans la distro et masquait le daemon natif où vivent les images du projet. Son réglage n'a pas survécu à un arrêt de Docker Desktop, et elle laissait un socket orphelin après chaque redémarrage de la distro. - La production a été coupée deux fois par des manipulations d'essai. Un
wsl --terminatea tué le processus qui maintient la distro WSL allumée, sans que rien ne le recrée : 45 extinctions en deux heures, chacune coupant IRC, le site et la base. Et unUPDATEsur la tableIriX_admina rechargé tous les liens d'IriX au lieu du seul lien d'essai, déconnectant celui de production pendant une minute. Dans les deux cas le service est revenu, mais l'interruption était réelle et évitable.
Avertissements
- Overtchat-Hybrid n'est pas en service et ne le sera pas sans une vraie configuration : le fichier livré reste le modèle, mots de passe
CHANGEZ-MOIet clés de masquage du dépôt compris. - Le port TLS reste fermé faute de certificat. Le serveur refuse de l'ouvrir en clair plutôt que de fournir un port faussement sûr, et le dit au journal.
- Le nom du lien de services doit être
services.overtchat.fr, et non le.netque propose le modèle. C'est le nom qu'IriX annonce dans ses UID ; le désaccord rend les services présents mais muets, sans message d'erreur d'aucun côté. - SASL,
MLOCK, l'historique de salon, WebSocket, les modules chargeables et la résolution DNS inverse restent non implémentés, et annoncés comme tels. REHASHsur un pseudonyme protégé déjà porté ne déloge pas son porteur : la protection agit à la connexion, pas rétroactivement.
4.0 1 version · 22 juillet 2026 1 addition 5 improvements 7 bugs fixed 1 mistake 6 warnings
4.0.0 — 22 juillet 2026
Version majeure, et le numéro n'est pas une coquetterie : deux changements modifient la nature du service. Le panel cesse d'être un écran de supervision pour devenir un outil de modération agissant sur les personnes connectées, et le réseau passe de l'ouverture par défaut à la création de salons sur demande. Un exploitant qui met à jour sans lire ce journal verra ses utilisateurs incapables d'ouvrir un salon.
Créations
| Fichier | Rôle |
|---|---|
IriX/cmds/irix-online.tcl | Reflet en base de la présence vue par le lien S2S |
IriX/cmds/irix-modq.tcl | Exécution des actions de modération, après vérification de l'access |
Web/pages/live.php | Onglet Connectés — présence en direct et actions |
Web/pages/demandes.php | Traitement des demandes d'ouverture de salon |
Web/inc/chanreq.php | Dépôt et décision des demandes de salon |
Web/site/salon.php | Formulaire public de demande |
Web/sql/008-mod-queue.sql, 009-chan-requests.sql | Files de modération et de demandes |
Config/unrealircd/ircd.motd | Message du jour, composé depuis identity.json |
Config/unrealircd/salons.conf | Fermeture de la création libre, avec exceptions |
Web/pages/controle.php | Onglet Contrôle — état voulu des services et des liens, actions groupées |
Web/site/chat.php | Page publique du chat (bêta) |
Web/public/assets/chat.js | Client IRC minimal, sur WebSocket |
Web/inc/ircauth.php | File d'identification IRC déposée depuis le site |
Web/sql/007-web-auth-queue.sql | Table IriX_web_authq |
IriX/cmds/irix-nickguard.tcl | Protection des pseudos + exécution de la file d'identification |
Config/unrealircd/websocket.conf | Listener WebSocket, lié à la boucle locale |
Évolutions
- Bandeau d'état de l'accueil.
site_services_hs()ne renvoyait qu'un booléen : le visiteur savait que « quelque chose » était perturbé, sans savoir si cela le concernait.site_etat_public()publie désormais une projection de quatre services nommés côté usage (irc,services,chat,comptes), rafraîchie toutes les 30 s par?p=etat. Rien d'interne n'en sort : ni PID, ni port, ni nom de brique, ni message d'erreur. - Intention contre impulsion. Le panel ne savait poser que des actions ponctuelles. L'onglet Contrôle écrit l'état voulu (
enabled,auto,auto_connect,log_enabled), et::soc::svc::scan_autole rétablit à chaque cycle. Ces colonnes existaient depuis l'origine du schéma sans que rien ne les lise. - Identification sans commande. Un visiteur peut demander son identification IRC depuis
?p=register. Le site ne vérifie rien : il dépose une empreinte, le bot contrôle la présence sur le lien, tranche, prévient par notice et efface l'empreinte. - Protection des pseudos. Notice puis renommage en
Invite…après 60 s. Éteinte par défaut (drapeaunickguard). - Chat dans le navigateur. Listener WebSocket d'UnrealIRCd sur
127.0.0.1:8000, relayé par Apache enwss://…/ws. Client maison, sans dépendance.
Bugs corrigés
- Le burst du lien serveur était jeté. Les lignes
UIDque le serveur envoie juste après le link arrivent en étatWAIT_EOB;on_readne dispatchait qu'enLINKEDet les ignorait. Le registre des clients ne contenait donc que les personnes arrivées après notre connexion :uid_to_nickrestait muet pour toutes les autres,src_is_adminrefusait leurs commandes bien qu'elles soient opérateurs, et la protection des pseudos ne les voyait pas. Défaut structurel, invisible tant que rien ne dépendait de cette liste. - Le registre des clients n'était jamais purgé en masse.
forget_userne retire qu'un UID à la fois, surQUIT— et unQUITsurvenu pendant que le lien est coupé n'arrive jamais. Les UID d'avant une coupure restaient donc en mémoire indéfiniment : la page Connectés a montré trois UID pour un seul bot. La remise à zéro se fait maintenant dansconnect_socket, avant le burst — la placer après l'aurait effacé. - L'identification ne posait aucun mode sur le client.
IDENTIFYécrivaitauth='oui'dans la base et s'arrêtait là. Or cette colonne n'est visible que de nous : le serveur ne savait rien, le WHOIS ne montrait rien, et les salons réservés aux personnes identifiées (+R) n'avaient aucun critère pour filtrer. Un pseudo identifié restait indiscernable d'un pseudo usurpé. Les deux chemins d'identification — commande et site — posent désormaisSVS2MODE +rd <compte>. authsurvivait à la déconnexion.IriX_users.authrestait àouiindéfiniment, la remise ànonn'ayant lieu qu'au démarrage du bot. Le porteur suivant d'un pseudo était donc considéré comme identifié, et la réinitialisation de mot de passe prenait cette marque pour une preuve de présence alors que plus personne n'était connecté.::soc::nickguard::gonela remet ànonà chaqueQUIT.- Trames WebSocket sans fin de ligne. UnrealIRCd en
type textenvoie chaque ligne sans CRLF final. Le client tamponnait jusqu'au séparateur — réflexe correct sur une socket TCP — et ne traitait donc jamais rien, pas même lePINGinitial que le serveur exige avant d'enregistrer un client. Symptôme muet : connexion ouverte, aucune erreur, écran figé sur « Connexion au réseau… ». - Salons mélangés dans le chat.
set::auto-joinplace tout client dans le salon principal en plus du sien : sans filtrage, la liste des présents mélangeait les deux et les messages de l'un s'affichaient comme venant de l'autre. - Cache d'état jamais écrit.
Web/.run/n'existait pas etfile_put_contentséchouait en silence : chaque visite relançaitps. Le répertoire est créé au besoin.
Erreurs
- La première configuration du listener plaçait le bloc
websocketà côté deoptionsau lieu de dedans, et ne chargeait niwebserverniwebsocket. Le test de configuration l'a arrêtée avant tout rechargement. À noter pour qui rencontrerait le cas : le message d'erreur d'UnrealIRCd (« websocket set, but type unspecified ») propose un exemple qui est lui-même faux.
Avertissements
- Trois fichiers échappent à
Tools/identite-config.shet sont à reprendre à la main en cas de renommage du réseau :websocket.conf(listeallow-origin),salons.conf(message de refus) etircd.motd(adresses du site). - Un salon approuvé n'est pas ouvert pour autant. L'approbation inscrit le salon dans
IriX_channels; il reste à ajouter l'exception danssalons.confpuis à recharger. Le panel le rappelle à chaque approbation, mais rien ne l'automatise. - Aucun courriel n'est envoyé au demandeur, ni à l'acceptation ni au refus.
WEBCHAT_CHANSne propose plus que#!Overtchat!:#accueilet#aidesont devenus injoignables avec la fermeture des salons, et les proposer aurait donné un refus à chaque visiteur.- La modération web exige d'être connecté sur IRC et opérateur. C'est le prix de la preuve d'access : sans elle, voler une session du panel donnerait l'oper.
- Les deux dépôts ont divergé (copie de travail Windows et installation de production) : la propagation s'est faite par copie de fichiers, sans passer par git.
3.5 1 version · 21 juillet 2026 13 additions 3 changes 1 removal 3 warnings
3.5.2 — 21 juillet 2026
Version la plus récente. Trois commits : fa98e88, 2f3fa3a, e9bd821. C'est de très loin la livraison la plus lourde du projet : elle introduit d'un seul bloc le module IriX, le panel web, la documentation et l'infrastructure Docker, puis referme deux problèmes de sécurité.
Créations
- Module IriX (
IriX/) : moteur métier Tcl sur MySQL.IriX-sql.tcl(≈ 9 680 lignes),IriX-table.tcl(schéma, ≈ 800 lignes),IriX-sql-IA.tcl(pipeline de modération, ≈ 1 055 lignes),IriX-sql-fixes.tcl,IriX-binds.tcl,irix-register.tcl,IriX-src.conf,IriX.json.example,irix.conf.example, plus les lanceursIriX/bin/installetIriX/bin/irix. - Panel et site web (
Web/) : - couche interne
Web/inc/—auth.php,db.php,ctl.php,sys.php,site.php,layout.php,mailer.php,contact.php,config.example.php; - pages du panel
Web/pages/—dashboard,admin,membres,salons,moder,ia,irix,ulines,services,serveur,logs,activite,messages,login; - site public
Web/site/—accueil,commandes,installation,charte,reglement,contact; - points d'entrée
Web/public/et feuilles de styleapp.css/site.css; - outillage
Web/start.shetWeb/pma-setup.sh. - Tables des comptes du site :
IriX_web_usersetIriX_web_tokens(Web/sql/001-web-users.sql, appliquées parWeb/sql/apply.sh). Les mots de passe du site sont stockés en bcrypt ; les jetons sont à usage unique et conservés hachés. - Infrastructure Docker :
Dockerfile(multi-étages),docker-compose.yml,.dockerignore,.env.example,docker/entrypoint.sh. docker/dctx.ps1: helper de pilotage des deux daemons Docker de la machine de développement (Docker Desktop etdockerdnatif sous WSL) via un contexte SSH.- Documentation (
Markdown/, 13 fichiers) :ARCHITECTURE.md,INSTALL.md,IRIX.md,WEB.md,DATABASE.md,DOCKER.md,SECURITY.md,BACKUP.md,API.md,MODULES.md,LAUNCH.md,PROJET.md,ROADMAP.md,README.md. Tools/backup-overtchat.sh: script de sauvegarde.Bootstrap/overtchat-setup.sh: assistant d'installation, ≈ 5 100 lignes.
Modifications
VERSION: passage de3.1.7à3.5.2.README.mdracine entièrement réécrit (présentation des composants).Config/config.json,Config/defaults.json,Runtime/version.json,.gitignore.
Suppressions
Config/access.json, retiré du suivi (le fichier reste utilisable localement, il n'est simplement plus versionné).
Avertissements
- Le pipeline de modération par IA est écrit mais jamais amorcé. Le classifieur est un bayésien local, sans appel à une API externe. Les tables
ia_tokens,auto_motsetia_configsont vides : le moteur est donc aveugle et ne classe rien. Par ailleurs le pontia_actionn'est écrit par aucun code du projet. La fonctionnalité est présente dans le dépôt mais non opérationnelle en l'état. - Les 13 divergences de grade ci-dessus ne sont pas corrigées à ce stade : elles sont constatées, pas résolues.
- Le numéro porté par
VERSION(3.5.2) et celui porté parRuntime/version.json(installed: 1.5.0) ne sont pas alignés ;Config/config.jsonannonce encore0.1.0. Trois compteurs de version coexistent donc dans le projet.
3.4 1 version · 23 avril 2026 20 additions 3 improvements 1 change 4 bugs fixed 4 removals 6 mistakes 2 warnings
3.4.2 — 23 avril 2026
Créations
VERSIONà la racine du dépôt (ca8de12), initialisé à3.4.2. Première tentative de numérotation formelle du projet.Config/access.jsonle 22/04/2026 (d7c763b) — fichier de comptes du panel. Il restera versionné à tort jusqu'au 21/07/2026.
Modifications
- Une quinzaine de retouches successives de
Bootstrap/overtchat-setupentre le 21 et le 22 avril, toutes envoyées via l'interface web GitHub sans message descriptif.
Période du 12 au 17 mai 2026 — bascule vers la bibliothèque Tcl
Pas de changement de numéro de version sur cette période.
Créations
Components/Service/lib/Tcl/Stable/IriX-sql.tcl(94b7fcf) etIriX-std.tcl(d2e3564) : séparation du moteur en une branche SQL et une branche standard.Components/Service/lib/Tcl/Stable/irix-register.tcl(f1e5f3d) : module d'enregistrement du owner — c'est ce fichier qui portera la faille du handlerpasscorrigée en 3.5.2.Components/Service/lib/installirix(09a11ab).Projet/01-04-2026/installirixetProjet/01-04-2026/overtchat-setup(90db60b).
Suppressions
Components/Service/lib/IriX.tcl(111e34e) : le monolithe historique, présent depuis le tout premier commit, est retiré au profit de la bibliothèqueTcl/Stable.Components/Service/lib/TCL/Stable(7e7da3c), créé la veille (aec2c55) avec une casse de répertoire erronée (TCLau lieu deTcl).
Erreurs
- Deux commits datés du 13/05/2026 portent le message « Update print statement from 'Hello' to 'Goodbye' » alors qu'ils ajoutent en réalité les deux fichiers Tcl majeurs de la bibliothèque. Le message ne correspond à rien du contenu.
- La correction de casse
TCL→Tcla nécessité une création puis une suppression le jour même.
Période du 1er avril au 12 mai 2026 — le dossier Projet/01-04-2026
Cette phase représente environ 80 commits, presque tous sans message utile, concentrés sur un répertoire de travail daté.
Créations
Projet/01-04-2026/overtchat.json(dc9d7d8), puisdepot.json,package.json,sock.json(da79314).Projet/01-04-2026/overtchat.sh(1dbeeab),setup(6dcd5e7) etovertchat(2d3ddbf).
Évolutions
- Développement itératif intensif :
overtchat.shetsetupsont modifiés des dizaines de fois entre le 1er avril et le 21 avril. La nature exacte de chaque itération n'est pas reconstituable depuis les messages de commit, tous identiques (« Add files via upload »).
Avertissements
- Ce répertoire
Projet/fonctionne comme un espace de travail parallèle à l'arborescence principale (Bootstrap/,Installer/,Components/). Rien dans l'historique n'indique explicitement lequel des deux faisait autorité à cette période.
Période du 4 mars au 20 mars 2026 — installateur et bootstrap
Créations
Installer/colors.sh(67a0585),Installer/control_package.sh(cf5c3f2),Installer/trap.sh(verrouillage et gestion d'erreurs,e5d9dfb).Builder/exposed.sh(téléchargement et validation JSON,7dbf330).Runtime/database.sh(cab4158) etRuntime/env.sh(72c0f41).- Réorganisation de
Components/: passage des scripts debin/verslib/pourServicecomme pourServeur(start.sh,install.sh,uninstall.sh), et création deComponents/Serveur/conf/server.json. Bootstrap/setup.sh(140ee92).
Suppressions
Components/Service/bin/install.shetbin/uninstall.sh,Components/Serveur/install.sh,uninstall.sh,server.json,start.sh— tous remplacés par leurs équivalents danslib/ouconf/.Installer/setup.sh(40a5ca1), unsetup.shcréé à la racine puis retiré le jour même (daf2ef4/be45fe3),Bootstrap/setup.sh(37ebc5f),Bootstrap/overtchat-setup.sh(47a4571).
Bugs corrigés
- Syntaxe de la commande
jqdanssetup.sh(e1d7c46), puis traitement des chemins de dossiers parjq(4352027). - Gestion du statut d'installation dans
setup.sh(d515846,4e9290f). - Gestion d'erreurs et journalisation du script d'installation (
191eed0). - Refactorisation des fonctions de log et export des variables de couleur (
0070f2e).
Erreurs
- Forte instabilité du point d'entrée : quatre fichiers d'amorçage différents (
setup.shà la racine,Installer/setup.sh,Bootstrap/setup.sh,Bootstrap/overtchat-setup.sh) sont créés puis supprimés en deux semaines avant queBootstrap/overtchat-setupne s'impose.
Période du 5 au 9 janvier 2026 — fondations
Premier commit du dépôt : cb61750, le 05/01/2026.
Créations
- Installateur :
Installer/avecconfig.sh,install.sh,installirix.sh,preflight.sh,repair.sh,state.sh,status.sh,ui.sh,uninstall.sh,update.sh. - Constructeur de paquets :
Builder/avecMAKEFILE,build.sh,builder.json,control_package.sh,encrypt.sh,package.sh. - Composants :
Components/Serveur/(serveur IRC) etComponents/Service/(Eggdrop) aveceggdrop.conf,service.json,IriX.tcletlogo.sh. - Configuration :
Config/avecconfig.json,config-base.json,defaults.json,irix.json,paths.json,schema.json, puisfolders.json(601b6d6). - Exécution :
Runtime/aveccmds_irix.json,state.json,version.json, et un répertoire de logs. LICENSEetREADME.md(d7c8785)..gitignore(d786b1d, 06/01/2026).
Évolutions
Runtime/version.jsonpasse deinstalled: nullà1.0.0le 08/01/2026, puis à1.5.0le 04/03/2026 (477aa7a) — valeur inchangée depuis.- Normalisation de la casse de toute l'arborescence le 07/01/2026 (
9fdcda6,6fe564a) :bootstrap/→Bootstrap/,builder/→Builder/,components/server/→Components/Serveur/,config/→Config/,runtime/→Runtime/.
Erreurs
- La normalisation de casse a mal tourné : entre
6ee941eet004758b(07/01/2026), l'intégralité de l'arborescence a été supprimée puis recréée en cinq commits successifs (« Delete bootstrap directory », « Delete builder directory », « Delete components directory », « Delete config directory », « Delete runtime directory ») avant restauration. Aucun contenu n'a été perdu, mais l'historique de ces fichiers est cassé à cet endroit. - Un fichier
overtchat-setupa été déposé à la racine le 05/01/2026 (9590a02) puis supprimé (f45ff40), doublon de celui présent dansbootstrap/. - Une douzaine de commits du 08 et 09/01/2026 sont intitulés « Merge branch 'main' of github.com:Servus33/Overtchat » alors qu'ils ne sont pas des fusions mais de simples modifications de
Bootstrap/overtchat-setup.
Avertissements
- Aucune activité n'est enregistrée dans le dépôt entre le 09 janvier et le 04 mars 2026 — près de deux mois sans commit. Rien dans l'historique n'explique cette interruption.
Récapitulatif des numéros de version observés — ⚠ ARRÊTÉ AU 31/07/2026
⚠⚠ CE TABLEAU NE DIT PAS QUELLE EST LA VERSION COURANTE, et il l'a fait deux fois. Il s'arrête au 31/07/2026 : les versions postérieures ont chacune leur section ## plus haut, et ce tableau ne les reprend pas.
Sa première ligne a annoncé « version courante » pour 4.6.6 cinq versions trop tard — c'est écrit dans sa propre colonne. Puis pour 4.10.0, alors que le dépôt était en 4.19.15 : quatre-vingt-dix versions de retard, sur une page que lisent les visiteurs. La mention est retirée. La seule source est le fichier VERSION à la racine, et la ligne « Version courante » en tête de ce document.
⚠ Le tableau n'a pas été complété jusqu'à aujourd'hui, et c'est délibéré : quatre-vingt-dix lignes recopiées à la main se périmeraient à la prochaine version. Ce qu'il garde d'utile, ce sont les empreintes de commit des premières versions, que l'historique générique ne permet pas de retrouver autrement.
| Version | Date | Commit | Remarque |
|---|---|---|---|
| 4.10.0 | 31/07/2026 | — | Le projet cesse de supposer qu'il est le seul, et qu'il s'appellera toujours pareil |
| 4.9.3 | 31/07/2026 | 80a88b6 | La commande APPEL pour les clients IRC, et le MOTD généré depuis l'état réel du filtre |
| 4.9.2 | 31/07/2026 | — | Le bouton d'appel dans le chat du site, et la charte qu'il porte |
| 4.9.1 | 31/07/2026 | — | Le guide d'installation, et Postfix qui cesse d'envoyer le courrier interne sur Internet |
| 4.9.0 | 31/07/2026 | 1dd8249 | Le système de mise à jour : la route /update, les sept commandes, l'alerte courriel |
| 4.8.0 | 30/07/2026 | — | Les conversations privées, leur onglet et leur modération |
| 4.7.0 | 30/07/2026 | 380f30a | La réservation de pseudo qui expire, et le chat qui sait la proposer |
| 4.6.13 | 30/07/2026 | 84e39ae | Quatre liens, la page Statut, et ce que trois liens simultanés ont révélé |
| 4.6.12 | 30/07/2026 | 2a997bd | Le lien p10 sert : l'op confirmé par le serveur, la sonde qui aboutit |
| 4.6.11 | 30/07/2026 | 893579f | Le décodeur appartient au dialecte |
| 4.6.10 | 30/07/2026 | — | Encodeur p10, et la notion d'« écrit mais pas utilisable » |
| 4.6.9 | 30/07/2026 | — | |
| 4.6.8 | 30/07/2026 | — | |
| 4.6.7 | 30/07/2026 | — | |
| 4.6.6 | 29/07/2026 | — | Ce tableau s'est arrêté ici jusqu'au 30/07 : il annonçait « version courante » cinq versions après |
| 4.6.5 | 29/07/2026 | — | |
| 4.6.4 | 29/07/2026 | — | |
| 4.6.3 | 29/07/2026 | — | |
| 4.6.2 | 29/07/2026 | — | |
| 4.6.1 | 29/07/2026 | — | |
| 4.6.0 | 28/07/2026 | — | |
| 4.5.7 | 28/07/2026 | — | |
| 4.5.6 | 27/07/2026 | — | |
| 4.0.0 | 22/07/2026 | (non commité) | Première dont le numéro n'est écrit qu'une fois, dans VERSION |
| 3.5.2 | 21/07/2026 | fa98e88 | |
| 3.1.7 | 27/04/2026 | 50c281c | |
| 3.1.5 | 27/04/2026 | 08ed0b8 | |
| 3.1.3 | 27/04/2026 | 7086403 | Régression depuis 3.4.2 |
| 3.4.2 | 23/04/2026 | ca8de12 | Création du fichier VERSION |
Aucun numéro de version n'est enregistré dans le dépôt avant le 23/04/2026 : les périodes de janvier à avril 2026 sont donc décrites ici par leurs dates et non par un numéro.
3.1 1 version · 27 avril 2026 2 changes 1 mistake
3.1.7 — 27 avril 2026
Modifications
VERSIONmis à jour trois fois dans la même journée :3.1.3(7086403), puis3.1.5(08ed0b8), puis3.1.7(50c281c).Bootstrap/overtchat-setupretouché à plusieurs reprises entre le 24 et le 28 avril (38d0cf0,587ae54,6885a62,394284b,c308db1,5f42a1b,f981f7c,df50b6f).
Erreurs
- Le fichier
VERSIONa été créé le 23/04/2026 avec la valeur3.4.2, puis redescendu à3.1.3quatre jours plus tard. La numérotation a donc reculé. L'historique ne donne aucune explication à cette régression ; les commits concernés sont intitulés simplement « Update VERSION ».
How to read this log
Chaque section correspond à une version ou à une période de développement, de la plus récente à la plus ancienne. Sous chaque section, les changements sont classés par rubriques :
| Rubrique | Contenu |
|---|---|
| Créations | Fichiers, modules ou tables ajoutés |
| Modifications | Fichiers existants retouchés |
| Suppressions | Fichiers ou répertoires retirés du dépôt |
| Évolutions | Changements structurels ou fonctionnels d'ensemble |
| Bugs corrigés | Défauts identifiés et fermés |
| Erreurs | Fautes de manipulation ou incohérences constatées dans l'historique |
| Avertissements | Points ouverts, risques connus, zones non finalisées |
| Vérifié (ou Éprouvé) | Ce qui a été mesuré, et comment. Compté sous le libellé « constats » |
Les rubriques sans contenu pour une version donnée sont simplement absentes.
⚠ These numbers count what is written, not what was done. A version whose changes are not filed under the usual headings shows as “not broken down”: it is not empty, it is not classified. Inferring its nature from its text would give a plausible and false figure — exactly what this project holds against unmeasured claims.
This public log keeps, for each version, only its summary sentence and its sections. Operating notes (commands, paths, addresses) are left out.