From 3f2c0944c652432903f9a266b17dd7cf558c2e0c Mon Sep 17 00:00:00 2001 From: axiomlogicnexus Date: Mon, 27 Apr 2026 18:04:16 +0200 Subject: [PATCH] Explain queue recovery in coach brief --- .../HyperTwistTrainingCoachLibrary.cpp | 62 ++++++++++++++----- 1 file changed, 47 insertions(+), 15 deletions(-) diff --git a/UnrealHyperTwist/Source/UnrealHyperTwist/Private/HyperTwistTraining/HyperTwistTrainingCoachLibrary.cpp b/UnrealHyperTwist/Source/UnrealHyperTwist/Private/HyperTwistTraining/HyperTwistTrainingCoachLibrary.cpp index 812eb91..9ef3036 100644 --- a/UnrealHyperTwist/Source/UnrealHyperTwist/Private/HyperTwistTraining/HyperTwistTrainingCoachLibrary.cpp +++ b/UnrealHyperTwist/Source/UnrealHyperTwist/Private/HyperTwistTraining/HyperTwistTrainingCoachLibrary.cpp @@ -344,44 +344,76 @@ TArray UHyperTwistTrainingCoachLibrary::DeriveCoachSigna const bool bArchiveAware = CoachMemorySnapshot.bHasArchiveAwareScheduleFriction; const bool bBlockedFollowUp = CoachMemorySnapshot.bHasBlockedFollowUpScheduleFriction; const bool bRepeatManualReschedule = CoachMemorySnapshot.bHasRepeatManualScheduleFriction; + const bool bQueueRecoverySource = + CoachMemorySnapshot.PreferredGuidanceSourceLabel.StartsWith(TEXT("coach-memory-queue-")); + const bool bQueueRecoveryFollowUp = + bQueueRecoverySource + && CoachMemorySnapshot.PreferredGuidanceLane == EHyperTwistTrainingCoachGuidanceLane::FollowUp; + const bool bQueueRecoveryRecommended = + bQueueRecoverySource + && CoachMemorySnapshot.PreferredGuidanceLane == EHyperTwistTrainingCoachGuidanceLane::Recommended; const float Score = 66.0f + FMath::Min(CoachMemorySnapshot.ScheduleExecutionPressureScore * 0.25f, 20.0f) + (bArchiveAware ? 5.0f : 0.0f) + (bBlockedFollowUp ? 6.0f : 0.0f) + (bRepeatManualReschedule ? 5.0f : 0.0f) - + (CoachMemorySnapshot.bHasQueueExecutionCompletionGap ? 4.0f : 0.0f); + + (CoachMemorySnapshot.bHasQueueExecutionCompletionGap ? 4.0f : 0.0f) + + (bQueueRecoverySource ? 2.0f : 0.0f); const EHyperTwistCoachFocusLane FocusLane = bArchiveAware ? EHyperTwistCoachFocusLane::Stability : EHyperTwistCoachFocusLane::Cadence; - const FString Headline = bBlockedFollowUp - ? TEXT("Follow-up scheduling friction is stalling the queue") - : (bArchiveAware - ? TEXT("Archive-aware scheduling friction needs cleanup") - : TEXT("Coaching queue scheduling needs intervention")); + const FString Headline = bQueueRecoveryFollowUp + ? TEXT("Recover the deferred follow-up lane before the queue drifts further") + : (bQueueRecoveryRecommended + ? TEXT("Recover the deferred recommended lane and restore queue cadence") + : (bBlockedFollowUp + ? TEXT("Follow-up scheduling friction is stalling the queue") + : (bArchiveAware + ? TEXT("Archive-aware scheduling friction needs cleanup") + : TEXT("Coaching queue scheduling needs intervention")))); const FString DeferralReasonLabel = !CoachMemorySnapshot.DominantScheduleDeferralReasonLabel.IsEmpty() ? CoachMemorySnapshot.DominantScheduleDeferralReasonLabel : TEXT("none"); + const FString RecoverySourceLabel = bQueueRecoverySource + ? CoachMemorySnapshot.PreferredGuidanceSourceLabel + : TEXT("none"); + const FString SignalId = bQueueRecoveryFollowUp + ? TEXT("schedule_friction_follow_up_recovery") + : (bQueueRecoveryRecommended + ? TEXT("schedule_friction_recommended_recovery") + : TEXT("schedule_friction")); + const EHyperTwistTrainingDeliveryMode SuggestedMode = bQueueRecoveryFollowUp + ? EHyperTwistTrainingDeliveryMode::CoachReviewed + : (bQueueRecoveryRecommended + ? CoachMemorySnapshot.DominantCoachSuggestedMode + : (bBlockedFollowUp + ? EHyperTwistTrainingDeliveryMode::CoachReviewed + : CoachMemorySnapshot.DominantCoachSuggestedMode)); + const EHyperTwistTrainingSelectionPolicy SuggestedSelectionPolicy = bQueueRecoveryFollowUp + ? EHyperTwistTrainingSelectionPolicy::Scripted + : (bQueueRecoveryRecommended + ? EHyperTwistTrainingSelectionPolicy::Weighted + : (bBlockedFollowUp + ? EHyperTwistTrainingSelectionPolicy::Scripted + : CoachMemorySnapshot.DominantCoachSelectionPolicy)); FHyperTwistCoachSignal Signal = HyperTwistTrainingCoachLibraryInternal::MakeSignal( - TEXT("schedule_friction"), + SignalId, FocusLane, Score, Headline, FString::Printf( - TEXT("deferred=%d, manual=%d, archiveAware=%d, blockedFollowUp=%d, completionGap=%d, deferralReason=%s"), + TEXT("deferred=%d, manual=%d, archiveAware=%d, blockedFollowUp=%d, completionGap=%d, deferralReason=%s, recoverySource=%s"), CoachMemorySnapshot.ScheduleDeferredEventCount, CoachMemorySnapshot.ScheduleManualRescheduleEventCount, CoachMemorySnapshot.ScheduleArchiveAwareEventCount, CoachMemorySnapshot.ScheduleBlockedFollowUpEventCount, CoachMemorySnapshot.bHasQueueExecutionCompletionGap ? 1 : 0, - *DeferralReasonLabel), - bBlockedFollowUp - ? EHyperTwistTrainingDeliveryMode::CoachReviewed - : CoachMemorySnapshot.DominantCoachSuggestedMode, - bBlockedFollowUp - ? EHyperTwistTrainingSelectionPolicy::Scripted - : CoachMemorySnapshot.DominantCoachSelectionPolicy); + *DeferralReasonLabel, + *RecoverySourceLabel), + SuggestedMode, + SuggestedSelectionPolicy); Signal.SuggestedDeckId = CoachMemorySnapshot.FocusDeckId; Signal.SuggestedMethodSegmentId = CoachMemorySnapshot.FocusMethodSegmentId; Signal.SuggestedCaseIds = CoachMemorySnapshot.SchedulePressureCaseIds.Num() > 0