43 KiB
Fiche CAM-B2p-I-VAL — Niveau N1 — Modèle prévu sonnet | utilisé claude-sonnet-5-5 — Agent lp-validator — Skills sk-protocol, sk-recount, debug-verification, lp-validate
CAM-B2p-I-VAL : validation statique de N2 (reprise de B2p-H) et de l'aide des contrôles derrière l'icône « i » (2026-10-14)
Portée : VAL statique (aucune compilation, aucun jeu, aucun éditeur, aucun commandlet, aucun MCP, aucune écriture git), par un validateur distinct de l'auteur.
Copie D:\Game\LifePlay-master 5.8, branche ue5.8 (git branch --show-current : ue5.8), UE 5.8, BuildSettingsVersion V7 (/we4456 /we4458 /we4459).
LPCameraModeSubsystem.cpp et .h sont non suivis par git (git status --short -- Source : ??) : pas de tag CAM-B2p-I-avant. Chaque point est jugé sur le diff entre instantanés (git diff --no-index), comme CAM-B2p-H-VAL.md. Convention : CAM-B2p-I0 = état d'avant le point I0 ; I0 = diff I0 vers I1 ; I1 = diff I1 vers final.
Niveaux de preuve : établi = lecture ou commande rejouée aujourd'hui ; estimé = déduit (raisonnement dit) ; incertain = non vérifié (essai nommé).
Commandes : Read, Grep, Glob ; deux scripts .ps1 du dossier temporaire de session (scratchpad\v1.ps1, scratchpad\v2.ps1), lancés par pwsh -NoProfile -File, hors dépôt. v1.ps1 a échoué (chemins des instantanés sans le sous-dossier Source\LifePlay : « ABSENT », diffs vides, rien d'utilisé) ; v2.ps1 corrige les chemins et fait foi.
1. Fiches amont relues
Docs/Migration/etat/CAM/CAM-B2p-I-IMPL.md(lue en entier ; seule IMPL du lot).Docs/Migration/etat/CAM/CAM-B2p-I-SPEC.md(lue en entier : DIAG § 1, SPEC § 2, risques § 3, essais § 4).Docs/Migration/etat/CAM/CAM-B2p-H-VAL.md(lue en entier : forme d'une VAL statique C++ de ce lot ; son N2 à la l. 188).- Lus en lecture seule :
CAM-B2p-G-PC-VAL_LPDumpFunction_20261014-135527.txt(l. 345-352, 1006-1014, 1163-1172, 3005-3043),CAM-B2p-E-IMPL.mdl. 44-49,CAM-B2p-G-SPEC.mdl. 11-14,Config/DefaultInput.inil. 97, 118, 150-160,LPBonusRewardSubsystem.cppl. 590-713,LPKeyboardSubsystem.cppl. 155-180 et 599,LifePlay.Build.csl. 12-52,Intermediate/Build/Win64/x64/*/*/LifePlay/Module.LifePlay.cpp(trois cibles). - Gabarit VAL lu :
D:\Game\LifePlay-Sandbox\Tools\claude\skills\lp-doc\gabarits.md(section VAL, sections 1 à 6 dans l'ordre). - Gabarit de l'IMPL (écart, N5) : l'IMPL n'a ni tête commune (« Fiche … — Niveau … »), ni section « Ce qui n'a pas été fait », ni ligne
Tours :. Ses sections sont numérotées 0 à 5 et non 1 à 6 ; les « points à confirmer » sont en § 4 (essais CAM-86 à CAM-90), les écarts en § 3, les fichiers à commiter en § 5. Le contenu est exact sauf un chiffre (voir § 3, contrôle 3).
2. Points à confirmer des IMPL (un par ligne)
| # | Point | Verdict | Preuve |
|---|---|---|---|
| I0 | N2 : LastSurfaceRefused.Reset() dans la seule branche où le couple bouge, rien d'autre |
PASS-STATIC | .cpp l. 1447-1448 (dans else if (CoupleSpotFree(…)), l. 1439-1449, après la boucle de déplacement l. 1443-1446) ; diff I0 vers I1 = +2 / −0 (§ 4) |
| C1 | Consigne 1 : TextBlock_1 invisible seulement si son texte commence par « Click any mouse button », sinon intact |
PASS-STATIC | .cpp l. 1778-1792 (§ 3.1) |
| C2 | Consigne 2 : SearchAction ou parent introuvable : rien d'inséré, une ligne de témoin |
PASS-STATIC pour le cas décrit ; réserve D1 (AddChild rendant nul) |
.cpp l. 1851-1858, 1889-1908 |
| C3 | Consigne 3 : texture info absente, un « i » en texte |
PASS-STATIC | .cpp l. 1868-1884, 1906-1908 |
| C4 | Consigne 4 : ligne de la molette retirée si CAM ne déplace pas le couple à la molette | PASS-STATIC (règle respectée à la lettre) ; observation D2 | .cpp l. 126, 1104, 1745-1746 ; LPKeyboardSubsystem.cpp:165 ; § 3.1 |
| C5 | Consigne 5 : hors du sexe, rien ne change | PASS-STATIC ; observation D3 | .cpp l. 1769, 1775, 1806-1811, 1820-1837 |
| C6 | Consigne 6 : aide en anglais, touches lues dans les mappages | PASS-STATIC | .cpp l. 295-317, 1743-1764 ; DefaultInput.ini l. 97, 118, 150-160 |
| E1 (IMPL § 3) | Icône en fin de rangée (AddChild), non juste après le champ |
PASS-STATIC, écart jugé acceptable | PanelWidget.h:68-72, PanelWidget.cpp:184-198 (§ 3.2) |
| E2 (IMPL § 3) | I-d par opacité de rendu et non par vidage du texte | PASS-STATIC, écart jugé acceptable | TextBlock.cpp:469-478 : SetText fait TextDelegate.Unbind() |
| E3 (IMPL § 3) | Pas de lecture MCP : confirmation au premier essai | reporté V7 | aucune lecture possible ici |
| E4 (non annoncé) | La SPEC § 2.1 I-c demandait un UBorder et un UTextBlock UMG avec contour ; l'IMPL fait une boîte Slate (SOverlay, SBorder, STextBlock) avec ombre |
PASS-STATIC, écart non annoncé (N6) | .cpp l. 1919-1955 ; même technique que EnsureWidget (l. 1682-1714) |
| CAM-86 | Ligne icone inseree (parent, classe), image info ; ligne 4 lignes d'origine masquees |
formats de lignes PASS-STATIC ; comportement reporté V7 | .cpp l. 1784, 1906-1908 |
| CAM-87 | Survol = info-bulle ; clic ouvre et ferme la boîte ; la fermeture du panneau la ferme | chemin de code PASS-STATIC ; comportement reporté V7 | .cpp l. 1814, 1886, 1912-1917, 1820-1837 |
| CAM-88 | Touches du clavier (Z/S, Q/D) ; suivent un remappage | PASS-STATIC (lecture à chaque 0,1 s) ; affichage reporté V7 | .cpp l. 1803, 1811-1814, 1828-1830 |
| CAM-89 | Hors sexe : icône absente du Cursor, texte de jouissance affiché |
icône et boîte PASS-STATIC ; texte de jouissance : observation D3, reporté V7 | .cpp l. 1806, 1822-1825 |
| CAM-90 | Deux passages sur la même commode écrivent deux lignes (N2) | PASS-STATIC (code) ; reporté V7 | .cpp l. 1433-1437, 1448 |
| Compilation | 0 erreur, 0 avertissement nouveau sous V7 | BLOCKED-compilation (à BUILD) | aucune compilation lancée ici |
3. Critères rejoués (commande → résultat)
| # | Contrôle | Commande / lecture | Résultat brut | Verdict |
|---|---|---|---|---|
| 1 | MD5, taille, fins de ligne des 6 fichiers | pwsh -NoProfile -File scratchpad\v2.ps1 (octets lus par ReadAllBytes, CR et LF comptés, sans grep -c) |
final .cpp size=85842 CR=0 LF=1969 MD5=73CC3BD667059A903E44405C5E793DE3, .h size=9813 CR=0 LF=179 MD5=6EDBBCCF61759B8C6EE4890DF9BC5FE7 ; I0 .cpp 73384 / 1687 / 210B665AA8D5D628B8C1AC429A339B74, .h 8471 / 152 / 239DA6094E7401E0E3B3699A635A8150 ; I1 .cpp 73526 / 1689 / 3A11A3872378485DC64804AEC0A761EE, .h 8471 / 152 / 239DA609… |
PASS : égalent la fiche et l'IMPL § 0 ; LF pur (CR=0), sans BOM (premiers octets 2f2f20), dernier octet 0a |
| 2 | Manifestes des instantanés | Get-Content …\CAM-B2p-I0\manifest.csv et I1 |
I0 : tailles 73384 / 8471 ; I1 : 73526 / 8471, MD5 identiques aux fichiers ; dossiers Source\LifePlay\ + manifest.csv, dates 14:40:05 et 14:40:13 |
PASS |
| 3 | Chiffres de l'IMPL recomptés (sk-recount) | Grep des 11 constantes, 9 includes, 6 fonctions, membres du .h l. 148-171 |
9 includes, 11 constantes, 3 déclarations avancées, 6 fonctions : conformes. Membres : HelpCursor, HelpButton, FadedHelpLines, FadedLinesOpacity, bHelpBoxOpen, HelpTextShown, HelpRoot, HelpText, HelpViewport = 9 ; l'IMPL § 2.2 dit « 10 membres » |
un écart (N7), sans effet sur le code |
| 4 | Diff brut et répartition | git diff --no-index -U0 puis --numstat (sorties dans § 4) |
I0 vers I1 .cpp +2/−0 ; I1 vers final .cpp +280/−0, .h +27/−0 ; I0 vers final .cpp +282/−0, .h +27/−0 |
PASS : la somme égale le global ; lignes 1687 + 282 = 1969 et 152 + 27 = 179 |
| 5 | Aucune ligne retirée ou modifiée dans B2p-C à B2p-H | lecture des 9 hunks (§ 4) : tous des ajouts purs, aucun retrait (numstat 0 retraits) |
hunks aux l. 6-14, 189-202, 293-318, 629, 635-636, 1447-1448, 1742-1969 (.cpp) ; 23-25 et 148-171 (.h) |
PASS-STATIC : aucune ligne de C à H n'est modifiée |
| 6 | Tick garde son comportement |
Read l. 633-685 |
TickControlsHelp(); en l. 636, avant ComputeLabel() (l. 637) ; la fonction rend void ; Tick n'a aucun retour avant l. 636 ; les retours l. 662 et 666 sont les anciens |
PASS-STATIC |
| 7 | Symboles uniques | Grep de 24 noms neufs sur Source |
90 occurrences, seulement dans LPCameraModeSubsystem.cpp (75) et .h (15) : aucun homonyme externe |
PASS |
| 8 | Dépendances du module | LifePlay.Build.cs l. 17 et 38 |
InputCore (public) ; Slate, SlateCore, UMG (privés, l. 38) ; Engine public |
PASS |
| 9 | Includes suffisants | .cpp l. 5-37 contre les types employés |
WidgetTree.h, Button.h, CanvasPanelSlot.h, HorizontalBoxSlot.h, Image.h, PanelWidget.h, TextBlock.h, Texture2D.h, SBorder.h ajoutés ; déjà présents : UserWidget.h, InputSettings.h (donc PlayerInput.h : FInputActionKeyMapping), CoreStyle.h, SOverlay.h, STextBlock.h, GameViewportClient.h, SlateApplication.h. Précédents du module pour les mêmes en-têtes : LPKeyboardSubsystem.cpp:5, LPSettingsSubsystem.cpp:6,9,12,13 |
PASS-STATIC |
| 10 | .generated.h et UFUNCTION privée |
.h l. 15, 27-30, 36, 156-157 |
#include "LPCameraModeSubsystem.generated.h" (l. 15, dernier include), UCLASS() + GENERATED_BODY() (l. 27-30), private: (l. 36), UFUNCTION() + void ToggleControlsHelp(); (l. 156-157). AddDynamic et AddUniqueDynamic sont appelés depuis une fonction membre de la classe (l. 1848, 1886) : l'accès au membre privé est licite. OnClicked est un DECLARE_DYNAMIC_MULTICAST_DELEGATE (Button.h:18, 76) : les deux macros existent. Précédent du module : LPKeyboardSubsystem.cpp:599 (AddDynamic, fonction publique). UHT génère le thunk et friend struct …_Statics pour une fonction privée (usage courant du moteur, estimé, sans exemple relu) |
PASS-STATIC (UHT et compilation : BUILD) |
| 11 | Unités compilées | Grep de Module.LifePlay.cpp (UnrealGame Development, Shipping, UnrealEditor Development) |
LPCameraModeSubsystem.cpp est absent des trois unités unifiées ; seul UHT/LPCameraModeSubsystem.gen.cpp y figure (UnrealGame Development, l. 6) : le .cpp se compile seul quand il est modifié |
PASS : aucune collision d'unité avec un autre .cpp ; BUILD doit vérifier que le module figure dans les unités compilées |
| 12 | Texte d'aide : Printf |
lecture l. 1748-1763 ; moteur Platform.h:1322, 1332, 1348 ; précédent moteur ShaderCompiler.cpp:5978-5979 |
8 %s (l. 1750 : 1 ; l. 1751 : 4 ; l. 1756 : 2 ; l. 1758 : 1) et 8 arguments (l. 1759 : 1 ; 1760 : 2 ; 1761 : 2 ; 1762 : 2 ; 1763 : 1), dans l'ordre : SwitchCamera, MoveForward +1 et −1, MoveRight −1 et +1, LeftRight, DownUp, Pause. TEXT(x) vaut WIDETEXT(x) = L ## x : L"…" "…" est une concaténation licite (même idiome que ShaderCompiler.cpp:5978-5979) ; texte entièrement en ASCII |
PASS-STATIC |
| 13 | Formats UE_LOG |
lecture l. 1784, 1791, 1855-1857, 1862-1863, 1906-1908, 1915 | 1/1, 0/0, 2/2 (%s conditionnel de deux tableaux : décroissent en const TCHAR*), 2/2, 4/4 (%s, %s, %d entier de GetChildrenCount, %s), 1/1 |
PASS-STATIC |
| 14 | Non-ASCII hors commentaires | Grep [^\x00-\x7F] sur le .cpp |
10 lignes (83, 155, 189, 543, 585, 1157, 1380, 1663, 1745, 1878), toutes des commentaires (189, 1745 et 1878 sont neuves ; les 7 autres existaient dans le fichier déjà compilé) ; aucun TEXT(…) non ASCII |
PASS |
| 15 | Fichiers STG / STE | Get-ChildItem … Sort LastWriteTime |
LPCameraModeSubsystem.cpp 14:43:20, .h 14:43:12 ; puis LPShowCoupleSubsystem.* 12:43:20 ; LPOutdoorRoomSubsystem.* et LPDirectControlSubsystem.* 12:05:58 ; aucun autre fichier de Source touché après 12:43 |
PASS (par les dates) |
| 16 | État git de la copie | git status --short -- Source Docs/Migration/etat/CAM Config |
M : LPDebugSubsystem, LPDirectControlSubsystem, LPOutdoorRoomSubsystem, LPShowCoupleSubsystem, LifePlay.cpp (autres lots) ; ?? : LPCameraModeSubsystem.*, LPBonusRewardSubsystem.*, LPSaveRelaunch.* |
PASS : aucun fichier inattendu pour ce lot |
3.1 Les six consignes de Big Boss, une à une
TextBlock_1invisible seulement si son texte commence par « Click any mouse button » —.cppl. 1775-1792.SexUI=GI.SexInterface(dump du PC l. 3030-3038 :VariableGet_108 GIversVariableGet_109 SexInterfaceversTextBlock_1) ;Lines->GetText().ToString().StartsWith("Click any mouse button", CaseSensitive)(l. 1778). Opacité à 0 seulement sibOldHelpet opacité > 0 (l. 1779-1785) ; sinon rien, sauf le retour de l'opacité si ce même bloc a été masqué par ce code et porte un autre texte (l. 1786-1792). Un bloc dont le texte ne commence pas par la phrase n'est jamais modifié.UTextBlock::GetText()rend le texte du widget Slate quand il existe (donc la liaison évaluée), sinonText(TextBlock.cpp:457-465) ;SetTextappelleTextDelegate.Unbind()(TextBlock.cpp:469-472) : choisir l'opacité de rendu, qui laisse la liaison, est correct.UWidget::SetRenderOpacitymet à jour la propriété et le widget Slate (Widget.cpp:454-463) ;GetRenderOpacitylit le widget Slate (Widget.cpp:443-452). PASS-STATIC.SearchActionou son parent introuvable : rien d'inséré, une ligne —.cppl. 1851-1858 :SearchBoxnul,SearchParentnul ouWidgetTreenul :UE_LOG« icone non inseree, <SearchAction | le parent de SearchAction> introuvable dans » puisreturn nullptravant toutConstructWidget: aucun widget n'est créé. L'ancrage étiré dans unCanvasPanelest refusé de la même façon (l. 1859-1865 ;Anchors.h:78, 81:IsStretchedVertical,IsStretchedHorizontal). PASS-STATIC ; réserve D1 : le cas oùAddChildrend nul (parent à un seul enfant) n'est pas traité (l. 1889).- Texture
infoabsente : un « i » —LoadObject<UTexture2D>(nullptr, "/Game/Heavy/New/info.info")(l. 1868) ; si nul :UTextBlock« i », policeBold18, blanc (l. 1877-1884) ; sinonUImage,SetBrushFromTexture,SetDesiredSizeOverride(28, 28)(l. 1871-1876 ;Image.h:81, 108). La ligne d'insertion nomme l'image (« absente, lettre i », l. 1906-1908). PASS-STATIC. - Ligne de la molette retirée si CAM ne déplace pas le couple à la molette —
bSexWheelZoom = false(.cppl. 126, constanteconst bool). Seul lecteur deScrollDownUpdansSource/LifePlay:.cppl. 1104,Wheel = bSexWheelZoom ? AxisValue(PC, AxisScroll) : 0.f;Wheeln'entre ensuite que dans des tests contre zéro (l. 1117, 1130) et un terme multiplié (l. 1132), donc nul. L'autre occurrence (LPKeyboardSubsystem.cpp:165) range le nom d'axe dans la catégorie « Camera » du menu Keyboard : elle ne lit aucune valeur. Aucune ligne « Mouse wheel » dans le texte (l. 1748-1758). PASS-STATIC. Observation D2 : la règle est respectée à la lettre, mais Room (Blueprint, hors C++) monte et descend bien le couple avec Maj + molette (CAM-B2p-E-IMPL.md:48: « Maj + molette avait monté le couple … » ;CAM-B2p-G-SPEC.md:13: « Z de 100 à 127 (molette …) » ;CAM-B2p-F-VAL.md:64) : l'aide omet un contrôle réel. Décision pour Big Boss. - Hors du sexe, rien ne change —
bSexOn(l. 1769) gouverne :SexUInul hors sexe (l. 1775), doncTextBlock_1n'est ni lu ni écrit ; l'insertion exigebSexOn(l. 1798) ; l'icône déjà insérée passe enCollapsed(l. 1806, 1807-1810) ;HelpBodyest vide (l. 1803) ;bPanelOpenest faux (l. 1821) doncbHelpBoxOpen = false(l. 1822-1825) et la boîte est repliée (l. 1834-1837). PASS-STATIC. Observation D3 : l'opacité 0 posée pendant le sexe n'est pas rendue à la fin du sexe (le code de retour d'opacité est lui aussi derrièrebSexOn). - Aide en anglais, touches lues dans les mappages — texte en anglais (l. 1748-1758) ; touches par
MappedKeys(l. 295-317), lu à chaque appel dansUInputSettings(même source queAxisValue, l. 272-291). Valeurs attendues avecDefaultInput.ini:SwitchCamera=C(l. 118) ;MoveForward+1 =Z,W, −1 =S(l. 155-157) ;MoveRight−1 =Q,A, +1 =D(l. 158-160) ;LeftRight=Right,Left(l. 150-151) ;DownUp=Up,Down(l. 152-153) ;Pause=SpaceBar(l. 97). PASS-STATIC.
3.2 Contrôles de lecture, fonction par fonction
MappedKeys(l. 295-317) : signes de l'axe :Sign == 0 || (Sign > 0 ? Scale > 0 : Scale < 0)(l. 302) ; avecDefaultInput.ini,MoveForwarddonneZ/Wpour +1 etSpour −1,MoveRightdonneQ/Apour −1 etDpour +1 : l'ordre des paramètres dePrintf(l. 1760-1761) est « avant, arrière, gauche, droite », comme le texte « closer / away » et « orbit ». Sens de l'axe : en mode Scène,Distance - Forward * SexDollySpeed * Step(l. 1132) :Forward> 0 rapproche, donc « closer » =MoveForward+1 (établi). Filtres!IsGamepadKey() && !IsMouseButton() && !IsAxis1D()(l. 303, 310) :FKeyles définit (InputCoreTypes.h:72-78) ;GetDisplayName(false)rend unFText(InputCoreTypes.h:89), puis.ToString();AddUniqueécarte les doublons ; repli « ? » (l. 316). Action :FInputActionKeyMapping::ActionName,Key(PlayerInput.h:148-174) ;GetActionMappings()etGetAxisMappings()non dépréciées (InputSettings.h:316-318). PASS-STATIC. Non filtré :Key.IsValid()(D6, négligeable).BuildControlsHelp(l. 1743-1764) :const, n'écrit rien ; contrôle 12. PASS-STATIC.TickControlsHelp(l. 1766-1842) :- garde
bSexOn(l. 1769) sur l'insertion (l. 1798), l'aide (l. 1803), la visibilité (l. 1806) ; - opacité gardée (
FadedLinesOpacity, l. 1781) et rendue (l. 1789) ; PC.CursorREF:ReadObject(PC, "CursorREF")(l. 1797 ; dump du PC l. 3012-3017, 1006-1007) ;- une tentative par instance :
HelpCursorest affecté avant l'appel (l. 1800-1801), comparé par pointeur faible (l. 1798) : une instance ratée n'est pas retentée ; - visibilité :
Visibleen sexe,Collapsedhors sexe, écrite seulement si elle change (l. 1806-1810) ; - info-bulle :
SetToolTipTextquand le texte change (l. 1811-1814 ;Widget.cpp:526-536met à jour le widget Slate vivant) ; - test du panneau comme
IfThenElse_10du PC : dans le dump,IfThenElse_10.Conditionvient deCallFunction_79,Widget::IsVisible()surCursorREF.BelowCursor(l. 3015-3023) ; le code faitPanelArea->IsVisible()sur le même widget (GetWidgetFromName("BelowCursor"), l. 1820-1821), etUWidget::IsVisiblelit la visibilité du widget Slate (Widget.cpp:395-404) : même fonction, même résultat. La fermeture par le PC (ExitSexActions, dump l. 1163-1170) metBelowCursorenCollapsed:bPanelOpendevient faux et la boîte se ferme ; - boîte fermée avec le panneau (l. 1822-1825, 1834-1837) ;
HelpTextetHelpRootsont valides quandEnsureHelpBox()rend vrai (l. 1919-1931). PASS-STATIC.
- garde
AttachHelpIcon(l. 1844-1910) :ActionCursor->WidgetTreeest unTObjectPtr<UWidgetTree>public (UserWidget.h:1524) ;ConstructWidget<UButton>(UButton::StaticClass(), nom)(WidgetTree.h:106;TSubclassOf(UClass*)implicite,SubclassOf.h:33; précédentLPBonusRewardSubsystem.cpp:621dans le mêmeCursor). NomsLPControlsHelp(l. 1866),LPControlsHelpIcon,LPControlsHelpLetter: une instance neuve a un arbre neuf (pas de collision) ; une icône déjà présente est reprise par nom avant (l. 1846-1850).AddChild, pasInsertChildAt:InsertChildAtappelleAddChildpuisShiftChild, qui ne réordonne queSlots; l'en-tête le dit (« This does not update the live slate version, it requires a rebuild of the whole UI »,PanelWidget.h:69-72,PanelWidget.cpp:184-198).AddChildpasse parOnSlotAdded, qui construit le slot Slate vivant pourHorizontalBox(HorizontalBox.cpp:32-39) etCanvasPanel(CanvasPanel.cpp:33-40). L'icône vient donc en fin de rangée : l'écart E1 est cohérent. Slots :UHorizontalBoxSlot::SetVerticalAlignment,SetPadding(HorizontalBoxSlot.h:48, 63) ;UCanvasPanelSlot::GetAnchors/GetPosition/GetSize/GetAlignment/GetZOrderconst et leursSet…(CanvasPanelSlot.h:104-156) ;UButton::SetBackgroundColor(FLinearColor)(Button.h:129) ;UContentWidget::SetContent(ContentWidget.h:23) ;UWidget::Slotpublic (précédentLPBonusRewardSubsystem.cpp:694). PASS-STATIC, sauf D1 (AddChildnul) ; autres types de panneau (WrapBox,ScrollBox) : l'icône est ajoutée sans réglage de slot (acceptable).ToggleControlsHelp(l. 1912-1917) :UFUNCTION()(.hl. 156) ; basculebHelpBoxOpen, une ligne, puisTickControlsHelp().TickControlsHelpn'appelle jamaisToggleControlsHelpni ne déclencheOnClicked: récursion d'un seul niveau, sans boucle. Le clic peut survenir pendant un traitement Slate :TickControlsHelpy crée au plus la boîte du viewport (AddViewportWidgetContent), ce que fait déjàEnsureWidgetdepuis un ticker. PASS-STATIC.EnsureHelpBox/RemoveHelpBox(l. 1919-1969) : même cycle de vie queEnsureWidget/RemoveWidget(l. 1682-1730) : retour vrai si la racine existe et le viewport est le même, sinonRemoveHelpBox()puis nouvelle racine ;AddViewportWidgetContent(…, HelpZOrder = 60);RemoveViewportWidgetContent.RemoveHelpBox()est appelé dansDeinitialize(l. 629, juste aprèsRemoveWidget()).FCoreStyle::Get().GetBrush("WhiteBrush"): la brosse existe dansStarshipCoreStyle.cpp:213etCoreStyle.cpp:301(FSlateColorBrushblanc, teinte parBorderBackgroundColorà 75 %). PASS-STATIC.
3.3 API du moteur 5.8 lues (D:\Game\Launcher\Engine\UE_5.8\Engine\Source\Runtime)
| API | Source lue | Résultat |
|---|---|---|
UTextBlock::GetText() const, SetText(FText), liaison |
UMG/Private/Components/TextBlock.cpp:457-465, 469-483 |
GetText : texte du widget Slate (liaison évaluée) sinon Text ; SetText délie TextDelegate |
UWidget::GetRenderOpacity() const, SetRenderOpacity(float), SetToolTipText(const FText&), IsVisible() const, GetVisibility() const |
UMG/Public/Components/Widget.h:556, 582, 586, 598, 602 ; Widget.cpp:395-404, 443-463, 526-536 |
conformes |
UButton::SetBackgroundColor(FLinearColor), OnClicked |
Button.h:18, 76, 129 |
conformes ; dynamique multicast |
UImage::SetDesiredSizeOverride(FVector2D), SetBrushFromTexture(UTexture2D*, bool) |
Image.h:81, 108 |
conformes (la variante dépréciée est SetBrushSize, non utilisée) |
UPanelWidget::AddChild(UWidget*) ; InsertChildAt ; rend nul si le panneau est à enfant unique et non vide |
PanelWidget.h:59-79 ; PanelWidget.cpp:132-142, 184-198 |
conformes ; le retour nul existe (D1) |
FAnchors::IsStretchedHorizontal/Vertical() const |
Slate/Public/Widgets/Layout/Anchors.h:78, 81 |
conformes |
FKey::IsAxis1D/IsMouseButton/IsGamepadKey/IsDigital/GetDisplayName(bool) |
InputCore/Classes/InputCoreTypes.h:72-89 |
conformes |
FInputActionKeyMapping, FInputAxisKeyMapping ; UInputSettings::GetActionMappings/GetAxisMappings |
Engine/Classes/GameFramework/PlayerInput.h:148-174, 216-230 ; InputSettings.h:316-318 |
conformes |
FCoreStyle « WhiteBrush » |
SlateCore/Private/Styling/StarshipCoreStyle.cpp:213, CoreStyle.cpp:301 |
présente |
UUserWidget::WidgetTree, GetWidgetFromName(const FName&) const ; UWidgetTree::ConstructWidget |
UserWidget.h:1426, 1524 ; WidgetTree.h:106 |
conformes |
TSubclassOf(UClass*) |
CoreUObject/Public/Templates/SubclassOf.h:33 |
implicite |
3.4 Compilation probable sous /we4456 /we4458 /we4459
- C4456 / C4457 (locaux englobants) : chaque fonction neuve relue en entier.
TickControlsHelp:GI,bSexOn,World,PC,SexUI,Lines(portée duif),bOldHelp,ActionCursor,HelpBody,HelpIcon(portée duif),IconVisibility,PanelArea,bPanelOpen: tous distincts.AttachHelpIcon: paramètreActionCursor, locauxExisting(portée duif),SearchBox,SearchParent,SearchCanvasSlot,IconButton,IconTexture,IconImage,IconLetter(blocs distincts),IconSlot,RowSlot,CanvasSlot: distincts.EnsureHelpBox:GI,ViewportClient,NewHelpText,NewHelpRoot.RemoveHelpBox:ViewportClient(portée duif).MappedKeys: paramètresName,Sign, locauxNames,Settings,Map(deux boucles, portées distinctes),bSign.BuildControlsHelp: une déclarationusing(pas de variable). Aucun doublon. - C4458 (membres) :
.hentier relu (l. 1-179). Membres de la classe :TickHandle,SwitchKeyHandle,bSwitchKeyDown,LastEmptyView,WitnessCooldown,OcclusionCooldown,bCharGenSeen,CharGenRepairTimeout,C1Cooldown,bMenuOnScreen,SexKeysCooldown,CoupleGrabMode,bLeftWasDown,bRightWasDown,bGrabMoved,bGrabHasHeight,GrabHeight,GrabOffset,GrabMouseStart,GrabLastMouseX,GrabTurned,GrabCamera,GrabCameraLocation,GrabCameraRotation,bCursorWarned,LastCouplePivot,bHasLastPivot,bHiddenRoomWarned,CoupleBoundsCooldown,CoupleMoveCooldown,bGrabJustEnded,bBoundsLogged,LastSpotBlocker,LastSurfaceRefused,bSceneFocusChecked,bFocusClickWasDown,GrabLeadStart,LastSexView,bSexC3Was,bMiddleWasDown,bMiddleHadMouse,bMiddleMoved,MiddleHeld,MiddleStart, les 9 membres neufs,Root,Text,Viewport,ShownLabel,bShown. Aucun nouveau local ni paramètre ne porte l'un de ces noms (les locauxHelpBody,HelpIcondiffèrent deHelpText,HelpButton). - C4459 (portée globale ou espace anonyme) : les constantes et
MappedKeyssont dansLPCameraModeLocal(espace nommé, l. 42). Grep, surSource/LifePlayhors CameraMode, des 25 noms locaux neufs (^\t?[A-Za-z_].*\b(Lines|Existing|CanvasSlot|Names|Sign|bSign|RowSlot|IconSlot|PanelArea|HelpBody|HelpIcon|SexUI|bOldHelp|bPanelOpen|IconVisibility|SearchBox|SearchParent|SearchCanvasSlot|IconButton|IconTexture|IconImage|IconLetter|ActionCursor|NewHelpText|NewHelpRoot)\b) : hitsExisting(LPDebugSubsystem.cpp:257, paramètre de fonction),CanvasSlot(LPBonusRewardSubsystem.cpp:695-713, local),Names(LPDirectControlSubsystem.cpp:1023,LPSessionLogSubsystem.cpp:321,LPShowCoupleSubsystem.cpp:585: locaux, les deux extrêmes relus aux l. 575-588 et 1012-1025),Lines(LPHairstyleSubsystem.cpp:284,LPKeyboardSubsystem.cpp:769,LPModGuard.cpp:515,LPModInfoSubsystem.cpp:221et:385,LPModInfoSubsystem.h:58: locaux ou paramètres). Aucune déclaration de portée globale. Les noms de membres, fonctions et constantes neufs (grep de 24 noms) : 90 occurrences, toutes dans CameraMode.CameraMode.cppn'est de toute façon pas dans une unité unifiée (contrôle 11). - Types :
UObject* ReadObject(const UObject*, FName)(l. 210) reçoitGIetPC; ternairesX* : nullptrsans conversion ambiguë ;TWeakObjectPtr<UButton/UTextBlock/UUserWidget>déclarés avec des classes avancées (précédent :TWeakObjectPtr<UGameViewportClient>avecUGameViewportClientavancé,.hl. 22 et 175) et définies dans le.cpp(l. 5-13) ;SNew(SOverlay) … + SOverlay::Slot() … [ SNew(SBorder) … [ SAssignNew(…) ] ]de même forme que l. 1697-1706 ;FString::Join(TArray<FString>, const TCHAR*)et ternaireFString/FString(TEXT("?"))de même type. Aucune erreur de type trouvée. - Résidu (N8) : un nom (
Names,Lines,Sign,Settings,Map) déclaré en portée globale par un en-tête moteur n'est excluable que par compilation ; improbable (SettingsetMapexistent déjà comme locaux compilés, l. 274, 280). À trancher par BUILD.
4. Diff lu en entier
Chaque diff a été lu en entier (git diff --no-index -U3, deux diffs .cpp et un diff .h ; -U0 et --numstat pour les comptes).
| Diff | .cpp ajoutées / retirées |
.h ajoutées / retirées |
Lignes avant vers après (LF) |
|---|---|---|---|
| I0 vers I1 | +2 / −0 (numstat : 2 0 ; -U0 : +2 −0) |
0 (diff vide) | .cpp 1687 vers 1689 |
| I1 vers final | +280 / −0 (numstat : 280 0) |
+27 / −0 (numstat : 27 0) |
.cpp 1689 vers 1969 ; .h 152 vers 179 |
| I0 vers final (global) | +282 / −0 | +27 / −0 | .cpp 1687 vers 1969 ; .h 152 vers 179 |
Sommes : 2 + 280 = 282 (.cpp) et 0 + 27 = 27 (.h), égales au global ; 1687 + 282 = 1969 et 152 + 27 = 179, égales aux lignes comptées (contrôle 1).
Hunks de I1 vers final (lignes de l'état final) :
| Fichier | Lignes | Contenu | Point |
|---|---|---|---|
.cpp |
6-14 (+9) | 9 includes | I1 |
.cpp |
189-202 (+14) | 11 constantes d'aide, commentaires, ligne vide | I1 |
.cpp |
293-318 (+26) | MappedKeys |
I1 |
.cpp |
629 (+1) | RemoveHelpBox(); dans Deinitialize |
I1 |
.cpp |
635-636 (+2) | commentaire et TickControlsHelp(); en tête de Tick |
I1 |
.cpp |
1742-1969 (+228) | BuildControlsHelp, TickControlsHelp, AttachHelpIcon, ToggleControlsHelp, EnsureHelpBox, RemoveHelpBox |
I1 |
.h |
23-25 (+3) | class UButton; class UTextBlock; class UUserWidget; |
I1 |
.h |
148-171 (+24) | 6 fonctions dont l'UFUNCTION, 9 membres |
I1 |
.cpp (I0 vers I1) |
1447-1448 (+2) | commentaire VAL B2p-H N2 et LastSurfaceRefused.Reset(); |
I0 |
9 + 14 + 26 + 1 + 2 + 228 = 280 ; 3 + 24 = 27. Aucun ajout non demandé : chaque hunk se rattache à I0 ou I1 de la fiche. Non-régression B2p-C à B2p-H : zéro ligne retirée, zéro ligne modifiée ; les fonctions de C à H (TickSexCamera, TickCoupleMouse, TickCoupleBounds, TickSceneCamera, TickPanelClick, CoupleSpotFree, ComputeLabel) ne reçoivent que le Reset() de I0 (l. 1448). TickSexCamera garde bSexWheelZoom (l. 1104) et l'appel de TickPanelClick (l. 1095).
5. Verdict
| Point | Verdict |
|---|---|
| I0 (N2) | PASS-STATIC : Reset() dans la seule branche où le couple bouge, rien d'autre (§ 2, § 4) |
| I1, consigne 1 | PASS-STATIC |
| I1, consigne 2 | PASS-STATIC, réserve D1 |
| I1, consigne 3 | PASS-STATIC |
| I1, consigne 4 | PASS-STATIC, observation D2 |
| I1, consigne 5 | PASS-STATIC, observation D3 |
| I1, consigne 6 | PASS-STATIC |
I1, MappedKeys, BuildControlsHelp, TickControlsHelp, AttachHelpIcon, ToggleControlsHelp, EnsureHelpBox/RemoveHelpBox |
PASS-STATIC (§ 3.2) |
| Contrôles transverses (types, includes, dépendances, C4456/C4458/C4459 par lecture, non-régression) | PASS-STATIC |
| Global | PASS-STATIC : aucun défaut bloquant. Non couvert : la compilation (BLOCKED-compilation, à confier à BUILD) et tout comportement en jeu (reporté V7). |
6. Points à confirmer par l'utilisateur (cases)
- BUILD :
LifePlaycompile avec 0 erreur et 0 avertissement nouveau sous V7 ;LPCameraModeSubsystem.cppdoit figurer dans les unités compilées ; UHT régénèreLPCameraModeSubsystem.generated.havecexecToggleControlsHelp(premièreUFUNCTIONde la classe). - Décision sur D1 : faire traiter
AddChildnul avant V7 (correction de quelques lignes, par l'auteur) ou laisser l'essai CAM-86 trancher ; sans correction, la ligne « icone inseree » peut être écrite alors que rien n'est inséré. - Décision sur D2 : garder l'aide sans la ligne « Maj + molette » (règle de Big Boss à la lettre) ou ajouter « Shift + mouse wheel: raise / lower the couple » (contrôle de Room, établi par COMMUN-7).
- CAM-86 : ligne
Aide sexe : icone inseree dans … (parent, classe, n enfants), image …; icône à côté du champ de filtre ou des boutons, même image que FAQ ; ligne4 lignes d'origine masquees; les 4 lignes disparues. - CAM-87 : le survol montre l'info-bulle ; le clic ouvre et ferme la boîte ; la boîte est au bon endroit (la SPEC voulait « au même endroit que les 4 lignes » ; le code la met en bas à droite, marge basse de 96 px, l. 1936) ; la fermeture du panneau la ferme ; un clic gauche sur l'icône ne déclenche ni prise du couple ni bascule du panneau.
- CAM-88 : touches affichées (
Z/W,S,Q/A,D,Right/Left,Up/Down,SpaceBar,C), suivant un remappage fait par le menu Keyboard. - CAM-89 : hors du sexe, l'icône est absente du
Cursoret la boîte fermée ; texte de jouissance deTextBlock_1visible s'il apparaît (D3). - CAM-90 (N2) : deux passages sur la même commode écrivent deux lignes
surface refusee. - Accepter l'écart non annoncé E4 (boîte Slate au lieu de
UBorder/UTextBlock, ombre au lieu de contour).
Tours : 37 / 40
Constats
Défauts bloquants
Aucun (preuves : contrôles 1 à 16, § 3.1 à 3.4 et lecture point par point).
Défauts non bloquants
| # | Lieu | Constat | Niveau de preuve | État |
|---|---|---|---|---|
| D1 | .cpp l. 1889-1909 |
UPanelWidget::AddChild rend nullptr quand le parent de SearchAction est un panneau à enfant unique déjà occupé (PanelWidget.cpp:139-142, bCanHaveMultipleChildren faux). IconSlot est alors nul : aucun réglage de slot, mais le journal écrit quand même « icone inseree dans … » (l. 1906-1908) et la fonction rend le bouton orphelin, que TickControlsHelp traite comme une icône (l. 1801, 1804-1810). La consigne 2 de Big Boss (« ne rien insérer et écrire une ligne de témoin ») est tenue pour les cas qu'elle nomme (SearchAction ou parent introuvable), non pour celui-ci ; l'essai CAM-86 peut passer à tort sur la seule ligne. Correction possible : if (!IconSlot) vers une ligne « non inseree, n'accepte pas d'enfant » et return nullptr. |
établi (lecture du code et du moteur) ; probabilité en jeu : estimée faible (DIAG § 1.2 : le parent est probablement HorizontalBox_0 ou WrapBox) |
levé par la reprise D1 (voir la section « Reprise D1 » en fin de document) |
| D2 | .cpp l. 1745-1758 |
L'aide ne cite pas la molette (règle de Big Boss respectée : CAM ne la lit plus, l. 126 et 1104). Mais Room monte et descend le couple avec Maj + molette (CAM-B2p-E-IMPL.md:48, CAM-B2p-G-SPEC.md:13, CAM-B2p-F-VAL.md:64) : contrôle réel absent de l'aide. La voie d'origine « Maj + bouton tenu + souris » (SPEC § 1.6, dernière ligne) est absente aussi (omission de la SPEC § 2.3). |
établi (documents) ; absence de lecture de la molette par le C++ : établi (Grep) | ouvert, décision de Big Boss |
| D3 | .cpp l. 1775-1792 |
L'opacité 0 de TextBlock_1 est posée en sexe et n'est jamais rendue hors sexe : SexUI est nul quand bSexOn est faux, donc la branche de restitution (l. 1786-1792) ne s'exécute pas. Si GI.SexOn passe à faux avant que TextBlock_1 affiche un autre texte (jouissance), ce texte reste invisible. Le code ne touche à rien hors sexe, ce qui respecte la consigne 5. Le texte de jouissance n'est montré qu'en sexe (DIAG § 1.1, estimé fort). |
estimé (lecture) ; essai : CAM-89 | ouvert |
| D4 | .cpp l. 1798-1802 |
Une seule tentative par instance de Cursor (consigne 2) : si PC.CursorREF est déjà non nul mais que son arbre n'est pas encore complet, l'instance est consommée sans retenter. Conforme à la consigne ; un témoin « introuvable » au premier essai révélerait le cas. |
estimé | ouvert, négligeable |
| D5 | .cpp l. 1803, 1859-1865 |
BuildControlsHelp() (8 parcours des mappages, allocations de FString) est appelée à chaque passage de TickControlsHelp, soit toutes les 0,1 s en sexe : coût négligeable. L'ancrage étiré est testé seulement quand SearchAction est dans un CanvasPanel (Cast<UCanvasPanelSlot> nul ailleurs : aucun refus). |
établi | ouvert, cosmétique |
| D6 | .cpp l. 303, 310, 1762 |
MappedKeys ne filtre pas Key.IsValid() ; l'ordre des touches suit DefaultInput.ini : LeftRight donne Right/Left, DownUp donne Up/Down (« Right/Left, Up/Down: move the couple »), lecture un peu inversée. |
établi | ouvert, cosmétique |
| N5 | IMPL | Écart de gabarit (§ 1) : tête commune, « Ce qui n'a pas été fait », Tours : absents ; numérotation 0 à 5. |
établi | non bloquant, à reporter à l'auteur |
| N6 | IMPL § 3 | L'écart E4 (boîte Slate au lieu de UBorder/UTextBlock de la SPEC § 2.1 I-c) figure en § 2.2 mais pas en § 3 « Écarts à la SPEC ». |
établi | non bloquant |
| N7 | IMPL § 2.2 | « 10 membres » : le .h en a 9 (l. 161-171). Les autres chiffres (9 includes, 11 constantes, 6 fonctions, MD5, lignes) sont exacts. |
établi | non bloquant |
| N8 | compilation | Résidu C4459 d'en-têtes moteur : non excluable sans compilation (voir § 3.4). | estimé (faible probabilité) | à trancher par BUILD |
Non mesuré
Compilation et avertissements ; UHT (execToggleControlsHelp, première UFUNCTION de la classe) ; tout essai en jeu (CAM-86 à CAM-90, reportés V7) ; parent réel de SearchAction dans Cursor_C et classe de ce parent (aucune lecture MCP, décision de Big Boss) ; texte réel de TextBlock_1 (les 4 lignes sont dans un seul bloc : DIAG « estimé fort ») ; si GI.Cursor et PC.CursorREF désignent la même instance (le code n'emploie que PC.CursorREF, comme le PC) ; position visuelle de la boîte d'aide et de l'icône ; rendu des touches (GetDisplayName(false) : noms exacts de Z, W, SpaceBar, Right…) ; évaluation de la liaison Get_TextBlock_1_Text appelée aussi depuis le ticker de CAM (une évaluation de plus toutes les 0,1 s, estimée sans effet) ; LPTestStringCompat et porte G-U3 (sans objet : ni chaîne de compatibilité, ni configuration, ni compilation dans ce lot).
Fichiers à commiter (VAL)
A Docs/Migration/etat/CAM/CAM-B2p-I-VAL.md (dépôt du jeu, branche ue5.8). Fichiers modifiés par la VAL : ce livrable seulement ; fichiers de travail dans le dossier temporaire de session (scratchpad : v1.ps1, v2.ps1, v3.ps1, I*vs*.diff), hors dépôt.
À verser
lp-validate§ 1 : les instantanés deSnapshot.ps1ont la forme<instantané>\Source\LifePlay\<fichier>(chemin relatif conservé) plusmanifest.csv; un script de diff doit viser ce sous-dossier (échec constaté avecv1.ps1).lp-validate§ 1 : le crochetecriture-gardienrefuse aussi une redirection>utilisée pour dériver un script parsed; écrire le script neuf avec Write dans le dossier temporaire.lp-ue-compat/lp-build:UPanelWidget::AddChildrendnullptrpour un panneau à enfant unique non vide (PanelWidget.cpp:139-142) etInsertChildAtne réordonne pas le Slate vivant (PanelWidget.h:69-72) ;UTextBlock::SetTextdélie la liaison (TextBlock.cpp:469-472) ;UWidget::IsVisiblelit le widget Slate lui-même (Widget.cpp:395-404) ;FCoreStylepossède « WhiteBrush » (StarshipCoreStyle.cpp:213) ;TEXT("a" "b")est licite (ShaderCompiler.cpp:5978-5979).
Reprise D1 (2026-10-14, VAL statique du correctif de D1)
Seul le tableau des défauts (état de D1) et la liste des fichiers de travail ont été touchés dans les sections ci-dessus ; tout le reste est inchangé. Les numéros de ligne des sections 2 à 5 décrivent l'état CAM-B2p-I2 (.cpp 73CC3BD6…, 1969 lignes) ; après la reprise, le code placé après la l. 1889 est décalé de +7.
| # | Contrôle | Commande / lecture | Résultat brut | Verdict |
|---|---|---|---|---|
| R1 | MD5, taille, fins de ligne | pwsh -NoProfile -File scratchpad\v3.ps1 |
.cpp size=86153 CR=0 LF=1976 first3=2f2f20 last=0a MD5=0F383EF777DED71608347E17D4A0861F ; .h size=9813 CR=0 LF=179 MD5=6EDBBCCF61759B8C6EE4890DF9BC5FE7 |
PASS : égalent l'attendu (MD5, 1976 lignes, .h inchangé), LF pur, sans BOM |
| R2 | Instantané CAM-B2p-I2 |
même script, manifest.csv et octets |
.cpp 85842 / CR=0 / LF=1969 / 73CC3BD667059A903E44405C5E793DE3, .h 6EDBBCCF… : identiques à mon état final validé |
PASS |
| R3 | Diff I2 vers final | git diff --no-index -U0 et --numstat |
.cpp +7 / −0 (numstat : 7 0) ; .h : diff vide ; un seul hunk @@ -1889,0 +1890,7 @@ dans AttachHelpIcon ; 1969 + 7 = 1976 |
PASS |
| R4 | Contenu du hunk (lu en entier, -U4) |
.cpp l. 1890-1896 |
juste après UPanelSlot* IconSlot = SearchParent->AddChild(IconButton); (l. 1889) : if (!IconSlot) puis UE_LOG(LogLifePlay, Log, TEXT("Aide sexe : icone non inseree, %s (%s) refuse un enfant de plus"), *SearchParent->GetName(), *SearchParent->GetClass()->GetName()); puis return nullptr; |
PASS : texte conforme à la demande (parent et classe) |
| R5 | Aucun usage de IconSlot sans garde |
Grep IconSlot |
3 occurrences : l. 1889 (définition), l. 1890 (garde), l. 1897 (Cast<UHorizontalBoxSlot>(IconSlot)) et l. 1902 (Cast<UCanvasPanelSlot>(IconSlot)) : les deux Cast suivent le retour de la l. 1895 ; la ligne « icone inseree » (l. 1913) et return IconButton (l. 1916) aussi |
PASS : chemin nul = journal « non inseree » puis nullptr, rien d'autre |
| R6 | Format UE_LOG |
lecture l. 1893-1894 | 2 %s, 2 arguments (FString déréférencées) |
PASS-STATIC |
| R7 | Effet de return nullptr en amont |
lecture de TickControlsHelp l. 1798-1810 |
HelpCursor est déjà affecté (une tentative par instance, pas de nouvel essai) ; HelpButton reçoit nullptr donc HelpButton.Get() est nul et le bloc de visibilité et d'info-bulle est sauté ; IconButton, sans référence ni parent, est ramassé par le GC (son lien OnClicked pointe vers le sous-système, sans effet) |
PASS-STATIC (ramassage : estimé) |
| R8 | Homonymes nouveaux | lecture du hunk | aucun nouveau local, paramètre, membre ni constante (le hunk n'emploie que IconSlot, SearchParent, LogLifePlay, existants) : pas de C4456, C4458 ni C4459 |
PASS-STATIC |
| R9 | Fichiers touchés | Get-ChildItem |
.cpp 14:58:56 ; .h 14:43:12 (inchangé) ; instantané I2 14:58:51 |
PASS |
D1 : levé (PASS-STATIC). Le cas « AddChild rend nul » écrit la ligne « icone non inseree, () refuse un enfant de plus » et rend nullptr avant tout usage du slot et avant la ligne « icone inseree » ; la consigne 2 de Big Boss est désormais tenue pour ce cas. L'essai CAM-86 ne peut plus passer à tort sur la seule ligne « icone inseree ».
Verdict de la reprise : PASS-STATIC, aucun défaut nouveau, aucun bloquant. Le verdict global de la § 5 reste PASS-STATIC (compilation à BUILD, comportement à V7). D2 (Maj + molette) et D3 restent ouverts, à Big Boss ; ils ne sont pas tranchés ici. Non mesuré en plus : compilation du nouveau .cpp ; passage réel par la branche nulle (nécessite un parent à enfant unique, non lu faute de MCP).
Correction de comptage : dans R5, les occurrences de IconSlot sont 4 (l. 1889, 1890, 1897, 1902), et non 3.
Tours de la reprise : 5 (écriture du script, exécution, 2 lectures et recherche, écriture du livrable) ; total du livrable : 42 (dépassement du budget de 40 de la fiche d'origine, la reprise étant une demande ultérieure).