From 789b065486c8dcfaf6568479621510517d1da99b Mon Sep 17 00:00:00 2001 From: axiomlogicnexus Date: Wed, 29 Apr 2026 16:32:51 +0200 Subject: [PATCH] Shape downstream guidance by drill follow-up packet sources --- .../HyperTwistTrainingCoachLibrary.cpp | 212 +++++++++++++++++- .../HyperTwistTrainingSubsystem.cpp | 137 +++++++++-- 2 files changed, 331 insertions(+), 18 deletions(-) diff --git a/UnrealHyperTwist/Source/UnrealHyperTwist/Private/HyperTwistTraining/HyperTwistTrainingCoachLibrary.cpp b/UnrealHyperTwist/Source/UnrealHyperTwist/Private/HyperTwistTraining/HyperTwistTrainingCoachLibrary.cpp index 63ee550..eeda4c1 100644 --- a/UnrealHyperTwist/Source/UnrealHyperTwist/Private/HyperTwistTraining/HyperTwistTrainingCoachLibrary.cpp +++ b/UnrealHyperTwist/Source/UnrealHyperTwist/Private/HyperTwistTraining/HyperTwistTrainingCoachLibrary.cpp @@ -86,6 +86,29 @@ namespace HyperTwistTrainingCoachLibraryInternal return SourceLabel.Contains(TEXT("method-drill-recovery-packet-")); } + bool IsMethodDrillFollowUpPacketSource(const FString& SourceLabel) + { + return SourceLabel.Contains(TEXT("method-drill-follow-up-packet-")); + } + + bool IsStrongMethodDrillFollowUpPacketMemorySource(const FString& SourceLabel) + { + return SourceLabel.StartsWith(TEXT("coach-memory-dashboard-method-drill-follow-up-packet-strong-")) + || SourceLabel == TEXT("dashboard-handoff-method-drill-follow-up-packet-strong-queued") + || SourceLabel == TEXT("dashboard-handoff-method-drill-follow-up-packet-strong-follow-up") + || SourceLabel == TEXT("dashboard-handoff-method-drill-follow-up-packet-strong-recommended") + || SourceLabel == TEXT("coach-memory-method-drill-follow-up-packet-strong"); + } + + bool IsWeakMethodDrillFollowUpPacketMemorySource(const FString& SourceLabel) + { + return SourceLabel.StartsWith(TEXT("coach-memory-dashboard-method-drill-follow-up-packet-weak-")) + || SourceLabel == TEXT("dashboard-handoff-method-drill-follow-up-packet-weak-queued") + || SourceLabel == TEXT("dashboard-handoff-method-drill-follow-up-packet-weak-follow-up") + || SourceLabel == TEXT("dashboard-handoff-method-drill-follow-up-packet-weak-recommended") + || SourceLabel == TEXT("coach-memory-method-drill-follow-up-packet-weak"); + } + bool IsStrongMethodDrillRecoveryMemorySource(const FString& SourceLabel) { return SourceLabel.StartsWith(TEXT("coach-memory-dashboard-method-drill-recovery-strong-")) @@ -158,6 +181,17 @@ namespace HyperTwistTrainingCoachLibraryInternal return EHyperTwistTrainingCoachHandoffKind::None; } + EHyperTwistTrainingCoachHandoffKind MethodDrillFollowUpPacketHandoffKindFromSourceLabel( + const FString& SourceLabel, + const EHyperTwistTrainingCoachHandoffKind FallbackKind) + { + const EHyperTwistTrainingCoachHandoffKind ParsedKind = + MethodDrillRecoveryPacketHandoffKindFromSourceLabel(SourceLabel); + return ParsedKind != EHyperTwistTrainingCoachHandoffKind::None + ? ParsedKind + : FallbackKind; + } + FString DescribeMethodDrillRecoveryPacketLane( const EHyperTwistTrainingCoachHandoffKind HandoffKind) { @@ -174,6 +208,22 @@ namespace HyperTwistTrainingCoachLibraryInternal } } + FString DescribeMethodDrillFollowUpPacketLane( + const EHyperTwistTrainingCoachHandoffKind HandoffKind) + { + switch (HandoffKind) + { + case EHyperTwistTrainingCoachHandoffKind::Queue: + return TEXT("queue-entry"); + case EHyperTwistTrainingCoachHandoffKind::FollowUp: + return TEXT("follow-up-packet"); + case EHyperTwistTrainingCoachHandoffKind::Recommended: + return TEXT("recommended-brief"); + default: + return TEXT("none"); + } + } + FString DescribeCoachHandoffKind(const EHyperTwistTrainingCoachHandoffKind HandoffKind) { switch (HandoffKind) @@ -506,6 +556,18 @@ namespace HyperTwistTrainingCoachLibraryInternal { return TEXT("successful drill-follow-up-packet history"); } + if (SourceLabel == TEXT("coach-memory-dashboard-method-drill-follow-up-packet-strong-queued")) + { + return TEXT("successful queued drill-follow-up-packet history"); + } + if (SourceLabel == TEXT("coach-memory-dashboard-method-drill-follow-up-packet-strong-follow-up")) + { + return TEXT("successful follow-up drill-follow-up-packet history"); + } + if (SourceLabel == TEXT("coach-memory-dashboard-method-drill-follow-up-packet-strong-recommended")) + { + return TEXT("successful recommended drill-follow-up-packet history"); + } if (SourceLabel == TEXT("coach-memory-method-drill-follow-up-weak")) { return TEXT("weak method-drill follow-up history"); @@ -514,6 +576,18 @@ namespace HyperTwistTrainingCoachLibraryInternal { return TEXT("weak drill-follow-up-packet history"); } + if (SourceLabel == TEXT("coach-memory-dashboard-method-drill-follow-up-packet-weak-queued")) + { + return TEXT("weak queued drill-follow-up-packet history"); + } + if (SourceLabel == TEXT("coach-memory-dashboard-method-drill-follow-up-packet-weak-follow-up")) + { + return TEXT("weak follow-up drill-follow-up-packet history"); + } + if (SourceLabel == TEXT("coach-memory-dashboard-method-drill-follow-up-packet-weak-recommended")) + { + return TEXT("weak recommended drill-follow-up-packet history"); + } if (SourceLabel == TEXT("coach-memory-method-drill-recovery-strong")) { return TEXT("successful drill-driven recovery history"); @@ -2110,6 +2184,23 @@ FHyperTwistCoachBrief UHyperTwistTrainingCoachLibrary::DeriveCoachFollowUpBrief( const FString MethodDrillRecoveryPacketLaneLabel = HyperTwistTrainingCoachLibraryInternal::DescribeMethodDrillRecoveryPacketLane( MethodDrillRecoveryPacketHandoffKind); + const bool bStrongMethodDrillFollowUpPacketSource = + HyperTwistTrainingCoachLibraryInternal::IsMethodDrillFollowUpPacketSource( + ActionPlan.PreferredCoachHandoffSourceLabel) + && HyperTwistTrainingCoachLibraryInternal::IsStrongMethodDrillFollowUpPacketMemorySource( + ActionPlan.PreferredCoachHandoffSourceLabel); + const bool bWeakMethodDrillFollowUpPacketSource = + HyperTwistTrainingCoachLibraryInternal::IsMethodDrillFollowUpPacketSource( + ActionPlan.PreferredCoachHandoffSourceLabel) + && HyperTwistTrainingCoachLibraryInternal::IsWeakMethodDrillFollowUpPacketMemorySource( + ActionPlan.PreferredCoachHandoffSourceLabel); + const EHyperTwistTrainingCoachHandoffKind MethodDrillFollowUpPacketHandoffKind = + HyperTwistTrainingCoachLibraryInternal::MethodDrillFollowUpPacketHandoffKindFromSourceLabel( + ActionPlan.PreferredCoachHandoffSourceLabel, + ActionPlan.PreferredCoachHandoffKind); + const FString MethodDrillFollowUpPacketLaneLabel = + HyperTwistTrainingCoachLibraryInternal::DescribeMethodDrillFollowUpPacketLane( + MethodDrillFollowUpPacketHandoffKind); const FString NarrowedContinuationSourceLabel = bNarrowedContinuationSource ? HyperTwistTrainingCoachLibraryInternal::DescribeCoachMemorySourceLabel( @@ -2144,7 +2235,53 @@ FHyperTwistCoachBrief UHyperTwistTrainingCoachLibrary::DeriveCoachFollowUpBrief( HyperTwistTrainingCoachLibraryInternal::MergeFocusCaseIds( ActionPlan.FocusCaseIds, RecoveryPacketCases); - if (bStrongMethodDrillRecoveryPacketSource) + if (bStrongMethodDrillFollowUpPacketSource) + { + switch (MethodDrillFollowUpPacketHandoffKind) + { + case EHyperTwistTrainingCoachHandoffKind::Queue: + if (bHasDeferredLaunchCases) + { + Brief.FocusCaseIds = HyperTwistTrainingCoachLibraryInternal::MergeFocusCaseIds( + OutcomeSummary.DeferredLaunchCaseIds, + bHasLaunchedFollowUpCases ? OutcomeSummary.FollowUpCaseIds : ActionPlan.FocusCaseIds); + FollowUpPacketStructureLabel = TEXT("drill-follow-up-queue-entry-first"); + } + break; + case EHyperTwistTrainingCoachHandoffKind::FollowUp: + if (bHasLaunchedFollowUpCases) + { + Brief.FocusCaseIds = HyperTwistTrainingCoachLibraryInternal::MergeFocusCaseIds( + OutcomeSummary.FollowUpCaseIds, + bHasDeferredLaunchCases ? OutcomeSummary.DeferredLaunchCaseIds : ActionPlan.FocusCaseIds); + FollowUpPacketStructureLabel = TEXT("drill-follow-up-follow-up-packet-first"); + } + break; + case EHyperTwistTrainingCoachHandoffKind::Recommended: + if (RecommendedPacketCases.Num() > 0) + { + Brief.FocusCaseIds = RecommendedPacketCases; + FollowUpPacketStructureLabel = TEXT("drill-follow-up-recommended-brief-first"); + } + break; + default: + break; + } + } + else if (bWeakMethodDrillFollowUpPacketSource + && MethodDrillFollowUpPacketHandoffKind + != EHyperTwistTrainingCoachHandoffKind::None) + { + if (RecommendedPacketCases.Num() > 0) + { + Brief.FocusCaseIds = RecommendedPacketCases; + FollowUpPacketStructureLabel = MethodDrillFollowUpPacketHandoffKind + == EHyperTwistTrainingCoachHandoffKind::Recommended + ? TEXT("drill-follow-up-recommended-brief-redirect") + : TEXT("drill-follow-up-broadened-redirect-first"); + } + } + else if (bStrongMethodDrillRecoveryPacketSource) { switch (MethodDrillRecoveryPacketHandoffKind) { @@ -2365,6 +2502,26 @@ FHyperTwistCoachBrief UHyperTwistTrainingCoachLibrary::DeriveCoachFollowUpBrief( *MethodDrillRecoveryPacketLaneLabel ); } + if (bStrongMethodDrillFollowUpPacketSource + && MethodDrillFollowUpPacketHandoffKind + != EHyperTwistTrainingCoachHandoffKind::None) + { + Brief.Headline = FString::Printf( + TEXT("%s (packet-proven drill follow-up %s continuation)"), + *Brief.Headline, + *MethodDrillFollowUpPacketLaneLabel + ); + } + else if (bWeakMethodDrillFollowUpPacketSource + && MethodDrillFollowUpPacketHandoffKind + != EHyperTwistTrainingCoachHandoffKind::None) + { + Brief.Headline = FString::Printf( + TEXT("%s (packet-proven drill follow-up %s redirect)"), + *Brief.Headline, + *MethodDrillFollowUpPacketLaneLabel + ); + } else if (bWeakMethodDrillRecoveryPacketSource && MethodDrillRecoveryPacketHandoffKind != EHyperTwistTrainingCoachHandoffKind::None) @@ -2382,7 +2539,7 @@ FHyperTwistCoachBrief UHyperTwistTrainingCoachLibrary::DeriveCoachFollowUpBrief( Brief.PriorityScore, Brief.Headline, FString::Printf( - TEXT("followUpCases=%d, deferredLaunchCases=%d, success=%d, failure=%d, timeout=%d, dnf=%d, launchBudget=%s, plannedLaunchCases=%d, requestedLaunchCases=%d, launchBudgetReason=%s, preferredHandoff=%s, preferredHandoffSource=%s, narrowedContinuation=%d, deferredFirstContinuation=%d, deferredPacketOrdering=%s, drillRecoveryPacketLane=%s, drillRecoveryPacketStance=%s"), + TEXT("followUpCases=%d, deferredLaunchCases=%d, success=%d, failure=%d, timeout=%d, dnf=%d, launchBudget=%s, plannedLaunchCases=%d, requestedLaunchCases=%d, launchBudgetReason=%s, preferredHandoff=%s, preferredHandoffSource=%s, narrowedContinuation=%d, deferredFirstContinuation=%d, deferredPacketOrdering=%s, drillFollowUpPacketLane=%s, drillFollowUpPacketStance=%s, drillRecoveryPacketLane=%s, drillRecoveryPacketStance=%s"), Brief.FocusCaseIds.Num(), OutcomeSummary.DeferredLaunchCaseIds.Num(), OutcomeSummary.SuccessCount, @@ -2404,6 +2561,12 @@ FHyperTwistCoachBrief UHyperTwistTrainingCoachLibrary::DeriveCoachFollowUpBrief( bNarrowedContinuationSource ? 1 : 0, bDeferredFirstContinuationSource ? 1 : 0, *FollowUpPacketStructureLabel, + *MethodDrillFollowUpPacketLaneLabel, + bStrongMethodDrillFollowUpPacketSource + ? TEXT("strong continuation") + : (bWeakMethodDrillFollowUpPacketSource + ? TEXT("weak redirect") + : TEXT("none")), *MethodDrillRecoveryPacketLaneLabel, bStrongMethodDrillRecoveryPacketSource ? TEXT("strong continuation") @@ -2550,6 +2713,19 @@ FHyperTwistCoachSessionQueueSummary UHyperTwistTrainingCoachLibrary::DeriveCoach bStrongRetainedMethodDrillRecoveryContinuation && HyperTwistTrainingCoachLibraryInternal::IsMethodDrillRecoveryPacketSource( CoachMemorySnapshot.PreferredCoachHandoffSourceLabel); + const bool bStrongRetainedMethodDrillFollowUpPacketContinuation = + HyperTwistTrainingCoachLibraryInternal::IsStrongMethodDrillFollowUpPacketMemorySource( + CoachMemorySnapshot.PreferredCoachHandoffSourceLabel + ) + && ((CoachMemorySnapshot.PreferredCoachHandoffKind + == EHyperTwistTrainingCoachHandoffKind::Queue + && Brief.bNeedsDeferredLaunchRecovery) + || (CoachMemorySnapshot.PreferredCoachHandoffKind + == EHyperTwistTrainingCoachHandoffKind::FollowUp + && SourceLabel == TEXT("follow-up-brief")) + || (CoachMemorySnapshot.PreferredCoachHandoffKind + == EHyperTwistTrainingCoachHandoffKind::Recommended + && SourceLabel == TEXT("primary-brief"))); const bool bWeakRetainedMethodDrillRecoveryRedirect = HyperTwistTrainingCoachLibraryInternal::IsWeakMethodDrillRecoveryMemorySource( CoachMemorySnapshot.PreferredCoachHandoffSourceLabel @@ -2567,10 +2743,28 @@ FHyperTwistCoachSessionQueueSummary UHyperTwistTrainingCoachLibrary::DeriveCoach bWeakRetainedMethodDrillRecoveryRedirect && HyperTwistTrainingCoachLibraryInternal::IsMethodDrillRecoveryPacketSource( CoachMemorySnapshot.PreferredCoachHandoffSourceLabel); + const bool bWeakRetainedMethodDrillFollowUpPacketRedirect = + HyperTwistTrainingCoachLibraryInternal::IsWeakMethodDrillFollowUpPacketMemorySource( + CoachMemorySnapshot.PreferredCoachHandoffSourceLabel + ) + && ((CoachMemorySnapshot.PreferredCoachHandoffKind + == EHyperTwistTrainingCoachHandoffKind::Queue + && Brief.bNeedsDeferredLaunchRecovery) + || (CoachMemorySnapshot.PreferredCoachHandoffKind + == EHyperTwistTrainingCoachHandoffKind::FollowUp + && SourceLabel == TEXT("follow-up-brief")) + || (CoachMemorySnapshot.PreferredCoachHandoffKind + == EHyperTwistTrainingCoachHandoffKind::Recommended + && SourceLabel == TEXT("primary-brief"))); const FString MethodDrillRecoveryPacketLaneLabel = HyperTwistTrainingCoachLibraryInternal::DescribeMethodDrillRecoveryPacketLane( HyperTwistTrainingCoachLibraryInternal::MethodDrillRecoveryPacketHandoffKindFromSourceLabel( CoachMemorySnapshot.PreferredCoachHandoffSourceLabel)); + const FString MethodDrillFollowUpPacketLaneLabel = + HyperTwistTrainingCoachLibraryInternal::DescribeMethodDrillFollowUpPacketLane( + HyperTwistTrainingCoachLibraryInternal::MethodDrillFollowUpPacketHandoffKindFromSourceLabel( + CoachMemorySnapshot.PreferredCoachHandoffSourceLabel, + CoachMemorySnapshot.PreferredCoachHandoffKind)); if (bNarrowedQueueContinuation || bNarrowedFollowUpContinuation || bNarrowedRecommendedContinuation) @@ -2592,7 +2786,19 @@ FHyperTwistCoachSessionQueueSummary UHyperTwistTrainingCoachLibrary::DeriveCoach *ContinuationLabel ); } - if (bStrongMethodDrillRecoveryPacketContinuation + if (bStrongRetainedMethodDrillFollowUpPacketContinuation + || bWeakRetainedMethodDrillFollowUpPacketRedirect) + { + Entry.Headline = FString::Printf( + TEXT("%s (packet-proven drill follow-up %s %s)"), + *Entry.Headline, + *MethodDrillFollowUpPacketLaneLabel, + bStrongRetainedMethodDrillFollowUpPacketContinuation + ? TEXT("continuation") + : TEXT("redirect") + ); + } + else if (bStrongMethodDrillRecoveryPacketContinuation || bWeakMethodDrillRecoveryPacketRedirect) { Entry.Headline = FString::Printf( diff --git a/UnrealHyperTwist/Source/UnrealHyperTwist/Private/HyperTwistTraining/HyperTwistTrainingSubsystem.cpp b/UnrealHyperTwist/Source/UnrealHyperTwist/Private/HyperTwistTraining/HyperTwistTrainingSubsystem.cpp index f7de66e..d0a9b5f 100644 --- a/UnrealHyperTwist/Source/UnrealHyperTwist/Private/HyperTwistTraining/HyperTwistTrainingSubsystem.cpp +++ b/UnrealHyperTwist/Source/UnrealHyperTwist/Private/HyperTwistTraining/HyperTwistTrainingSubsystem.cpp @@ -260,6 +260,60 @@ namespace HyperTwistTrainingSubsystemInternal && CoachMemorySnapshot.MethodDrillFollowUpAverageOutcomeScore <= 55.0f; } + bool IsStrongMethodDrillFollowUpPacketMemory( + const FHyperTwistTrainingCoachMemorySnapshot& CoachMemorySnapshot) + { + return CoachMemorySnapshot.PreferredGuidanceSourceLabel + == TEXT("coach-memory-method-drill-follow-up-packet-strong") + || CoachMemorySnapshot.PreferredCoachHandoffSourceLabel.StartsWith( + TEXT("coach-memory-dashboard-method-drill-follow-up-packet-strong-")); + } + + bool IsWeakMethodDrillFollowUpPacketMemory( + const FHyperTwistTrainingCoachMemorySnapshot& CoachMemorySnapshot) + { + return CoachMemorySnapshot.PreferredGuidanceSourceLabel + == TEXT("coach-memory-method-drill-follow-up-packet-weak") + || CoachMemorySnapshot.PreferredCoachHandoffSourceLabel.StartsWith( + TEXT("coach-memory-dashboard-method-drill-follow-up-packet-weak-")); + } + + EHyperTwistTrainingCoachHandoffKind MethodDrillFollowUpPacketHandoffKindFromSourceLabel( + const FString& SourceLabel, + const EHyperTwistTrainingCoachHandoffKind FallbackKind) + { + if (SourceLabel.EndsWith(TEXT("-queued"))) + { + return EHyperTwistTrainingCoachHandoffKind::Queue; + } + if (SourceLabel.EndsWith(TEXT("-follow-up"))) + { + return EHyperTwistTrainingCoachHandoffKind::FollowUp; + } + if (SourceLabel.EndsWith(TEXT("-recommended"))) + { + return EHyperTwistTrainingCoachHandoffKind::Recommended; + } + + return FallbackKind; + } + + FString DescribeMethodDrillFollowUpPacketLane( + const EHyperTwistTrainingCoachHandoffKind HandoffKind) + { + switch (HandoffKind) + { + case EHyperTwistTrainingCoachHandoffKind::Queue: + return TEXT("queue-entry"); + case EHyperTwistTrainingCoachHandoffKind::FollowUp: + return TEXT("follow-up-packet"); + case EHyperTwistTrainingCoachHandoffKind::Recommended: + return TEXT("recommended-brief"); + default: + return TEXT("follow-up-packet"); + } + } + FHyperTwistTrainingSessionTemplate ApplyMethodDrillFollowUpMemoryBias( const FHyperTwistTrainingSessionTemplate& SessionTemplate, const FHyperTwistTrainingMethodDrillDiagnosticPacket& DiagnosticPacket, @@ -274,7 +328,14 @@ namespace HyperTwistTrainingSubsystemInternal CoachMemorySnapshot ); const bool bWeakMethodDrillMemory = IsWeakMethodDrillFollowUpMemory(CoachMemorySnapshot); - if (bStrongMethodDrillMemory == bWeakMethodDrillMemory) + const bool bStrongMethodDrillPacketMemory = IsStrongMethodDrillFollowUpPacketMemory( + CoachMemorySnapshot + ); + const bool bWeakMethodDrillPacketMemory = IsWeakMethodDrillFollowUpPacketMemory( + CoachMemorySnapshot + ); + if (bStrongMethodDrillMemory == bWeakMethodDrillMemory + && bStrongMethodDrillPacketMemory == bWeakMethodDrillPacketMemory) { return SessionTemplate; } @@ -288,7 +349,18 @@ namespace HyperTwistTrainingSubsystemInternal if (bStrongMethodDrillMemory) { - const int32 TightenedCaseCount = DiagnosticPacket.bBoundaryTriggeredByPendingCases ? 2 : 3; + const EHyperTwistTrainingCoachHandoffKind PacketHandoffKind = + MethodDrillFollowUpPacketHandoffKindFromSourceLabel( + CoachMemorySnapshot.PreferredCoachHandoffSourceLabel, + CoachMemorySnapshot.PreferredCoachHandoffKind); + const FString PacketLaneLabel = DescribeMethodDrillFollowUpPacketLane(PacketHandoffKind); + const bool bPacketSpecificNarrowing = + bStrongMethodDrillPacketMemory && !bWeakMethodDrillPacketMemory; + const int32 TightenedCaseCount = bPacketSpecificNarrowing + ? (PacketHandoffKind == EHyperTwistTrainingCoachHandoffKind::Recommended + ? (DiagnosticPacket.bBoundaryTriggeredByPendingCases ? 3 : 4) + : (DiagnosticPacket.bBoundaryTriggeredByPendingCases ? 2 : 3)) + : (DiagnosticPacket.bBoundaryTriggeredByPendingCases ? 2 : 3); Result.RecommendedCaseCount = FMath::Clamp( FMath::Min(Result.RecommendedCaseCount, TightenedCaseCount), 1, @@ -301,16 +373,38 @@ namespace HyperTwistTrainingSubsystemInternal Result.SuggestedSelectionPolicy = EHyperTwistTrainingSelectionPolicy::Scripted; Result.bPreferReviewRun = true; Result.bPreferShortReviewSet = true; - Result.GuidanceLabel = Result.GuidanceLabel.IsEmpty() - ? TEXT("successful drill follow-up history is keeping this packet narrow") - : FString::Printf( - TEXT("%s | successful drill follow-up history is keeping this packet narrow"), - *Result.GuidanceLabel - ); + if (Result.GuidanceLabel.IsEmpty()) + { + Result.GuidanceLabel = bPacketSpecificNarrowing + ? FString::Printf( + TEXT("successful drill-follow-up-packet history is keeping this %s packet narrow"), + *PacketLaneLabel) + : TEXT("successful drill follow-up history is keeping this packet narrow"); + } + else + { + Result.GuidanceLabel = bPacketSpecificNarrowing + ? FString::Printf( + TEXT("%s | successful drill-follow-up-packet history is keeping this %s packet narrow"), + *Result.GuidanceLabel, + *PacketLaneLabel) + : FString::Printf( + TEXT("%s | successful drill follow-up history is keeping this packet narrow"), + *Result.GuidanceLabel); + } } else { - const int32 BroadenDelta = DiagnosticPacket.bBoundaryTriggeredByPendingCases ? 1 : 2; + const EHyperTwistTrainingCoachHandoffKind PacketHandoffKind = + MethodDrillFollowUpPacketHandoffKindFromSourceLabel( + CoachMemorySnapshot.PreferredCoachHandoffSourceLabel, + CoachMemorySnapshot.PreferredCoachHandoffKind); + const FString PacketLaneLabel = DescribeMethodDrillFollowUpPacketLane(PacketHandoffKind); + const bool bPacketSpecificRedirect = + bWeakMethodDrillPacketMemory && !bStrongMethodDrillPacketMemory; + const int32 BroadenDelta = bPacketSpecificRedirect + ? (PacketHandoffKind == EHyperTwistTrainingCoachHandoffKind::Recommended ? 3 : 2) + : (DiagnosticPacket.bBoundaryTriggeredByPendingCases ? 1 : 2); Result.RecommendedCaseCount = FMath::Clamp( FMath::Max( Result.RecommendedCaseCount, @@ -324,12 +418,25 @@ namespace HyperTwistTrainingSubsystemInternal Result.SuggestedSelectionPolicy = EHyperTwistTrainingSelectionPolicy::Weighted; } Result.bPreferShortReviewSet = Result.RecommendedCaseCount <= 4; - Result.GuidanceLabel = Result.GuidanceLabel.IsEmpty() - ? TEXT("weak drill follow-up history is broadening this packet before redirect") - : FString::Printf( - TEXT("%s | weak drill follow-up history is broadening this packet before redirect"), - *Result.GuidanceLabel - ); + if (Result.GuidanceLabel.IsEmpty()) + { + Result.GuidanceLabel = bPacketSpecificRedirect + ? FString::Printf( + TEXT("weak drill-follow-up-packet history is broadening this %s packet before redirect"), + *PacketLaneLabel) + : TEXT("weak drill follow-up history is broadening this packet before redirect"); + } + else + { + Result.GuidanceLabel = bPacketSpecificRedirect + ? FString::Printf( + TEXT("%s | weak drill-follow-up-packet history is broadening this %s packet before redirect"), + *Result.GuidanceLabel, + *PacketLaneLabel) + : FString::Printf( + TEXT("%s | weak drill follow-up history is broadening this packet before redirect"), + *Result.GuidanceLabel); + } } return Result.IsStructurallyValid() ? Result : SessionTemplate;