LifePlay-Revival/Docs/Migration/etat/OUTC/OUTC-T2-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

19 KiB
Raw Blame History

Fiche OUTC-T2 — Niveau N1 — Modèle prévu sonnet | utilisé claude-sonnet-5-5 — Agent lp-impl — Skills sk-protocol (préchargé), sk-windows-shell (invoqué), sk-repo § 2 et § 6 et lp-repo § 7 (lus par Read), ue-cpp-build / lp-build / lp-ue-compat (préchargés, sans objet)

OUTC-T2-IMPL : Tools\Verrou.ps1 et Tools\Numero.ps1 (2026-10-11)

Résultat : réussi, avec un écart de moyen à décider (§ 2 E1 : création du dossier de verrou par CreateDirectoryW et non par New-Item, parce que New-Item sans -Force n'est pas atomique, mesure à l'appui). Essais : 124 appels et contrôles, 0 écart (SYNTHESE de OUTC-T2_essais.txt l. 417) ; vrai VERROU lu en -Etat seulement ; vrai NUMEROS.md jamais écrit.

1. Fichiers modifiés (chemins, lignes)

Dépôt du jeu D:\Game\LifePlay-master 5.8, branche ue5.8, HEAD ae5d5e4 (la fiche citait 06dfb55 : le HEAD a avancé, sans effet sur ces fichiers). Les deux sont neufs, LF, sans BOM, ASCII seul (FileCheck.ps1 : LF, CRLF=0, BOM -, alertes 0 ; octets > 0x7F = 0 ; analyse syntaxique pwsh : 0 erreur).

Fichier Lignes Taille MD5 Contenu
Tools\Verrou.ps1 228 11 010 o 788B21F30155200A497C3919FB3CBA29 en-tête d'aide l. 1-58 ; param l. 59 ; New-DossierAtomique l. 75 ; Get-VerrouK l. 86 ; Get-Qui l. 99 ; Fin l. 123 ; New-LignesOccupe l. 130 ; -Prendre l. 157 ; -Rendre l. 190 ; -Etat l. 216 ; catch général (code 2) l. 225
Tools\Numero.ps1 291 13 849 o 8803E6A42DAD21292DFE3024732BF589 en-tête d'aide ; param l. 63 ; Get-MaxFichier l. 85 ; Get-MaxDocs l. 100 ; Get-MaxRegistre l. 116 ; Get-Maxima l. 134 ; usage l. 168 ; -Dernier l. 178 ; -Reserver l. 194 ; try l. 220 ; catch l. 270 ; finally (rend le verrou) l. 273

Comportement livré (conforme à OUTC-SPEC.md § 3.2 et § 3.3 sauf § 2) :

  • Verrou.ps1 -Prendre <ticket> [-Session] | -Rendre [-Ticket] | -Etat, -Racine (défaut <projet>\Docs\Migration\etat\REPO\VERROU), -Json. Codes 0 / 1 / 2 comme la SPEC. Rien n'est supprimé ni renommé, aucun paramètre de forçage ; au-delà de 30 min, suffixe ANCIEN (signaler, ne pas forcer).
  • Numero.ps1 -Reserver CHG|ERR|DOC -Lot -Demandeur [-Nombre] [-Copie55] [-Fichier] [-Racine] [-Json] et -Dernier CHG|ERR|DOC. Écriture par ajout d'octets (FileStream en Append), séparateur détecté, contrôle du préfixe (MD5 des n octets d'avant), de la longueur et de la fin ; verrou rendu dans un finally.

