feat(installation): un poste neuf sort utilisable, et le bouton redémarrer redémarre - #54
Merged
Merged
Conversation
…arrer redémarre Quatre défauts trouvés en installant un poste de production, dont deux le rendaient inutilisable. Aucun n'était visible sans installer pour de vrai. 1. LE BOUTON « REDÉMARRER LE POSTE » LAISSAIT LE POSTE ÉTEINT. setRecovery n'appelait que SetRecoveryActions, jamais SetRecoveryActionsOnNonCrashFailures. Windows met ce drapeau à faux par défaut, et faux veut dire « n'appliquer les reprises que si le service s'arrête SANS signaler SERVICE_STOPPED ». Or l'arrêt ordonné de §13.4 se termine proprement et le signale : le SCM voyait un arrêt normal et n'appliquait aucune des trois reprises de §15.2. La prémisse fausse était écrite à cinq endroits, dont ADR-055 lui-même et un banc VERT intitulé « THE CODE IS THE MECHANISM ». Tous corrigés ; l'ADR porte un amendement daté plutôt qu'une réécriture. setRecovery prend désormais une interface de deux méthodes, parce qu'un banc qui ne lirait que le plan resterait vert si quelqu'un retirait le second appel — c'est exactement le défaut qui avait été livré. Les postes déjà installés ne sont pas réparés par ce lot : décision de périmètre du propriétaire du produit. TROUBLESHOOTING.md dit sans détour qu'une mise à jour ne répare pas ce défaut, le réglage fautif vivant dans Windows et non dans le binaire. 2. UNE ADRESSE D'ÉCOUTE VIDE VERROUILLAIT TOUTE L'ADMINISTRATION. Export remet le bloc réseau à zéro et la cible release exige un export : le fichier livré porte littéralement "listen": "", donc le poste refusait sa propre configuration de livraison. PUT /admin/api/config valide le document ENTIER, si bien qu'une seule faute portant sur un champ qu'aucun écran n'éditait empêchait le moindre enregistrement, sur toutes les pages. Config.UnmarshalJSON ramène une adresse vide à celle du profil neutre, comme il le fait déjà pour update.repository et ui.min_products_for_chip. L'ordre de livraison était contraint et il a été tenu : la garde d'import d'abord, le rattrapage du décodeur ensuite. Dans l'autre sens, un défaut bloquant serait devenu silencieux — le 422 était le seul garde-fou empêchant un export importé de déplacer l'écouteur d'un poste de 0.0.0.0:8085 vers la boucle locale. La page Poste gagne enfin les champs network.listen et admin_on_lan : la mécanique de déplacement à chaud était livrée depuis toujours, seul le champ manquait — et §14.4 ne le listait pas, c'est de là que venait l'oubli. 3. LE PLANCHER DU MOT DE PASSE D'ADMINISTRATION PASSE À QUATRE. Demande du propriétaire du produit. Le chiffre existait en six exemplaires que rien ne reliait ; il est ramené à une autorité, web.MinPasswordLength, les copies qu'un autre langage impose étant liées à elle par un banc qui LIT le fichier source. Un vrai défaut, indépendant de la valeur, a été trouvé au passage : la route HTTP comptait des octets là où la ligne de commande comptait des runes. Les quatre portes comptent maintenant des points de code, PowerShell compris. 4. L'INSTALLATION DEMANDE CE QU'ELLE SEULE PEUT SAVOIR (ADR-060). Mot de passe d'administration, numéro et nom du poste, et la balance sort déclarée absente faute d'en avoir une de branchée. Nouvelle action « openscale config station ». Aucune option de config ne prend de secret : le mot de passe passe par l'entrée standard, un argument se lisant dans la liste des processus. Un poste neuf passe de 4 fautes à 1. L'empreinte va de 6c06605a à 79ba8bfc tant que la balance est déclarée absente, puis revient à 6c06605a dès qu'elle est redéclarée — mesuré dans les deux sens, et dit sur la fiche, dans le message de fin et dans INSTALLATION.md, parce que §15.5 fait comparer les quatre empreintes à l'œil. Une relecture adverse a rattrapé ce qui aurait annulé le bénéfice : --no-scale vide scale.type, or aucun geste de l'écran ne le remettait. La détection servait pourtant déjà le driver reconnu, et detect.go l'écrivait dans son propre commentaire depuis toujours. Un bouton « Utiliser cette balance » écrit présence, protocole et port d'un seul geste. LES DEUX INSTALLEURS MARCHENT DÉSORMAIS EN COUPLE. install.sh porte les six mêmes options, les mêmes questions, le même plancher, la même fiche et le même message de fin. La règle n'est pas gardée par la bonne volonté : deploy/parity_test.go lit le param() de l'un et le case de l'autre et compare dans les deux sens. Une exception est permise, jamais muette — motivée dans le banc ET dans le script qui n'a pas l'option. Deux pièges mesurés plutôt que devinés. Sous dash, la longueur de chaîne du shell compte des OCTETS quelle que soit la locale : un plancher de quatre appliqué ainsi aurait accepté « éàç », que le binaire refuse. Et /proc/<pid>/cmdline est lisible par tous les comptes quand /proc/<pid>/environ ne l'est que du propriétaire : le secret descend par l'environnement, effacé avant le premier processus fils. STATUT : l'application est EN PRODUCTION. Recette passée en magasin, deux semaines d'exploitation réelle tenues. Le lot L9 est clos. Vérification : go build, go test en deux passes (avec cgo et -race, puis sans), 3 141 tests verts sur 35 paquets, go vet et gofmt muets, 1 021 tests web, svelte-check à 0 erreur, les six scripts PowerShell parsent sous 5.1 et 7, les quatre scripts POSIX passent sous le vrai dash d'une Debian. Ce qui n'est PAS fait, et n'est pas à croire fait : aucun poste réel n'a été installé avec ce binaire ; sc qfailureflag n'a pas été relevé sur le poste de production ; doctor ne contrôle pas le drapeau de reprise, donc ce défaut resterait invisible sans matériel ; install.sh n'a jamais été lancé en entier, donc rien de ce qui touche apt-get, useradd, udev, polkit ni systemctl n'est éprouvé ; les deux bootstraps ne sont pas à parité sur leurs options propres, écart jugé non bloquant par le propriétaire du produit.
…nner Linux La CI a refusé le lot précédent, et elle avait raison. Sur ubuntu-latest, pwsh EST installé : les trois bancs ajoutés le 10/08/2026 démarraient donc, puis mouraient en dot-sourçant common.ps1, dont la toute première ligne dérive ses chemins de %ProgramFiles% — vide hors Windows. « Join-Path: Cannot bind argument to parameter 'Path' because it is null », une panne qui ne dit rien de ce que le banc voulait prouver et tout de la machine qui l'a joué. LE PIÈGE ÉTAIT DÉJÀ DOCUMENTÉ, et c'est ce qui rend l'incident intéressant : TestTheBackupAndTheRestoreWorkOnAThrowawayDirectory portait ce raisonnement depuis toujours — dans un commentaire, à lui seul. Trois bancs neufs sont passés à côté sans le voir. Le raisonnement déménage donc sur requireWindowsToRunCommonPs1, pour que le suivant ait à passer devant un NOM plutôt que devant le commentaire de quelqu'un d'autre. La moitié STATIQUE de TestTheFourthDoorCountsCodePointsLikeTheOtherThree — le refus d'un plancher comparé à un .Length — continue de tourner partout : elle lit du texte. Seule la moitié MESURÉE est gardée. ET LE TROU QUE LA GARDE OUVRAIT EST FERMÉ AUSSI. Les jobs ubuntu jouent le paquet entier et sautent désormais ces trois bancs ; le job windows-latest, lui, ne joue qu'un sous-ensemble NOMMÉ, pour ne pas jouer le paquet deux fois. Mis bout à bout, un banc pouvait être ajouté, gardé, et ne tourner NULLE PART : vert sur tous les jobs, ne prouvant rien. C'est pire qu'un test manquant — un banc sauté se lit comme couvert. TestEveryWindowsOnlyBenchIsRunByTheWindowsJob le refuse : il relève les bancs qui appellent la garde, LIT le -run du job Windows là où il vit plutôt que d'en tenir une seconde copie, et exige que chacun y soit sélectionné. Vérifié en le cassant : un nom retiré du filtre, le banc rougit en nommant le banc orphelin et le fichier à corriger. Vérification : go build, go test en deux passes (avec cgo et -race, puis sans), go vet et gofmt muets. La preuve qui manque est celle que seule la CI peut donner — que les trois bancs sautent proprement sur ubuntu et s'exécutent sur windows-latest.
…t le binaire qui la mange Premier passage de ces bancs sur un VRAI Windows, et il a trouvé quelque chose qu'aucune machine de développement n'avait reproduit : sous powershell.exe 5.1, le tube vers un processus natif livre EF BB BF quoi qu'on règle. La marque est présente jusque dans la mesure de RÉFÉRENCE en us-ascii que ce banc journalise — elle ne vient donc d'aucun des deux réglages de Set-NativeOutputEncoding, qui demandent bien tous les deux UTF8Encoding($false). pwsh 7 ne le fait pas. Or 5.1 est le seul shell qu'ait le poste réel : common.ps1 le dit dans son propre en-tête. CE QUI COMPTE EST LE CONTRAT, et le contrat est ce que le binaire HACHE : le mot de passe qui a été tapé. Exiger un tube immaculé exigeait plus que ça, sur un shell dont nous ne gouvernons pas le comportement. Le banc admet donc une marque de tête — que readSecretLine retire déjà, et que TestAByteOrderMarkIsNotPartOfThePassword tient — et continue d'exiger ce qui murerait vraiment un poste : aucun accent transformé en « ? ». DEUX COMMENTAIRES DEVENAIENT FAUX ET SONT CORRIGÉS. common.ps1 affirmait que son réglage « fait que la question ne se pose pas » : la mesure dit le contraire, et la fonction sert en réalité l'ACCENT, pas la marque. Et le retrait du U+FEFF dans readSecretLine cesse d'être présenté comme un bonus : il est PORTEUR, sur le seul shell qui soit livré. Le supprimer murerait tout poste installé depuis une console 5.1 avec un mot de passe accentué. C'est la deuxième chose que ce job Windows trouve en deux commits, après n'avoir jamais joué ces bancs : il valait la peine d'y brancher les trois.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Quatre défauts trouvés en installant un poste de production, dont deux le rendaient inutilisable. Aucun n'était visible sans installer pour de vrai.
L'application est désormais en production : recette passée en magasin, deux semaines d'exploitation réelle tenues. Le lot L9 est clos.
1. Le bouton « Redémarrer le poste » laissait le poste éteint
setRecoveryn'appelait queSetRecoveryActions, jamaisSetRecoveryActionsOnNonCrashFailures. Windows met ce drapeau àFALSEpar défaut, et faux veut dire « n'appliquer les reprises que si le service s'arrête sans signalerSERVICE_STOPPED». Or l'arrêt ordonné de §13.4 se termine proprement et le signale : le SCM voyait un arrêt normal et n'appliquait aucune des trois reprises de §15.2.La prémisse fausse était écrite à cinq endroits, dont ADR-055 lui-même et un banc vert intitulé « THE CODE IS THE MECHANISM » — le pire état possible. Tous corrigés ; l'ADR porte un amendement daté plutôt qu'une réécriture.
setRecoveryprend désormais une interface de deux méthodes, parce qu'un banc qui ne lirait que le plan resterait vert si quelqu'un retirait le second appel — c'est exactement le défaut qui avait été livré. Vérifié en le cassant.2. Une adresse d'écoute vide verrouillait toute l'administration
Exportremet le bloc réseau à zéro et la cible release exige un export : le fichier livré porte littéralement"listen": "", donc le poste refusait sa propre configuration de livraison.PUT /admin/api/configvalide le document entier, si bien qu'une seule faute portant sur un champ qu'aucun écran n'éditait empêchait le moindre enregistrement, sur toutes les pages.Config.UnmarshalJSONramène une adresse vide à celle du profil neutre, comme il le fait déjà pourupdate.repositoryetui.min_products_for_chip.L'ordre de livraison était contraint et il a été tenu : la garde d'import d'abord, le rattrapage du décodeur ensuite. Dans l'autre sens, un défaut bloquant serait devenu silencieux — le 422 était le seul garde-fou empêchant un export importé de déplacer l'écouteur d'un poste de
0.0.0.0:8085vers la boucle locale.La page Poste gagne enfin les champs
network.listenetadmin_on_lan: la mécanique de déplacement à chaud était livrée depuis toujours, seul le champ manquait — et §14.4 ne le listait pas, c'est de là que venait l'oubli.3. Le plancher du mot de passe d'administration passe à quatre
Le chiffre existait en six exemplaires que rien ne reliait ; il est ramené à une autorité,
web.MinPasswordLength, les copies qu'un autre langage impose étant liées à elle par un banc qui lit le fichier source.Un vrai défaut, indépendant de la valeur, a été trouvé au passage : la route HTTP comptait des octets là où la ligne de commande comptait des runes — « é » vaut un caractère au clavier et deux sur le fil. Les quatre portes comptent maintenant des points de code.
4. L'installation demande ce qu'elle seule peut savoir (ADR-060)
Mot de passe d'administration, numéro et nom du poste ; la balance sort déclarée absente, faute d'en avoir une de branchée. Nouvelle action
openscale config station. Aucune option deconfigne prend de secret.network.listencatalog.options.url, éditable à l'écranL'empreinte va de
6c06605aà79ba8bfctant que la balance est déclarée absente, puis revient à6c06605adès qu'elle est redéclarée — mesuré dans les deux sens, et dit sur la fiche, dans le message de fin et dansINSTALLATION.md, parce que §15.5 fait comparer les quatre empreintes à l'œil.Une relecture adverse a rattrapé ce qui aurait annulé le bénéfice :
--no-scalevidescale.type, or aucun geste de l'écran ne le remettait. La détection servait pourtant déjà le driver reconnu, etdetect.gol'écrivait dans son propre commentaire depuis toujours (« what goes into the form is the driver that recognised what came out of the cable »). L'écran le jetait. Un bouton « Utiliser cette balance » écrit présence, protocole et port d'un seul geste.Les deux installeurs marchent désormais en couple
install.shporte les six mêmes options, les mêmes questions, le même plancher, la même fiche et le même message de fin. La règle n'est pas gardée par la bonne volonté :deploy/parity_test.golit leparam()de l'un et lecasede l'autre et compare dans les deux sens. Une exception est permise, jamais muette — motivée dans le banc et dans le script qui n'a pas l'option, et une raison de moins de 60 caractères fait rougir.Deux pièges mesurés plutôt que devinés :
dash, la longueur de chaîne du shell compte des octets quelle que soit la locale : un plancher de quatre appliqué ainsi aurait accepté « éàç » — 3 caractères, 6 octets — que le binaire refuse ;/proc/<pid>/cmdlineest lisible par tous les comptes quand/proc/<pid>/environne l'est que du propriétaire : le secret descend par l'environnement, effacé avant le premier processus fils.Vérification
go build·go test ./...(deux passes : avec cgo et-race, puis sans)go vet·gofmtnpm test·svelte-checkdashd'une DebianCe qui n'est PAS fait, et n'est pas à croire fait
sc qfailureflagn'a pas été relevé sur le poste de production : le diagnostic tient sur le source et la sémantique Windows, pas sur une mesure terrain.doctorne contrôle pas le drapeau de reprise — ce défaut resterait invisible sans matériel. Le contrôle qui l'aurait attrapé n'est pas écrit.install.shn'a jamais été lancé en entier : rien de ce qui toucheapt-get,useradd,udev,polkitnisystemctln'est exercé.--force,--force-install) : divergence de structure,bootstrap.shdéléguant àupdate.shlà oùbootstrap.ps1lance toujoursinstall.ps1. Jugé non bloquant par le propriétaire du produit — ces options gouvernent le chemin de téléchargement, pas ce qu'un poste devient. Le banc déclare son périmètre au lieu de prétendre le couvrir.TROUBLESHOOTING.mddit sans détour qu'une mise à jour ne répare pas ce défaut, le réglage fautif vivant dans Windows et non dans le binaire.