Weight drill recovery packets in dashboard decisions

This commit is contained in:
axiomlogicnexus 2026-04-29 15:27:25 +02:00
parent ba4a8cab6a
commit 29da2611ea

View file

@ -83,6 +83,25 @@ namespace HyperTwistCoachDashboardWidgetInternal
bool bHasSignal = false;
};
struct FMethodDrillRecoveryPacketDashboardBias
{
int32 QueueEntryHistoryCount = 0;
int32 FollowUpPacketHistoryCount = 0;
int32 RecommendedBriefHistoryCount = 0;
int32 StrongQueueEntryCount = 0;
int32 StrongFollowUpPacketCount = 0;
int32 WeakRecommendedBriefCount = 0;
int32 LaunchRecoveryBias = 0;
int32 PromoteRecoveryBias = 0;
int32 QueueHandoffBias = 0;
int32 FollowUpHandoffBias = 0;
int32 RecommendedHandoffBias = 0;
EHandoffRecommendationKind PreferredHandoffKind = EHandoffRecommendationKind::None;
bool bHasStrongContinuationSignal = false;
bool bHasWeakRedirectSignal = false;
bool bHasSignal = false;
};
template <typename TEnum>
FString EnumDisplayName(const TEnum Value)
{
@ -1083,6 +1102,129 @@ namespace HyperTwistCoachDashboardWidgetInternal
+ Bias.WeakRetainedMethodDrillRecommendedRecommendationCount * 2;
}
FMethodDrillRecoveryPacketDashboardBias DeriveMethodDrillRecoveryPacketDashboardBias(
const TArray<FHyperTwistCoachDashboardMethodDrillRecoveryMemoryHistoryEntry>& Entries,
const int32 MaxEntriesToInspect = 8)
{
FMethodDrillRecoveryPacketDashboardBias Bias;
if (Entries.Num() <= 0)
{
return Bias;
}
const int32 StartIndex = FMath::Max(0, Entries.Num() - MaxEntriesToInspect);
for (int32 Index = StartIndex; Index < Entries.Num(); ++Index)
{
const FHyperTwistCoachDashboardMethodDrillRecoveryMemoryHistoryEntry& Entry = Entries[Index];
if (!Entry.IsStructurallyValid()
|| Entry.GeneratedGuidancePacketKindLabel.IsEmpty()
|| (!Entry.bUsedMethodDrillRecoveryMemoryForRecovery
&& !Entry.bUsedMethodDrillRecoveryMemoryForHandoff))
{
continue;
}
int32 HistoryWeight = 1;
if (Entry.MethodDrillRecoveryAverageOutcomeScore >= 70.0f)
{
++HistoryWeight;
}
if (Entry.MethodDrillRecoveryHistoryCount >= 4)
{
++HistoryWeight;
}
HistoryWeight = FMath::Clamp(HistoryWeight, 1, 3);
const bool bStrongPacket =
Entry.bGeneratedPacketUsedStrongRetainedMethodDrillRecoveryPosture
|| Entry.bStrongPressureDominant;
const bool bWeakPacket =
Entry.bGeneratedPacketUsedWeakRetainedMethodDrillRecoveryPosture
|| Entry.bWeakPressureDominant;
const bool bGenericPacket =
Entry.bGeneratedPacketUsedGenericMethodDrillRecoveryMemory
&& !bStrongPacket
&& !bWeakPacket;
if (Entry.GeneratedGuidancePacketKindLabel.Equals(TEXT("queue-entry"), ESearchCase::IgnoreCase))
{
++Bias.QueueEntryHistoryCount;
if (bStrongPacket)
{
Bias.StrongQueueEntryCount += HistoryWeight;
Bias.QueueHandoffBias += HistoryWeight * 2;
Bias.LaunchRecoveryBias += HistoryWeight;
Bias.bHasStrongContinuationSignal = true;
Bias.bHasSignal = true;
}
else if (bGenericPacket)
{
Bias.QueueHandoffBias += HistoryWeight;
Bias.LaunchRecoveryBias += HistoryWeight;
Bias.bHasSignal = true;
}
}
else if (
Entry.GeneratedGuidancePacketKindLabel.Equals(
TEXT("follow-up-packet"),
ESearchCase::IgnoreCase))
{
++Bias.FollowUpPacketHistoryCount;
if (bStrongPacket)
{
Bias.StrongFollowUpPacketCount += HistoryWeight;
Bias.FollowUpHandoffBias += HistoryWeight * 3;
Bias.LaunchRecoveryBias += HistoryWeight * 2;
Bias.bHasStrongContinuationSignal = true;
Bias.bHasSignal = true;
}
else if (bGenericPacket)
{
Bias.FollowUpHandoffBias += HistoryWeight;
Bias.LaunchRecoveryBias += HistoryWeight;
Bias.bHasSignal = true;
}
}
else if (
Entry.GeneratedGuidancePacketKindLabel.Equals(
TEXT("recommended-brief"),
ESearchCase::IgnoreCase))
{
++Bias.RecommendedBriefHistoryCount;
if (bWeakPacket)
{
Bias.WeakRecommendedBriefCount += HistoryWeight;
Bias.RecommendedHandoffBias += HistoryWeight * 3;
Bias.PromoteRecoveryBias += HistoryWeight * 2;
Bias.bHasWeakRedirectSignal = true;
Bias.bHasSignal = true;
}
else if (bGenericPacket)
{
Bias.RecommendedHandoffBias += HistoryWeight;
Bias.PromoteRecoveryBias += HistoryWeight;
Bias.bHasSignal = true;
}
}
}
int32 BestScore = 0;
const auto ConsiderKind = [&BestScore, &Bias](
const EHandoffRecommendationKind Kind,
const int32 Score)
{
if (Score > BestScore)
{
BestScore = Score;
Bias.PreferredHandoffKind = Kind;
}
};
ConsiderKind(EHandoffRecommendationKind::Queue, Bias.QueueHandoffBias);
ConsiderKind(EHandoffRecommendationKind::FollowUp, Bias.FollowUpHandoffBias);
ConsiderKind(EHandoffRecommendationKind::Recommended, Bias.RecommendedHandoffBias);
return Bias;
}
void CollectMethodDrillRecoveryOutcomeIndices(
const TArray<FHyperTwistCoachDashboardQueueRecoveryOutcome>& Outcomes,
TArray<int32>& OutIndices)
@ -5402,6 +5544,11 @@ FHyperTwistCoachDashboardQueueRecoveryWeighting UHyperTwistCoachDashboardWidget:
HyperTwistCoachDashboardWidgetInternal::DeriveHandoffHistoryDashboardBias(
HandoffHistoryEntries
);
const HyperTwistCoachDashboardWidgetInternal::FMethodDrillRecoveryPacketDashboardBias
MethodDrillRecoveryPacketBias =
HyperTwistCoachDashboardWidgetInternal::DeriveMethodDrillRecoveryPacketDashboardBias(
MethodDrillRecoveryMemoryHistoryEntries
);
auto ConsumeOutcome = [
&Weighting,
@ -5577,6 +5724,11 @@ FHyperTwistCoachDashboardQueueRecoveryWeighting UHyperTwistCoachDashboardWidget:
);
Weighting.bHasMethodDrillMemorySignal = true;
}
if (MethodDrillRecoveryPacketBias.bHasSignal)
{
Weighting.MethodDrillLaunchBiasCount += MethodDrillRecoveryPacketBias.LaunchRecoveryBias;
Weighting.MethodDrillPromoteBiasCount += MethodDrillRecoveryPacketBias.PromoteRecoveryBias;
}
if (CachedCoachPanelState.PreferredGuidanceSourceLabel
== TEXT("coach-memory-method-drill-follow-up-strong"))
{
@ -5592,7 +5744,8 @@ FHyperTwistCoachDashboardQueueRecoveryWeighting UHyperTwistCoachDashboardWidget:
Weighting.MethodDrillLaunchBiasCount > 0
|| Weighting.MethodDrillPromoteBiasCount > 0
|| Weighting.bHasMethodDrillOutcomeSignal
|| Weighting.bHasMethodDrillMemorySignal;
|| Weighting.bHasMethodDrillMemorySignal
|| MethodDrillRecoveryPacketBias.bHasSignal;
const bool bHasDirectOutcomeSignal = Weighting.PromoteCount > 0 || Weighting.LaunchCount > 0;
Weighting.bHasSignal = bHasDirectOutcomeSignal || Weighting.bHasMethodDrillSignal;
@ -7171,6 +7324,11 @@ void UHyperTwistCoachDashboardWidget::UpdateDashboardPresentation()
MethodDrillRecoveryMemoryHistoryEntries,
false
);
const HyperTwistCoachDashboardWidgetInternal::FMethodDrillRecoveryPacketDashboardBias
MethodDrillRecoveryPacketHandoffBias =
HyperTwistCoachDashboardWidgetInternal::DeriveMethodDrillRecoveryPacketDashboardBias(
MethodDrillRecoveryMemoryHistoryEntries
);
const HyperTwistCoachDashboardWidgetInternal::EMethodDrillRecoveryMemoryBias
EffectiveMethodDrillRecoveryMemoryHandoffBias =
RetainedMethodDrillRecoveryMemoryHandoffBias
@ -7215,6 +7373,24 @@ void UHyperTwistCoachDashboardWidget::UpdateDashboardPresentation()
return false;
}
};
const bool bPacketPrefersQueueContinuation =
MethodDrillRecoveryPacketHandoffBias.PreferredHandoffKind
== HyperTwistCoachDashboardWidgetInternal::EHandoffRecommendationKind::Queue
&& bQueueReadyForHandoff
&& bQueueLooksFollowUpOrRecovery;
const bool bPacketPrefersFollowUpContinuation =
MethodDrillRecoveryPacketHandoffBias.PreferredHandoffKind
== HyperTwistCoachDashboardWidgetInternal::EHandoffRecommendationKind::FollowUp
&& bFollowUpReadyForHandoff;
const bool bPacketPrefersQueueRedirect =
MethodDrillRecoveryPacketHandoffBias.PreferredHandoffKind
== HyperTwistCoachDashboardWidgetInternal::EHandoffRecommendationKind::Queue
&& bQueueReadyForHandoff
&& bQueueLooksRecommendedOrPrimary;
const bool bPacketPrefersRecommendedRedirect =
MethodDrillRecoveryPacketHandoffBias.PreferredHandoffKind
== HyperTwistCoachDashboardWidgetInternal::EHandoffRecommendationKind::Recommended
&& bRecommendedReadyForHandoff;
if (!bCanUseCoachHandoff)
{
CoachHandoffRecommendationStatusLine =
@ -7271,6 +7447,18 @@ void UHyperTwistCoachDashboardWidget::UpdateDashboardPresentation()
bHandoffRecommendationUsedDeferredOverflowHistory = true;
bHandoffRecommendationUsedMethodDrillWeighting = true;
}
else if (bPacketPrefersQueueContinuation)
{
HandoffRecommendationKind =
HyperTwistCoachDashboardWidgetInternal::EHandoffRecommendationKind::Queue;
bHandoffRecommendationUsedMethodDrillWeighting = true;
}
else if (bPacketPrefersFollowUpContinuation)
{
HandoffRecommendationKind =
HyperTwistCoachDashboardWidgetInternal::EHandoffRecommendationKind::FollowUp;
bHandoffRecommendationUsedMethodDrillWeighting = true;
}
else if (HandoffHistoryBias.PreferredKind
== HyperTwistCoachDashboardWidgetInternal::EHandoffRecommendationKind::Queue
&& bQueueReadyForHandoff
@ -7307,7 +7495,19 @@ void UHyperTwistCoachDashboardWidget::UpdateDashboardPresentation()
&& (bFollowUpReadyForHandoff
|| (bQueueReadyForHandoff && bQueueLooksFollowUpOrRecovery)))
{
if (HandoffHistoryBias.PreferredKind
if (bPacketPrefersQueueContinuation)
{
HandoffRecommendationKind =
HyperTwistCoachDashboardWidgetInternal::EHandoffRecommendationKind::Queue;
bHandoffRecommendationUsedMethodDrillRecoveryMemory = true;
}
else if (bPacketPrefersFollowUpContinuation)
{
HandoffRecommendationKind =
HyperTwistCoachDashboardWidgetInternal::EHandoffRecommendationKind::FollowUp;
bHandoffRecommendationUsedMethodDrillRecoveryMemory = true;
}
else if (HandoffHistoryBias.PreferredKind
== HyperTwistCoachDashboardWidgetInternal::EHandoffRecommendationKind::Queue
&& bQueueReadyForHandoff
&& bQueueLooksFollowUpOrRecovery)
@ -7354,6 +7554,18 @@ void UHyperTwistCoachDashboardWidget::UpdateDashboardPresentation()
bHandoffRecommendationUsedDeferredOverflowHistory = true;
bHandoffRecommendationUsedMethodDrillWeighting = true;
}
else if (bPacketPrefersRecommendedRedirect)
{
HandoffRecommendationKind =
HyperTwistCoachDashboardWidgetInternal::EHandoffRecommendationKind::Recommended;
bHandoffRecommendationUsedMethodDrillWeighting = true;
}
else if (bPacketPrefersQueueRedirect)
{
HandoffRecommendationKind =
HyperTwistCoachDashboardWidgetInternal::EHandoffRecommendationKind::Queue;
bHandoffRecommendationUsedMethodDrillWeighting = true;
}
else if (HandoffHistoryBias.PreferredKind
== HyperTwistCoachDashboardWidgetInternal::EHandoffRecommendationKind::Queue
&& bQueueReadyForHandoff
@ -7390,7 +7602,19 @@ void UHyperTwistCoachDashboardWidget::UpdateDashboardPresentation()
&& (bRecommendedReadyForHandoff
|| (bQueueReadyForHandoff && bQueueLooksRecommendedOrPrimary)))
{
if (HandoffHistoryBias.PreferredKind
if (bPacketPrefersRecommendedRedirect)
{
HandoffRecommendationKind =
HyperTwistCoachDashboardWidgetInternal::EHandoffRecommendationKind::Recommended;
bHandoffRecommendationUsedMethodDrillRecoveryMemory = true;
}
else if (bPacketPrefersQueueRedirect)
{
HandoffRecommendationKind =
HyperTwistCoachDashboardWidgetInternal::EHandoffRecommendationKind::Queue;
bHandoffRecommendationUsedMethodDrillRecoveryMemory = true;
}
else if (HandoffHistoryBias.PreferredKind
== HyperTwistCoachDashboardWidgetInternal::EHandoffRecommendationKind::Recommended
&& bRecommendedReadyForHandoff)
{
@ -7742,6 +7966,17 @@ void UHyperTwistCoachDashboardWidget::UpdateDashboardPresentation()
*HyperTwistCoachDashboardWidgetInternal::DescribeMethodDrillRecoveryMemoryBias(
EffectiveMethodDrillRecoveryMemoryHandoffBias)
);
CoachHandoffRecommendationDetailLine += FString::Printf(
TEXT(" | packet history queue/follow-up/recommended %d/%d/%d | strong packet queue/follow-up %d/%d | weak packet recommended %d | packet preferred: %s"),
MethodDrillRecoveryPacketHandoffBias.QueueEntryHistoryCount,
MethodDrillRecoveryPacketHandoffBias.FollowUpPacketHistoryCount,
MethodDrillRecoveryPacketHandoffBias.RecommendedBriefHistoryCount,
MethodDrillRecoveryPacketHandoffBias.StrongQueueEntryCount,
MethodDrillRecoveryPacketHandoffBias.StrongFollowUpPacketCount,
MethodDrillRecoveryPacketHandoffBias.WeakRecommendedBriefCount,
*HyperTwistCoachDashboardWidgetInternal::DescribeHandoffRecommendationKind(
MethodDrillRecoveryPacketHandoffBias.PreferredHandoffKind)
);
CoachHandoffRecommendationDetailLine += FString::Printf(
TEXT(" | strong posture q/f/r %d/%d/%d, weak posture q/f/r %d/%d/%d"),
HandoffHistoryBias.StrongRetainedMethodDrillQueueAcceptedDeltaCount,
@ -7759,6 +7994,14 @@ void UHyperTwistCoachDashboardWidget::UpdateDashboardPresentation()
? TEXT(" | Drill history says broader coach handoff is now stronger than another narrow drill follow-up.")
: TEXT(" | Drill history is balanced against broader coach handoff."));
}
if (MethodDrillRecoveryPacketHandoffBias.bHasSignal)
{
CoachHandoffRecommendationDetailLine += MethodDrillRecoveryPacketHandoffBias.bHasStrongContinuationSignal
? TEXT(" | Retained drill-recovery packet history is reinforcing narrower queue/follow-up continuation.")
: (MethodDrillRecoveryPacketHandoffBias.bHasWeakRedirectSignal
? TEXT(" | Retained drill-recovery packet history is reinforcing broader recommended redirect.")
: TEXT(" | Retained drill-recovery packet history is present but balanced."));
}
if (!MethodDrillUpstreamMemoryLine.IsEmpty())
{
CoachHandoffRecommendationDetailLine += MethodDrillUpstreamMemoryLine;
@ -8012,6 +8255,11 @@ void UHyperTwistCoachDashboardWidget::UpdateDashboardPresentation()
: HyperTwistCoachDashboardWidgetInternal::DescribeCoachMemorySourceLabel(
CachedCoachPanelState.PreferredQueueRecoveryActionSourceLabel);
const FHyperTwistCoachDashboardQueueRecoveryWeighting QueueRecoveryWeighting = BuildQueueRecoveryWeighting();
const HyperTwistCoachDashboardWidgetInternal::FMethodDrillRecoveryPacketDashboardBias
MethodDrillRecoveryPacketQueueBias =
HyperTwistCoachDashboardWidgetInternal::DeriveMethodDrillRecoveryPacketDashboardBias(
MethodDrillRecoveryMemoryHistoryEntries
);
const HyperTwistCoachDashboardWidgetInternal::EMethodDrillRecoveryMemoryBias
QueueRecoveryMethodDrillMemoryBias =
HyperTwistCoachDashboardWidgetInternal::ResolveMethodDrillRecoveryMemoryBias(
@ -8057,7 +8305,12 @@ void UHyperTwistCoachDashboardWidget::UpdateDashboardPresentation()
? TEXT("prefer launch-recovery")
: TEXT("no upstream preference"));
const FString QueueRecoveryMethodDrillStatus =
QueueRecoveryWeighting.bHasMethodDrillMemorySignal
MethodDrillRecoveryPacketQueueBias.bHasSignal
? (MethodDrillRecoveryPacketQueueBias.LaunchRecoveryBias
>= MethodDrillRecoveryPacketQueueBias.PromoteRecoveryBias
? TEXT(" | Retained drill-recovery packet history is reinforcing launch recovery.")
: TEXT(" | Retained drill-recovery packet history is reinforcing promote-deferred recovery."))
: (QueueRecoveryWeighting.bHasMethodDrillMemorySignal
? (QueueRecoveryWeighting.PreferredActionKind
== FHyperTwistCoachDashboardQueueRecoveryOutcome::EActionKind::LaunchRecovery
? TEXT(" | Upstream drill-driven recovery memory is reinforcing launch recovery.")
@ -8072,7 +8325,7 @@ void UHyperTwistCoachDashboardWidget::UpdateDashboardPresentation()
== FHyperTwistCoachDashboardQueueRecoveryOutcome::EActionKind::LaunchRecovery
? TEXT(" | Drill-driven accepted handoff history is reinforcing launch recovery.")
: TEXT(" | Drill-driven accepted handoff history is present, but promote-deferred recovery still holds."))
: TEXT("")));
: TEXT(""))));
const bool bHasQueueRecoveryFriction =
CachedCoachSchedulePolicySummary.bHasBlockedFollowUpDeferrals
|| CachedCoachSchedulePolicySummary.bHasArchiveAwareDeferrals
@ -8131,7 +8384,7 @@ void UHyperTwistCoachDashboardWidget::UpdateDashboardPresentation()
: *QueueDeferredFirstSuppressionSignal->Detail)
: TEXT("");
const FString QueueRecoveryDetailLine = FString::Printf(
TEXT("Deferred events %d | Promoted %d | Manual %d | Pressure %.2f | Dominant reason: %s | Follow-up deferrals: %s | Archive-aware deferrals: %s | Completion gap: %s | Upstream action source: %s%s || Learned promote %d/%d reduced, %d failed, avg delta %.2f | launch %d/%d reduced, %d failed, avg delta %.2f | deferred-first promote/launch reduced %d/%d over %d/%d | drill-driven outcome promote/launch reduced %d/%d over %d/%d | retained strong-launch %d/%d, weak-promote %d/%d | drill-driven bias promote/launch %d/%d | upstream drill recovery strong/weak/history %d/%d/%d avg %.1f | retained drill-recovery stance: %s"),
TEXT("Deferred events %d | Promoted %d | Manual %d | Pressure %.2f | Dominant reason: %s | Follow-up deferrals: %s | Archive-aware deferrals: %s | Completion gap: %s | Upstream action source: %s%s || Learned promote %d/%d reduced, %d failed, avg delta %.2f | launch %d/%d reduced, %d failed, avg delta %.2f | deferred-first promote/launch reduced %d/%d over %d/%d | drill-driven outcome promote/launch reduced %d/%d over %d/%d | retained strong-launch %d/%d, weak-promote %d/%d | drill-driven bias promote/launch %d/%d | packet history queue/follow-up/recommended %d/%d/%d | packet bias promote/launch %d/%d | upstream drill recovery strong/weak/history %d/%d/%d avg %.1f | retained drill-recovery stance: %s"),
CachedCoachQueueExecutionSummary.DeferredEventCount,
CachedCoachQueueExecutionSummary.PromotedEventCount,
CachedCoachQueueExecutionSummary.ManualRescheduleEventCount,
@ -8166,6 +8419,11 @@ void UHyperTwistCoachDashboardWidget::UpdateDashboardPresentation()
QueueRecoveryWeighting.WeakRetainedMethodDrillPromoteCount,
QueueRecoveryWeighting.MethodDrillPromoteBiasCount,
QueueRecoveryWeighting.MethodDrillLaunchBiasCount,
MethodDrillRecoveryPacketQueueBias.QueueEntryHistoryCount,
MethodDrillRecoveryPacketQueueBias.FollowUpPacketHistoryCount,
MethodDrillRecoveryPacketQueueBias.RecommendedBriefHistoryCount,
MethodDrillRecoveryPacketQueueBias.PromoteRecoveryBias,
MethodDrillRecoveryPacketQueueBias.LaunchRecoveryBias,
QueueRecoveryWeighting.MethodDrillUpstreamStrongCount,
QueueRecoveryWeighting.MethodDrillUpstreamWeakCount,
QueueRecoveryWeighting.MethodDrillUpstreamHistoryCount,