2. Écarts à la SPEC (obligatoire)

  • E1 (à décider) — moyen de création du dossier de verrou. SPEC § 3.2 point 2 et fiche § 5 prescrivent New-Item -ItemType Directory sans -Force, « échoue si le dossier existe ». Vrai en séquentiel, faux en concurrence : essai en 100 tours de 8 threads alignés sur une Threading.Barrier, tous appelant New-Item -ItemType Directory -Path <même chemin> -ErrorAction Stop (pwsh 7.6.6) : exactement 1 succès dans 12 tours, plusieurs succès dans 88 tours, 0 tour sans succès (sortie de la commande, tour 9 de cette fiche ; commande rappelée ci-dessous). Même essai avec CreateDirectoryW de kernel32 (P/Invoke par Add-Type) : 1 succès dans 100 tours sur 100 ; second appel séquentiel : False, GetLastWin32Error = 183 (ERROR_ALREADY_EXISTS) (scratchpad\OUTC-T2\stress2.ps1, sortie dans ce compte rendu). Avec New-Item, deux gardiens pourraient donc se croire titulaires du même k+1, ce que le verrou doit empêcher. Choix fait : New-DossierAtomique (Verrou.ps1 l. 75-84) appelle CreateDirectoryW ; 183 = occupé (code 1), autre erreur = code 2. Effet de bord : Add-Type coûte ≈ 640 ms au premier appel de chaque processus. Retour à la lettre de la SPEC : remplacer le corps de cette seule fonction par try { New-Item -ItemType Directory -Path $Path -ErrorAction Stop | Out-Null; $true } catch { if (Test-Path -LiteralPath $Path) { $false } else { throw } } ; je ne le recommande pas. Preuve en processus séparés (A17) : 5 tours de 6 processus Verrou.ps1 -Prendre lancés ensemble : à chaque tour un seul code 0, cinq codes 1, qui.txt du dossier = celui du gagnant (l. 184-204 de OUTC-T2_essais.txt). Commande de l'essai New-Item (non rangée en fichier, rejouable) : pwsh -NoProfile -Command avec foreach ($r in 1..100) { $p = Join-Path $base "r$r"; $bar = [Threading.Barrier]::new(8); $res = 1..8 | ForEach-Object -Parallel { $b = $using:bar; $path = $using:p; $b.SignalAndWait(); try { New-Item -ItemType Directory -Path $path -ErrorAction Stop | Out-Null; 1 } catch { 0 } } -ThrottleLimit 8; ... somme des 1 par tour }.
  • E2 — course simulée : paramètre caché -TestCourse ([Parameter(DontShow)], décrit dans l'aide) : juste avant la création, crée le dossier cible comme le ferait un tiers (avec qui.txt TIERS-TEST pour -Prendre). Prévu par la fiche (« paramètre caché de test, à décrire »).
  • E3 — affichage d'un verrou occupé : première ligne qui.txt (k=<k>) : <contenu brut>, dernière ligne VERROU OCCUPE k=<k> par <qui> depuis <min> min, où <qui> = qui.txt sans la date finale. -Etat n'imprime que la ligne de verdict. La SPEC dit « affiche <k>\qui.txt » sans préciser le format. Refus de -Rendre -Ticket : VERROU REFUS k=<k> : tenu par <qui>, pas par <ticket> (libellé non fixé par la SPEC).
  • E4 — -Rendre -Ticket T : correspondance = qui.txt commence par T suivi d'un caractère autre que lettre, chiffre, _ ou - (ou fin de ligne), insensible à la casse ; la SPEC dit « commence par ce ticket », ce qui ferait rendre le verrou de OUTC-R10 à OUTC-R1 (essais A11b, A11c).
  • E5 — points laissés ouverts par la SPEC, tranchés : sans -Session, qui.txt porte session non precisee ; -Ticket sans -Rendre et -Session sans -Prendre = paramètres incohérents, code 2 ; racine vide = k 0, libre ; -Rendre sans -Ticket rend le verrou tenu, quel qu'en soit le titulaire (SPEC § 3.2 point 3 ne demande le contrôle qu'avec -Ticket).
  • E6 — -Json accepté par les trois actions de Verrou.ps1 (la SPEC ne le cite que pour -Etat) : Numero.ps1 en a besoin pour lire k et le code.
  • E7 — Numero.ps1, format : date AAAA-MM-JJ HH:MM (heure locale ; la SPEC montre AAAA-MM-JJ, la fiche § 5 prescrit Get-Date -Format 'yyyy-MM-dd HH:mm', comme les lignes existantes) ; plusieurs numéros : NUMERO RESERVE CHG-330 CHG-331 lot=TEST verrou=5 ; JSON : type, numeros[] (entiers), ids[] (CHG-330), lot, demandeur, verrou, fichier, date, maxima{copie58, copie55, registre, max}, avertissements[] (la SPEC liste {type, numeros[], lot, verrou, maxima{}}, ces ajouts sont rétrocompatibles) ; -Dernier : DERNIER CHG max=327 5.8=326 5.5=297 registre=327.
  • E8 — cas non couverts par la SPEC : source 5.8 absente ou sans numéro = code 2 (jamais « max = 0 ») ; copie 5.5 absente = avertissement et 5.5=absent dans la ligne ; -Nombre hors 1..50 = code 2 ; | du lot ou du demandeur remplacé par /, sauts de ligne par un blanc ; session du verrou = demandeur tronqué à 80 caractères, ticket NUMERO-<LOT> ; fichier vide ou sans aucun saut de ligne = code 2 après la prise du verrou (le verrou est rendu : essais B6a, B6b) ; fichier à fins de ligne mixtes = avertissement, séparateur du dernier saut de ligne retenu ; verrou non rendu après une réservation réussie = ligne VERROU NON RENDU et code 2.
  • E9 — le livrable OUTC-T2_essais.txt demandé par la fiche est ignoré par git (.gitignore:75 /Docs/Migration/etat/**, seuls .md et .csv sont repris, l. 77) : il reste sur disque, hors « Fichiers à commiter ».

3. Instantané (lot, manifeste)

Lot OUTC : D:\Game\LifePlay-master 5.8 instantané D:\Game\LifePlay_Backup_5.5\OUTC\manifest.csv (2026-10-11 06:26) ; les deux fichiers y sont Existed=False, Size=0 (lu l. 3-4 du manifeste) : rien à restaurer, le repli est « ne pas commiter / retirer les deux fichiers neufs » (Tools\Restore.ps1 -Lot OUTC, proposé, non lancé).

4. Ce qui n'a pas été fait

  • Aucun essai en écriture sur le vrai VERROU ni sur le vrai NUMEROS.md (interdit). Le vrai verrou n'a été lu que par Verrou.ps1 -Etat (A18, série officielle : VERROU LIBRE k=93, 186 dossiers, liste identique avant / après l'appel) et par Get-ChildItem. Le vrai NUMEROS.md n'a été lu que par Numero.ps1 -Dernier (B1r) et Get-FileHash ; MD5 CD7800199276A0AB4F2019D4044816DF au début, à la copie et à la fin de la série.
  • Pas d'essai de concurrence entre processus pour Numero.ps1 (fait pour Verrou.ps1, A17) : l'exclusion repose sur Verrou.ps1.
  • Windows PowerShell 5.1 : 6 commandes seulement (§ D du fichier d'essais : Verrou -Etat, -Prendre, occupé, -Rendre -Ticket ; Numero -Dernier, -Reserver), codes attendus, puis FileCheck de la copie sous pwsh 7 ; pas la série complète.
  • Pas d'essai d'erreur de droits d'écriture ni de fichier verrouillé par un autre processus.
  • Pas de mise à jour de sk-repo § 2 ni de lp-repo § 7 (qui décrivent encore mkdir et la lecture manuelle) : lot DOC séparé (SPEC § 5, décision E5).
  • Aucun autre fichier de Tools\ touché ; pas de commit, pas de git en écriture, aucune suppression.

5. Points à confirmer en VAL

  • E1 : l'orchestrateur confirme CreateDirectoryW (recommandé) ou demande le retour à New-Item ; la VAL peut rejouer scratchpad\OUTC-T2\stress2.ps1 -Base <dossier neuf> (attendu : exactement 1 succes=100).
  • V7 rejoué : Prendre (0), Prendre encore (1), Etat (1), Rendre -Ticket autre (1), Rendre (0), Rendre encore (1), Etat (0) = essais A2 à A8 (essais.ps1 du scratchpad, -Base neuf obligatoire : le script refuse une base où VERROU existe).
  • V7 course : -TestCourse rend 1 pour -Prendre et pour -Rendre, le qui.txt du tiers n'est pas écrasé (A12, A13).
  • V8 rejoué : Numero.ps1 -Reserver CHG -Lot TEST -Fichier <copie> -Racine <test> deux fois puis -Nombre 2 : numéros consécutifs 328, 329, 330-331 ; préfixe de 12 601 octets de MD5 identique ; FileCheck : CRLF, LF=0, CR=0 (B2, B4) ; verrou occupé = code 1, MD5 entier inchangé (B5).
  • Le format de la ligne ajoutée (statut réservé avec accents UTF-8 ; date avec heure) convient au gardien et à lp-repo § 7.
  • -Rendre sans -Ticket (E5) : acceptable pour le gardien, ou exiger -Ticket.
  • Coût de ≈ 640 ms d'Add-Type par appel de Verrou.ps1 acceptable (≈ 1 085 appels de verrou en 72 h d'après la SPEC).
  • À la DOC (T5), Numero.ps1 -Reserver CHG réel sans -Fichier ni -Racine : le défaut est le vrai NUMEROS.md et le vrai VERROU ; à ce jour (06:44) le registre réel donne max=327 (CHG-326 et CHG-327 posés par d'autres sessions depuis la rédaction de la fiche).

6. Fichiers à commiter

Dépôt du jeu D:\Game\LifePlay-master 5.8, branche ue5.8 :

  • A Tools/Verrou.ps1
  • A Tools/Numero.ps1
  • A Docs/Migration/etat/OUTC/OUTC-T2-IMPL.md

Non commités : Docs/Migration/etat/OUTC/OUTC-T2_essais.txt (ignoré, .gitignore:75) ; scratchpad <scratchpad>\OUTC-T2\ (essais.ps1, stress2.ps1, racines et copies de test VERROU*, NUMEROS-test.md, NUM-*.md, essais de mise au point dev1, dev2, stress, stress2, sorties dev1.txt, dev2.txt ; rien supprimé). essais.ps1 est réutilisable par la VAL : à ranger dans Saved\OUTC\ ou à copier, selon sk-protocol § 7.

Table des essais (commande → code → sortie)

Sorties brutes complètes : D:\Game\LifePlay-master 5.8\Docs\Migration\etat\OUTC\OUTC-T2_essais.txt (76 appels >>> / <<<, dont 7 de la section D lancés à la main hors du script, + 55 contrôles CHECK, tous OK ; les 124 de SYNTHESE = 69 appels comptés par le script + 55 contrôles). Racine de test …\scratchpad\OUTC-T2\VERROU (départ 1 1-libre 2 2-libre, k = 2). Toutes les commandes sont pwsh -NoProfile -File <script> ….

Id Commande (abrégée) Code Sortie / dossiers
A1 Verrou -Etat 0 VERROU LIBRE k=2
A2 Verrou -Prendre OUTC-T2-A -Session "essai Verrou" 0 VERROU PRIS k=3 ticket=OUTC-T2-A ; dossier 3, qui.txt = OUTC-T2-A, session essai Verrou, 2026-10-11 06:44, LF seul
A3 Verrou -Prendre OUTC-T2-B 1 VERROU OCCUPE k=3 par OUTC-T2-A, session essai Verrou depuis 0 min ; qui.txt inchangé
A4 Verrou -Etat 1 VERROU OCCUPE k=3 par …
A5 Verrou -Rendre -Ticket AUTRE-TICKET 1 VERROU REFUS k=3 : tenu par OUTC-T2-A, … ; pas de 3-libre
A6 Verrou -Rendre -Ticket OUTC-T2-A 0 VERROU RENDU k=3 ; 3-libre créé
A7 Verrou -Rendre 1 VERROU DEJA LIBRE k=3
A8 Verrou -Etat 0 VERROU LIBRE k=3 ; dossiers 1 1-libre 2 2-libre 3 3-libre
A9-A11 sans -Session ; -Etat -Json ; -Prendre OUTC-R10 puis -Rendre -Ticket OUTC-R1 (1) puis -Ticket outc-r10 (0) ; -Prendre -Json (0 puis 1) 0 / 1 session non precisee ; JSON valide (etat, k, code) ; R1 ne rend pas R10
A12 Verrou -Prendre OUTC-T2-X -TestCourse 1 qui.txt (k=7) : TIERS-TEST, session essai de course … ; dossier 7 créé par le « tiers », son qui.txt non écrasé, aucun qui.txt OUTC-T2-X ; -Etat 1 ; -Rendre -Ticket TIERS-TEST 0
A13 Verrou -Rendre -TestCourse (tiers crée 8-libre avant nous) 1 VERROU DEJA LIBRE k=8 ; -Etat 0
A14 aucune action ; deux actions ; -Ticket avec -Etat ; -Session avec -Etat ; racine introuvable ; -Prendre "" 2 (×6) messages Verrou.ps1 : … ; dossiers inchangés
A15 racine avec 2 daté de 45 min : -Etat ; -Prendre 1 / 1 … depuis 45 min ANCIEN (signaler, ne pas forcer) ; rien forcé
A16 9 9-libre 10 : -Etat ; 10 10-libre 9 9-libre : -Etat ; racine vide : -Etat, -Rendre, -Prendre 1 / 0 / 0 / 1 / 0 k=10 (tri numérique) ; k=0 ; PRIS k=1
A17 5 tours × 6 processus Verrou -Prendre P<t>-<i> lancés ensemble 0 ×1 + 1 ×5 par tour gagnants P1-2, P2-2, P3-1, P4-1, P5-1 ; qui.txt = celui du gagnant ; -Rendre -Ticket <gagnant> 0 à chaque tour
A18 Verrou -Etat (vrai VERROU, sans -Racine) 0 VERROU LIBRE k=93 ; 186 dossiers avant et après l'appel, listes identiques
B1 `Numero -Dernier CHG ERR DOC -Fichier ;-Json; vrai fichier par défaut ; plage150 à 190`
B2a Numero -Reserver CHG -Lot TEST -Demandeur essai -Fichier <copie> -Racine <VERROU-NUM> 0 NUMERO RESERVE CHG-328 lot=TEST verrou=3
B2b idem 0 NUMERO RESERVE CHG-329 lot=TEST verrou=4
B2c idem -Nombre 2 0 NUMERO RESERVE CHG-330 CHG-331 lot=TEST verrou=5 ; dossiers 1 1-libre … 5 5-libre
B3 -Reserver ERR ; DOC ; CHG -Json (demandeur avec ` ) ; CHG -Copie55 ;DOC` avec accents 0 ×5
B4 contrôles sur la copie après 8 appels — préfixe : 12 601 octets, MD5 avant = après CD7800199276A0AB4F2019D4044816DF ; longueur 12 601 → 13 664 ; 9 lignes ajoutées, toutes au format SPEC, CRLF, 0 LF seul, pas de BOM ; FileCheck : CRLF, LF=0, CR=0, alertes 0
B5 -Reserver CHG avec verrou 2 occupé par un tiers 1 NUMERO REFUSE : verrou occupe (…) ; rien n'a ete ecrit ; MD5 entier de la copie et liste du verrou inchangés
B6 fichier sans saut de ligne ; fichier vide ; fichier introuvable 2 ×3 erreur nommée ; verrou pris puis rendu (2-libre, 3-libre) pour les deux premiers ; aucun verrou pris pour le troisième ; fichiers non modifiés
B7 fichier LF sans saut final ; fichier CRLF sans saut final 0 ×2 CHG-327 ; LF conservé (LF seul 6, CRLF 0) ; CRLF conservé (CRLF 6, LF seul 0) ; préfixe identique
B8 pas de type ; deux types ; type inconnu ; -Lot ou -Demandeur manquant ; -Nombre 0 ; racine de verrou introuvable 2 ×7 messages d'usage ; aucun verrou pris ; copie inchangée
C vrai NUMEROS.md / vrai VERROU après la série — MD5 réel inchangé CD78… ; aucune ligne TEST dans le vrai fichier ; 1 dossier apparu dans le vrai VERROU (93-libre, autre session), aucun ticket des essais
D powershell.exe 5.1.26100.9549 : Verrou -Etat ; -Prendre PS51-A ; -Prendre PS51-B ; -Rendre -Ticket PS51-A ; Numero -Dernier CHG ; -Reserver CHG -Lot TEST51 ; puis FileCheck (pwsh 7) 0 / 0 / 1 / 0 / 0 / 0 / 0 PRIS k=2 ; OCCUPE k=2 ; RENDU k=2 ; DERNIER CHG max=333 … ; NUMERO RESERVE CHG-334 lot=TEST51 verrou=3 ; copie CRLF, LF=0, alertes 0

Commande rejouable de la série complète : pwsh -NoProfile -File "…\scratchpad\OUTC-T2\essais.ps1" -Base <dossier neuf> (garde interne : tout appel qui écrit exige -Racine et -Fichier sous -Base).

Tours : 26 / 40 (compte propre, à confirmer par python -I Tools/FicheStats.py --lot OUTC ; la fiche demande 40, le plafond de l'agent est 75)

Constats

  1. New-Item n'est pas atomique (E1) : l'hypothèse de sk-repo § 2 / de la SPEC (« mkdir échoue si le dossier existe, opération atomique ») est vraie pour cmd mkdir et CreateDirectoryW, pas pour New-Item de PowerShell. Un gardien qui poserait le verrou à la main par New-Item (et non par mkdir de cmd ou par Verrou.ps1) hériterait du même défaut ; à noter pour le lot DOC qui réécrira sk-repo § 2.
  2. Le vrai NUMEROS.md a changé pendant l'IMPL (11 885 octets à ma première lecture, avec CHG-326 ; 12 601 octets à 06:41, avec CHG-327 ; réservations d'autres sessions) : une copie de test doit être faite et hachée au même instant ; B0 compare la copie au vrai fichier avant et après la copie.
  3. Dossier vide D:\Game\LifePlay-master 5.8\Docs\Migration\etat\REPO\3-libre (créé le 2026-10-10 10:46, hors de VERROU\) : vraisemblablement un mkdir 3-libre fait au mauvais endroit ; sans effet sur les scripts (hors racine), non touché.
  4. git status montre aussi M Tools/EtatDir.ps1 et ?? Tools/GitEtat.ps1 (OUTC-T3) : pas de moi, non touchés.
  5. UeState.ps1 / FileCheck.ps1 : FileCheck.ps1 accepte plusieurs fichiers par pwsh -Command "& 'Tools\FileCheck.ps1' a, b" mais pas par pwsh -File … a b (« paramètre positionnel », piège connu de lp-build § 8) ; la commande de la fiche (-File … <copie>, un seul fichier) fonctionne.
  6. Fixes de mise au point faits sur mes propres essais (pas sur les scripts livrés) : Measure-Object -Maximum rend un double (format D3 invalide), citation '' dans un pwsh -Command sous Git Bash, comparaison du vrai NUMEROS.md à un MD5 pris trop tôt.