158 lines
16 KiB
Markdown
158 lines
16 KiB
Markdown
Fiche OUTC-T1 — Niveau N3 — Modèle prévu opus | utilisé claude-opus-5-5 — Agent lp-impl — Skills sk-protocol, ue-cpp-build, lp-build, lp-ue-compat (préchargés), sk-windows-shell, lp-paths (invoqués)
|
||
# OUTC-T1-IMPL : CopieEtat.ps1, UeState.ps1 -Copie/-Json, FileCheck.ps1 -Json (2026-10-11)
|
||
|
||
Sources : `OUTC-SPEC.md` § 2, § 3.1, § 4, § 7 ; consignes de l'orchestrateur reçues en cours de fiche (A : préparer au
|
||
scratchpad puis remplacer en une écriture ; B : ajouts Big Boss ; contrôle `UnrealEditor-Cmd.exe` avant écriture).
|
||
Sorties brutes : `D:\Game\LifePlay-master 5.8\Docs\Migration\etat\OUTC\OUTC-T1_essais.txt` (636 lignes, LF).
|
||
Scratchpad des essais : `<scratchpad>\OUTC-T1\`
|
||
(versions de travail, scripts d'essai `essais-nr.ps1`, `essais-copie.ps1`, `essais-tools.ps1`, `installer.ps1`, `parse51.ps1`, copies factices, rien supprimé).
|
||
|
||
## 1. Fichiers modifiés
|
||
|
||
Copie `D:\Game\LifePlay-master 5.8`, branche `ue5.8`. Les trois fichiers sont en LF, sans BOM, ASCII seul
|
||
(`FileCheck.ps1` : `LF` ; `tr -cd '\r' | wc -c` = 0 ; octets > 0x7F = 0 ; Grep `[^\x00-\x7F]` : aucun) et passent
|
||
l'analyse syntaxique de Windows PowerShell 5.1.26100 (0 erreur, `parse51.ps1`).
|
||
|
||
| Fichier | MD5 | Lignes | Contenu |
|
||
|---|---|---|---|
|
||
| `A Tools\CopieEtat.ps1` | `4A83F321C9EBBA12FF0AB64DA85CD3D2` | 460 | neuf (SPEC § 3.1 + ajouts Big Boss) |
|
||
| `M Tools\UeState.ps1` | `736FBF158C0772BAB81E98E96604809F` (avant `A47107D5…`) | 167 | l. 14, 29-39, 44 (aide) ; 50-52 (`-Copie`, `-Json`) ; 63-81 (racine normalisée, `Test-LPCopie`) ; 85 (filtre dans `Get-LPUeProcess`) ; 118-133 (`Write-LPUeJson`) ; 136-140 (`-Json` sans attente) ; 153, 156-159, 161 (`-Json` avec `-WaitExit`) |
|
||
| `M Tools\FileCheck.ps1` | `1FD13C705EF5869F79E5165D039F3AAA` (avant `CA9CBA16…`) | 203 | l. 31-36, 41 (aide) ; 49-50 (`-Json`) ; 86, 90-93 (manifeste introuvable en JSON) ; 95, 97 (lignes `Lot`/`Projet` hors JSON) ; 101, 110-113 (introuvables collectés, sans `Write-Host`) ; 151, 163-164 (`Taille`, `Modifie`, calculés seulement avec `-Json`) ; 170-189 (bloc JSON) |
|
||
|
||
`git diff --stat` : 2 fichiers, 107 insertions, 8 suppressions ; les 8 lignes retirées sont réécrites à l'identique
|
||
sous une garde `if ($Json)` / `if (-not $Json)` (relu par `git diff -U0`). `git ls-files --eol` : `i/lf w/lf` pour les deux.
|
||
|
||
Interface de `CopieEtat.ps1` : celle de la SPEC § 3.1, plus `-BackupRoot`. Codes 0 / 1 / 2. Synthèse réelle :
|
||
`COPIE <OK|ALERTE> lot= copie= proc= assets= absents= modifies= git=j/a/m hors_declares= parasites= jeu_hors_docs= jeu_docs= head=j/a/m verrou=k:etat cpu=n% alertes=`.
|
||
JSON : `synthese, horodatage, duree_s, lot, copie, depots{jeu,addon,modules}, processus{copie[],autres[]}, assets[], git{jeu[],addon[],modules[],jeu_hors_docs[],jeu_docs[]}, parasites[], verrou{racine,k,etat,qui}, cpu, alertes[{type,detail}], code`.
|
||
|
||
## 2. Écarts à la SPEC
|
||
|
||
1. **Méthode d'écriture (consigne A de l'orchestrateur)** : versions préparées et testées au scratchpad (Write / Edit),
|
||
puis chaque fichier de `Tools\` remplacé en **une** écriture par `Copy-Item -Force` (`installer.ps1`). Aucune
|
||
édition en place : MD5 avant écriture = instantané (`A47107D5…`, `CA9CBA16…`). Contrôle `UnrealEditor-Cmd.exe`
|
||
juste avant chaque écriture : 0 processus à 06:51:31 (UeState) et 06:51:32 (FileCheck), aucune attente.
|
||
2. **Ajouts Big Boss (demande du 2026-10-11, information sans alerte sauf 7z)** : (B1) processus `7z.exe`, `7za.exe`,
|
||
`7zG.exe` par requête CIM dans CopieEtat (UeState inchangé par défaut), champ `Exe` et `Start`, alerte `PROC` si la
|
||
ligne de commande ou l'exécutable cite la copie, sinon `autres` ; (B2) `git status` de tout l'arbre du jeu,
|
||
`jeu_hors_docs` / `jeu_docs` ; (B3) `head=` des 3 dépôts (+ `branche` dans `depots`) ; (B4) dernier verrou
|
||
`REPO\VERROU` en lecture seule (k numérique, `libre` / `occupe` / `vide` / `absent`, `qui.txt` si occupé) ;
|
||
(B5) `cpu=` moyenne de `Win32_Processor.LoadPercentage`. Les champs s'insèrent avant `alertes=`.
|
||
3. **Git du jeu** : un seul `git status` sur tout l'arbre (B2) ; la liste soumise à l'alerte est filtrée par préfixe
|
||
sensible à la casse `^(Content|Config|Source)(/|$)` au lieu de `-- Content Config Source` (même ensemble, un
|
||
parcours de moins).
|
||
4. **Format porcelain** : `--porcelain=v1 -z` et `-c core.quotePath=false`, sortie lue en UTF-8 par
|
||
`Diagnostics.Process` (chemins avec espace ou non ASCII non cités ; stderr séparé). Toujours lecture seule.
|
||
5. **Règle P9 étendue** (UeState `-Copie` et CopieEtat) : segments `.` et `..` résolus avant la comparaison. Motif
|
||
établi : l'éditeur réel PID 7972 (`UnrealEditor.exe … "D:\Game\LifePlay-Sandbox-5.8\Tools\debug\..\..\..\LifePlay-master 5.8\LifePlay.uproject" … -game`,
|
||
lancé 06:44:21, pas par moi) était classé `autres` en passe 1 alors qu'il tourne sur la copie 5.8.
|
||
6. **UeState `-Json`** : objet `{ copie, compte, processus[] }` (+ `attente` avec `-WaitExit`), car un tableau JSON
|
||
ne peut pas porter de champ `compte` ; `Start` en texte ISO `yyyy-MM-ddTHH:mm:ss`. Avec `-WaitExit -Json`, aucune
|
||
ligne d'attente, un seul JSON à la fin ; codes inchangés (0 / 1 / 2).
|
||
7. **FileCheck `-Json`** : objet `{ projet, lot, manifeste, lignes[], introuvables[], comptes{fichiers,fins,alertes,introuvables,contenu}, synthese, code }` ;
|
||
manifeste introuvable : `{ projet, lot, erreur, code = 2 }`. `Modifie` = `LastWriteTime` local au format ISO sans fuseau.
|
||
8. **`instantane`** : vocabulaire de FileCheck, donc aussi `nouveau`, `absent`, `absent (prevu)` en plus de
|
||
identique / modifie / pas sauvegarde.
|
||
9. **`modifies=`** compte tout MD5 différent de la référence, autorisé ou non ; l'alerte `ASSET_MODIFIE` seule
|
||
respecte `-Autorise` (essai `V5-md5-falsifie-Autorise` : `modifies=1 alertes=aucune`). Champ `reference` par asset.
|
||
10. **Listes sous `pwsh -File`** : `pwsh -File` passe `a,b` en une chaîne (découpée par le script) et `a, b` en deux
|
||
jetons. `[CmdletBinding(PositionalBinding = $false)]` + `-Reste` (ValueFromRemainingArguments) : sans eux, le 2e
|
||
élément de `-Assets a, b` était lié **en silence** à `-Autorise` (passe 1 : `assets=1`). Les jetons restants
|
||
rejoignent la seule liste terminée par une virgule, sinon code 2.
|
||
11. **Erreurs (code 2)** : ligne `COPIE ERREUR lot=<LOT> : <motif>` ; en `-Json`, `{ synthese, horodatage, lot, copie, erreur, code }` ;
|
||
`-Sortie` n'est pas écrit en code 2 et exige un dossier existant (aucun dossier créé). Racine du jeu et de l'addon
|
||
vérifiées comme racines git (`rev-parse --show-toplevel`), sinon code 2 (git remonterait au dépôt parent).
|
||
12. **`-Autorise`** : chemin relatif au dépôt, à la copie (`Content/Modules/…` pour Modules) ou absolu ; `*` et `?` acceptés.
|
||
13. **Contexte de la fiche** : HEAD réel `ae5d5e4` (fiche : `06dfb55`), sans effet (MD5 de départ = instantané) ;
|
||
assets `Content\LifePlay\GI.uasset` inexistants, remplacés par `Content\BPs\GI.uasset` et `Content\BPs\GM.uasset` (Glob).
|
||
14. **Essais PROC** : copies de `cmd.exe` renommées `LifePlayFauxOUTC.exe` et `7z.exe` dans le scratchpad, lancées
|
||
deux fois environ 30 s (06:46:49-06:47:24, 06:50:00-06:50:33, arrêt seul, `restants=0`). Elles apparaissaient
|
||
comme famille `Jeu` dans un UeState complet d'une autre session pendant ces fenêtres. Ce n'est pas le jeu.
|
||
15. **Skill lp-validate** non invoqué : fins de ligne contrôlées par `FileCheck.ps1` et comptage d'octets (`tr`), selon
|
||
la mémoire `eol-check-etat-lf`.
|
||
|
||
## 3. Instantané
|
||
|
||
`D:\Game\LifePlay_Backup_5.5\OUTC\manifest.csv` (pris par l'orchestrateur à 06:26:32) : `Tools\CopieEtat.ps1`
|
||
Existed=False ; `Tools\UeState.ps1` `A47107D53ED98A6914598BAA19567887` ; `Tools\FileCheck.ps1`
|
||
`CA9CBA1654A5762B4D3A189647A282CA` ; copies dans `D:\Game\LifePlay_Backup_5.5\OUTC\Tools\`. Repli proposé, non lancé :
|
||
`Tools\Restore.ps1 -Lot OUTC`.
|
||
|
||
## 4. Ce qui n'a pas été fait
|
||
|
||
- Code 0 de V3/V4 sur la **copie réelle** après le correctif P9 : l'éditeur PID 7972 de la copie 5.8 tournait
|
||
pendant tous les essais (alerte `PROC` à juste titre). Code 0 prouvé sur `copie-propre` (dépôts jetables) et sur la
|
||
copie réelle en passe 1 (06:46, `V4-reel-Reference` code 0) avant le correctif, journal de la passe 1 écrasé
|
||
par la passe 2 (seule la sortie de la commande l'atteste).
|
||
- Non essayés : `-WaitExit -Json` expiré (code 2) ; entrées git renommées (`R`) ; chemins non ASCII ; CopieEtat sur
|
||
la copie 5.5 (seul `UeState -Copie 'D:/Game/LifePlay-master 5.5/'` essayé : 0 processus) ; verrou `vide`.
|
||
- Erreur de liaison de pwsh lui-même (paramètre inconnu `-Foo`) : code 1 de pwsh, pas 2 (limite, non contournée).
|
||
- `pwsh -Command "& '<script>' …"` rend 0/1 (statut de la commande), pas le code du script : ajouter
|
||
`; exit $LASTEXITCODE` (constaté sur `FileCheck-Json-Absent` : processus 1, JSON `code=2` ; même règle pour l'ancienne version).
|
||
- Aucun commit, aucune entrée CHG, aucune modification de skill ni d'agent.
|
||
|
||
## 5. Points à confirmer en VAL
|
||
|
||
- V1 : `git ls-files --eol` et `FileCheck.ps1` sur les 3 fichiers : LF, pas de BOM, aucun octet > 0x7F dans `CopieEtat.ps1`.
|
||
- V2 : sortie octet pour octet et code identiques à `D:\Game\LifePlay_Backup_5.5\OUTC\Tools` pour UeState (sans paramètre, `-Brief`, `-Kind Editeur -Brief`, avec et sans processus) et FileCheck (liste, `-Lot OUTC`, `-OnlyChanged`, introuvable, manifeste absent, dossier) : 10/10 IDENTIQUE avant et après installation.
|
||
- V3/V4 sur la copie réelle, éditeur 5.8 fermé : code 0, `modifies=0` avec `-Reference` (et `-Autorise` des 3 entrées addon en cours si elles sont encore là).
|
||
- V5 : codes 1 et type d'alerte : `ASSET_ABSENT`, `ASSET_MODIFIE` (référence falsifiée), `GIT` (copie factice et état réel non déclaré), `PARASITE` (3 dossiers factices, `publication\PUB2\neutral\Docs` non compté), `PROC` (faux processus, éditeur réel).
|
||
- V6 : code 2 pour `-Copie` inexistante et `-Reference` introuvable (texte et `-Json`), plus copie hors table sans `-Addon`, copie non dépôt, `-Lot` absent, Modules introuvable.
|
||
- Durée < 30 s sur la copie 5.8 : 4,5 s mesurés (`duree_s` interne 3,9 s).
|
||
- Filtre P9 : `5.8b` exclu, `/` accepté, `..` résolu (PID 7972), `-WaitExit -Copie` attend les seuls processus de la copie (18 s, le faux `5.8b` ignoré).
|
||
- Ajouts Big Boss B1-B5 présents dans la synthèse et le JSON (`7z` en `copie` et en `autres`, `jeu_hors_docs`, `jeu_docs`, `head=`, `verrou=93:libre` et `10:occupe` factice, `cpu=`).
|
||
- Relecture des 3 diffs en entier (V11) : aucune commande git d'écriture, aucun `Remove-Item`.
|
||
|
||
## 6. Fichiers à commiter
|
||
|
||
Dépôt jeu, copie `D:\Game\LifePlay-master 5.8`, branche `ue5.8` :
|
||
A Tools/CopieEtat.ps1
|
||
M Tools/UeState.ps1
|
||
M Tools/FileCheck.ps1
|
||
A Docs/Migration/etat/OUTC/OUTC-T1-IMPL.md
|
||
(`Docs/Migration/etat/OUTC/OUTC-T1_essais.txt` : `.txt` sous `etat\`, ignoré par git, non commité.)
|
||
|
||
## 7. Table des essais (rubrique 7 de la fiche)
|
||
|
||
Toutes les commandes sont lancées par `pwsh -NoProfile -File`, dossier courant = copie 5.8. Durées mesurées par
|
||
`Stopwatch` autour du processus (lancement de pwsh compris). `<S>` = scratchpad, `<P>` = copie 5.8.
|
||
|
||
| Essai | Commande (abrégée) | Code | Durée | Ligne de synthèse / résultat |
|
||
|---|---|---|---|---|
|
||
| NR ×10 (scratch, puis Tools) | ancienne vs neuve, voir § 5 V2 | = | 0,5-1,3 s | 10/10 IDENTIQUE (MD5 stdout + stderr + code), deux fois |
|
||
| NR avec processus | `UeState.ps1` pendant les faux processus | 1 / 1 | 1,2 s | IDENTIQUE |
|
||
| UeState-Copie58-Json | `UeState.ps1 -Copie <P> -Json` (faux processus) | 1 | 1,2 s | JSON valide ; `processus=2 editeur=1 … jeu=1` ; PID 7972, 25260 (pas 35976 `5.8b`) |
|
||
| UeState-WaitExit-Copie-Json | `-Copie <P> -Kind Jeu -WaitExit -TimeoutSeconds 90 -Json` | 0 | 18,1 s | JSON seul, `"attente": "terminee apres 17 s"` (`OUTC-T1_essais.txt` l. 410) |
|
||
| FileCheck-Json ×4 | `-Json` liste / `-Lot OUTC` / introuvable / manifeste absent | 0 / 0 / 2 / 2 | 0,6-1 s | JSON valide, `Taille`, `Modifie` ; introuvables listés ; `erreur` (code 2 via `-File`) |
|
||
| V3-reel-Sortie | `CopieEtat.ps1 -Lot OUTC -Copie <P> -Assets GI,GM -Sortie <S>\ref.json` | 1 | 4,5 s | `COPIE ALERTE … proc=1 assets=2 absents=0 modifies=0 git=1/3/0 hors_declares=3 parasites=0 jeu_hors_docs=5 jeu_docs=95 head=ae5d5e4/3f94b5e/c8661cd verrou=93:libre … alertes=PROC,GIT` ; `ref.json` valide, LF, sans BOM, ASCII |
|
||
| Contrôle MD5 | `FileCheck.ps1 GI, GM` | 0 | — | `FE4406A0…` / `DAC10494…` = MD5 de CopieEtat |
|
||
| V3-reel-Autorise | + `-Autorise` des 3 fichiers addon en cours | 1 | 4,6 s | `hors_declares=0 … alertes=PROC` (éditeur 7972) |
|
||
| V4-reel-Reference (+ `-Json`) | `-Reference <S>\ref.json` | 1 | 4,7 s | `modifies=0 hors_declares=0 alertes=PROC` ; passe 1 (avant § 2.5) : code 0 `COPIE OK` |
|
||
| Code0-copie-propre | `-Copie <S>\copie-propre -Addon … -ModulesGitDir … -Assets Content\BPs\A.uasset -Sortie` | 0 | 4,1 s | `COPIE OK … git=1/0/0 hors_declares=0 parasites=0 … verrou=-:absent alertes=aucune` |
|
||
| Code0-copie-propre-Reference | + `-Reference <S>\propre.json -Json` | 0 | 4,1 s | JSON valide, `code=0` |
|
||
| V5-asset-absent | `-Assets GI,Content\BPs\Absent_OUTC.uasset` | 1 | 4,5 s | `absents=1 … alertes=PROC,ASSET_ABSENT` |
|
||
| V5-md5-falsifie | `-Reference <S>\ref-falsifie.json` | 1 | 4,7 s | `modifies=1 … alertes=PROC,ASSET_MODIFIE` (md5 0…0 → FE4406A0…) |
|
||
| V5-md5-falsifie-Autorise | + `-Autorise Content/BPs/GI.uasset` | 1 | 4,5 s | `modifies=1 … alertes=PROC` (plus d'`ASSET_MODIFIE`) |
|
||
| V5-reel-non-declare | sans `-Assets` | 1 | 4,4 s | `hors_declares=4 … alertes=PROC,GIT` (GI.uasset + 3 addon) |
|
||
| Usage-liste-espace | `-Assets GI, GM` (deux jetons) | 1 | 4,5 s | `assets=2` (passe 1 sans `PositionalBinding=$false` : `assets=1`) |
|
||
| V5-factice | `-Copie <S>\copie-factice -Addon … -ModulesGitDir … -Assets Content\BPs\A.uasset -Sortie` | 1 | 4,3 s | `git=3/0/1 hors_declares=3 parasites=3 … verrou=10:occupe alertes=GIT,PARASITE` ; parasites `X\etat`, `Y\Docs`, `Z\Migration` ; `publication\PUB2\neutral\Docs` non compté |
|
||
| V5-factice-Autorise-Json | + `-Autorise Content/x-non-declare.txt,Content/Modules/M1/* -Json` | 1 | 4,2 s | JSON valide ; `hors_declares=0 … alertes=PARASITE` |
|
||
| PROC-reel-faux | V4 pendant les faux processus | 1 | 5 s | `proc=3` : éditeur 7972, faux `Jeu` 25260, 7z 28036 (`/`) ; `autres` : 35976 (`5.8b`), 7z 35860 (5.5) |
|
||
| V6-copie-inexistante | `-Copie <S>\copie-inexistante` | 2 | 0,6 s | `COPIE ERREUR lot=OUTC : copie introuvable : …` |
|
||
| V6-reference-introuvable (+ `-Json`) | `-Reference <S>\ref-inexistante.json` | 2 / 2 | 0,6 s | `COPIE ERREUR … reference introuvable` ; JSON `code=2` |
|
||
| Code2 ×4 | hors table sans `-Addon` ; copie non dépôt ; sans `-Lot` ; Modules introuvable | 2 ×4 | 0,5-0,8 s | motif précis à chaque fois |
|
||
| T-V3 / T-V4 / T-V4-Json (Tools, copie par défaut) | `Tools\CopieEtat.ps1 -Lot OUTC -Assets GI,GM …` | 1 / 1 / 1 | 4,5 s | `hors_declares=0 modifies=0 alertes=PROC` (éditeur 7972) ; `duree_s=3.9` |
|
||
|
||
Tours : 31 / 75 (60 de la fiche + 15 accordés par l'orchestrateur pour les ajouts B)
|
||
|
||
## Constats
|
||
|
||
- L'éditeur PID 7972 (mode `-game`, lancé depuis `D:\Game\LifePlay-Sandbox-5.8\Tools\debug\` avec un chemin relatif
|
||
vers `LifePlay-master 5.8\LifePlay.uproject`) est un cas réel du piège P9 : la colonne `Copy` d'UeState (inchangée)
|
||
affiche `LifePlay-Sandbox-5.8` pour un processus de la copie 5.8. Seuls `-Copie` et CopieEtat le rattachent à la bonne copie.
|
||
- Piège à reporter dans `sk-windows-shell` (lot DOC) : `pwsh -File` lie en position un jeton orphelin d'une liste
|
||
`a, b` au paramètre suivant **sans erreur** ; parade : `[CmdletBinding(PositionalBinding = $false)]`.
|
||
- `git status --porcelain -- Tools` montre aussi `M Tools/EtatDir.ps1` et `?? Tools/GitEtat.ps1`, `Numero.ps1`,
|
||
`Verrou.ps1` : pas de mon fait (autres fiches OUTC ; `EtatDir.ps1` modifié à 06:32:38, avant mon installation de 06:51).
|
||
- `ConvertFrom-Json` (pwsh 7) transforme les dates ISO en `DateTime` : un consommateur de ces JSON qui réécrit le
|
||
JSON doit les reformater (fait dans CopieEtat, `Format-LPDate`).
|