21 KiB
Fiche STG-B2q-VAL — Niveau N1 — Modèle prévu (agent lp-validator) | utilisé claude-sonnet-5-5 — Agent lp-validator — Skills lp-validate, sk-protocol, sk-recount, debug-verification
STG-B2q-VAL : validation statique de B2q-a (bornes de rendu des Person) et du témoin T-cull (2026-10-14)
Méthode : VAL statique, sans UE ni compilation, aucune écriture hors de ce livrable. Copie D:\Game\LifePlay-master 5.8 (branche ue5.8, HEAD 0745917). Moteur lu : D:\Game\Launcher\Engine\UE_5.8.
Les chemins moteur ci-dessous sont relatifs à Engine\Source\Runtime\.
Deux états validés : les sections 1 à 6 portent sur la première version (cpp C9D1AC98…, 1717 lignes) ; la section 4b contrôle le delta de la version corrigée par l'orchestrateur (cpp 7448C8FB…, 1724 lignes).
1. Fiches amont relues
| Fiche | Fichier | Relue |
|---|---|---|
| STG-B2q-DIAG | Docs\Migration\etat\ST\STG\STG-B2q-DIAG.md (137 lignes) |
en entier |
| STG-B2q-IMPL | Docs\Migration\etat\ST\STG\STG-B2q-IMPL.md (88 lignes, version de la 1re VAL) |
en entier |
| Diff | Docs\Migration\etat\ST\STG\STG-B2q.diff (167 lignes, version de la 1re VAL) |
en entier |
| Instantané | D:\Game\LifePlay_Backup_5.5\STG-B2q\ (manifest.csv, 2 entrées) |
relu |
Aucune autre IMPL dans le lot B2q (DIAG puis IMPL). L'IMPL § 2b et § 5 mis à jour par l'orchestrateur après la 1re VAL ne sont pas relus ici (le contrôle du delta porte sur le code, section 4b).
2. Points à confirmer des IMPL
| # | Point (IMPL § 4) | Statut | Motif |
|---|---|---|---|
| 1 | Bar et café : C2 autour des personnages assis, aucune disparition, lignes B2q-a / T-cull mesure, aucune alerte |
reporté (COMMUN-8) | essai en jeu, hors VAL statique |
| 2 | Personnage couché : même contrôle | reporté (COMMUN-8) | idem |
| 3 | Coût : stat unit avant et après, ou lignes LPDebug hitch |
reporté (COMMUN-8) | mesure en jeu |
| 4 | Alerte T-cull avec dans=1 : cause hors bornes |
reporté (COMMUN-8) | dépend du journal de jeu |
3. Critères rejoués (commande, sortie)
3.1 MD5 (point 1 de la fiche) : PASS
Commande : md5sum Source/LifePlay/LPDirectControlSubsystem.{cpp,h} et md5sum sur l'instantané.
c9d1ac98df479a4aac95e44213766f78 *Source/LifePlay/LPDirectControlSubsystem.cpp
5f3492917b8202b267d8879e4613966b *Source/LifePlay/LPDirectControlSubsystem.h
1a74d6b724bd63f04e04fda42682446d *D:/Game/LifePlay_Backup_5.5/STG-B2q/Source/LifePlay/LPDirectControlSubsystem.cpp
519e23dc9eb2809fa36c1bbf942a7667 *D:/Game/LifePlay_Backup_5.5/STG-B2q/Source/LifePlay/LPDirectControlSubsystem.h
Égal à IMPL § 5 (C9D1AC98… / 5F349291…) et § 1 (1A74D6B7… / 519E23DC…) à l'époque de la 1re VAL. manifest.csv : mêmes MD5, tailles 53814 / 3552. Tools\FileCheck.ps1 -Lot STG-B2q -OnlyChanged : fichiers=2 CRLF=2 alertes=0 introuvables=0, contenu modifie=2, code 0. Le cpp actuel a changé (section 4b).
3.2 Diff régénéré (point 2) : PASS, avec un écart de compte
Commande : diff -u <instantané> <actuel> pour chaque fichier, comparé à STG-B2q.diff (lignes d'en-tête et CR ôtés) : aucune différence (sortie vide). diff normal : cpp 0 retirée / 123 ajoutées ; h 0 retirée / 5 ajoutées. Recompte du fichier .diff (grep -c '^+' hors +++) : 128.
- Écart E1 : IMPL § 2 annonce « 127 lignes ajoutées » ; recompté 128 (123 + 5). Sans conséquence sur le code ; chiffre de l'IMPL à corriger.
- Rien d'autre que l'IMPL § 2 : hunks cpp = include
Camera/PlayerCameraManager.h, appelFitPersonBounds(DeltaTime)dansTick, corps de la fonction ; hunks h = déclaration + 3 membres. Aucun ajout non annoncé. git diff --stat HEADdonne 635/24 lignes sur ces deux fichiers : ce sont les lots antérieurs (M1e, C6-b, C7-a, etc.) non encore commités ; le delta B2q est celui de l'instantané.
3.3 Fins de ligne, ASCII, en-tête (point 6) : PASS
Commande : script python -I (comptage d'octets) sur les fichiers.
Source/LifePlay/LPDirectControlSubsystem.cpp CRLF 1717 LFseul 0 CRseul 0 nonascii bytes 6 BOM False
Source/LifePlay/LPDirectControlSubsystem.h CRLF 101 LFseul 0 CRseul 0 nonascii bytes 0 BOM False
Docs/Migration/etat/ST/STG/STG-B2q-IMPL.md CRLF 0 LFseul 88 CRseul 0 nonascii bytes 182 BOM False
D:/Game/LifePlay_Backup_5.5/STG-B2q/.../LPDirectControlSubsystem.cpp CRLF 1594 LFseul 0 nonascii bytes 6
- cpp : CRLF pur (1594 + 123 = 1717, donc les 123 lignes ajoutées sont en CRLF), aucun LF isolé. h : CRLF pur.
- Non-ASCII du cpp : 6 octets avant (instantané) et 6 après, aux lignes 455 (
« %s ») et 514 (accent), préexistantes ; 0 ajouté. Les 123 + 5 lignes ajoutées sont ASCII. - IMPL : LF pur, en-tête complet (« Fiche … — Niveau N3 — Modèle prévu … | utilisé … — Agent … — Skills … »), aucun
C:\Users(Grep, 0 résultat).
3.4 Gardes de Big Boss, par lecture de FitPersonBounds (point 3) : PASS-STATIC
Source : Source/LifePlay/LPDirectControlSubsystem.cpp l. 1065-1185 (version de la 1re VAL ; le diff les range en l. 23-142).
| Garde | Lecture | Verdict |
|---|---|---|
| Boucle unique toutes les 0,5 s | BoundsDelay += DeltaTime; if (BoundsDelay < ScanInterval) return; puis remise à 0 ; une seule boucle TActorIterator<ACharacter> (+ un nettoyage de MeasuredSeats, borné par le nombre de personnes mesurées). Appel unique dans Tick (l. 875) |
PASS |
| Person visibles seulement | continue si pas de maillage, Person->IsHidden(), !Body->IsVisible(), GetNumBones()==0, ou classe ne commençant pas par Person_C (même filtre que LPDebugSubsystem.cpp l. 198 et 367, LPOutdoorRoomSubsystem.cpp l. 343) |
PASS |
| S borné à [1 ; 4] | FMath::Clamp(static_cast<float>(Needed), 1.f, MaxScale) avec MaxScale = 4.f ; Needed part de 1.0 et ne fait que croître |
PASS |
| Hystérésis 10 % | if (FMath::Abs(Scale - Current) > ScaleChange * Current), ScaleChange = 0.1f, relatif à l'échelle courante |
PASS |
| Journal B2q-a | une UE_LOG dans le seul bloc « changement de plus de 10 % » |
PASS |
| Journal T-cull mesure | une UE_LOG par nouveau meuble : MeasuredSeats.FindRef(Person).Get() != Seat puis Add ; entrée retirée quand OccupyingFnt est vide |
PASS |
| Alerte T-cull ≤ 1/s | CullAlertDelay décrémenté à chaque tick, condition CullAlertDelay <= 0.f, remis à AlertInterval = 1.f à l'émission ; un seul délai global |
PASS |
| Collisions et tracés | voir ci-dessous | PASS |
Collisions et tracés (lu dans le moteur 5.8) :
UPrimitiveComponent::SetBoundsScale(Engine\Private\Components\PrimitiveComponent.cppl. 2538-2543) :BoundsScale = Nouveau; UpdateBounds(); MarkRenderTransformDirty();Rien d'autre.USkinnedMeshComponent::InvalidateCachedBounds(SkinnedMeshComponent.cppl. 3313-3339) : met à fauxbCachedLocalBoundsUpToDate/bCachedWorldSpaceBoundsUpToDatesur le composant, ses suiveurs de pose et ses enfants skinnés. État de cache de bornes seulement.CalcMeshBound(SkinnedMeshComponent.cppl. 2300-2301) :BoxExtent *= BoundsScaleetSphereRadius *= BoundsScale, centre inchangé.bEnableLineCheckWithBounds(SkeletalMeshComponent.hl. 904) etLineCheckBoundsScale(l. 468) : absents du diff et de toutSource/(Grep, 0 résultat).SkeletalMeshComponent.cppne les initialise qu'au constructeur (l. 450).- La seule lecture de
Boundsailleurs dansSource/LifePlayqui sert à une décision (LPDirectControlSubsystem.cppl. 1352,GetClosestPointTo) porte sur desUStaticMeshComponentde meubles, pas sur le corps d'une Person. - Le diff ne touche ni capsule, ni profil de collision, ni asset physique.
3.5 Logique du facteur (point 4) : PASS-STATIC, avec réserves
Formule de la 1re version (l. 1125-1135) : Extent = Bounds.BoxExtent / Current (demi-étendue à l'échelle 1), Half = max(Extent[axe], 10), Needed = max(1, max sur les axes de (|Bassin - Origin| + Half) / Half).
- Stabilité : établi par lecture.
Bounds.Originne dépend pas deBoundsScale(seulBoxExtentest multiplié,CalcMeshBoundl. 2300) ;Extentdivisé parCurrentredonne la valeur à l'échelle 1 ;Neededest donc le même avant et après application, et au scan suivant|Scale - Current| = 0: pas d'oscillation entre deux valeurs. Le cache de bornes est invalidé avantSetBoundsScale, indispensable carUSkeletalMeshComponent::CalcBounds(SkeletalMeshComponent.cppl. 3424-3445) réutilise sinon les bornes en cache, qui portent l'ancienne échelle. - Division par zéro impossible :
Current >= KINDA_SMALL_NUMBER(1e-4f,UnrealMathUtility.hl. 131) etHalf >= MinExtent = 10.0. - Cas debout (réserve R1, traitée en 4b) : la formule de la 1re version donne
Needed = 1 + |écart| / Halfpar axe, donc S > 1 dès que le bassin n'est pas exactement au centre (S = 1,1 à 1,3 estimé). IMPL § 2 disait S = 1 : inexact à la lettre. - Variation avec l'orientation (R2) : les bornes du moteur sont une AABB monde ; une rotation en lacet change
ExtentetOffset, doncNeeded. Une personne qui tourne peut faire changer S de plus de 10 % et produire une ligne par balayage (0,5 s). Borné, mais bruyant. - Échelle déjà > 1 venant d'ailleurs (R3) :
Currentest lue et divisée, donc le calcul reste juste, mais S est ensuite imposé (borné à [1 ; 4]) : une valeur externe de 3 sur le corps serait ramenée à S si S diffère de plus de 10 %, et un Blueprint qui remet 3 provoquerait un va-et-vient. Le DIAG § 2.2 estime la valeur du gabarit à 1 (non vérifié par MCP). LesSetBoundsScale(3.0)dePerson::NewProxyportent sur les vêtements enbUseAttachParentBound, dont les bornes viennent du parent (SceneComponent.cppl. 1696-1699) : sans conflit. - Enfants
bUseAttachParentBound:Body->GetChildrenComponents(true, Children)(tous descendants) ; pour chaqueUPrimitiveComponentavec le drapeau :UpdateBounds()puisMarkRenderTransformDirty(). Le corps est mis à jour avant les enfants. Correct.
3.6 Compilabilité par lecture des en-têtes UE 5.8 (point 5) : PASS-STATIC (non compilé)
| Symbole | Lu | Accès / signature |
|---|---|---|
UPrimitiveComponent::BoundsScale |
PrimitiveComponent.h l. 970 |
float, après public: (l. 961) : OK |
SetBoundsScale(float) |
l. 1558 | public (ENGINE_API) |
WasRecentlyRendered(float) const |
l. 999 | public |
bUseAttachParentBound |
SceneComponent.h l. 236 |
uint8 : 1, après public: (l. 223) : OK |
Bounds |
SceneComponent.h l. 129 |
FBoxSphereBounds, public (l. 127) |
GetBox(), Origin, BoxExtent |
Math\BoxSphereBounds.h l. 226 (GetBox() const) |
membres publics |
FBox::IsInside(const TVector<T>&) const |
Math\Box.h l. 494 |
OK avec FVector |
FVector::GetAbs, operator[](int32) |
Math\Vector.h l. 457 et 465 |
T operator[](int32) const : OK en double |
GetChildrenComponents(bool, TArray<USceneComponent*>&) const |
SceneComponent.h l. 725 |
public |
UpdateBounds() |
SceneComponent.h l. 1130 (virtuel) |
public |
MarkRenderTransformDirty() |
ActorComponent.h l. 1134 |
public (zone public: l. 889-1420) |
InvalidateCachedBounds() |
SkinnedMeshComponent.h l. 1846 |
public (public: l. 1838) |
GetPhysicsAsset() const |
SkinnedMeshComponent.cpp l. 2210 |
public |
GetNumBones, GetBoneIndex, GetBoneName, GetBoneLocation |
SkinnedMeshComponent.h l. 1144, 1156, 1165, 2014 |
GetBoneLocation(FName, Space = WorldSpace) const |
ProjectWorldLocationToScreen(FVector, FVector2D&, bool=false) const |
PlayerController.h l. 742 |
const : OK via const APlayerController* |
GetViewportSize(int32&, int32&) const |
PlayerController.h l. 1191 |
const : OK |
PlayerCameraManager->GetCameraLocation() const |
PlayerCameraManager.h l. 705 ; PlayerController.h l. 287 |
include Camera/PlayerCameraManager.h ajouté (l. 19) |
TMap::FindRef(KeyInitType), Add(...), Remove(KeyInitType), CreateIterator, RemoveCurrent |
Containers\Map.h.inl l. 661, 323-326, 409, 979, 943/965 |
conformes ; précédent : TMap<TWeakObjectPtr<AActor>, ...> dans LPOutdoorRoomSubsystem.h l. 78 et Seen.Add(Person, ...) dans LPOutdoorRoomSubsystem.cpp l. 361 |
TActorIterator, FObjectPropertyBase, CastField |
EngineUtils.h inclus (l. 30) ; motif OccupyingFnt déjà compilé aux l. 526, 570-571, 972-973 |
OK |
KINDA_SMALL_NUMBER |
UnrealMathUtility.h l. 67 et 131 |
(1.e-4f) float ; dépréciation désactivée par défaut ; déjà utilisé dans LPOutdoorRoomSubsystem.cpp |
Conversions float / double (C4244) : Current, Scale, CullAlertDelay sont des float ; FMath::Max(float, float), FMath::Clamp(float, 1.f, 4.f) : types identiques. Extent[Axis], MinExtent, Needed : double. Needed ramené en float par static_cast explicite. Bounds.BoxExtent / Current : FVector / float accepté. Aucun C4244 attendu (estimé : seul le build COMMUN-8 le prouvera). Ambiguïté possible de surcharge sur MeasuredSeats.Add(Person, Seat) : même appel que le précédent Seen.Add(Person, ...) ; estimé sans risque.
Collisions de noms (unity) : membres BoundsDelay, CullAlertDelay, MeasuredSeats, FitPersonBounds : 24 occurrences dans 2 fichiers, aucun ailleurs dans Source/. Les constantes locales n'ont pas d'homonyme de portée fichier ni de macro dans Source/. Aucune variable locale ne masque un membre de la classe.
4. Diff lu en entier
- Fichiers : 2 (
LPDirectControlSubsystem.cpp,LPDirectControlSubsystem.h), 3 hunks cpp + 2 hunks h. - Lignes (1re version) : 128 ajoutées (123 + 5), 0 retirée. IMPL annonce 127 (écart E1).
- Aucun fichier hors IMPL § 2 modifié par ce lot (instantané limité à ces deux fichiers).
git status --short Source/montre d'autres fichiers modifiés ou non suivis (LPDebugSubsystem.*,LPOutdoorRoomSubsystem.*,LifePlay.cpp,LPBonusRewardSubsystem.*,LPCameraModeSubsystem.*,LPSaveRelaunch.*) : autres lots, hors périmètre.
4b. Contrôle du delta (7448C8FB)
Demandé par l'orchestrateur après la 1re VAL : l'orchestrateur a corrigé E2 (S > 1 debout) et le transitoire d'apparition. Verdict de cette section : PASS-STATIC.
- MD5 (
md5sum) : cpp7448c8fb1091bd2a994cca4aa7f8b7a6, h5f3492917b8202b267d8879e4613966b(inchangé).FileCheck.ps1 -Lot STG-B2q -OnlyChanged: même MD5,alertes=0. Établi. - Contenu du delta (version corrigée contre l'instantané) :
git diff --no-index --numstat=130 0; 1re version = 123 + 0 ; delta = +7 lignes, 0 retirée.git diff --no-index -U0: 3 hunks (-18,0 +19,-873,0 +875,-1062,0 +1065,128: 121 + 7). Les lignes portant les termes du delta sont exactement :- l. 1068, phrase du commentaire d'en-tête : « … borne a [1, 4], au-dela d'un ecart tolere de 0,3 demi-etendue (debout : S = 1) ; applique seulement … » (ligne modifiée, même nombre de lignes) ;
- l. 1078-1079 : commentaire et
constexpr double Tolerance = 0.3;(+2) ; - l. 1130-1134 :
if (Extent.GetMax() < 1.0) { // commentaire ; continue; }(+5) ; - l. 1140 :
Needed = FMath::Max(Needed, (FMath::Max(0.0, Offset[Axis] - Tolerance * Half) + Half) / Half);(ligne modifiée). Total : 2 + 5 = 7 lignes ajoutées + 2 lignes modifiées, cohérent avec 130 − 123 = 7. Le fichierSTG-B2q.diffactuel est identique au diff régénéré du cpp et du h (diffdes deux flux, sortie vide). Limite : la versionC9D1AC98…n'existe plus sur disque ; mon essai de la reconstituer en retirant ces lignes du fichier actuel (sed+md5sum) a donné09493e3a…et nonC9D1AC98…(reconstitution des deux lignes modifiées non fidèle à l'octet près, non élucidée). L'absence d'autre changement repose donc sur le compte (130 = 123 + 7, aucune ligne retirée) et sur la lecture des l. 1065-1145 contre le diff que j'ai lu en entier lors de la 1re VAL, pas sur une comparaison d'octets. Estimé fort, non prouvé à l'octet.
- Stabilité et types :
Needed = max(1, max sur les axes de (max(0, Offset − 0,3·Half) + Half) / Half): toujours fonction deExtent(échelle 1) et deOffset, donc indépendante deBoundsScalecourante ; au scan suivantScale == Current: pas d'oscillation (raisonnement de 3.5 conservé). Établi par lecture.- Si tous les écarts sont ≤ 0,3
Half, le termemax(0, …)vaut 0 et chaque rapport vaut exactement 1 : S = 1. Établi. Marge de couverture : le bassin est couvert siS·Half ≥ écart; la formule donneS·Half = écart + 0,7·Half, donc la marge autour du bassin passe de 1,0 à 0,7 demi-étendue (réduite, bassin toujours dans les bornes tant que S < 4). Risque faible, à lire dans COMMUN-8. - Types :
FVector::GetMax() constrenvoieT(Vector.hl. 516,TVector<double>) ;Extent.GetMax() < 1.0double contre double ;FMath::Max(0.0, Offset[Axis] - Tolerance * Half):0.0,Offset[Axis](double),ToleranceetHalf(double) :FMath::Max<double>sans conversion ; résultat additionné àHalfet divisé : double. Aucun C4244 attendu (estimé, non compilé). - Saut
Extent.GetMax() < 1.0:continueplacé après le calcul dePelvisetCurrent, avant le calcul de S, de la mesure T-cull et de l'alerte : une personne aux bornes encore nulles est ignorée entièrement pour ce balayage (0,5 s), y compris pour la mesure de meuble (refaite au balayage suivant,MeasuredSeatsnon mis à jour). Sans effet gênant. Toute personne dont l'étendue réelle serait inférieure à 1 cm serait ignorée en permanence : non réaliste pour un corps humain.
- Fins de ligne et ASCII :
FileCheck: cppCRLF 1724,LF 0,CR 0, pas de BOM ; hCRLF 101. Soit 1724 CR pour 1724 LF (1717 + 7). Grep[^\x00-\x7F]sur le cpp : 2 lignes seulement, l. 455 et 514, les mêmes qu'avant ; 0 non-ASCII ajouté (le « é » du commentaire a bien disparu).
Résultat : E2 est corrigé dans le code (le terme de tolérance rend S = 1 debout, sous la réserve de 0,3 demi-étendue mesurée sur les vraies bornes en COMMUN-8) ; le transitoire d'apparition est écarté par le saut. R1 est donc levé à la lecture ; R2 (rotation) et R3 (échelle externe) restent. E1 et E3 (documentation de l'IMPL) restent à la charge de l'orchestrateur ; l'IMPL § 2b / § 5 n'a pas été relu ici.
5. Verdict
PASS-STATIC pour la 1re version (7 constats ci-dessous) et PASS-STATIC pour le delta 7448C8FB… (section 4b), avec la limite d'octets nommée en 4b. Les MD5 concordent, le diff régénéré est identique au .diff, les quatre gardes de Big Boss sont tenues à la lecture, aucun effet sur collisions ni tracés, l'API relue en UE 5.8 est présente avec l'accès attendu. Non compilé, non exécuté.
Écarts :
- E1 : IMPL § 2 annonce 127 lignes ajoutées ; recompté 128 (1re version), 135 (130 + 5 du .h) pour la version corrigée.
- E2 : IMPL § 2 « debout S = 1 et rien ne change » inexact à la lettre dans la 1re version ; corrigé dans le code (4b).
- E3 (forme) : l'IMPL n'a pas la section « Écarts à la SPEC » du gabarit IMPL (gabarits.md : § 2), et sa liste « Fichiers à commiter » n'indique pas
A/M/D. Les sections sont dans un autre ordre (instantané en premier).
Risques à surveiller en COMMUN-8 :
- Coût de rendu et ombres : jusqu'à 4 fois plus grandes, les bornes des personnes assises ou couchées les font traiter plus souvent (rendu hors champ, passe d'ombre, requêtes d'occlusion) ; l'avertissement de
PrimitiveComponent.hl. 966 le dit (« reduce performance and shadow quality »). Le streaming de textures utilise aussi le rayon des bornes (SkinnedMeshComponent.cppl. 2200-2207) : des mips plus élevés possibles pour ces corps. Coût d'écriture borné : un balayage de tous lesACharacterpar 0,5 s. - Personnes en scène de sexe : le bassin y est loin de la racine, donc S montera vers 4 pour les deux corps ; aucun conflit de code trouvé, mais l'essai doit couvrir au moins une scène.
- Bassin loin pour une autre raison (animation de danse, ragdoll, téléportation, os 0 mal choisi sur un squelette sans
hipnipelvis) : S est quand même relevé jusqu'à 4. Au-delà de 3 demi-étendues d'écart, le plafond ne couvre plus le corps (alerte T-cull attendue avecdans=0). - Bruit de l'alerte T-cull : le filtre « non caché » n'écarte pas une personne légitimement occultée derrière un mur (bassin dans le viewport à moins de 15 m,
WasRecentlyRenderedfaux). La limite d'1 ligne par seconde est tenue, mais le journal peut en contenir une par seconde dans ce cas. - Échelle externe sur le corps (R3 de 3.5) : va-et-vient possible si un Blueprint impose sa propre valeur.
- Rotation (R2) : une personne qui tourne peut produire une ligne
B2q-apar balayage. - Non établi : les dimensions réelles des bornes des assets
bridget_gpetmichael(non lues), donc la valeur réelle de la tolérance de 0,3 ; l'effet réel sur les disparitions (essai en jeu).
6. Points à confirmer par l'utilisateur
- COMMUN-8 : bar, café
fnt_new048et lit sans disparition, lignesB2q-a/T-cull mesureprésentes (IMPL § 4 points 1 et 2). - COMMUN-8 : coût (
stat unitouLPDebug hitch) (IMPL § 4 point 3). - COMMUN-8 : relever les lignes
B2q-ades personnes debout : attendu aucune ligne (S = 1 sous la tolérance de 0,3) ; s'il y en a, la tolérance est trop basse. - Corriger dans l'IMPL le chiffre de lignes ajoutées (E1) et la forme (E3) : décision de l'orchestrateur ; non fait ici.
- Fiche à part si une alerte
T-cullapparaît avecdans=1(IMPL § 4 point 4).
Fichiers à commiter : Docs/Migration/etat/ST/STG/STG-B2q-VAL.md (A). Aucun autre fichier écrit.
Tours : 24 / 30