LifePlay-Revival/Docs/Migration/etat/ETAT2/ETAT2-T4-IMPL.md
edujiro5972 8084622450 LifePlay UE 5.8 : état de développement au 2026-10-19
Tickets : REP1-T4

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-19 22:57:42 +02:00

32 KiB
Raw Blame History

ETAT2-T4-IMPL — étape A4 : gabarits etat des skills et Tools\SyncModSources.ps1 (addon, lot/DC3-atelier)

Fiche ETAT2-T4-IMPL (étape A4) — Niveau N2 — Modèle prévu lp-impl | utilisé Opus 5.5 (claude-opus-5-5, identifiant donné par l'environnement de l'agent) — Agent lp-impl (invite système de l'agent : rôle A-IMPL-H, N3) — Skills sk-protocol, ue-cpp-build, lp-build, lp-ue-compat (préchargés) ; lp-paths et sk-change-safety cités par la fiche, non préchargés et non invoqués (procédure d'instantané suivie telle que la fiche l'écrit)

Date : 2026-10-09, 15:13 à 15:20. Dépôt touché : D:\Game\LifePlay-Sandbox (branche lot/DC3-atelier, HEAD 6295829). Aucun commit, aucune écriture dans D:\Game\LifePlay-Sandbox-5.8 ni dans les jeux, aucun UE lancé, aucune suppression. Source appliquée : D:\Game\LifePlay-master 5.5\Docs\Migration\etat\ETAT2\ETAT2-T1-CART.md § 3 (l. 278-294), § 5 (l. 319-395), § 6 ligne A4 (l. 408). Décisions : D10 (a), D11 (a), D12 (a).

Résultat : partiel. Étapes a, b, c faites ; analyse syntaxique 0 erreur ; l'essai à blanc renvoie le code 2 (refus : UnrealEditor ouvert (PID 32972)) au lieu de 174 IDENTIQUE et du code 0 attendus ; essai positif non lancé (même refus, voir § 5).

1. Contrôles de départ (établi)

Contrôle Résultat Commande
Branche, état addon lot/DC3-atelier, arbre propre, HEAD 6295829 git -C D:\Game\LifePlay-Sandbox branch --show-current ; status --short ; log --oneline -1
Tag ETAT2* préexistant aucun git -C … tag -l 'ETAT*'
Passages « Texte actuel » du § 3 les 11 correspondent au fichier réel, aux lignes citées (lp-build:33,115,118-119, lp-commandlets:21-22, lp-lot:50-51, lp-paths:32,43,49-51, lp-validate:14,50,83) grep -n -E "etat[\\/]" <5 SKILL.md> (26 lignes / 9 fichiers dans tout skills, comme § 1.2) ; lecture des lignes
.gitignore du jeu cité par la ligne facultative lp-paths:43 :53 = /Docs/Migration/etat/**/*.txt, :74 = /Docs/Migration/etat/ (identique sur main et ue5.8) grep -n -i etat .gitignore ; git -C …5.8 show ue5.8:.gitignore | grep -n -i etat
Format des fichiers voisins 5 SKILL.md : UTF-8 sans BOM, LF ; Tools\*.ps1 de l'addon : ASCII sans BOM, LF (.gitattributes : * -text) git ls-files --eol ; od -c ; head -c3 | od
Processus Unreal 32972 UnrealEditor (UE_5.8\…\UnrealEditor.exe, lancé 14:53:13, session STM de la copie 5.8) Get-Process -Name UnrealEditor,UnrealEditor-Cmd

2. Instantané et tag

Commande (rejouée telle que la fiche l'écrit) :

pwsh -NoProfile -Command "Set-Location 'D:\Game\LifePlay-master 5.5'; .\Tools\Snapshot.ps1 -Lot ETAT2-addon -ProjectRoot 'D:\Game\LifePlay-Sandbox' -Path Tools\claude\skills\lp-build\SKILL.md,Tools\claude\skills\lp-commandlets\SKILL.md,Tools\claude\skills\lp-lot\SKILL.md,Tools\claude\skills\lp-paths\SKILL.md,Tools\claude\skills\lp-validate\SKILL.md,Tools\SyncModSources.ps1"

Sortie : 6 entrées, code 0. Manifeste D:\Game\LifePlay_Backup_5.5\ETAT2-addon\manifest.csv :

Rel Existed Taille MD5
Tools\claude\skills\lp-build\SKILL.md True 13586 7BA202F866F64B04A38CBB16DAB779E6
Tools\claude\skills\lp-commandlets\SKILL.md True 4829 0CB3950069DB11C81C0F759A65FC5DAC
Tools\claude\skills\lp-lot\SKILL.md True 4856 2FD9BD1D834A61F4F999350F96ECF545
Tools\claude\skills\lp-paths\SKILL.md True 5332 DEF8D39CEE738F085FFD3E6D77F38162
Tools\claude\skills\lp-validate\SKILL.md True 6525 B7D210B7193D193A7EB062A27545A65C
Tools\SyncModSources.ps1 False 0 — (sera déplacé par Restore.ps1)

Tag : git -C D:\Game\LifePlay-Sandbox tag ETAT2-avant → 62958298209db54abed1d38d51889aed2447cfb9 refs/tags/ETAT2-avant (= HEAD). Retour arrière possible : Tools\Restore.ps1 -Lot ETAT2-addon -ProjectRoot 'D:\Game\LifePlay-Sandbox' ou git -C … checkout ETAT2-avant -- Tools/claude/skills (proposé seulement).

3. Modifications (étape c)

3.1 Contrôle des formats après écriture (établi)

python -c "…b.count(b'\r\n')…" : les 5 SKILL.md et SyncModSources.ps1 ont CRLF 0, BOM absent ; SyncModSources.ps1 : 70 lignes, 0 octet non ASCII, se termine par LF, MD5 4cff4f9935825c303353fbdb4f9fc61a. Le script est identique à l'octet au bloc du § 5 : diff <(sed -n '324,393p' ETAT2-T1-CART.md | tr -d '\r') Tools/SyncModSources.ps1 → aucune différence (extrait par sed, pas recopié à la main).

3.2 git -C D:\Game\LifePlay-Sandbox diff --stat

 Tools/claude/skills/lp-build/SKILL.md       | 12 ++++++++----
 Tools/claude/skills/lp-commandlets/SKILL.md |  3 ++-
 Tools/claude/skills/lp-lot/SKILL.md         |  3 ++-
 Tools/claude/skills/lp-paths/SKILL.md       | 10 ++++++----
 Tools/claude/skills/lp-validate/SKILL.md    |  6 +++---
 5 files changed, 21 insertions(+), 13 deletions(-)
  • 1 fichier non suivi : Tools/SyncModSources.ps1 (texte : § 5 de la cartographie, l. 324-393).

3.3 Diff complet (git -C D:\Game\LifePlay-Sandbox diff)

--- a/Tools/claude/skills/lp-build/SKILL.md
+++ b/Tools/claude/skills/lp-build/SKILL.md
@@ -30,7 +30,8 @@ Set-Location 'D:\Game\LifePlay-master 5.8'
   UBA a donné des C1001/C2206 non déterministes sous mémoire engagée élevée.
 - Code 3 et rien lancé si un `UnrealEditor`/`UnrealEditor-Cmd` tourne. Sinon renvoie le code de `Build.bat`.
 - Journal complet : `<copie>\Saved\Logs\portage\<lot>_Build_<horodatage>.log`.
-- **Résumé compté** : `<copie>\Docs\Migration\etat\<lot>_Build_<horodatage>.txt` : code, durée, ligne `Using Visual
+- **Résumé compté** : `<copie>\Docs\Migration\etat\<projet>\<lot>\<Lot>_Build_<horodatage>.txt` (dossier déduit du
+  lot par `Tools\EtatDir.ps1`, `-EtatDir` pour l'imposer) : code, durée, ligne `Using Visual
   Studio`, makefile recréé ou réutilisé, nombre d'actions, erreurs et avertissements du compilateur groupés par code
   avec `fichier:ligne`, autres lignes d'erreur (UBT, UHT, liens), unités compilées, DLL liées, `Total execution time`.
   Le compte rendu recopie ces comptes ; il ne les refait pas à la main.
@@ -112,10 +113,13 @@ journal ; (8) pour l'addon : une ligne de journal propre au nouveau code. Code 0
 échec probable : signaler `Makefile.bin` / DLL périmées. L'échec EST le résultat : ne rien corriger.
 
 ## 10. Où écrire les livrables
-- Fiches et comptes rendus de lot : `D:\Game\LifePlay-master 5.5\Docs\Migration\etat\U58\<lot>\<LOT>-Tn-BUILD.md`
+- Fiches et comptes rendus de lot : `D:\Game\LifePlay-master 5.5\Docs\Migration\etat\<projet>\<lot>\<LOT>-Tn-BUILD.md`
+  (U58, ST, OB…)
   (dossier de référence pour les deux copies, hors git). `D:\Game\LifePlay_Backup_5.5\etat` n'est qu'une sauvegarde :
   ne pas y écrire.
-- Résumés automatiques (`Build.ps1`, `RunCommandlet.ps1`) : restent dans `<copie>\Docs\Migration\etat\` ; la fiche
-  cite leur chemin complet.
+- Résumés automatiques (`Build.ps1`, `RunCommandlet.ps1`, `ReimportCorrectif.ps1`) :
+  `<copie>\Docs\Migration\etat\<projet>\<lot>\` de la copie qui les produit (table lot → projet de `Tools\EtatDir.ps1` ;
+  lot hors table : `etat\<Lot>\` + avertissement) ; la fiche cite leur chemin complet. Résumés antérieurs à ETAT2 :
+  `etat/MAPPING.csv` (5.5), `MAPPING-58.csv` (5.8).
 
 Catalogue symptôme → cause : `symptoms.md` (annexe).
--- a/Tools/claude/skills/lp-commandlets/SKILL.md
+++ b/Tools/claude/skills/lp-commandlets/SKILL.md
@@ -19,7 +19,8 @@
 - Journal complet : `Saved\Logs\portage\<Lot>_<Commandlet>_<horodatage>.log` ; résumé (erreurs et avertissements
-  dédoublonnés, lignes `LogLP*`) : `Docs\Migration\etat\<Lot>_<Commandlet>_<horodatage>.txt`. Ne jamais supprimer.
+  dédoublonnés, lignes `LogLP*`) : `Docs\Migration\etat\<projet>\<lot>\<Lot>_<Commandlet>_<horodatage>.txt`
+  (`Tools\EtatDir.ps1` ; `-EtatDir` impose un dossier). Ne jamais supprimer.
--- a/Tools/claude/skills/lp-lot/SKILL.md
+++ b/Tools/claude/skills/lp-lot/SKILL.md
@@ -48,7 +48,8 @@
   copie 5.8 ; `D:\Game\LifePlay_Backup_5.5\etat` n'est qu'une sauvegarde (ne pas y écrire). Résumés automatiques de
-  `Build.ps1` / `RunCommandlet.ps1` : `<copie>\Docs\Migration\etat\`, cités par leur chemin complet.
+  `Build.ps1` / `RunCommandlet.ps1` : `<copie>\Docs\Migration\etat\<projet>\<lot>\` (dans la copie 5.8 : sa propre
+  arborescence `etat`, mêmes noms de dossiers), cités par leur chemin complet.
--- a/Tools/claude/skills/lp-paths/SKILL.md
+++ b/Tools/claude/skills/lp-paths/SKILL.md
@@ -29,7 +29,7 @@
-| Journaux de commandlets | `Saved\Logs\portage\` (complet) ; `Docs\Migration\etat\` (résumés `.txt`) |
+| Journaux de commandlets | `Saved\Logs\portage\` (complet) ; `Docs\Migration\etat\<projet>\<lot>\` (résumés `.txt`, `Tools\EtatDir.ps1`) |
@@ -40,15 +40,17 @@
 `Releases/`, `Mods/` (doit être **vide** pendant build et commit), `ModSources/`, `AnimSources/`,
-`Plugins/McpAutomationBridge/`, `Docs/Migration/etat/**/*.txt`, `*.png`, `*.7z`, `*.mp4`, packs d'animation
+`Plugins/McpAutomationBridge/`, `Docs/Migration/etat/` (tout le dossier, `.gitignore:74` ; `:53` pour les `.txt`),
+`*.png`, `*.7z`, `*.mp4`, packs d'animation
 (`Content/Quaternius`, `Content/AnimPacks`…). Addon : `/Content/` (jonction), `Binaries`, `Intermediate`, `Saved`,
@@
 - `ModSources/<id>/Content/` est ignoré par git (`.gitignore:38` de l'addon) : un nouveau worktree ou checkout de
-  l'addon ne l'a pas. Avant `BuildMod`, le copier depuis `D:\Game\LifePlay-Sandbox\ModSources\<id>\Content`
-  (copie, MD5 contrôlés ; U7-T15). État actuel : copié dans `D:\Game\LifePlay-Sandbox-5.8` le 2026-10-09.
+  l'addon ne l'a pas. Avant `BuildMod` : `.\Tools\SyncModSources.ps1 -Target <checkout>` (à blanc : liste NOUVEAU /
+  IDENTIQUE / DIFFERENT / EN_TROP ; `-Apply` copie, MD5 relus ; ERR-046). État au 2026-10-09 :
+  `D:\Game\LifePlay-Sandbox-5.8` identique à `D:\Game\LifePlay-Sandbox` (174 fichiers).
--- a/Tools/claude/skills/lp-validate/SKILL.md
+++ b/Tools/claude/skills/lp-validate/SKILL.md
@@ -11,7 +11,7 @@
-- Lire la fiche du lot et **tous** les livrables amont (`…\Docs\Migration\etat\U58\<lot>\`).
+- Lire la fiche du lot et **tous** les livrables amont (`…\Docs\Migration\etat\<projet>\<lot>\`).
@@ -47,7 +47,7 @@
-  `<copie>\Docs\Migration\etat\<lot>_LPTestStringCompat_<horodatage>.txt`).
+  `<copie>\Docs\Migration\etat\<projet>\<lot>\<Lot>_LPTestStringCompat_<horodatage>.txt`).
@@ -80,6 +80,6 @@
-- Livrable : `D:\Game\LifePlay-master 5.5\Docs\Migration\etat\U58\<lot>\<LOT>-VAL.md`, en-tête
+- Livrable : `D:\Game\LifePlay-master 5.5\Docs\Migration\etat\<projet>\<lot>\<LOT>-VAL.md`, en-tête

(Contexte inchangé abrégé pour lp-commandlets, lp-lot, lp-paths, lp-validate ; diff intégral rejouable : git -C D:\Game\LifePlay-Sandbox diff ETAT2-avant.)

Correspondance § 3 → lignes après modification : lp-build:33-34, :116-117, :120-123 ; lp-commandlets:22-23 ; lp-lot:51-52 ; lp-paths:32, :43-44, :51-53 ; lp-validate:14, :50, :83. Décalages induits : lp-build +4 lignes, lp-commandlets +1, lp-lot +1, lp-paths +2, lp-validate 0.

4. Contrôles statiques (étape d, établi)

Analyse syntaxique :

pwsh -NoProfile -Command '[System.Management.Automation.Language.Parser]::ParseFile("D:\Game\LifePlay-Sandbox\Tools\SyncModSources.ps1",[ref]$t,[ref]$e) ; $e.Count'
→ erreurs d'analyse : 0 ; jetons : 721

5. Essais (étape d)

5.1 Essai à blanc LifePlay-Sandbox → LifePlay-Sandbox-5.8 : échec (refus, code 2)

cd D:\Game\LifePlay-Sandbox
pwsh -NoProfile -File 'D:\Game\LifePlay-Sandbox\Tools\SyncModSources.ps1' -Source 'D:\Game\LifePlay-Sandbox' -Target 'D:\Game\LifePlay-Sandbox-5.8'
SyncModSources : refus : UnrealEditor ouvert (PID 32972)
code de sortie = 2

Attendu par la fiche : 174 IDENTIQUE, code 0. Cause (établie) : SyncModSources.ps1:29-30 refuse dès qu'un UnrealEditor/UnrealEditor-Cmd tourne sur le poste, y compris à blanc et sans filtre de chemin ; le PID 32972 est l'éditeur 5.8 de la session STM (D:\Game\Launcher\Engine\UE_5.8\Engine\Binaries\Win64\UnrealEditor.exe, lancé 14:53:13, toujours actif à 15:16:57). Ce refus est conforme au § 5 (« Refus : … UnrealEditor ouvert ») : aucun contournement (pas de paramètre ajouté, pas d'arrêt du processus).

Lecture seule de la cible (établi) :

  • git -C D:\Game\LifePlay-Sandbox-5.8 status --short : vide avant (15:16:15) et après (code 0 les deux fois).
  • Dates : relevé FullName|Length|LastWriteTimeUtc.Ticks de D:\Game\LifePlay-Sandbox-5.8\ModSources (récursif, 798 entrées) avant et après : diff vide.
  • Aucun rapport écrit : D:\Game\LifePlay_Backup_5.5\SYNC-MODSOURCES n'existe pas.

5.2 Essai positif dans D:\Game\LifePlay_Backup_5.5\ETAT2\sync-test\ : non lancé

Le contrôle de l'éditeur (:29-30) précède tout traitement (identifiants, .uplugin, hachage) : l'essai aurait rendu le même refus. La cible jetable n'a pas été créée (aucune copie de .uplugin). À rejouer en A5 quand aucun éditeur ne tourne.

5.3 Contre-vérification indépendante de l'état annoncé dans lp-paths (lecture seule, hors script)

La phrase ajoutée « D:\Game\LifePlay-Sandbox-5.8 identique à D:\Game\LifePlay-Sandbox (174 fichiers) » est établie par une autre voie : (cd <racine>/ModSources && find */Content -type f -print0 | sort -z | xargs -0 md5sum) pour chaque racine, puis diff → vide ; 174 lignes de chaque côté (lpr_anim_freeanims 20, lpr_anim_quaternius 84, lpr_hair_pocolov 70). Ceci ne valide pas le script.

5.4 Sonde en lecture seule (hors fiche) : code d'une cible absente

pwsh -NoProfile -File 'D:\Game\LifePlay-Sandbox\Tools\SyncModSources.ps1' -Target 'D:\Game\LifePlay_Backup_5.5\ETAT2\cible-inexistante'
Resolve-Path: D:\Game\LifePlay-Sandbox\Tools\SyncModSources.ps1:27 … Impossible de trouver le chemin d'accès « D:\Game\LifePlay_Backup_5.5\ETAT2\cible-inexistante », car il n'existe …
code de sortie = 1

Rien créé (ls : absent). Voir observation O2.

6. git -C D:\Game\LifePlay-Sandbox status --short (fin de tâche)

 M Tools/claude/skills/lp-build/SKILL.md
 M Tools/claude/skills/lp-commandlets/SKILL.md
 M Tools/claude/skills/lp-lot/SKILL.md
 M Tools/claude/skills/lp-paths/SKILL.md
 M Tools/claude/skills/lp-validate/SKILL.md
?? Tools/SyncModSources.ps1

git -C D:\Game\LifePlay-Sandbox-5.8 status --short : vide. Les jonctions .claude\skills des deux jeux pointent sur ce checkout : les 5 skills modifiés sont déjà servis aux deux copies (rechargement constaté dans la session de l'agent).

7. Écarts avec la cartographie

  • E1 (lp-paths:49-51, choix de l'agent, réversible) : le texte proposé écrit « A58 identique à A55 » ; A55/A58 sont des abréviations définies seulement dans la cartographie (ETAT2-T1-CART.md:7), inconnues des skills. Écrit à leur place leur définition exacte : D:\Game\LifePlay-Sandbox-5.8 / D:\Game\LifePlay-Sandbox. Variante littérale disponible si l'orchestrateur la préfère.
  • E2 (lecture des parenthèses) : les parenthèses de la colonne « Texte proposé » sont reprises comme texte : lp-build:33 « (dossier déduit du lot par … pour l'imposer) » et lp-build:115 « (U58, ST, OB…) ». La seconde, placée sur sa propre ligne, précède la parenthèse existante « (dossier de référence pour les deux copies, hors git) » : deux parenthèses se suivent.
  • E3 (mise en page) : seules les lignes citées ont changé ; quand le texte s'allonge, la ligne est coupée vers 120 colonnes (lp-build 33, 115, 118-119 ; lp-commandlets 22 ; lp-lot 51 ; lp-paths 43, 50-51), sans retoucher les lignes voisines. La ligne de tableau lp-paths:32 fait maintenant plus de 120 colonnes (les tableaux du fichier en ont déjà, :37 = 158).
  • E4 (ligne facultative) : lp-paths:43 est appliquée, parce que la ligne A4 du § 6 (l. 408) compte 11 passages, dont celui-ci, et que .gitignore:53 et :74 sont vérifiés.
  • E5 (critère d'essai non atteint) : essai à blanc → code 2 (§ 5.1), essai positif non lancé (§ 5.2). Critère « 174 IDENTIQUE, code 0 » non satisfait par le script ; l'état des fichiers est établi par une autre voie (§ 5.3).
  • E6 (sonde hors fiche) : § 5.4, lecture seule, ajoutée pour étayer l'observation O2.

8. Observations sur le script du § 5 (rapportées, non corrigées)

  • O1 (établi, SyncModSources.ps1:29-30) : le refus « éditeur ouvert » s'applique aussi à blanc et à tout éditeur du poste, même celui de l'autre copie. C'est le même type de risque que Build.ps1:55 (cartographie § 1.1). Conséquence : A5 ne peut pas tourner tant que l'éditeur STM est ouvert. Choix pour l'orchestrateur : (a) attendre la fermeture de l'éditeur ou la porte G-STM-FIN ; (b) amender la SPEC pour ne contrôler l'éditeur qu'avec -Apply.

  • O2 (établi, § 5.4) : une erreur non interceptée (Resolve-Path à :27 ; toute erreur bloquante sous $ErrorActionPreference = 'Stop', :25) sort en code 1, le même code que « écarts restants » (:69). Un appelant ne peut donc pas distinguer un écart d'une panne.

  • O3 (établi, :68) : EN_TROP n'entre pas dans le code 1. C'est conforme à « signalé, jamais touché ». À confirmer si « 1 = écarts restants » doit l'inclure.

  • O4 (établi, :66) : après -Apply, le résumé console regroupe par Etat (état avant copie, p. ex. NOUVEAU 174), pas par Action. En A5, le critère « 174 copiés, MD5 174/174 » se compte dans le rapport D:\Game\LifePlay_Backup_5.5\SYNC-MODSOURCES\sync_<horodatage>.csv, colonne Action = copie OK.

  • O5 (établi) : les skills, servis dès maintenant aux deux copies, annoncent etat\<projet>\<lot>\ et MAPPING-58.csv. Or :

    • les scripts 5.8 (Build.ps1:61, RunCommandlet.ps1:36 sur ue5.8, cartographie § 1.1) écrivent encore à la racine jusqu'à B1 ;
    • MAPPING-58.csv n'existe qu'après B3 ;
    • Tools\EtatDir.ps1 de main est en cours (A1 : non suivi, non commité, git -C "D:\Game\LifePlay-master 5.5" status --short).

    Cet écart est temporaire et attendu par D11 (a), mais la session STM en cours lit déjà ces skills.

  • O6 (établi, Restore.ps1:35) : la cible d'essai Backup_5.5\ETAT2\sync-test\ partage le dossier de l'instantané A1 (ETAT2\manifest.csv, ETAT2\Tools\). Restore.ps1 ne parcourt que les lignes du manifeste et ne la toucherait donc pas.

9. Fichiers écrits

  • D:\Game\LifePlay-Sandbox\Tools\claude\skills\lp-build\SKILL.md, …\lp-commandlets\SKILL.md, …\lp-lot\SKILL.md, …\lp-paths\SKILL.md, …\lp-validate\SKILL.md (modifiés)
  • D:\Game\LifePlay-Sandbox\Tools\SyncModSources.ps1 (nouveau)
  • D:\Game\LifePlay_Backup_5.5\ETAT2-addon\manifest.csv + 5 copies (instantané)
  • tag local ETAT2-avant (addon)
  • ce livrable ; fichiers de relevé dans le dossier temporaire de session (a58_avant.txt, a58_apres.txt, md5_LifePlay-Sandbox*.txt)

10. Compte rendu sk-protocol

[sk-protocol] Skills présents dans le contexte : sk-protocol, ue-cpp-build, lp-build, lp-ue-compat (lp-paths, sk-change-safety : non préchargés).

  1. Résultat : partiel. § 3 (11 passages) et § 5 appliqués, analyse syntaxique 0 erreur ; essai à blanc refusé (code 2, éditeur STM PID 32972) ; essai positif non lancé.
  2. Preuves : git -C D:\Game\LifePlay-Sandbox diff ETAT2-avant ; diff du script contre ETAT2-T1-CART.md:324-393 vide ; ParseFile 0 erreur ; sortie § 5.1 ; git status de la cible vide avant et après, 798 dates identiques.
  3. Chiffres : 5 fichiers modifiés, 21 insertions et 13 suppressions, 1 nouveau fichier de 70 lignes (git diff --stat) ; instantané de 6 entrées ; MD5 indépendant 174/174 (20/84/70).
  4. Incertitudes : comportement du script à blanc et avec -Apply non exécuté (A5, après fermeture de l'éditeur) ; O3 à trancher.
  5. Écarts : E1 à E6 (§ 7). Fichiers écrits : § 9.
  6. Suite : l'orchestrateur doit trancher E1 et O1 (attendre la fin de l'éditeur STM ou amender la SPEC), puis lancer A5 (ETAT2-T5-VAL) sans éditeur ouvert. État : modifications en place sur lot/DC3-atelier, non commitées, tag ETAT2-avant posé.

11. Reprise (2026-10-09, 15:20 à 15:25, décisions de l'orchestrateur)

Décisions reçues :

  • E1 accepté : chemins complets dans lp-paths.
  • Corriger le script :
    • O1 : refus « éditeur ouvert » seulement avec -Apply ;
    • O2 : erreur imprévue → code 3, codes documentés dans l'en-tête ;
    • O3 : EN_TROP informatif, compté au résumé, sans code 1 ;
    • O4 : résumé par action.
  • lp-paths à mettre en accord.
  • Éditeur STM annoncé fermé : essai à blanc, essai de cible inexistante et essai positif -Apply (ligne A5) demandés.

Pas de nouvel instantané : ETAT2-addon\manifest.csv garde la première sauvegarde de lp-paths et SyncModSources.ps1 (Existed=False). La version initiale du script reste récupérable à l'octet depuis ETAT2-T1-CART.md:324-393.

11.1 Modifications

D:\Game\LifePlay-Sandbox\Tools\SyncModSources.ps1 (86 lignes) :

  • ASCII, LF, sans BOM, fin LF (contrôle python … count(b'\r\n') → CRLF 0, nonascii 0), MD5 a8d36da7ee05019375d4fbf34b062cc3.
  • Analyse syntaxique ParseFile → 0 erreur.

Diff contre le § 5 (diff -u <(sed -n '324,393p' ETAT2-T1-CART.md | tr -d '\r') Tools/SyncModSources.ps1) :

@@ -3,12 +3,19 @@
 .DESCRIPTION
-  Par mod : NOUVEAU (absent de la cible), IDENTIQUE, DIFFERENT, EN_TROP (cible seule), par chemin relatif et MD5.
-  -Apply : copie les NOUVEAU ; les DIFFERENT seulement avec -Overwrite (ancien fichier cible DEPLACE vers
-  <BackupRoot>\<Lot>\<horodatage>\...) ; EN_TROP signale, jamais touche ; MD5 relu sur la cible apres copie ;
-  rapport <BackupRoot>\<Lot>\sync_<horodatage>.csv. Refus : Source = Target, UnrealEditor ouvert, mod monte
-  (ModSources\<id>\<id>.uplugin absent d'un cote : voir Mount-ModSource de Tools\ModSource.ps1), Content source absent.
-  Codes : 0 conforme ou copie controlee ; 1 ecarts restants ; 2 refus ; 3 MD5 faux apres copie.
+  Par mod, par chemin relatif et MD5 : IDENTIQUE, MANQUANT (absent de la cible), DIFFERENT, EN_TROP (cible seule).
+  A blanc (defaut) : lecture seule des deux cotes, rien n'est ecrit ; permis meme avec un UnrealEditor ouvert.
+  -Apply : copie les MANQUANT ; les DIFFERENT seulement avec -Overwrite (ancien fichier cible DEPLACE vers
+  <BackupRoot>\<Lot>\<horodatage>\...) ; MD5 relu sur la cible apres copie (COPIE_OK, sinon COPIE_KO) ;
+  rapport <BackupRoot>\<Lot>\sync_<horodatage>.csv. EN_TROP : informatif, compte au resume, jamais touche.
+  Resume affiche : par mod et au total, comptes IDENTIQUE, COPIE_OK, COPIE_KO, DIFFERENT, MANQUANT, EN_TROP.
+  Refus : Source = Target ; avec -Apply, UnrealEditor ou UnrealEditor-Cmd ouvert ; mod monte
+  (ModSources\<id>\<id>.uplugin absent d'un cote : voir Mount-ModSource de Tools\ModSource.ps1) ; Content source absent.
+  Codes de sortie :
+    0  conforme (aucun MANQUANT ni DIFFERENT restant ; EN_TROP n'y entre pas) ou copie controlee
+    1  ecarts restants : MANQUANT a blanc, DIFFERENT sans -Apply -Overwrite
+    2  refus (liste ci-dessus) ; rien n'est ecrit
+    3  erreur : Source ou Target introuvable, exception imprevue, MD5 faux apres copie (COPIE_KO)
@@ -23,11 +30,16 @@
 $ErrorActionPreference = 'Stop'
+trap { Write-Host "SyncModSources : erreur (ligne $($_.InvocationInfo.ScriptLineNumber)) : $($_.Exception.Message)"; exit 3 }
 function Stop-Sync([string]$Why) { Write-Host "SyncModSources : refus : $Why"; exit 2 }
+function Stop-Error([string]$Why) { Write-Host "SyncModSources : erreur : $Why"; exit 3 }
+foreach ($p in $Source, $Target) { if (-not (Test-Path -LiteralPath $p -PathType Container)) { Stop-Error "$p introuvable" } }
 $src = (Resolve-Path -LiteralPath $Source).Path.TrimEnd('\'); $dst = (Resolve-Path -LiteralPath $Target).Path.TrimEnd('\')
 if ($src -eq $dst) { Stop-Sync 'Source = Target' }
-$ed = Get-Process -Name 'UnrealEditor', 'UnrealEditor-Cmd' -ErrorAction SilentlyContinue
-if ($ed) { Stop-Sync "UnrealEditor ouvert (PID $($ed.Id -join ', '))" }
+if ($Apply) {
+    $ed = Get-Process -Name 'UnrealEditor', 'UnrealEditor-Cmd' -ErrorAction SilentlyContinue
+    if ($ed) { Stop-Sync "UnrealEditor ouvert (PID $($ed.Id -join ', ')) : -Apply exige l'editeur ferme (a blanc permis)" }
+}
@@ -41,12 +53,12 @@
-        $st = if (-not $ht.ContainsKey($k)) { 'NOUVEAU' } elseif …
-        $rows.Add([pscustomobject]@{ Mod = $m; Rel = $k; Etat = $st; MD5Source = $hs[$k]; MD5Cible = $ht[$k]; Action = '' })
+        $st = if (-not $ht.ContainsKey($k)) { 'MANQUANT' } elseif …
+        $rows.Add([pscustomobject]@{ Mod = $m; Rel = $k; Etat = $st; Resultat = $st; MD5Source = $hs[$k]; MD5Cible = $ht[$k] })
-    foreach ($r in @($rows | Where-Object { $_.Etat -eq 'NOUVEAU' -or …
+    foreach ($r in @($rows | Where-Object { $_.Etat -eq 'MANQUANT' -or …
@@ -56,15 +68,19 @@
-        $r.Action = if ($r.MD5Cible -eq $r.MD5Source) { 'copie OK' } else { 'copie MD5 KO' }
+        $r.Resultat = if ($r.MD5Cible -eq $r.MD5Source) { 'COPIE_OK' } else { 'COPIE_KO' }
-$rows | Group-Object Mod, Etat | Sort-Object Name | ForEach-Object { '{0,-45} {1,5}' -f $_.Name, $_.Count }
-if ($rows | Where-Object Action -eq 'copie MD5 KO') { exit 3 }
-$left = @($rows | Where-Object { ($_.Etat -eq 'NOUVEAU' -and -not $Apply) -or ($_.Etat -eq 'DIFFERENT' -and -not ($Apply -and $Overwrite)) })
-if ($left) { Write-Host "$($left.Count) fichier(s) a copier ou a arbitrer (-Apply, -Overwrite)"; exit 1 }
+$cats = 'IDENTIQUE', 'COPIE_OK', 'COPIE_KO', 'DIFFERENT', 'MANQUANT', 'EN_TROP'
+$line = { param($name, $set) ('{0,-24}' -f $name) + (($cats | ForEach-Object { $c = $_; ' {0} {1,4}' -f $c, @($set | Where-Object Resultat -eq $c).Count }) -join ' ') }
+Write-Host "SyncModSources : $(if ($Apply) { '-Apply' } else { 'a blanc' }) $src -> $dst"
+foreach ($m in $Id) { & $line $m @($rows | Where-Object Mod -eq $m) }
+& $line 'TOTAL' $rows
+if (@($rows | Where-Object Resultat -eq 'COPIE_KO').Count) { exit 3 }
+$left = @($rows | Where-Object { $_.Resultat -in 'MANQUANT', 'DIFFERENT' })
+if ($left.Count) { Write-Host "$($left.Count) fichier(s) MANQUANT ou DIFFERENT a copier ou a arbitrer (-Apply, -Overwrite)"; exit 1 }
 exit 0

(Les lignes de contexte inchangées sont abrégées par « … ».)

lp-paths/SKILL.md:51-55, mis en accord avec le script. La section compte maintenant +4 lignes par rapport à ETAT2-avant, au lieu de +2 :

  l'addon ne l'a pas. Avant `BuildMod` : `.\Tools\SyncModSources.ps1 -Target <checkout>` (à blanc, lecture seule,
  permis éditeur ouvert : comptes IDENTIQUE / MANQUANT / DIFFERENT / EN_TROP, ce dernier informatif ; `-Apply`,
  éditeur fermé : copie les MANQUANT, `-Overwrite` remplace les DIFFERENT, MD5 relus → COPIE_OK ; codes 0 conforme,
  1 MANQUANT ou DIFFERENT restants, 2 refus, 3 erreur ; ERR-046). État au 2026-10-09 :
  `D:\Game\LifePlay-Sandbox-5.8` identique à `D:\Game\LifePlay-Sandbox` (174 fichiers).

Fichier toujours en LF (CRLF 0). Aucun autre texte de l'addon ne décrit le script (seul lp-paths le cite).

Choix de nommage (écart R-E1) :

  • NOUVEAU est renommé MANQUANT, comme dans la liste de l'orchestrateur.
  • « COPIE/COPIE_OK » est rendu par COPIE_OK, et COPIE_KO est ajouté : c'est le seul cas qui produit le code 3 après une copie.
  • Le CSV garde Etat (comparaison avant action) et remplace Action par Resultat.

11.2 Essais (établi, commandes rejouables ; pwsh -NoProfile -File 'D:\Game\LifePlay-Sandbox\Tools\SyncModSources.ps1' …)

# Essai Sortie (TOTAL) Code Attendu
0 Get-Process UnrealEditor,UnrealEditor-Cmd à 15:22:14, 15:22:57, 15:23:41 aucun processus — éditeur fermé : OK
1 à blanc -Source D:\Game\LifePlay-Sandbox -Target D:\Game\LifePlay-Sandbox-5.8 IDENTIQUE 174 (20 / 84 / 70), autres 0 0 174 IDENTIQUE, 0 : OK
1b cible 5.8 avant / après git -C D:\Game\LifePlay-Sandbox-5.8 status --short vide avant et après ; 798 entrées ModSources (chemin, taille, LastWriteTimeUtc) : diff vide ; Backup_5.5\SYNC-MODSOURCES absent après — cible inchangée : OK
2 -Target D:\Game\LifePlay_Backup_5.5\ETAT2\cible-inexistante SyncModSources : erreur : D:\Game\LifePlay_Backup_5.5\ETAT2\cible-inexistante introuvable ; rien créé 3 3 : OK
P0 préparation : sync-test\ModSources\<id>\<id>.uplugin ×3, copiés par cp -p MD5 des 3 .uplugin identiques à la source — —
P1 à blanc → sync-test MANQUANT 174, autres 0 ; « 174 fichier(s) MANQUANT ou DIFFERENT … » 1 174 manquants, 1 : OK
P2 -Apply → sync-test COPIE_OK 174, COPIE_KO 0 ; rapport D:\Game\LifePlay_Backup_5.5\SYNC-MODSOURCES\sync_20261009-152303.csv 0 174 copiés, MD5 OK : OK
P2b recompte du CSV (Import-Csv) 174 lignes ; MANQUANT, COPIE_OK : 174 ; MD5Source = MD5Cible : 174 — OK
P2c MD5 indépendant (find … | xargs md5sum, source contre sync-test) diff vide, 174/174 — OK
P3 à blanc → sync-test IDENTIQUE 174, autres 0 0 OK
P4a 1 octet ajouté à sync-test\…\lpr_hair_pocolov\Content\Hairs\Pocolov03_Cap.uasset (MD5 4b72…7344 → 3b17…0464a3), puis à blanc IDENTIQUE 173, DIFFERENT 1 1 ligne A5 : DIFFERENT 1, 1 : OK
P4b -Apply -Overwrite COPIE_OK 1, IDENTIQUE 173 ; rapport sync_20261009-152329.csv ; ancien fichier déplacé vers D:\Game\LifePlay_Backup_5.5\SYNC-MODSOURCES\20261009-152329\sync-test\ModSources\lpr_hair_pocolov\Content\Hairs\Pocolov03_Cap.uasset (4916 octets, MD5 3b17bef7… = version altérée) 0 A5 : déplacé, 0 : OK
P4c à blanc IDENTIQUE 174 0 OK
P5 fichier EN_TROP_essai.txt ajouté dans sync-test\…\lpr_anim_freeanims\Content, puis à blanc IDENTIQUE 174, EN_TROP 1 (compté au résumé) 0 O3 : informatif, pas de code 1 : OK
S source inchangée MD5 des 174 fichiers de D:\Game\LifePlay-Sandbox\ModSources\*\Content après essais : diff vide avec le relevé de 15:17 — OK

Essai non fait : le refus « éditeur ouvert » avec -Apply. Aucun éditeur n'était ouvert pour le provoquer, et je n'en ai lancé aucun (interdit). La branche correspondante du code est lue (:39-42), pas exécutée.

11.3 Limites restantes (rapportées, non corrigées)

  • R1 (établi) : une erreur de liaison des paramètres (paramètre inconnu, -Target vide) survient avant le trap et sort avec le code de pwsh, pas 3. Commande : pwsh -NoProfile -NonInteractive -File … -Target D:\Game\LifePlay-Sandbox-5.8 -Bogus 1 → code 1, message « Nous ne pouvons pas trouver un paramètre qui correspond au nom de paramètre « Bogus » ». Elle se confond donc avec « écarts restants ».
  • R2 (estimé, lecture de :60-77) : si une exception survient au milieu d'un -Apply, le trap sort en code 3 avant Export-Csv. Les copies déjà faites et les fichiers déjà déplacés n'ont alors pas de rapport ; seul le dossier SYNC-MODSOURCES\<horodatage>\ en garde la trace.
  • R3 (établi, :40) : avec -Apply, le contrôle de l'éditeur ne filtre pas par chemin. C'est la même classe de risque que Build.ps1:55, gardée volontairement.
  • R4 : le texte lp-paths diffère désormais du § 3 de la cartographie (décision de reprise), et les noms d'état diffèrent du § 5 et de la ligne A5 (NOUVEAU y est devenu MANQUANT). La VAL A5 doit s'appuyer sur ce § 11.

11.4 Fichiers écrits pendant la reprise

  • D:\Game\LifePlay-Sandbox\Tools\SyncModSources.ps1 (réécrit) ; D:\Game\LifePlay-Sandbox\Tools\claude\skills\lp-paths\SKILL.md (l. 51-55).
  • Cible jetable D:\Game\LifePlay_Backup_5.5\ETAT2\sync-test\ : 3 .uplugin, 174 fichiers copiés, EN_TROP_essai.txt.
  • D:\Game\LifePlay_Backup_5.5\SYNC-MODSOURCES\ : sync_20261009-152303.csv, sync_20261009-152329.csv, 20261009-152329\…\Pocolov03_Cap.uasset (déplacé).
  • Aucune suppression ; LifePlay-Sandbox-5.8 et les jeux non touchés ; pas de commit.

git -C D:\Game\LifePlay-Sandbox diff --stat après reprise : 5 fichiers, 23 insertions, 13 suppressions (lp-paths 12 au lieu de 10), plus ?? Tools/SyncModSources.ps1. git -C D:\Game\LifePlay-Sandbox-5.8 status --short : vide.

Compte rendu de reprise : réussi. O1 à O4 sont corrigés, l'analyse syntaxique donne 0 erreur, et tous les essais demandés sont conformes : 174 IDENTIQUE avec code 0 et cible 5.8 inchangée, code 3 pour la cible absente, puis 174 COPIE_OK et retour à IDENTIQUE avec code 0. Restent les limites R1 et R2. Suite : l'orchestrateur doit décider R1 et R2 (accepter ou faire corriger), puis lancer A5 (VAL, sur la base du § 11) et le commit A6. État : non commité, tag ETAT2-avant posé.