9.5 KiB
Fiche FIX1-F6-VAL — Niveau N1 — Modèle prévu sonnet | utilisé claude-sonnet-5-5 — Agent lp-validator — Skills sk-protocol, sk-recount, debug-verification, lp-validate
FIX1-F6-VAL : validation statique de la redirection Saves/… (2026-10-20)
Verdict : PASS-STATIC avec réserves (équivalent de « PASS avec réserves » de la fiche : statique complet et rejoué, aucun essai en jeu).
Rien n'a été modifié hors ce livrable. Seule écriture par commande : deux résumés FIX1-VAL_BuildLog_20261020-191429.txt et -191430.txt produits par Build.ps1 -FromLog dans etat\REL\FIX1\ (ignorés par git, .gitignore:75).
1. Fiches amont relues
etat\REL\FIX1\FIX1-F6-SPEC.md(lue en entier, § 2.1 a-g et § 7.1).etat\REL\FIX1\FIX1-F6-IMPL.md(lue en entier, § 5 points à confirmer).etat\REL\FIX1\FIX1-F6-PRE.md: existe, non relue (la SPEC la cite, elle n'est pas un critère).- Journaux
Saved\Logs\portage\FIX1_Build_20261020-190716.loget-190831.log. - Instantané
D:\Game\LifePlay_Backup_5.5\FIX1\(manifeste et copie du fichier).
2. Points à confirmer des IMPL
| Id | Verdict | Preuve |
|---|---|---|
| V1 | PASS | git diff --stat -- Plugins/ModdingExtra : 1 file changed, 120 insertions(+), 2 deletions(-) ; recompté par git diff --no-index --numstat <instantané> <fichier> : 120 2. Le « ≈ 100 » de la SPEC est bien une estimation basse (IMPL écart 3), le texte est celui de la SPEC. |
| V2 | PASS | ResolvePath, branche !Match : return FPaths::ProjectContentDir() + ContentRelativePath; (diff, bloc b). Identique à l'ancienne expression. |
| V3 | PASS | Diff complet : seules LoadTxt (:308) et SaveTxt (:354) changent. :313 (relecture ProjectContentDir() + FileNameA), :307 TryGet(FileNameA…), :309 Record(FileNameA…), :357 OnWritten(FileNameB…) hors hunks, donc inchangées. |
| V4 | PASS | _session : Slot.Equals("_session", IgnoreCase) renvoie NewPath sans test de dossier. Écriture : bForWrite renvoie NewPath. L'ancien chemin n'est rendu que hors Saves/ ou avec -LPNoSavesRedirect, ou pour une lecture de slot de repli. |
| V5 | PASS | git ls-files --eol : i/lf w/lf attr/-text ; CR comptés par tr -cd '\r' | wc -c : 0. |
| V6 | PASS | § 3. |
| B1 | PASS (constat) | LPKeyboardSubsystem.cpp : MD5 611c21489d80374a4817f70e408cf4db (attendu 611c2148), i/crlf w/crlf, lot KEY2, non touché par F6. Les binaires contiennent donc F6 + KEY2 ; à retenir pour le build de référence. |
| B2 | reporté | Paquet Development non produit (IMPL § 5 B2) : hors périmètre VAL statique, étape suivante de l'ordonnateur. |
| B3 | reporté | Shipping non compilé. |
| B4 | non rejoué | Recherche UTF-16 de chaînes dans les binaires : non refaite (preuve de liaison seulement, sans valeur de comportement). Les unités compilées (§ 3) suffisent pour la liaison. |
| C1 | PASS (lu) | Fichier posé directement dans Saves/ : Slot vide, journal Saves slot '' : nouvelle racine, cosmétique. Voir § 5 réserve 3. |
| C2 | PASS-STATIC | static const bool dans IsDisabled() : initialisation thread-safe C++11, lue au premier appel après l'initialisation de la ligne de commande (premier LoadTxt BP). E6 le tranchera en jeu. |
| E1-E9 | reporté | Essais en jeu non faits (aucun jeu lancé). |
3. Critères rejoués
| Contrôle | Commande | Résultat |
|---|---|---|
| MD5 du fichier | md5sum Plugins/ModdingExtra/…/ModdingExtraBPLibrary.cpp |
1f93601c71d126f173fe30636aec0660 (attendu 1f93601c : conforme) |
| MD5 instantané | md5sum D:/Game/LifePlay_Backup_5.5/FIX1/Plugins/…/ModdingExtraBPLibrary.cpp |
7628837e7b77c68c3921acfad3d92ec0 (conforme) |
| Autres fichiers de plugin/source | git status --porcelain -- Plugins Source |
M …ModdingExtraBPLibrary.cpp et M Source/LifePlay/LPKeyboardSubsystem.cpp (KEY2, MD5 ci-dessus). LPDataCache.*, Build.cs, .uplugin non modifiés. LifePlay.uproject est modifié (date 2026-10-19 23:32, antérieur au lot, 15+/7-) : hors F6. |
| Build 1 (LifePlayEditor) | pwsh -NoProfile -File Tools/Build.ps1 -Lot FIX1-VAL -FromLog …190716.log -EtatDir <abs> |
erreurs=0 avertissements=1 autres=20 unites=3 ; Result: Succeeded (log l. 61) ; Total execution time: 57.83 seconds ; l. 51 Compile [x64] ModdingExtraBPLibrary.cpp, l. 52 Module.ModdingExtra.cpp, l. 42 Module.LifePlay.cpp. Le code -1 du résumé est celui de -FromLog (code de sortie non dans le journal), pas un échec. |
| Build 2 (LifePlay Development) | idem, …190831.log |
erreurs=0 avertissements=1 autres=0 unites=3 ; Result: Succeeded (l. 33) ; 60.91 s ; mêmes 3 unités [NoUba]. |
| Avertissement | Grep warning C dans les deux journaux |
seul LPCameraModeSubsystem.cpp(2378) : warning C4701 (Aim), connu ; aucun dans ModdingExtraBPLibrary.cpp. |
| Toolchain | ligne Using Visual Studio des deux résumés |
14.50.35739 toolchain (…\MSVC\14.50.35717) : conforme à la copie 5.8. |
| PubCheck | pwsh -NoProfile -File Tools/PubCheck.ps1 -Fichiers Plugins/ModdingExtra/Source/ModdingExtra/Private/ModdingExtraBPLibrary.cpp -Depot "D:/Game/LifePlay-master 5.8" (stdin /dev/null) |
PubCheck : 0 constat(s), code 0. |
Non rejoué : LPTestStringCompat (la fiche ne le demande pas ; le test ne couvre pas ce code), compilation (la fiche demande de recompter seulement).
4. Diff lu en entier
git diff -U3 -- Plugins/ModdingExtra lu en entier : 1 fichier, 120 insertions, 2 suppressions, hunks a, b, c, d, e, f, g de la SPEC § 2.1 et rien d'autre. Les deux lignes retirées sont exactement celles de la SPEC (f, g). L'IMPL signale que la ligne vide du bloc b est en fin de bloc plutôt qu'en tête : présentation uniquement, constatée dans le diff (l. 29-31 et 140-142 du fichier). Texte des blocs a-g relu ligne à ligne contre la SPEC : conforme, aucun ajout. Fichier non modifié par script d'après l'IMPL (outil Edit).
Revue de logique (établi par lecture du code) :
| Exigence | Constat |
|---|---|
Seul le préfixe exact Saves/ est redirigé |
\ remplacé par /, / de tête retirés, StartsWith("Saves/", IgnoreCase). saves\x, /Saves/x redirigés ; Modules/… et tout autre : ProjectContentDir() + chemin d'origine. Chemin absolu (C:/…) : non redirigé, comme avant. |
| Repli par slot | Si <SavedDir>/Saves/<Slot> absent ET <Content>/Saves/<Slot> présent : lecture dans l'ancien. Sinon nouvelle racine. |
_session jamais de repli |
confirmé (V4). |
| Écriture toujours vers la nouvelle racine | confirmé, hors -LPNoSavesRedirect. |
-LPNoSavesRedirect |
rétablit ProjectContentDir() + chemin pour Saves/… ; ligne de journal unique ; bilan (redirection desactivee). |
| Témoin sans débordement | une ligne racine, puis une par couple (racine, slot en minuscules) via TSet, plus 3 compteurs. Borné par le nombre de slots. |
| LPDataCache | TryGet et OnWritten reçoivent FileNameA/FileNameB relatifs d'origine ; TryGet ne sert que modules/ ; ResolvePath n'est appelée que si le cache n'a pas servi (court-circuit `bFromCache |
| Accès concurrent | non sûr s'il y a plusieurs threads : voir réserve 1. |
5. Verdict et réserves numérotées
Verdict : PASS-STATIC avec réserves. V1-V6 conformes ; build 2/2 Succeeded, seul C4701 connu ; essais en jeu non faits.
Réserves :
- Concurrence :
NewReads/OldReads/Writes(static int32non atomiques),SeenetWarned(TSetstatiques) et lesstatic bool(bFirst,bLogged) ne sont pas protégés. Sûr seulement sur le thread de jeu (le commentaire du code le dit). C'est cohérent avec le code existant (ReportedFailures, commentaire l. 326 « Appele uniquement depuis les Blueprints »), et la SPEC prescrit ce code ; mais si un appel arrive d'un autre thread, courses possibles (compteurs faux, corruption duTSet). Aucun appel hors thread de jeu n'a été mesuré ici (incertain). - Traversée
..(R7 de la SPEC, accepté) :Saves/../Modules/xest redirigé sous<SavedDir>/Modules/x;Saves/../../xécrirait au-dessus de<SavedDir>(aucune normalisation). Cas inverse :Modules/../Saves/xn'est pas détecté et reste dans l'ancienContent/Saves. Aucun littéral connu de ces formes ; un mod pourrait les produire. - Cas limites non couverts par un traitement dédié : (a)
Savesseul (sans/) : non redirigé, ancien chemin ; (b)Saves/final ouSaves//x: redirigé,Slotvide, traité comme fichier direct sans repli, journalSaves slot '' …; (c) nom de slot vide : même cas ; (d)./Saves/xnon détecté. Aucun usage connu (SPEC § 1.1). - Binaires : contiennent aussi KEY2 non commité (B1) ; la référence E8 « même build sans F6 » est à choisir en tenant compte de cela.
- Écart de format : l'IMPL n'a pas de section ordonnée exactement « Constats » avant « Fichiers à commiter » : la section « Constats » est après
Tours :, conforme au gabarit (section libre à la fin). Aucun écart.
6. Points à confirmer par l'utilisateur
- Accepter les réserves 1 à 3 (SPEC R7 déjà acceptée) pour la build 1.
- Faire produire le paquet Development (IMPL B2) puis jouer E1-E8 (SPEC § 7.2) ; les cas E1-E9 restent à passer.
- Choisir le journal de référence de E8 en tenant compte de KEY2.
Témoin en jeu : COMMUN- à créer (le cas de la fiche de tests commune pour F6 n'est pas identifié ici ; demande à l'ordonnateur : E1-E8 de la SPEC § 7.2).
Fichiers à commiter : A Docs/Migration/etat/REL/FIX1/FIX1-F6-VAL.md (les deux FIX1-VAL_BuildLog_*.txt sont ignorés par git).
Tours : 9 / 40