fix(hosts): require 3 loadAvg values and sweep orphan temp files (#25) #37
No reviewers
Labels
No labels
autopilot:pending-human
source:analyste
source:defenseur
source:human
source:medic
status:approved
status:blocked
status:in-progress
status:needs-clarification
status:needs-fix
status:ready
status:review
status:triage
type:bug
type:feature
type:infra
type:refactor
type:schema
type:security
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set.
Reference: maximus/vps-health-api#37
Loading…
Reference in a new issue
No description provided.
Delete branch "issue-25-hosts-review-followups"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Fixes #25
Les quatre constats de la revue de la pile monitoring des postes (#18-#23), selon les décisions de l'analyse du 2026-09-29.
1.
loadAvg: exactement 3 nombres.sanitizeCpu()refuse toute autre longueur (cpu.loadAvg must hold exactly 3 finite numbers, 400, rien n'est écrit). Avant,[]était accepté et[1..5]tronqué. Un fichier déjà stocké hors format dégrade enneverSeenà la relecture. L'agent envoieos.loadavg(), toujours 3 valeurs : aucune rupture côté poste.2.
cleanString: commentaire et phrase dans le README. Les chaînes sont tronquées, pas filtrées, et la sûreté repose sur l'échappement du consommateur.3. Débris
.tmp:sweepStaleTempFiles(), appelée au démarrage avantlisten. Elle ne touche que le format exact.<id>.<pid>.<ms>.tmp(même regex d'id que la route), que des fichiers réguliers (lstat), et seulement au-delà d'une heure : plus jeune, un autre conteneur peut être en train d'écrire pendant un redéploiement. UnHOSTS_DIRabsent reste silencieux ; tout autre échec est journalisé sans bloquer le démarrage.4.
frozenRequest: le commentaire précise quenew Date()lit l'horloge réelle, y compris lereceivedAtd'un POST.Tests : 155 -> 171 dans
hosts.test.js(329 au total). Le test du démarrage lance le vrainode index.jssur unHOSTS_DIRpréparé : ce n'est pas une épingle sur le source.Preuve par mutation (
index.jsrestauré depuis une copie,git diff --statidentique avant/après) :slice(0, 3)sans contrôle de longueur/\.tmp$/.joker)isFile()retiréeconsole.errorle voit)Suite locale : 329/329 vitest, 45/45
test-curl.sh,boot-from-copy: PASS.Déploiement :
index.jschange, donc il faut redéployer après le merge. Aucune nouvelle variable d'environnement, aucun nouveau module (leCOPYdu Dockerfile est inchangé).🤖 Generated with Claude Code
Verdict : APPROVE
Résumé : les quatre points de #25 sont traités comme l'analyse l'a tranché. Le contrôle de longueur de
loadAvget le balayage des.tmpsont corrects et bornés. Chaque mutation annoncée dans le corps de la PR, rejouée par le relecteur, fait tomber le nombre de tests déclaré.Vérifié
523d90b: 329/329 vitest, 45/45test-curl.sh,boot-from-copy: PASS. Statut de commit CI :success.index.jsrestauré puiscmpidentique) :length !== 3(retour au comportement sans troncature)length < 3au lieu de!== 3/\.tmp$/isFile()retiréelisten(setTimeout)ENOENTjournaliséreaddirqui lève au lieu de rendre[]pull_refdepuis #37 avecref_action: "closes", donc la fermeture se fera au merge, comme voulu.TEMP_FILE_REest construit depuisHOST_ID_PATTERN(même source que la route). Pas de point possible dans l'id, donc pas d'ambiguïté de découpage.COPYdu Dockerfile est inchangé. Décompte : 155 + 11 (balayage) + 4 (matrice) + 1 (dégradation) = 171, et 313 + 16 = 329.Suggestions (non bloquantes)
index.js:451) : le commentaire affirme qu'un symlink « is neither followed nor removed », mais remplacerlstatSyncparstatSynclaisse la suite verte (221/221 sur hosts et agent). Avecstat, un symlink au bon nom qui pointe vers un vieux fichier régulier serait supprimé (le lien seulement, pas la cible, donc sans gravité). Un testfs.symlinkSyncvers un fichier vieux, qui vérifie que le lien et la cible survivent, figerait l'affirmation.^non épinglée (index.js:434) : la retirer laisse aussi la suite verte, parce qu'aucun des noms hors format ne contient de sous-chaîne valide. Un cas"prefix.thinkpad.4242.1700000000000.tmp"dans letest.each« never touches » la couvrirait.<=contre<à exactement une heure : non testée. C'est cosmétique, rien à faire.🤖 Generated with Claude Code
Mergé en fast-forward sur
main(523d90b) après rejeu local du tip :npm ci, 329/329 vitest, 45/45test-curl.sh,boot-from-copy: PASS. Forgejo ne détecte pas le ff local, fermeture manuelle. Les deux tests manquants signalés par la revue (symlink, ancre^) sont reportés dans une issue de suivi.Pull request closed