12 KiB
Fiche AMEL1-V1b — Niveau N1 — Modèle prévu sonnet | utilisé claude-sonnet-5-5 — Agent lp-validator — Skills sk-protocol, sk-recount, debug-verification, lp-validate
AMEL1-V1b-VAL : validation de Tools\Indicateurs.py (fiche AMEL1-M1) contre le plan AMEL1-INDICATEURS.md (2026-10-14)
Verdict : PASS avec une réserve (R1, définition de I3, § 5). Rien n'est corrigé.
1. Fiches amont relues
AMEL1-M1-IMPL.md(livrable de la fiche M1, lu en entier : § 1 à 6 et constats C1 à C6).AMEL1-MESURE-P3.md(sortie de M1, comparée au rejeu ; 17 743 o).AMEL1-INDICATEURS.md(plan : § 1, § 2, § 2.1 et définitions retenues).Tools\Indicateurs.py(1 715 lignes, lu en entier ; MD5f67033231719195d4d0facf979c2c794, identique à celui de l'IMPL avant et après mes essais).- Données de recompte :
etat\EVAL2\data\*.csv,EVAL2-T1b-INV.mdl. 47, batterieD:\Game\LifePlay_Backup_5.5\P7-H2\.
2. Points à confirmer de l'IMPL (§ 5 de M1)
| Point | Objet | Résultat |
|---|---|---|
| P1 | I5b, seuil d'activité 25 % | PASS-STATIC : le code (i_I5b, l. 1252-1276) applique « intervalle retenu si heures actives / durée ≥ 0,25 », lecture cohérente avec le § 2.1 ; valeur 29,3 h rejouée à l'identique (V1) mais non recalculée par une autre méthode (hors tirage). Le choix du seuil reste une décision, reporté à l'orchestrateur |
| P2 | I6, « COMMIT refus » en début d'opération | PASS-STATIC : re.match("(?i)COMMIT refus", r[4]) (l. 851) = définition du § 2.1 ; 6 / 49 rejoué ; non recompté (hors tirage) |
| P3 | I8b, filtre des retouches en bloc et 4 liens | reporté : hors tirage, EVAL2-T5-INV.md l. 114-118 non relu ; le filtre est bien celui du § 2.1 (l. 1066, bloc ≥ 10 fichiers à la seconde) |
| P4 | I8a, critère strict ou large | reporté : décision de libellé de la règle R8 (§ 2.1 retient le strict, 1 / 34) |
| P5 | I10b, cas distincts = lots | PASS : recompté (V2) 7 relevés, 3 clés (STE, CAM, STG) |
| P6 | I12, I13, I14 écarts à l'ancien « Avant » | PASS : les trois valeurs (5 / 25, 2 / 7, 2 / 32) sont exactement celles que le § 2.1 retient ; I13 : dénominateur 7 recompté (subagents.csv, 7 lp-inventory) |
| P7 | I2b, jeu réuni ou cas.jsonl seul |
PASS : recompté 154 / 174 (V2) ; le § 2.1 retient le jeu réuni (88,5 %) |
| P8 | fuseau UTC+2, option --decalage-utc |
reporté : option présente (l. 1671), non exercée (aucune fenêtre après le 2026-10-25) |
| P9 | granularité du jour (I6, I10b, I11a) | PASS : constaté en V3 (I6 = 150,0 pour 2 commits de la fenêtre, 3 refus datés du jour) |
3. Critères rejoués
Copie D:\Game\LifePlay-master 5.8, branche ue5.8, Python 3.14.4.
V1 rejeu P3 : PASS
Commande : python -I -X utf8 Tools/Indicateurs.py --debut "2026-10-11 05:30:00" --fin "2026-10-14 18:25:41" --coupure "2026-10-13 12:07:16" --sortie Docs/Migration/etat/EVAL2/AMEL1/V1b/rejeu.md → CODE=0, 26 s, 17 737 o.
diff AMEL1-MESURE-P3.md V1b/rejeu.md : code 1, 3 hunks, tous en en-tête (ligne Commande avec le nom de sortie, ligne Sessions exclues avec l'heure et la durée, ligne Relevés avec les durées). Les 27 lignes d'indicateurs, les notes, le tableau « attendu / obtenu » et la section Etat sont identiques octet pour octet (0 écart sur les comptes, donc dans le ±1 admis ; y compris I11a-fichier 87 / 463 et BOSS-JOURNAL). Tableau de contrôle : 50 PASS, 3 FAIL (I12, I13, I14) comme dans l'IMPL ; ces 3 écarts à l'ancienne lecture manuelle sont ceux que le § 2.1 du plan a ensuite retenus.
V2 formules, 8 indicateurs tirés (graine 20261014)
Tirage : random.seed(20261014); random.sample(<I1a…I14 puis G-a…G-d, 27 identifiants dans l'ordre du plan>, 8) → G-a, I10b, I3, I13, I2b, I9, I11a, I10a (script scratchpad\tirage.py).
| Ind. | Formule du code | Valeur rejeu | Recompte par autre méthode | Verdict |
|---|---|---|---|---|
G-a (i_Ga, l. 1460) |
(jetons principales + sous-agents) / (CHG + ERR de la fenêtre) | 2970,1 M / 76 = 39,1 M | sessions.csv niveau session 2 407,5 M + subagents.csv 562,4 M = 2 969,9 M (écart 0,2 M) ; chg.csv 26 + err.csv 50 = 76 |
PASS |
I10b (i_I10b, l. 1376) |
relevés retenu=oui, type_retenu=instantane_manquant, cas = clé (ecart X) sinon lot |
3 cas, 7 relevés | lecture directe de ecarts.csv (filtre sur la fenêtre) : 7 lignes ; clés STE (4 dont BOSS/JOURNAUX1), CAM, STG = 3 |
PASS (proxy « un cas = un lot », § 2.1) |
I3 (i_I3, l. 1207) |
KO avec découvreur agent ou script / KO avec découvreur | 12,5 % = 6 / 48 | commun.csv : 6 agent, 3 mixte, 39 utilisateur = 48 ; 13 builds de la fenêtre. Voir réserve R1 |
PASS avec réserve |
I13 (i_I13, l. 1435) |
passages lp-inventory avec refus ET (dernier résultat refus, ou compte rendu cite un refus, ou fin sans compte rendu, ou reprise) |
2 / 7 | dénominateur : 7 lp-inventory dans subagents.csv. Numérateur : proxy, non recompté ligne à ligne (le § 2.1 retient 2 / 7) |
PASS (dénominateur), numérateur incertain |
I2b (i_I2b, l. 1184) |
cas dont l'attendu est « refus » refusés (code 2) / cas dont l'attendu est « refus », 3 jeux réunis | 88,5 % = 154 / 174 | script indépendant scratchpad\recompte2.py : 3 jeux de 69, 138, 56 cas, 174 adverses, 154 refusés ; non refusés : A6, A7, A12, V03, V29, V49, H01 à H12, G01, G02 (20, liste identique à C5 de l'IMPL) ; MD5 des jeux 7851f65a, a670c5e3, 6343f981 |
PASS |
I9 (i_I9, l. 1354) |
lp-cart hors budget (tours ou pic) / passages lp-cart |
79 % = 11 / 14 | subagents.csv : 14 lp-cart, 11 hors_budget ; EVAL2-T1b-INV.md l. 47 : « 14 … 79 % » |
PASS |
I11a (i_I11a, l. 1393) |
lignes du BOSS-JOURNAL de la fenêtre avec HH:MM / lignes de la fenêtre |
19,0 % = 51 / 268 | Grep (compte) ^| 2026-10-1[1-4] : 268 ; ^| 2026-10-1[1-4][ T]\d{1,2}:\d{2} : 51 |
PASS |
I10a (i_I10a, l. 1364) |
CopieEtat + GitEtat / (eux + git status + empreintes) | 4,0 % = 66 / 1 655 | commandes.csv : CopieEtat 43 + GitEtat 23 = 66 ; git status 662 ; familles a.* 168 + 16 + 4 + 730 + 9 = 927 (union 927) ; 66 + 662 + 927 = 1 655 |
PASS |
Aucune des 8 formules ne s'écarte du § 2 ni du § 2.1, sauf la nuance R1 de I3. Les relevés de commun.csv sont de la saisie manuelle (E4 de l'IMPL) : le recompte confirme le calcul, pas la saisie. |
V3 chemin d'échec : PASS
Commande : python -I -X utf8 Tools/Indicateurs.py --debut "2026-10-14 18:30:00" --fin "2026-10-14 21:00:00" --sortie Docs/Migration/etat/EVAL2/AMEL1/V1b/echec.md → CODE=1, 14 lignes NON MESURABLE : <raison> (I2a, I3, I4a, I4b, I5a, I5b, I8a, I8b, I9, I11b, I13, I14, G-c, G-d), chacune avec sa raison (par exemple I3 : « aucun essai commun de la fenetre dans builds.csv … fournir --builds-csv et --commun-csv »). 13 autres indicateurs sont calculés sur la petite activité de la fenêtre (35 tours, 7 appels shell de sous-agents) : la fenêtre n'est donc pas « sans aucune donnée », mais le critère (code 1, lignes NON MESURABLE motivées) est rempli. Observations : I6 = 150,0 pour 100 commits (artefact de P9) et I2b = 88,5 % (indépendant de la fenêtre).
V4 innocuité : PASS
- Lecture du code en entier. Écriture : seul
ecrire_sortie(l. 1651-1653 :os.makedirsdu dossier de--sortie,open(cfg.sortie, "w")). Grepls-remote|urllib|socket|requests|http|shutil|os.remove|rename|unlink: seule occurrence = le commentaire l. 23. - Sous-processus (
subprocess.run, l. 115 et 814) :git log,git log --all,git log -p,git rev-parse --short HEAD(lecture seule,GIT_TERMINAL_PROMPT=0, délai 600 s) et le crochet lancé parsys.executable -Isur une charge JSON simulée, depuis le dossier temporaire ; aucune commande de la batterie n'est exécutée. - Crochet
%USERPROFILE%\.claude\hooks\ecriture-gardien.py: MD5f00d973927cd292723a82be859d5c5bdavant (début) et après (fin, après 2 rejeux du script et mon recompte de 174 charges simulées) = inchangé. - Fichiers apparus pendant la validation : uniquement
etat\EVAL2\AMEL1\V1b\rejeu.mdetechec.md(git status --shortne montre de neuf queV1b/pour ce dossier ;Tools/Indicateurs.pyétait déjà non suivi).
V5 fichier : PASS
- LF :
tr -cd '\r' < … | wc -c= 0 pourIndicateurs.py,AMEL1-M1-IMPL.md,AMEL1-MESURE-P3.md,rejeu.md,echec.md. - Bibliothèque standard : imports l. 33-46 +
shlex(l. 225) = argparse, collections, csv, datetime, glob, hashlib, json, os, re, statistics, subprocess, sys, tempfile, time, shlex ; rien d'autre. python -I -X utf8 Tools/Indicateurs.py --help: code 0 (HELP=0).pwsh -NoProfile -File Tools/PubCheck.ps1 -Fichiers Tools/Indicateurs.py Docs/Migration/etat/EVAL2/AMEL1/AMEL1-M1-IMPL.md Docs/Migration/etat/EVAL2/AMEL1/AMEL1-MESURE-P3.md→PubCheck : 0 constat(s), code 0. (Un second appel sur les sortiesV1b/*.mden chemin relatif a répondufichier introuvable, code 2 : erreur de chemin de ma part, non rejoué, hors critère.)
4. Diff lu en entier
Fichier neuf non suivi : Tools/Indicateurs.py lu intégralement (1 715 lignes, 3 pages de lecture) ; AMEL1-M1-IMPL.md lu en entier. Pas de tag AMEL1-M1-avant pertinent (fichiers neufs, Existed=False d'après l'IMPL § 3). Non rejoué : Snapshot.ps1/FileCheck.ps1 (sans objet, fichier neuf), compilation, LPTestStringCompat (sans objet, script Python).
5. Verdict : PASS (avec réserve R1)
| Critère | Verdict |
|---|---|
| V1 rejeu | PASS |
| V2 formules (8 / 8) | PASS (R1 sur I3) |
| V3 chemin d'échec | PASS |
| V4 innocuité | PASS |
| V5 fichier | PASS |
| Témoin en jeu : sans objet (outil de mesure, aucun comportement du jeu ne change). |
Écarts et réserves :
- R1, I3, dénominateur :
i_I3(l. 1209) retienttype == "cas"avec découvreur quel que soit le verdict, donc 8 lignesOK_PARTIEL(1 agent, 2 mixte, 5 utilisateur) entrent dans les 48 « KO ». La formule du plan dit « cas KO, KO partiels et défauts hors fiche KO ». Lecture stricte (KO,KO_PARTIELethors_ficheKO) : 5 / 40 = 12,5 %, soit la même valeur que 6 / 48. Le plan donne lui-même « 6 / 48 », donc le code reproduit le plan, mais la définition de la P4 doit trancher (inclure ou nonOK_PARTIEL), sinon la comparaison avant / après peut changer de sens sans que l'outil le dise. - R2, I10a (observation) : le dénominateur additionne les familles
a.*(somme_emp, l. 1367) au lieu de prendre l'union des appels ; égal en P3 (927 = 927), peut compter deux fois un appel qui porte deux empreintes en P4. - R3, I13 et I5b : valeurs rejouées mais numérateur de I13 (proxy) et valeur de I5b non recomptés par une autre méthode (hors tirage).
- Données saisies (I3, G-c, G-d, I8b, I10b) : le calcul est confirmé, la saisie manuelle des CSV n'est pas vérifiée.
6. Points à confirmer par l'utilisateur
- I3 : compter ou non les cas
OK_PARTIELavec découvreur dans les KO (R1) ; à fixer avant la P4. - I8a : libellé exact de la règle R8 (critère strict ou large) avant la mesure P4.
- I5b : seuil d'activité de 25 % (P1).
- Après le 2026-10-25 : passer
--decalage-utc 1si la fenêtre P4 franchit l'heure d'hiver (P8).
Tours : 14 / 40
Constats
Fichiers écrits : D:\Game\LifePlay-master 5.8\Docs\Migration\etat\EVAL2\AMEL1\AMEL1-V1b-VAL.md, D:\Game\LifePlay-master 5.8\Docs\Migration\etat\EVAL2\AMEL1\V1b\rejeu.md, D:\Game\LifePlay-master 5.8\Docs\Migration\etat\EVAL2\AMEL1\V1b\echec.md. Scripts de recompte (hors dépôt) : %LOCALAPPDATA%\Temp\claude\D--Game-LifePlay-master-5-8\be193763-a670-4b37-9245-ae89a7580435\scratchpad\{tirage,recompte,recompte2,recompte3}.py.
Fichiers à commiter : A Docs/Migration/etat/EVAL2/AMEL1/AMEL1-V1b-VAL.md, A Docs/Migration/etat/EVAL2/AMEL1/V1b/rejeu.md, A Docs/Migration/etat/EVAL2/AMEL1/V1b/echec.md (dépôt jeu, branche ue5.8) ; aucun autre fichier modifié.