LifePlay-Revival/Docs/Migration/etat/ST/STA/STA-T2c-DOC.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

210 lines
40 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

Fiche STA-T2c — Niveau N1 — Modèle prévu (modèle de l'agent lp-writer) | utilisé claude-sonnet-5-5 — Agent lp-writer — Skills sk-protocol, lp-doc, lp-lot
# STA-T2c-DOC : consolidation des 5 diagnostics STA-T2b en un tableau famille → cause → correctif (2026-10-09)
Lecture seule des livrables amont. Aucun DIAG, registre ni doc numéroté modifié ; aucun CHG / ERR ; aucun commit.
Abréviations : **U8** = journal CIBLE (build Development 5.8 U8 essai, `LifePlay.log`, 52 550 lignes) ; **U6** = journal REF (`LifePlay_58_session2.log`, 17 317 lignes) ;
`CSV:n` = ligne n de `STA-T1-familles.csv` ; `BEAUTE`, `GIUBER`, `GIVAR`, `PERSON`, `VILLE` = `STA-T2b-<nom>-DIAG.md` (dossier `D:\Game\LifePlay-master 5.5\Docs\Migration\etat\ST\STA\`) ;
`INV` = `STA-T1-INV.md`. Les chiffres des colonnes U8 / U6 sont ceux des DIAG et du CSV, repris tels quels. Un compte absent des DIAG est écrit « non donné ».
Les colonnes **Type**, **Effort** et la répartition en « confirmée / estimée / indécise » (§ B) sont des lectures de T2c (estimé), pas des constats des DIAG, sauf mention.
## 1. Fichiers écrits
- `D:\Game\LifePlay-master 5.5\Docs\Migration\etat\ST\STA\STA-T2c-DOC.md` (ce livrable, un seul Write). Aucun autre fichier écrit.
## 2. Numéros pris (CHG, ERR) et commande de contrôle
sans objet : la fiche interdit toute entrée CHG / ERR (§ 6) ; aucun numéro pris, aucun fichier de journal ou de registre touché.
## 3. Index et plages mis à jour
sans objet : aucun doc numéroté créé, `README.md` et `STA-TACHES.md` non touchés (le registre appartient à l'orchestrateur).
## 4. Écarts à la fiche
1. **Skills** : l'en-tête cite `lp-lot` en plus de `sk-protocol` et `lp-doc`, parce que les trois sont préchargés dans le contexte de l'agent.
2. **Point amont 5 (dumps)** : la fiche cite `RandomizeFace` et `RandomizeAll` de Person et `MapMarkers`. BEAUTE ne les demande pas : `RandomizeAll` et `RandomizeFace` sont des événements du graphe d'événements de Person, déjà dumpé (appel de `RandomizeFace` en `Person__EventGraph.txt:17802`, BEAUTE § 1 pile 2) ; ils manquent de nom, pas de dump. `MapMarkers_C` est noté « non dumpé » par VILLE (§ Compte rendu 5), sans demande de dump. Les deux sont listés « mentionnés, non demandés » au § D.
3. **Point amont 1 (fusion K4 / clearVariable)** : fusionnés en une ligne (R12) et un correctif, mais les comptes ne sont pas identiques. GIVAR § 1 : 36 messages `Person_24` sur 39 précèdent un avertissement `clearVariable`, les 3 autres « viennent d'ailleurs » ; VILLE K4 range les 39 sous la même cause. R12 garde donc 72 + 39 = 111 événements U8, dont 3 en bucket « indécise ».
4. **Point amont 4 (clés indécises)** : `Array_Get_Item_53` (GIUBER, non traité) porte la même pile que VILLE K8 (`FocusOnMapMarkers`, CIBLE:7382-7399 contre 7380-7399) ; T2c le rattache à R28 (estimé), il ne reste donc qu'une clé réellement non traitée, `Companion` / SceneStart (R10). Les « 12 / 18 restants » de BEAUTE sont R02. Les clés indécises restantes sont R06, R07, R08 (GIUBER K4-K6), R25, R26 (VILLE K5-K6).
5. **Point amont 3 (priorité S3)** : « S3 = 1 » est posée sur R01 seulement. Les DIAG ne classent pas les autres lignes en S3 (doc 29:55 : 1 visible ou plantage, 2 erreur au journal, 3 `Accessed None`, 4 avertissement récurrent) ; le classement S3 de chaque ligne est laissé à STA-T4.
6. **Total 3 549 / 1 121** : il couvre les catégories (a) `Accessed None` et (b) index hors bornes (INV § 2.4). Les hitchs K9 (2 / 4, catégorie (e)) et les 4 lignes `pending kill` de `BGA` en U6 (INV § 2.7 n° 24, catégorie (d)) sont hors de ce total ; ils sont dans le tableau avec la mention « hors total ».
7. **Contradiction entre DIAG** (PERSON F et VILLE K1), non tranchée ici : voir § Constats F.1.
8. **Aucun recomptage des journaux** : T2c lit les DIAG et le CSV. Les sommes sont recalculées sur les chiffres repris (commandes en § B).
## Constats
### A. Tableau consolidé (29 lignes, une par clé de DIAG ; fusions et clés « hors total » signalées)
Types : Blueprint (BP) / C++ / données. Garde : « oui » = le DIAG juge l'état None ou vide normal ; « non » = corriger l'état ; « à trancher » = question ouverte. Effort (estimé T2c) : S = un point de modification (1 à 3 nœuds), aucun prérequis bloquant ; M = plusieurs nœuds ou événements, ou une vérification préalable ; « provisoire » = cause indécise, effort non confirmé ; « non estimable » = nœud non localisé. Prérequis : `D<n>` = dump du § D, `C<n>` = décision du § C, `E<n>` = lecture ou essai du § D.
| ID | Famille / clé (DIAG) | U8 / U6 | Cause | Verdict | Correctif proposé | Type | Garde | Effet en jeu | Effort | Prérequis | Source |
|---|---|---|---|---|---|---|---|---|---|---|---|
| R01 | BEAUTE-A : `GI_C:getBeautyValue`, `getRandomAge`, `getRandomEthnicity` / `Floats_3` | 2 579 / 0 (getBeautyValue 2 493, getRandomAge 56, getRandomEthnicity 30 ; 2 493 = 2 505 − 12 de R02) | Table `BeautyStandards` vide pendant la génération des PNJ (`Map_Find` dont la sortie « trouvé » n'est pas testée) ; remplie seulement à l'ouverture de la création de personnage, des contacts ou au début d'une scène | confirmée ; mécanisme précis estimé (`ConsolidateBeautyStandards` non dumpée) | A : appel de `ConsolidateBeautyStandards` dans `GI.EventGraph` entre `CallFunction_1037.then` et `CallFunction_41.execute` (variante A' : 3 gardes `Map_Length = 0`) | BP | non : corriger l'état, une table vide n'est pas normale | **visible en jeu (estimé)** : âge = premier tag d'âge, ethnie = premier tag d'ethnie, morphs tirés au hasard sans attractivité ; **S3 = 1** | M | D1, D4, C2 (P1-P3 de BEAUTE C3) | BEAUTE § 3b, C2, C3 ; CSV:2, 15, 24 |
| R02 | BEAUTE-B : résidu `Floats_3` de `getBeautyValue` | 12 / 18 (tous index 0, féminins ; U8 : trame 419 ; inclus dans les 2 505 / 18 de CSV:2) | Clés de la liste féminine absentes de `BeautyStandards` une fois remplie (morph, ou tag de forme ou d'ethnie) ; lesquelles : inconnu ; nœud `:64X` non résolu | indécise (H2 à faire) | B1 : ajouter les clés dans `beauty_standards_default.txt` ; B2 : 3 `IfThenElse` (F0, F8, F5) sur `Map_Find.ReturnValue` dans `getBeautyValue` uniquement | données (B1) ou BP (B2) | à trancher (C1) ; aucun garde dans `getRandomAge` / `getRandomEthnicity` | B2 : résultat inchangé (`Accum` garde sa valeur initiale, estimé) ; B1 : non donné | M | D1 à D4, E3, C1 | BEAUTE § 4, C4 ; CSV:2 |
| R03 | GIUBER-K1 : `GI_C:ExecuteUbergraph_GI` / `CallFunc_ParseIntoArray_ReturnValue_3` | 570 / 570 | Ligne de données de vêtements découpée sur `': '` : 3 champs, 4e champ (index 3) lu sans test (événement populateClothes4, estimé ; cause « 3 champs » estimée) | confirmée (nœud `GetArrayItem_65` et mécanisme établis) | `Branch` `Array_Length(CallFunction_1061.ReturnValue) > 3` avant le consommateur ; faux → chaîne vide vers `MakeStruct_8.Strings2` (pas de `Select` pur) | BP (+ données selon C3) | oui (compte identique U8 / U6) | journal seul (estimé nul : le moteur journalise et poursuit) | S | C3, E2 | GIUBER K1 ; CSV:9 |
| R04 | GIUBER-K2 : `ExecuteUbergraph_GI` / `…ParseIntoArray_ReturnValue_29` et `_28` | 60 / 60 (40 + 20 / 40 + 20) | Ligne de `Modules/MorphTags/<nom>.txt` sans `': '` : tableau de longueur 1, index 1 lu sans test (PopulateEachMorphTags) ; nature des lignes : incertaine | confirmée (`GetArrayItem_56` et `_58` ; attribution `_28` / `_29` à `1012` / `1016` incertaine) | `Branch` `Array_Length >= 2` avant `Map_Add` dans `MacroInstance_64` et `_65` ; faux → ligne ignorée (ou valeur vide : SPEC) | BP (+ données) | oui (constant U8 / U6) | non donné | S | C3, C4, E1 | GIUBER K2 ; CSV:10, 11 |
| R05 | GIUBER-K3 : `ExecuteUbergraph_GI` / `Interacting in GI_C` | 7 / 24 | `Interacting` None, état posé par le graphe lui-même ; appels `clearDaily`, `PlayDaily`, `PlayIdle` à cible multiple et `BooleanAND_91` pur, sans garde ; 3 événements (StopDurationUpdate, TakeModActionWithBuilding, ActionDurationUpdate) | estimée : mécanisme confirmé, nœud par événement estimé (deux) ou incertain (un) ; écart 7 / 24 non analysé | (a) `CallFunction_864`, `_863` : séparer la cible multiple, Interacting derrière `IsValid` ; (b) `_866` idem ; (c) `BooleanAND_91` → `Branch(IsValid(Interacting))` | BP | oui | non donné | M | C4 (ou remontée d'exécution, N2) | GIUBER K3 ; CSV:3 |
| R06 | GIUBER-K4 : `ExecuteUbergraph_GI` / `TintUI in GI_C` | 5 / 17 | `TintUI` non valide dans HideUI et ShowUI ; 0 `VariableSet` dans l'EventGraph (écriture ailleurs ou absente) | indécise (nœuds identifiés, estimé) | Conservatoire : `IsValid` sur `VariableGet_1375` avant `CallFunction_2310` et sur `VariableGet_2515` avant `CallFunction_939`, la branche non valide rejoint `VariableSet_1341` / `CallFunction_760` | BP | à trancher (normal ou défaut d'affectation) | non donné ; défaut d'affectation possible | S (provisoire) | D11 | GIUBER K4 ; CSV:4 |
| R07 | GIUBER-K5 : `ExecuteUbergraph_GI` / `CallFunc_K2_GetRootComponent_ReturnValue_1` | 1 / 6 | `RootComponent` de `SceneCapture` None sur `SetVisibility(false)` dans HideRender (estimé) ; acteur apparemment valide sans racine (incertain) | indécise | Séparer la cible multiple de `CallFunction_5578` ; `SceneCapture.RootComponent` derrière `IsValid` | BP | à trancher | non donné | S (provisoire) | E4 (affectation de `SceneCapture`, trace N3) | GIUBER K5 ; CSV:6 |
| R08 | GIUBER-K6 : `ExecuteUbergraph_GI` / `CallFunc_K2_GetRootComponent_ReturnValue_2` | 0 / 5 (U6 seul) | Même mécanisme dans ShowRender (`CallFunction_3014`) ; getter fautif `_3097` ou `_3103` incertain | indécise (comme R07) | Cibles `RootComponent` de `CallFunction_3014` derrière `IsValid` (même lot que R07) | BP | à trancher | non donné | S (provisoire) | E4 ; rejouer la création de personnage | GIUBER K6 ; CSV:8 |
| R09 | GIUBER-K7 : `GI_C:clearScenePersons` / `Companion` + `Interacting` | 4 / 8 (2 + 2 / 4 + 4) | `CumOn(['Clear'])` appelé sur PlayerCharacter, Companion et Interacting sans garde ; les deux derniers sont None en fin de scène sans compagnon ni partenaire | confirmée | Séparer `CallFunction_4` en trois appels, ou Companion et Interacting derrière `IsValid` (motif de `MacroInstance_1`) | BP | oui | non donné | S | aucun | GIUBER K7 ; CSV:34, 35 |
| R10 | GIUBER-NT1 : `ExecuteUbergraph_GI` / `Companion in GI_C` (SceneStart) | 2 / 4 | Non traité (budget) ; pile SceneStart via ReadSceneLine ; 19 `VariableGet 'Companion'` dans l'EventGraph, aucun rattaché | non traité | non donné | — | — | non donné | non estimable | E5, C4 | GIUBER § Clés non traitées ; CSV:5 |
| R11 | GIUBER-NT2 : `ExecuteUbergraph_GI` / `CallFunc_Array_Get_Item_53` (FocusOnMapMarkers) | 1 / 2 | Non traité par GIUBER ; VILLE K8 § 1 donne la même pile (CIBLE:7380-7399) : suite de la lecture `WidgetComponents[0]` sur tableau vide (rattachement par T2c) | estimée (fusion probable avec R28) | Celui de R28 (`Branch` `Array_IsValidIndex` sur `CustomEvent_183`) | BP | oui (via R28) | sans plantage (VILLE K8) | S | C10 ; en VAL, vérifier que la ligne disparaît avec R28 | GIUBER § Clés non traitées ; VILLE K8 § 1 ; CSV:7 |
| R12 | **Fusion** GIVAR-F1 + VILLE-K4 : `GI_C:clearVariable` / `CallFunc_Array_Get_Item in not an UClass` et `GI_C:(Script Msg)` / `Person_24 in Variable` | 111 / 153 (72 + 39 / 94 + 59) | `GetVariable(Var).Person[0]` sur un tableau `Person` vide (longueur 0), lu aussi dans la condition d'un OR pur (`Prefix`, `SaveSlot`) ; 36 appels × 2 avertissements ; 36 des 39 messages hors plage précèdent un avertissement `clearVariable`, 3 viennent d'ailleurs (GIVAR § 1) | confirmée (préexistant 5.5, journal 55 lu par GIVAR) ; 3 messages sur 39 : source non identifiée | `IfThenElse` après `GetVariable` sur `Array_IsValidIndex(Person, 0)` ; faux → fin. Une fonction corrigée pour 4 appelants (getRelative 28, GetSpecific 30, getPerson 10, GeneratePerson 4) | BP | oui : vide = rien à effacer, comportement déjà « aucune action » | journal seul (GIVAR § 4) | S | D5, C11 | GIVAR F1 ; VILLE K4 ; CSV:12, 16 |
| R13 | GIVAR-F2 : `MainMenu_C:Get_SpinBox_0_Value_0` (4 clés CSV) | 30 / 30 (12 + 6 + 6 + 6 / idem) | Binding de `SpinBox_0` évalué dans `SynchronizeProperties` avant l'événement qui remplit `GI` ; 6 évaluations × 5 avertissements | confirmée (préexistant 5.5, 45 lignes au journal 55) | A (racine, préféré) : déplacer `GetGameInstance` → `Cast To GI` → `Set GI` vers un nouvel `Event On Initialized`. B : `IsValid(GI)` dans le binding, `else` → retour 0.0 | BP | B oui (état transitoire voulu par le moteur) ; A corrige l'ordre | valeur 0.0 pendant 3 évaluations à la construction (estimé) | M (A) ou S (B) | D7, C6 | GIVAR F2 ; CSV:20 à 23 |
| R14 | GIVAR-F2 (mention) : `MainMenu_C:ExecuteUbergraph_MainMenu` / `GI in MainMenu_C` | 2 / 2 | Même cause que R13 (`BndEvt__SpinBoxSquirtMult`, `CommitValue` de la construction) | estimée (GIVAR § 4 : « estimé ») | Traité par R13-A seul ; B ne le traite pas | BP | — | non donné | inclus en R13 | D7, C6 | GIVAR F2 § 4-5 ; INV 2.4 n° 19 ; CSV:40 |
| R15 | GIVAR-F3 : `GI_C:determinePersonVars` / `currentMatchRace in GI_C` | 30 / 34 | `MatchRace` None (paramètre facultatif) ; `getRace` et `getEthnicity` appelés avant le test `IsValid` déjà présent | confirmée (préexistant 5.5, 36 lignes au journal 55) | `IfThenElse` entre `FunctionEntry_0` et `CallFunction_18`, condition = `IsValid` existant `CallFunction_30`, `else` → `VariableSet_27` | BP | oui (None prévu, déjà testé) | comportement inchangé (GIVAR § 4) | S | aucun | GIVAR F3 ; CSV:19 |
| R16 | PERSON-A : `Person_C:standIdle` / `Near` (42 / 30) + sans propriété (14 / 10) | 56 / 40 | `Near` optionnel (None depuis `PlayIdle`) lu par `VariableSet_6` (NearVec) avant la garde ; 3 « Near » + 1 nu par appel | confirmée | `IsValid(Near)` entre `VariableSet_3.then` et `VariableSet_6.execute` ; non valide → `MacroInstance_1` | BP | oui, neutre (NearVec non consommé si None) | neutre | S | D6 (non bloquant) | PERSON A ; CSV:13, 14 |
| R17 | PERSON-B : `Person_C:ExecuteUbergraph_Person` / `HeadtrackStatic` | 11 / 10 | `SelectVector_998` pur : `HeadtrackStatic.K2_GetComponentLocation` évalué même si non valide ; `HeadtrackStatic` remis à None (EG:19002) | confirmée | Variable locale « cible » par deux `Branch` / `IsValid` avant `K2_SetActorRotation` ; deux None → sauter | BP | oui | si les deux sont None : orientation vers l'origine du monde aujourd'hui (estimé), donc visible possible | M | C7, D6 | PERSON B ; CSV:25 |
| R18 | PERSON-C : `ExecuteUbergraph_Person` / `HeadtrackTarget` (3 / 2) + sans propriété (3 / 2) | 6 / 4 | Même instruction que R17, cas « les deux None » | confirmée | Celui de R17 (une seule modification) | BP | oui | idem R17 | inclus en R17 | C7 | PERSON C ; CSV:27, 28 |
| R19 | PERSON-D : `ExecuteUbergraph_Person` / `OccupyingFnt` | 10 / 17 | Personnage sans meuble occupé ; `StaticMesh` lu sans test dans le test de nom | confirmée | `IsValid(OccupyingFnt)` avant `IfThenElse_75` (rebrancher `IfThenElse_89.else` et `VariableSet_173.then`) ; pas d'`IsValid` en entrée d'un AND / OR | BP | oui, neutre | neutre | S | aucun | PERSON D ; CSV:26 |
| R20 | PERSON-E : `Person_C:assignHome` / `FamilyLiveWiths` | 2 / 2 | `BooleanAND_2` évalue `FamilyLiveWiths[SaveSlot]` même si `Prefix` n'est pas `F` ; tableau vide | confirmée | Cascade de `Branch` : `Prefix == 'F'` → `IsValidIndex` → valeur → `Map_Add` ; sinon `IfThenElse_3` | BP | oui, neutre (hors bornes donne faux) | neutre | S | aucun | PERSON E ; CSV:36 |
| R21 | PERSON-F : `Person_C:assignHome` / `CallFunc_SearchByAmenitySafe_Buildings` | 2 / 1 | `Buildings` vide → `RandomInteger(0)` → index 0 → `Map_Add` d'une structure par défaut dans `AI_Homes` ; amont : `CurrentCityExpansion` None (R22) | confirmée (conséquence) | `Branch(Array_Length(Buildings) > 0)` avant `Map_Add` ; correctif amont préféré par PERSON (voir écart 7) | BP | à trancher (C8) | PNJ sans domicile exploitable (estimé), donc visible possible | S | C8 ; R22 d'abord | PERSON F ; CSV:37 |
| R22 | VILLE-K1 : `StreetMap_Static_C:SearchByAmenitySafe` / `CurrentCityExpansion in GI_C` + sans propriété | 10 / 15 (9 + 1 / 14 + 1) | `CurrentCityExpansion` None tant que la ville n'a pas d'extension sauvegardée (état normal), lu sans `IsValid` ; le repli sur `StreetMap.Buildings` donne un résultat juste | confirmée (9) ; forme nue (1) : même appel, nœud incertain | Deux macros `IsValid` : entre `IfThenElse_5.then` et `VariableSet_3`, entre `IfThenElse_5.else` et `IfThenElse_6` ; même garde dans `findNearbyBuilding` | BP | oui | journal seul (résultat juste) | S | D10 (non bloquant) | VILLE K1 ; CSV:30, 31 |
| R23 | VILLE-K2 : `StreetMap_Static_C:ExecuteUbergraph_StreetMap_Static` / `BGA` | 5 / 6 (+ 4 `pending kill` en U6, hors total) | `BGA` None avant le premier `SpawnSound2D` (et après collecte) ; 3 lectures sans `IsValid` | confirmée | 3 `IsValid(BGA)` (`IfThenElse_22` then et else, devant `CallFunction_124`) | BP | oui | bénin (`Stop` sur None ne fait rien, le son est lancé) | S | aucun | VILLE K2 ; CSV:32 |
| R24 | VILLE-K3 : `Room_C:pickPresetWorld` / `BuildingPoints` | 4 / 10 | Rue sans polygone ; `BuildingPoints[0]` et `[1]` lus sans test | confirmée (tableau vide normal) | `Branch` `Array_Length >= 2` entre `IfThenElse_0.else` et `VariableSet_1` ; faux → `Strings[0]` ; risque voisin non observé : `len = 0` | BP | oui | préréglage fixe (le premier de la liste), sans défaut visible (estimé) | S | aucun | VILLE K3 ; CSV:33 |
| R25 | VILLE-K5 : `GI_C:(Script Msg)` / `Texture2dArray_3 in Te2dArray` | 6 / 0 | Lecture `[0]` d'un tableau vide au changement d'animation de la scène de couple (estimé) ; fonction de GI non localisée | indécise | Générique : `Array_IsValidIndex(Texture2dArray, 0)` avant le Get | BP | à trancher | non donné | M (provisoire) | D8 | VILLE K5 ; CSV:17 |
| R26 | VILLE-K6 : `SexInterface_C:(Script Msg)` / `SexPersons in GI_C` | 3 / 0 | Lectures à index fixes 2, 3, 4 pour 2 participants (estimé) | indécise | `Array_IsValidIndex(GI.SexPersons, i)` devant chaque emplacement, ou `ForEach` | BP | à trancher | bénin pour une scène à deux (estimé) | M (provisoire) | D9 | VILLE K6 ; CSV:38 |
| R27 | VILLE-K7 : `Person_C:(Script Msg)` / `Standspots_Occupied in Room_C` | 15 / 9 | Tableau parallèle creux (`Array_Set` avec `bSizeToFit`) ; le Get hors bornes rend None, l'emplacement est vu libre | confirmée (bénin) | `Branch` `Array_IsValidIndex(Standspots_Occupied, Array Index)` avant `MacroInstance_3` ; faux → `Knot_1`. Autre voie : dimensionner dans `Room` (non dumpé) | BP | oui | bénin, comportement voulu | S | aucun | VILLE K7 ; CSV:29 |
| R28 | VILLE-K8 : `GI_C:(Script Msg)` / `WidgetComponents in MapMarkers_C` | 1 / 2 | `FocusOnMapMarkers` (`CustomEvent_183`) lit `WidgetComponents[0]` avant le tick de la garde C++ (0,25 s) | confirmée (reste d'ERR-008) | `Branch` `Array_IsValidIndex(MapMarkers.WidgetComponents, 0)` après l'événement ; faux → `SetInputMode_GameAndUIEx` sans widget, ou rien | BP | oui | sans plantage | S | C10 | VILLE K8 ; CSV:18 |
| R29 | VILLE-K9 : hitch `MapMarkers_C.LPFocusWidgetComponent` | 2 / 4 (**hors total 3 549 / 1 121**, catégorie (e)) | `NewObject` à nom fixe sur un composant détruit non encore collecté (`LPMapMarkersGuardSubsystem.cpp:127`) | confirmée | `MakeUniqueObjectName(Markers, UWidgetComponent::StaticClass(), TEXT("LPFocusWidgetComponent"))` (une ligne ; même signature en 5.5 et 5.8) | C++ | sans objet (pas un garde) | saccades mesurées en U8 : 1,77 ms et 11,66 ms | S + BUILD | C10 | VILLE K9 ; INV 2.8 |
#### A2. Clés du CSV sans DIAG (cause non donnée)
| ID | Famille / clé | U8 / U6 | Remarque | Source |
|---|---|---|---|---|
| H1 | `GI_C:ReturnStatIfNeeded` / `Person in not an UClass` | 2 / 2 | Aucun diagnostic. Constant des deux côtés (INV § Constats 1.5) | CSV:39 |
| H2 | `GI_C:isCreatureType` / `Actor in not an UClass` | 1 / 0 | Aucun diagnostic. Nouveau côté U8 (INV § Constats 1.6) | CSV:41 |
| H3 | `PC_C:ExecuteUbergraph_PC` / `CallFunc_getFirstDick_Person_1 in not an UClass` | 1 / 0 | Aucun diagnostic. Nouveau côté U8 | CSV:42 |
| H4 | `Person_C:UpdateDailyPose` / `ContactMenu in GI_C` | 0 / 63 | Objet du correctif déjà appliqué, 0 événement en U8 (INV § Constats 1.7) | CSV:43 |
| H5 | `CharGen_C:ExecuteUbergraph_CharGen` / sans propriété (0 / 2) et `GI in CharGen_C` (0 / 1) | 0 / 3 | Chemin non joué en U8 (création de personnage) | CSV:44, 45 |
| H6 | `StreetMap_Static_C:findNearbyBuilding` / `CurrentCityExpansion in GI_C` | 0 / 2 | Citée par VILLE K1 (même garde que R22, fonction non dumpée) | CSV:46 |
| H7 | `CharGen_C:PopulateGenitalSlidersDaz` / `CallFunc_GetSkeletalMesh_ReturnValue in not an UClass` | 0 / 1 | Chemin non joué en U8 | CSV:47 |
| H8 | `CityMenu_C:ExecuteUbergraph_CityMenu` / `GI in CityMenu_C` | 0 / 1 | Chemin non joué en U8 | CSV:48 |
| | **Total H1 à H8 (9 clés CSV : H5 en compte 2)** | **4 / 72** | | |
Comptage des clés : 38 clés du CSV portées par les lignes R01 à R28 (R01 = 3 clés, R02 = 0 car sous-ensemble de la clé CSV:2 de R01, R04 = 2, R09 = 2, R12 = 2, R13 = 4, R16 = 2, R18 = 2, R22 = 2, les 19 autres lignes 1 chacune : 3 + 0 + 2 + 2 + 2 + 4 + 2 + 2 + 2 + 19 = 38) + 9 clés en A2 (H5 = 2 clés) = 47 = `awk` sur le CSV (§ B). R29 n'est pas une clé du CSV (hitch).
### B. Couverture chiffrée (événements U8, total STA-T1 = 3 549 = 256 `Accessed None` + 3 293 index hors bornes)
Commande de contrôle des totaux (lecture seule) :
`awk -F';' 'NR>1{n++;c+=$4;r+=$5;if($2=="A"){ac+=$4;ar+=$5}else{bc+=$4;br+=$5}}END{print n,c,r,ac,ar,bc,br}' STA-T1-familles.csv` → `47 3549 1121 256 390 3293 731`.
**B1. Par niveau de cause (U8)**
| Niveau de cause | Lignes (événements U8) | Total U8 |
|---|---|---|
| Confirmée | R01 2 579 ; R03 570 ; R04 60 ; R09 4 ; R12 108 (72 + 36) ; R13 30 ; R15 30 ; R16 à R21 87 (56 + 11 + 6 + 10 + 2 + 2) ; R22 9 ; R23 5 ; R24 4 ; R27 15 ; R28 1 | **3 502** |
| Estimée (mécanisme ou rattachement estimé) | R05 7 ; R14 2 ; R11 1 ; R22 forme nue 1 | **11** |
| Indécise | R02 12 ; R06 5 ; R07 1 ; R08 0 ; R12 3 (messages `Person_24` hors `clearVariable`) ; R25 6 ; R26 3 | **30** |
| Non traitée | R10 2 | **2** |
| Sans DIAG (A2) | H1 2 ; H2 1 ; H3 1 | **4** |
| **Total** | 3 502 + 11 + 30 + 2 + 4 | **3 549** |
Contrôle : `echo $((3502+11+30+2+4))` → 3549. Sous-totaux : `echo $((2579+570+60+4+108+30+30+87+9+5+4+15+1))` → 3502 ; `echo $((7+2+1+1))` → 11 ; `echo $((12+5+1+0+3+6+3))` → 30.
Règle de classement (T2c) : « confirmée » = verdict du DIAG sans réserve sur le nœud ou la cause de l'événement ; « estimée » = mécanisme confirmé mais nœud ou rattachement estimé par le DIAG (R05, R22 forme nue, R14) ou par T2c (R11) ; « indécise » = verdict du DIAG ou de T2c « indécise ».
**B2. Par DIAG source (U8 / U6)**
| DIAG | Lignes | U8 | U6 | Remarque |
|---|---|---|---|---|
| BEAUTE | R01, R02 | 2 591 | 18 | 2 579 + 12 ; U6 : 0 + 18 |
| GIUBER | R03 à R11 | 650 | 696 | `ExecuteUbergraph_GI` 646 / 688 + `clearScenePersons` 4 / 8 (GIUBER § 0.1) |
| GIVAR | R12 (part clearVariable 72 / 94), R13, R14, R15 | 134 | 160 | 72 + 30 + 2 + 30 / 94 + 30 + 2 + 34 |
| PERSON | R16 à R21 | 87 | 74 | 56 + 27 + 4 / 40 + 31 + 3 (PERSON § Totaux) |
| VILLE (hors K9) | R12 (part Person_24 39 / 59), R22, R23, R24, R25, R26, R27, R28 | 83 | 101 | 10 + 5 + 4 + 39 + 6 + 3 + 15 + 1 / 15 + 6 + 10 + 59 + 0 + 0 + 9 + 2 |
| Sans DIAG | H1 à H8 | 4 | 72 | A2 |
| **Total** | | **3 549** | **1 121** | `echo $((2591+650+134+87+83+4))` → 3549 ; `echo $((18+696+160+74+101+72))` → 1121 |
Somme des lignes R01 à R28 (R12 pour 111 / 153) : U8 3 545, U6 1 049 (`echo` du total des cellules du tableau A) ; + A2 (4 / 72) = 3 549 / 1 121. R29 (hitch) est en dehors.
### C. Décisions à prendre (questions Q des 5 DIAG, dédoublonnées)
| # | Décision | Origine | Lignes | Posée à | Bloque |
|---|---|---|---|---|---|
| C1 | Résidu `Floats_3` : ajouter les clés manquantes au fichier de normes (B1, dépôt local Modules jamais poussé) ou garde dans `getBeautyValue` (B2) ? Dépend de D1 à D4 et E3 | BEAUTE Q1 | R02 | SPEC ou utilisateur | IMPL-GI-A (partie résidu) |
| C2 | Point d'insertion du correctif A : après `PopulateBeautyStandardsDefault` (`CallFunction_1037`) ou après le chargement des réglages (entre `CallFunction_1055.then` et `VariableSet_353.execute`) ? Selon P2 (D1) | BEAUTE Q2 | R01 | SPEC | IMPL-GI-A |
| C3 | Données de vêtements et de tags : garde seule, ou aussi correction des données (et des mods) ? Pour K2 : ligne ignorée ou `Map_Add` avec valeur vide ? | GIUBER Q1 | R03, R04 | SPEC | IMPL-GI-B (partie données) |
| C4 | Faire imprimer par l'outil de dump le nom des événements personnalisés (`CustomFunctionName`, référence d'événement) et des temporaires compilés. Besoin cité par quatre DIAG : GIUBER Q2 et 0.7, GIVAR F2 (`K2Node_Event_1`), PERSON (remarque transverse), VILLE (§ Établi / estimé). Modifier l'outil de dump est un changement hors T2c | GIUBER Q2 (+ GIVAR, PERSON, VILLE) | R04, R05, R10, R13 et tous les rattachements « estimés » | orchestrateur | non bloquant, mais lève la plupart des « estimé » |
| C5 | Retirer le « décalage `:<offset>X` » de la méthode : il vaut `64X` pour toutes les lignes (GIUBER 0.2 : 646 / 646 ; PERSON remarque transverse), donc inopérant | GIUBER Q3 (+ PERSON) | toutes | orchestrateur (méthode) | aucun |
| C6 | Correctif de `Get_SpinBox_0_Value_0` : A seul, B seul ou A + B ? (GIVAR recommande A ; B ne traite pas R14) | GIVAR § 5 (arbitrage de l'orchestrateur) | R13, R14 | orchestrateur | IMPL-MENU-A |
| C7 | Si ni `HeadtrackStatic` ni `HeadtrackTarget` n'est valide : sauter la rotation (proposé) ou garder l'orientation vers le vecteur nul (comportement probable aujourd'hui) ? | PERSON Q1 | R17, R18 | SPEC ou utilisateur | IMPL-PERSON-A |
| C8 | Si la recherche de domicile échoue : garder l'écriture d'un domicile vide dans `AI_Homes`, ou ne rien écrire (proposé) ? Dépend de R22 et de l'écart 7 | PERSON Q2 | R21 | SPEC ou utilisateur | IMPL-PERSON-B (partie R21) |
| C9 | Ouvrir les DIAG voisins demandés par PERSON Q3 : `Standspots_Occupied` est traité par VILLE K7 (R27) ; `SearchByAmenitySafe` / `CurrentCityExpansion` par VILLE K1 (R22), qui répond « None = ville sans extension sauvegardée », pas « lié à `MakePermanent` ». Question caduque sous réserve de confirmation par l'orchestrateur | PERSON Q3 | R21, R22, R27 | orchestrateur | aucun |
| C10 | Garder la garde C++ et corriger seulement le nom (`MakeUniqueObjectName`, R29), ou corriger `FocusOnMapMarkers` en Blueprint (R28, R11) et retirer la création du composant de focus ? La première voie ne touche aucun Blueprint | VILLE Q1 | R11, R28, R29 | SPEC ou utilisateur | IMPL-CPP-A, partie de IMPL-GI-B |
| C11 | Une seule fiche IMPL pour `clearVariable` (GIVAR F1 + VILLE K4). Les deux DIAG le recommandent ; R12 l'applique. À valider | VILLE Q2 (+ GIVAR § 5, fiche T2c) | R12 | orchestrateur | IMPL-GI-B |
Aucune autre question n'est posée dans les 5 DIAG. Les « Points à confirmer » (P1 à P3 de BEAUTE, nom de `K2Node_Event_1`, etc.) sont des vérifications techniques, listées au § D.
### D. Dumps et essais complémentaires (liste unique, dédoublonnée)
Forme de commande reprise des DIAG, non rejouée : `RunCommandlet.ps1 -Commandlet LPDumpFunction -Args '-BP=<BP> -Fn=<fonction> -Pins -Exec'` (BEAUTE § 5). Rappel : le Grep lancé sur `dumps\` depuis un dossier ignoré par git renvoie 0 résultat (BEAUTE C5, `.gitignore:74`) ; chercher par fichier ou par `path` explicite.
| # | Blueprint | Objet à dumper | Demandé par | Lève | Bloque |
|---|---|---|---|---|---|
| D1 | GI | fonction `ConsolidateBeautyStandards` (16 nœuds, `GI__graphes.txt:355`) | BEAUTE § 5 (H2-1), C3 P1 à P3 | R01, R02 | IMPL-GI-A (bloquant) |
| D2 | GI | fonction `filterMorphList` | BEAUTE § 5 (H2-1) | R02 | résidu de IMPL-GI-A |
| D3 | Person | fonction `pickAppropriateFaces` (59 nœuds, `Person__graphes.txt:115`) | BEAUTE § 5 (H2-1) | R02 | résidu de IMPL-GI-A |
| D4 | GI | CDO (`LPDumpCDO`) : `BeautyStandardTags`, `Shapes`, `Ethnics`, fichier source de `MorphTags_false` | BEAUTE § 5 (H2-2) | R01 (tags aux indices 7-13 et 15-20), R02 | IMPL-GI-A |
| D5 | GI | fonctions `getRelative`, `GetSpecific`, `getPerson` (aucune ne doit dépendre de l'effet du cas vide) | GIVAR F1 § 5 (vérification N1) | R12 | IMPL-GI-B |
| D6 | Person | fonction `PlayIdle` (corps absent des dumps ; transmission `Near`, affectation de `HeadtrackStatic` hors EventGraph) | PERSON § Établi / estimé / incertain | R16, R17 | non bloquant |
| D7 | MainMenu | nom ou référence de `K2Node_Event_1` (Construct ou Pre Construct ?), par un dump qui imprime l'événement ou un coup d'œil dans l'éditeur | GIVAR F2 § 5 | R13, R14 | IMPL-MENU-A (correctif A) |
| D8 | GI | 6 fonctions candidates : `PlayAppropriateSexAnimation`, `PlayAnimationMorph`, `PersonPlayAnimationMorph`, `getFaceTexture`, `getMID`, `CumSound` (`GI__graphes.txt:80, 8, 81, 267, 26, 269`), puis recherche de `Texture2dArray_3` | VILLE K5 § 5 (N0) | R25 | IMPL-GI-B (partie R25) |
| D9 | SexInterface | liste des graphes (`-BP=SexInterface`), puis la fonction qui lit `SexPersons` | VILLE K6 § 5 (N0) | R26 | IMPL-SEX-A |
| D10 | StreetMap_Static | fonction `findNearbyBuilding` (U6 : 2 événements) | VILLE K1 § 4 | H6 | non bloquant (même garde que R22) |
| D11 | GI | écriture de `TintUI` : `-Fn=*` ou dump des widgets qui écrivent `GI.TintUI`, puis recherche de `variable 'TintUI'` | GIUBER K4 § 5 (N2) | R06 | IMPL-GI-C (partie R06) |
| D12 | tous | noms des `K2Node_CustomEvent` et des temporaires (outil de dump, voir C4) | GIUBER Q2 | R04, R05, R10, R13 | non bloquant |
14 fonctions nommées en D1 à D12 (1 + 1 + 1 + 3 + 1 + 6 + 1 : D1, D2, D3, D5, D6, D8, D10), plus la liste de SexInterface (D9), un CDO (D4), un nom d'événement (D7) et un changement d'outil (D12).
**Lectures et essais hors dump**
| # | Essai | Demandé par | Lève |
|---|---|---|---|
| E1 | Lister les lignes sans `': '` de `Content/Modules/MorphTags/*.txt` (N1) | GIUBER K2 § 5 | R04 |
| E2 | Identifier les lignes à 3 champs lues par populateClothes4 (N2) | GIUBER K1 § 5 | R03 |
| E3 | Différence entre les morphs de la liste féminine filtrée et les clés du fichier de normes (après D2 à D4) | BEAUTE § 5 (H2-3) | R02 |
| E4 | Lire l'affectation de `SceneCapture` dans GI et tracer `IsValid` / `GetRootComponent` dans une build de diagnostic (N3) ; rejouer la création de personnage après correction | GIUBER K5, K6 § 5 | R07, R08 |
| E5 | Remonter l'exécution depuis les 19 `VariableGet 'Companion'` jusqu'à SceneStart (dump `GI__EventGraph.txt` existant) | GIUBER § Clés non traitées | R10 |
| E6 | Remonter le déclencheur de `CallFunction_3040` (chaîne `readUniforms` > `PopulateAllMorphTags` > `PopulateBeautyStandardsDefault`) avant toute entrée en pièce (P3), dans le dump existant | BEAUTE C3 P3 | R01 |
**Mentionnés, non demandés** : Person `RandomizeFace` et `RandomizeAll` (événements de `Person__EventGraph.txt`, déjà dumpés, noms absents : écart 2) ; `MapMarkers_C` (non dumpé, VILLE § Compte rendu 5 ; la destruction du composant de focus par `HideAllMarkers` reste « estimée ») ; `Room` au-delà de `pickPresetWorld` (alternative de R27). Le corps de `FocusOnMapMarkers` est localisé par VILLE K8 (`GI__EventGraph.txt:13185-13212`) : GIUBER ne l'avait pas localisé, aucun dump nécessaire.
### E. Lots IMPL proposés (par Blueprint, un lot = une famille de causes)
« U8 visés » = somme des événements U8 des lignes du lot (comptes repris du § A) ; « cond. » = ligne dont la cause est indécise ou non traitée, à n'inclure qu'après le prérequis. Ordre et priorité : renvoyés à STA-T4. Les lots d'un même Blueprint modifient le même asset binaire : à exécuter l'un après l'autre (estimé, pas de fusion d'assets).
| Lot | Blueprint | Famille de causes | Lignes | U8 visés | Mesure de VAL attendue (reprise des DIAG) | Prérequis | Effort |
|---|---|---|---|---|---|---|---|
| IMPL-GI-A | GI (EventGraph) | Table `BeautyStandards` non remplie à la génération des PNJ | R01 ; cond. R02 | 2 579 ; cond. 12 | `array Floats_3_` : 0 pour `getRandomAge` et `getRandomEthnicity`, résidu seul dans `getBeautyValue` (BEAUTE C3) ; **visible en jeu (estimé), S3 = 1** | D1, D4, E6, C2 (C1 pour le résidu avec D2, D3, E3) | M |
| IMPL-GI-B | GI (EventGraph, `clearVariable`) | Lecture d'un tableau vide ou court sans test de longueur | R03, R04, R12, R28, R11 ; cond. R25 | 743 (570 + 60 + 111 + 1 + 1) ; cond. 6 | `GI_C:clearVariable:` = 0 ; `array 'Person_24…' of length 0` = 3 (les 3 messages hors `clearVariable`) ; R03 et R04 : non donné (attendu 0) ; R28 et R11 : non donné | D5, C3, C10, C11 ; cond. D8 | M |
| IMPL-GI-C | GI (EventGraph, `clearScenePersons`, `determinePersonVars`) | Référence None normale utilisée sans `IsValid` | R05, R09, R15 ; cond. R06, R07, R08, R10 | 41 (7 + 4 + 30) ; cond. 8 (5 + 1 + 0 + 2) | `property currentMatchRace in /Game/BPs/GI.GI_C` = 0 (GIVAR F3) ; `clearScenePersons` = 0 (GIUBER K7) ; R05 : non donné | C4 (rattachement de R05) ; cond. D11, E4, E5 | M |
| IMPL-PERSON-A | Person (`standIdle`, EventGraph) | Référence None, ou nœud pur évalué en entier, sans `IsValid` | R16, R17, R18, R19 | 83 (56 + 11 + 6 + 10) | −56 / −40 (R16) ; −17 / −14 (R17 + R18) ; −10 / −17 (R19), U8 / U6 (PERSON § 4) | C7 | M |
| IMPL-PERSON-B | Person (`assignHome`, `standIdle`) | Tableau vide ou creux lu sans test | R20, R21, R27 | 19 (2 + 2 + 15) | −2 / −2 (R20) ; −2 / −1 (R21, si garde locale) ; R27 : non donné. À enchaîner après IMPL-PERSON-A (même fonction `standIdle`) | C8, R22 | S |
| IMPL-MENU-A | MainMenu | Ordre d'initialisation : binding évalué avant `GI` | R13, R14 | 32 (30 + 2) | `Get_SpinBox_0_Value_0:64X` = 0 et `property GI in /Game/UI/MainMenu.MainMenu_C` = 0 (GIVAR F2 § 5) | D7, C6 | M (A) / S (B) |
| IMPL-SMS-A | StreetMap_Static | Référence None normale sans `IsValid` | R22, R23 | 15 (10 + 5) | 0 ligne `property CurrentCityExpansion`, 0 forme nue sous `SearchByAmenitySafe` ; 0 ligne `property BGA` ou `via property BGA` (VILLE K1, K2) | D10 (non bloquant) | S |
| IMPL-ROOM-A | Room (`pickPresetWorld`) | Tableau vide lu sans test | R24 | 4 | 0 ligne `array BuildingPoints`, préréglage de la rue inchangé (VILLE K3) | aucun | S |
| IMPL-SEX-A (conditionnel) | SexInterface | Tableau court lu à index fixes | R26 | cond. 3 | non donné | D9 | M (provisoire) |
| IMPL-CPP-A | C++ `LPMapMarkersGuardSubsystem` | Nom d'objet fixe sur un composant détruit non collecté | R29 | 0 (2 hitchs, hors total) | 0 ligne `overwrite took` sur `LPFocusWidgetComponent`, ligne de garde `slot de focus` toujours présente (VILLE K9 § 5) | C10 | S + BUILD |
Contrôle : lots fermes 2 579 + 743 + 41 + 83 + 19 + 32 + 15 + 4 = **3 516** ; conditionnels 12 + 6 + 8 + 3 = **29** ; 3 516 + 29 = **3 545** = lignes R01 à R28 (§ B) ; + 4 sans DIAG = 3 549 (`echo $((2579+743+41+83+19+32+15+4))` → 3516 ; `echo $((12+6+5+1+0+2+3))` → 29).
### F. Constats transverses et points de vigilance
**F.1 Contradiction entre PERSON F et VILLE K1 (non tranchée).** PERSON F (§ 4) désigne `CurrentCityExpansion` None comme cause racine de R21 et écrit que le correctif amont « rend cette garde inutile dans le cas observé ». VILLE K1 (§ 3 et § 4) établit que, avec `CurrentCityExpansion` None, `SearchByAmenitySafe` rend déjà le repli `StreetMap.Buildings` et que « le résultat de la fonction est juste » : le correctif R22 est neutre sur le contenu de `Buildings`. Lecture de T2c (estimée) : R22 supprime l'avertissement `Accessed None` qui précède R21, mais ne garantit pas que `Buildings` cesse d'être vide. Essai qui trancherait : après IMPL-SMS-A, rejouer le parcours `MakePermanent` / `SetDating` et compter `CallFunc_SearchByAmenitySafe_Buildings` (2 attendus si R21 subsiste). D'ici là, la garde locale de R21 ne doit pas être écartée au motif de R22.
**F.2 Technique commune.** Quatre DIAG reposent sur le même piège : un nœud pur (AND, OR, Select, macro de lecture) est évalué en entier, donc un `IsValid` placé en entrée n'empêche pas la lecture fautive. Les correctifs proposés remplacent le nœud par des branches en cascade : R05 (c), R12, R17 et R18, R20, R19 (consigne explicite). Les cibles multiples d'un nœud d'appel (R05, R09, R07) se traitent en séparant les cibles.
**F.3 Préexistant 5.5.** Établi seulement pour trois lignes (R12, R13, R15), par lecture du journal 55 (GIVAR). Pour les autres, U6 tourne déjà sur 5.8 : l'absence de régression de la montée 5.8 est estimée (PERSON A, VILLE K1 à K8), non vérifiée contre un journal 5.5.
**F.4 Rafale R01 : pas un écart propre à 5.8.** U6 tourne aussi sur 5.8 et n'a que le résidu (18) : la différence vient du scénario (création de personnage ou non avant la première génération de PNJ). L'hypothèse amont « boucle de reprise de `pickAppropriateFaces` » est réfutée (compte fixe par sexe, BEAUTE § 3b). Correction de STA-T2a (BEAUTE § 1) : `RandomizeAll`, `RandomizeFace`, `pickAppropriateFaces` sont absents des dumps, pas du Blueprint.
**F.5 Fusions et dépendances entre lignes.** R12 = GIVAR F1 + VILLE K4 (écart 3). R11 rattachée à R28 (écart 4). R17 + R18 = une seule modification. R07 + R08 = un seul lot (même mécanisme). R14 traitée par R13-A seulement. R21 dépend de la décision C8 et de l'essai F.1. R27 et R16 sont dans la même fonction `standIdle`.
**F.6 Budgets.** Les cinq DIAG sont marqués « hors budget » dans `STA-TACHES.md` (154 à 235 k jetons) ; BEAUTE, GIUBER et VILLE sont « partiels ». Cette consolidation ne les rouvre pas.
**F.7 Établi / estimé / incertain (sk-protocol § 1).**
- Établi : les 47 clés, leurs totaux (3 549 / 1 121, A 256 / 390, B 3 293 / 731) relus au CSV par `awk` ; les comptes par clé repris des DIAG avec leur source ; les sommes de B1, B2 et E recalculées (`echo $((…))`, sorties citées).
- Estimé : colonnes Type et Effort ; classement en niveaux de cause (B1) ; rattachement de R11 à R28 ; contradiction F.1 ; ordre d'exécution des lots d'un même Blueprint ; « 2 493 = 2 505 − 12 » (soustraction de T2c à partir de BEAUTE § 3b : 12 appels de la trame 419, tous `getBeautyValue`).
- Incertain : tout ce que les DIAG marquent incertain (nœud de la forme nue de R22, site `:64X` de R02, attribution `_28` / `_29`, contenu de `BeautyStandardTags`, comportement de `GetVariable` sur une variable inexistante) ; la répartition des 3 messages `Person_24` hors `clearVariable` (R12) ; les comptes U6 de GIVAR F1 et F3 (« non recomptés », repris de STA-T1).
## Compte rendu (sk-protocol § 3)
[sk-protocol] Skills présents : sk-protocol, lp-doc, lp-lot.
1. **Résultat** : réussi. 29 lignes consolidées (5 DIAG, 47 clés CSV dont 38 portées par les lignes et 9 sans DIAG), 11 décisions, 12 dumps et 6 essais, 10 lots IMPL proposés.
2. **Preuves** : lecture des 5 DIAG (§ Constats et tableaux d'abord), de `STA-T1-familles.csv`, `STA-T1-INV.md`, `STA-TACHES.md`, `gabarits.md`, `29_Projet_Stabilisation_V2.md:55` (définition de S3). Chaque ligne cite sa section de DIAG et sa ligne de CSV.
3. **Chiffres** : `awk` sur le CSV → `47 3549 1121 256 390 3293 731` ; niveaux de cause 3 502 + 11 + 30 + 2 + 4 = 3 549 ; par DIAG 2 591 + 650 + 134 + 87 + 83 + 4 = 3 549 (U6 : 18 + 696 + 160 + 74 + 101 + 72 = 1 121) ; lots 3 516 + 29 = 3 545 (+ 4 sans DIAG). Toutes les sommes recalculées par `echo $((…))` en Bash.
4. **Incertitudes** : contradiction PERSON F / VILLE K1 (F.1) ; 3 messages `Person_24` sans source (R12) ; efforts et types estimés ; `ConsolidateBeautyStandards` non dumpée (R01 reste conditionnel à D1).
5. **Écarts** : voir § 4 (8 points). Fichier écrit : `D:\Game\LifePlay-master 5.5\Docs\Migration\etat\ST\STA\STA-T2c-DOC.md` (seul).
6. **Handoff** : Suite : l'orchestrateur doit accepter STA-T2c, lancer un N0 pour D1 à D12, trancher C1 à C11 (priorité C2, C6, C7, C10), puis passer le tout à STA-T4 ; état : consolidation livrée, aucune modification du projet.