From 8467b002250cb3c89fcbef3ba3ace3bc83a884fa Mon Sep 17 00:00:00 2001 From: axiomlogicnexus Date: Sat, 9 May 2026 19:12:17 +0200 Subject: [PATCH] Expose dashboard live guidance preview and rationale surfaces --- .../HyperTwistCoachDashboardWidget.cpp | 789 ++++++++++++++++++ .../HyperTwistCoachDashboardWidget.h | 16 + .../HyperTwistTrainingTypes.h | 468 +++++++++++ ...RTWIST_ROADMAP_OVERHAUL_EXPANSION_GUIDE.md | 4 +- ...RENCE_INSPECT_SURFACE_PACKET_2026-05-09.md | 58 ++ 5 files changed, 1333 insertions(+), 2 deletions(-) create mode 100644 docs/arch/HYPERTWIST_PHASE4_DASHBOARD_LIVE_GUIDANCE_PREVIEW_SELECTION_CASE_DETAIL_RATIONALE_PREFERENCE_INSPECT_SURFACE_PACKET_2026-05-09.md diff --git a/UnrealHyperTwist/Source/UnrealHyperTwist/Private/HyperTwistTraining/HyperTwistCoachDashboardWidget.cpp b/UnrealHyperTwist/Source/UnrealHyperTwist/Private/HyperTwistTraining/HyperTwistCoachDashboardWidget.cpp index c5a3986..e7c2c50 100644 --- a/UnrealHyperTwist/Source/UnrealHyperTwist/Private/HyperTwistTraining/HyperTwistCoachDashboardWidget.cpp +++ b/UnrealHyperTwist/Source/UnrealHyperTwist/Private/HyperTwistTraining/HyperTwistCoachDashboardWidget.cpp @@ -9106,6 +9106,795 @@ UHyperTwistCoachDashboardWidget::GetDisplayedGuidanceDecisionWeightingInspectSur return Surface; } +FHyperTwistTrainingCoachDashboardGuidancePreviewSelectionInspectSurface +UHyperTwistCoachDashboardWidget::GetDisplayedGuidancePreviewSelectionInspectSurface() const +{ + FHyperTwistTrainingCoachDashboardGuidancePreviewSelectionInspectSurface Surface; + Surface.Headline = TEXT("Preview selection"); + + const auto BuildPreviewLaneLabel = [](const EHyperTwistCoachDashboardGuidancePreviewLane Lane) -> FString + { + return Lane == EHyperTwistCoachDashboardGuidancePreviewLane::Recommended + ? TEXT("recommended") + : (Lane == EHyperTwistCoachDashboardGuidancePreviewLane::FollowUp + ? TEXT("follow-up") + : TEXT("none")); + }; + + const FHyperTwistTrainingDeck* ActivePreviewDeck = GetActiveGuidancePreviewDeck(); + const FHyperTwistTrainingCase* SelectedGuidancePreviewCase = + ActivePreviewDeck != nullptr + && SelectedGuidancePreviewCaseIndex >= 0 + && SelectedGuidancePreviewCaseIndex < ActivePreviewDeck->Cases.Num() + ? &ActivePreviewDeck->Cases[SelectedGuidancePreviewCaseIndex] + : nullptr; + Surface.ActivePreviewLaneLabel = BuildPreviewLaneLabel(ActiveGuidancePreviewLane); + Surface.bHasActivePreviewDeck = ActivePreviewDeck != nullptr; + Surface.bHasSelectedCase = SelectedGuidancePreviewCase != nullptr; + Surface.DeckId = + ActivePreviewDeck != nullptr && !ActivePreviewDeck->DeckId.IsEmpty() + ? ActivePreviewDeck->DeckId + : TEXT("n/a"); + Surface.DeckTitle = + ActivePreviewDeck != nullptr && !ActivePreviewDeck->Title.IsEmpty() + ? ActivePreviewDeck->Title + : TEXT("n/a"); + Surface.DeckLabel = + ActivePreviewDeck != nullptr + ? (ActivePreviewDeck->Title.IsEmpty() ? Surface.DeckId : ActivePreviewDeck->Title) + : TEXT("n/a"); + Surface.SelectionPolicyLabel = + ActivePreviewDeck != nullptr + ? HyperTwistCoachDashboardWidgetInternal::EnumDisplayName( + ActivePreviewDeck->SelectionPolicy) + : TEXT("n/a"); + Surface.DifficultyBand = + ActivePreviewDeck != nullptr && !ActivePreviewDeck->DifficultyBand.IsEmpty() + ? ActivePreviewDeck->DifficultyBand + : TEXT("n/a"); + Surface.SubsetId = + ActivePreviewDeck != nullptr && !ActivePreviewDeck->SubsetId.IsEmpty() + ? ActivePreviewDeck->SubsetId + : TEXT("n/a"); + Surface.SelectedCaseId = + SelectedGuidancePreviewCase != nullptr && !SelectedGuidancePreviewCase->CaseId.IsEmpty() + ? SelectedGuidancePreviewCase->CaseId + : TEXT("n/a"); + Surface.SelectedCasePromptLabel = + SelectedGuidancePreviewCase != nullptr + && !SelectedGuidancePreviewCase->PromptLabel.IsEmpty() + ? SelectedGuidancePreviewCase->PromptLabel + : TEXT("n/a"); + Surface.SelectedCaseIndex = SelectedGuidancePreviewCaseIndex; + Surface.TotalCaseCount = ActivePreviewDeck != nullptr ? ActivePreviewDeck->Cases.Num() : 0; + + const bool bQueueRecoveryMemorySource = + HyperTwistCoachDashboardWidgetInternal::IsQueueRecoveryMemorySource( + CachedCoachPanelState.PreferredGuidanceSourceLabel); + Surface.bClosedLoopIdleDashboard = + IsCoachLoopActionabilityClosed() + && ( + bQueueRecoveryMemorySource + || !CachedCoachPanelState.PreferredGuidanceSourceLabel.IsEmpty() + || DisplayedCoachHandoffRecommendationKind != EHyperTwistTrainingCoachHandoffKind::None); + + Surface.StatusLine = + SelectedGuidancePreviewCase != nullptr && ActivePreviewDeck != nullptr + ? FString::Printf( + TEXT("Active preview: %s | case %d/%d | deck %s"), + *Surface.ActivePreviewLaneLabel, + SelectedGuidancePreviewCaseIndex + 1, + ActivePreviewDeck->Cases.Num(), + *Surface.DeckLabel) + : FString::Printf( + TEXT("Active preview: %s | build a coach deck preview to inspect specific cases"), + *Surface.ActivePreviewLaneLabel); + Surface.DetailLine = + ActivePreviewDeck != nullptr + ? FString::Printf( + TEXT("Preview selection detail: deck %s | selection %s | difficulty %s | subset %s | selected prompt %s"), + *Surface.DeckLabel, + *Surface.SelectionPolicyLabel, + *Surface.DifficultyBand, + *Surface.SubsetId, + *Surface.SelectedCasePromptLabel) + : TEXT("Preview selection detail: no active preview deck is currently surfaced."); + if (Surface.bClosedLoopIdleDashboard) + { + Surface.StatusLine = + TEXT("Active preview: none | the coach-to-review loop is closed and idle."); + Surface.DetailLine = + TEXT("Preview selection detail: retained coach memory remains inspectable, but no live preview deck remains active."); + } + return Surface; +} + +FHyperTwistTrainingCoachDashboardGuidancePreviewCaseDetailInspectSurface +UHyperTwistCoachDashboardWidget::GetDisplayedGuidancePreviewCaseDetailInspectSurface() const +{ + FHyperTwistTrainingCoachDashboardGuidancePreviewCaseDetailInspectSurface Surface; + Surface.Headline = TEXT("Preview case"); + + const auto BuildPreviewLaneLabel = [](const EHyperTwistCoachDashboardGuidancePreviewLane Lane) -> FString + { + return Lane == EHyperTwistCoachDashboardGuidancePreviewLane::Recommended + ? TEXT("recommended") + : (Lane == EHyperTwistCoachDashboardGuidancePreviewLane::FollowUp + ? TEXT("follow-up") + : TEXT("none")); + }; + + const FHyperTwistTrainingDeck* ActivePreviewDeck = GetActiveGuidancePreviewDeck(); + const FHyperTwistTrainingCase* SelectedGuidancePreviewCase = + ActivePreviewDeck != nullptr + && SelectedGuidancePreviewCaseIndex >= 0 + && SelectedGuidancePreviewCaseIndex < ActivePreviewDeck->Cases.Num() + ? &ActivePreviewDeck->Cases[SelectedGuidancePreviewCaseIndex] + : nullptr; + Surface.ActivePreviewLaneLabel = BuildPreviewLaneLabel(ActiveGuidancePreviewLane); + Surface.DeckLabel = + ActivePreviewDeck != nullptr + ? (ActivePreviewDeck->Title.IsEmpty() ? ActivePreviewDeck->DeckId : ActivePreviewDeck->Title) + : TEXT("n/a"); + Surface.CaseId = + SelectedGuidancePreviewCase != nullptr && !SelectedGuidancePreviewCase->CaseId.IsEmpty() + ? SelectedGuidancePreviewCase->CaseId + : TEXT("n/a"); + Surface.PromptLabel = + SelectedGuidancePreviewCase != nullptr + && !SelectedGuidancePreviewCase->PromptLabel.IsEmpty() + ? SelectedGuidancePreviewCase->PromptLabel + : TEXT("n/a"); + Surface.PromptKindLabel = + SelectedGuidancePreviewCase != nullptr + ? HyperTwistCoachDashboardWidgetInternal::EnumDisplayName( + SelectedGuidancePreviewCase->PromptKind) + : TEXT("n/a"); + Surface.SubsetId = + SelectedGuidancePreviewCase != nullptr && !SelectedGuidancePreviewCase->SubsetId.IsEmpty() + ? SelectedGuidancePreviewCase->SubsetId + : TEXT("n/a"); + Surface.ScrambleNotation = + SelectedGuidancePreviewCase != nullptr + && !SelectedGuidancePreviewCase->ScrambleNotation.IsEmpty() + ? SelectedGuidancePreviewCase->ScrambleNotation + : TEXT("n/a"); + Surface.CanonicalNotation = + SelectedGuidancePreviewCase != nullptr + && !SelectedGuidancePreviewCase->CanonicalNotation.IsEmpty() + ? SelectedGuidancePreviewCase->CanonicalNotation + : TEXT("n/a"); + Surface.TimeTargetMs = + SelectedGuidancePreviewCase != nullptr ? SelectedGuidancePreviewCase->TimeTargetMs : 0; + Surface.SelectedCaseIndex = SelectedGuidancePreviewCaseIndex; + Surface.TotalCaseCount = ActivePreviewDeck != nullptr ? ActivePreviewDeck->Cases.Num() : 0; + Surface.bHasActivePreviewDeck = ActivePreviewDeck != nullptr; + Surface.bHasSelectedCase = SelectedGuidancePreviewCase != nullptr; + + const bool bQueueRecoveryMemorySource = + HyperTwistCoachDashboardWidgetInternal::IsQueueRecoveryMemorySource( + CachedCoachPanelState.PreferredGuidanceSourceLabel); + Surface.bClosedLoopIdleDashboard = + IsCoachLoopActionabilityClosed() + && ( + bQueueRecoveryMemorySource + || !CachedCoachPanelState.PreferredGuidanceSourceLabel.IsEmpty() + || DisplayedCoachHandoffRecommendationKind != EHyperTwistTrainingCoachHandoffKind::None); + + Surface.StatusLine = + SelectedGuidancePreviewCase != nullptr + ? FString::Printf( + TEXT("Preview case: %s | Prompt: %s | Kind: %s | Subset: %s | Target: %d ms | Scramble: %s | Canonical: %s"), + *Surface.CaseId, + *Surface.PromptLabel, + *Surface.PromptKindLabel, + *Surface.SubsetId, + Surface.TimeTargetMs, + *Surface.ScrambleNotation, + *Surface.CanonicalNotation) + : TEXT("Preview case: none selected yet."); + Surface.DetailLine = + SelectedGuidancePreviewCase != nullptr + ? FString::Printf( + TEXT("Preview case detail: lane %s | deck %s | selected %d/%d"), + *Surface.ActivePreviewLaneLabel, + *Surface.DeckLabel, + SelectedGuidancePreviewCaseIndex + 1, + Surface.TotalCaseCount) + : TEXT("Preview case detail: move the preview case selector or build a preview deck to inspect a surfaced case."); + if (Surface.bClosedLoopIdleDashboard) + { + Surface.StatusLine = + TEXT("Preview case: no active guidance preview remains in the closed-loop idle state."); + Surface.DetailLine = + TEXT("Preview case detail: retained coach memory remains inspectable, but no live preview case remains active."); + } + return Surface; +} + +FHyperTwistTrainingCoachDashboardGuidanceRationaleInspectSurface +UHyperTwistCoachDashboardWidget::GetDisplayedGuidanceRationaleInspectSurface() const +{ + FHyperTwistTrainingCoachDashboardGuidanceRationaleInspectSurface Surface; + Surface.Headline = TEXT("Guidance rationale"); + + const auto BuildPreviewLaneLabel = [](const EHyperTwistCoachDashboardGuidancePreviewLane Lane) -> FString + { + return Lane == EHyperTwistCoachDashboardGuidancePreviewLane::Recommended + ? TEXT("recommended") + : (Lane == EHyperTwistCoachDashboardGuidancePreviewLane::FollowUp + ? TEXT("follow-up") + : TEXT("none")); + }; + + const FHyperTwistTrainingDeck* ActivePreviewDeck = GetActiveGuidancePreviewDeck(); + const FHyperTwistTrainingCase* SelectedGuidancePreviewCase = + ActivePreviewDeck != nullptr + && SelectedGuidancePreviewCaseIndex >= 0 + && SelectedGuidancePreviewCaseIndex < ActivePreviewDeck->Cases.Num() + ? &ActivePreviewDeck->Cases[SelectedGuidancePreviewCaseIndex] + : nullptr; + const FHyperTwistCoachBrief* ActivePreviewBrief = GetActiveGuidancePreviewBrief(); + + Surface.ActivePreviewLaneLabel = BuildPreviewLaneLabel(ActiveGuidancePreviewLane); + Surface.bHasActivePreviewBrief = ActivePreviewBrief != nullptr; + Surface.SelectedCaseId = + SelectedGuidancePreviewCase != nullptr && !SelectedGuidancePreviewCase->CaseId.IsEmpty() + ? SelectedGuidancePreviewCase->CaseId + : TEXT("n/a"); + Surface.GuidanceSourceLabel = + HyperTwistCoachDashboardWidgetInternal::DescribeCoachMemorySourceLabel( + CachedCoachPanelState.PreferredGuidanceSourceLabel); + Surface.LaunchBiasLabel = + HyperTwistCoachDashboardWidgetInternal::DescribeLaunchBudgetBias( + CachedCoachPanelState.PreferredLaunchBudgetBias); + Surface.LaunchBiasSourceLabel = + HyperTwistCoachDashboardWidgetInternal::DescribeCoachMemorySourceLabel( + CachedCoachPanelState.PreferredLaunchBudgetSourceLabel); + Surface.BroadenedLaunchHistoryCount = + CachedCoachPanelState.BroadenedLaunchBudgetHistoryCount; + Surface.TightenedLaunchHistoryCount = + CachedCoachPanelState.TightenedLaunchBudgetHistoryCount; + Surface.DeferredTightenedLaunchHistoryCount = + CachedCoachPanelState.DeferredTightenedLaunchHistoryCount; + Surface.DeferredLaunchHistoryCaseCount = + CachedCoachPanelState.DeferredLaunchHistoryCaseCount; + + bool bSelectedPreviewCaseIsExplicitFocus = false; + int32 SelectedPreviewCaseSignalCount = 0; + FString SelectedPreviewCaseSignalLine = TEXT("none"); + FString SignalSummaryLine = TEXT("none"); + int32 SignalCount = 0; + if (ActivePreviewBrief != nullptr) + { + SignalCount = ActivePreviewBrief->Signals.Num(); + if (SelectedGuidancePreviewCase != nullptr) + { + bSelectedPreviewCaseIsExplicitFocus = + ActivePreviewBrief->FocusCaseIds.Contains(SelectedGuidancePreviewCase->CaseId); + } + + TArray SignalSummaryParts; + SignalSummaryParts.Reserve(FMath::Min(ActivePreviewBrief->Signals.Num(), 2)); + for (const FHyperTwistCoachSignal& Signal : ActivePreviewBrief->Signals) + { + if (SelectedGuidancePreviewCase != nullptr + && Signal.SuggestedCaseIds.Contains(SelectedGuidancePreviewCase->CaseId)) + { + ++SelectedPreviewCaseSignalCount; + if (SelectedPreviewCaseSignalLine == TEXT("none")) + { + SelectedPreviewCaseSignalLine = FString::Printf( + TEXT("%s | %s"), + Signal.Headline.IsEmpty() ? TEXT("signal") : *Signal.Headline, + Signal.Detail.IsEmpty() ? TEXT("no detail") : *Signal.Detail); + } + } + + if (SignalSummaryParts.Num() < 2) + { + SignalSummaryParts.Add(FString::Printf( + TEXT("%s (%.2f)"), + Signal.Headline.IsEmpty() ? TEXT("signal") : *Signal.Headline, + Signal.Score)); + } + } + + if (SignalSummaryParts.Num() > 0) + { + SignalSummaryLine = FString::Join(SignalSummaryParts, TEXT(" | ")); + } + } + + Surface.SelectedPreviewCaseSignalCount = SelectedPreviewCaseSignalCount; + Surface.SelectedPreviewCaseSignalLine = SelectedPreviewCaseSignalLine; + Surface.TopSignalSummaryLine = SignalSummaryLine; + Surface.SignalCount = SignalCount; + Surface.bSelectedPreviewCaseIsExplicitFocus = bSelectedPreviewCaseIsExplicitFocus; + Surface.bDeferredOverflowShaping = + CachedCoachPanelState.PreferredLaunchBudgetSourceLabel + == TEXT("recommendation-history-deferred-tightened-launch"); + + if (ActivePreviewBrief != nullptr) + { + Surface.PriorityLabel = + HyperTwistCoachDashboardWidgetInternal::EnumDisplayName( + ActivePreviewBrief->Priority); + Surface.FocusLaneLabel = + HyperTwistCoachDashboardWidgetInternal::EnumDisplayName( + ActivePreviewBrief->FocusLane); + Surface.SuggestedModeLabel = + HyperTwistCoachDashboardWidgetInternal::EnumDisplayName( + ActivePreviewBrief->SuggestedMode); + Surface.SuggestedSelectionLabel = + HyperTwistCoachDashboardWidgetInternal::EnumDisplayName( + ActivePreviewBrief->SuggestedSelectionPolicy); + Surface.BriefHeadline = + ActivePreviewBrief->Headline.IsEmpty() ? TEXT("n/a") : ActivePreviewBrief->Headline; + Surface.PrimaryActionLabel = + ActivePreviewBrief->PrimaryActionLabel.IsEmpty() + ? TEXT("n/a") + : ActivePreviewBrief->PrimaryActionLabel; + Surface.FocusDeckId = + ActivePreviewBrief->FocusDeckId.IsEmpty() + ? TEXT("n/a") + : ActivePreviewBrief->FocusDeckId; + Surface.FocusMethodSegmentId = + ActivePreviewBrief->FocusMethodSegmentId.IsEmpty() + ? TEXT("n/a") + : ActivePreviewBrief->FocusMethodSegmentId; + Surface.FocusCaseCount = ActivePreviewBrief->FocusCaseIds.Num(); + Surface.PriorityScore = ActivePreviewBrief->PriorityScore; + Surface.bNeedsCoachReview = ActivePreviewBrief->bNeedsCoachReview; + Surface.bNeedsCadenceRecovery = ActivePreviewBrief->bNeedsCadenceRecovery; + Surface.bNeedsVarietyRotation = ActivePreviewBrief->bNeedsVarietyRotation; + } + else + { + Surface.PriorityLabel = TEXT("n/a"); + Surface.FocusLaneLabel = TEXT("n/a"); + Surface.SuggestedModeLabel = TEXT("n/a"); + Surface.SuggestedSelectionLabel = TEXT("n/a"); + Surface.BriefHeadline = TEXT("n/a"); + Surface.PrimaryActionLabel = TEXT("n/a"); + Surface.FocusDeckId = TEXT("n/a"); + Surface.FocusMethodSegmentId = TEXT("n/a"); + } + + Surface.StatusLine = + ActivePreviewBrief != nullptr + ? FString::Printf( + TEXT("Rationale: %s lane | Priority: %s (%.2f) | Focus: %s | Mode: %s | Selection: %s"), + *Surface.ActivePreviewLaneLabel, + *Surface.PriorityLabel, + Surface.PriorityScore, + *Surface.FocusLaneLabel, + *Surface.SuggestedModeLabel, + *Surface.SuggestedSelectionLabel) + : FString::Printf( + TEXT("Rationale: %s lane | build a recommended or follow-up preview to inspect the coach rationale"), + *Surface.ActivePreviewLaneLabel); + Surface.DetailLine = + ActivePreviewBrief != nullptr + ? FString::Printf( + TEXT("Brief: %s | Action: %s | Deck: %s | Method: %s | Focus cases: %d | Review: %s | Cadence: %s | Variety: %s | Guidance source: %s | Launch bias: %s from %s | broadened/tightened history %d/%d | deferred tightened launches %d | deferred launch cases %d%s | Selected focus: %s | Matching signals: %d | Case signal: %s | Top signals: %s"), + *Surface.BriefHeadline, + *Surface.PrimaryActionLabel, + *Surface.FocusDeckId, + *Surface.FocusMethodSegmentId, + Surface.FocusCaseCount, + Surface.bNeedsCoachReview ? TEXT("yes") : TEXT("no"), + Surface.bNeedsCadenceRecovery ? TEXT("yes") : TEXT("no"), + Surface.bNeedsVarietyRotation ? TEXT("yes") : TEXT("no"), + *Surface.GuidanceSourceLabel, + *Surface.LaunchBiasLabel, + *Surface.LaunchBiasSourceLabel, + Surface.BroadenedLaunchHistoryCount, + Surface.TightenedLaunchHistoryCount, + Surface.DeferredTightenedLaunchHistoryCount, + Surface.DeferredLaunchHistoryCaseCount, + Surface.bDeferredOverflowShaping + ? TEXT(" | This preview is being shaped by remembered deferred overflow continuation.") + : TEXT(""), + Surface.bSelectedPreviewCaseIsExplicitFocus ? TEXT("yes") : TEXT("no"), + Surface.SelectedPreviewCaseSignalCount, + *Surface.SelectedPreviewCaseSignalLine, + *Surface.TopSignalSummaryLine) + : TEXT("Rationale detail: unavailable until a guidance preview lane is active."); + + const bool bQueueRecoveryMemorySource = + HyperTwistCoachDashboardWidgetInternal::IsQueueRecoveryMemorySource( + CachedCoachPanelState.PreferredGuidanceSourceLabel); + Surface.bClosedLoopIdleDashboard = + IsCoachLoopActionabilityClosed() + && ( + bQueueRecoveryMemorySource + || !CachedCoachPanelState.PreferredGuidanceSourceLabel.IsEmpty() + || DisplayedCoachHandoffRecommendationKind != EHyperTwistTrainingCoachHandoffKind::None); + if (Surface.bClosedLoopIdleDashboard) + { + Surface.StatusLine = + TEXT("Rationale: closed-loop idle state | no active guidance preview remains."); + Surface.DetailLine = + TEXT("Rationale detail: retained coach memory and history remain available for inspection, but no live preview packet is active."); + } + return Surface; +} + +FHyperTwistTrainingCoachDashboardGuidancePreferenceInspectSurface +UHyperTwistCoachDashboardWidget::GetDisplayedGuidancePreferenceInspectSurface() const +{ + FHyperTwistTrainingCoachDashboardGuidancePreferenceInspectSurface Surface; + Surface.Headline = TEXT("Guidance preference"); + + const auto BuildPreviewLaneLabel = [](const EHyperTwistCoachDashboardGuidancePreviewLane Lane) -> FString + { + return Lane == EHyperTwistCoachDashboardGuidancePreviewLane::Recommended + ? TEXT("recommended") + : (Lane == EHyperTwistCoachDashboardGuidancePreviewLane::FollowUp + ? TEXT("follow-up") + : TEXT("none")); + }; + + const FHyperTwistCoachDashboardGuidanceLanePreference GuidanceLanePreference = + BuildGuidanceLanePreference(); + Surface.bHasPreference = GuidanceLanePreference.IsStructurallyValid(); + Surface.ActivePreviewLaneLabel = BuildPreviewLaneLabel(ActiveGuidancePreviewLane); + Surface.PreferredGuidanceLaneLabel = + BuildPreviewLaneLabel(GuidanceLanePreference.PreferredLane); + Surface.GuidancePreferenceSourceLabel = [&]() -> FString + { + if (GuidanceLanePreference.bHasDecisionSignal) + { + if (GuidanceLanePreference.bHasReliableAlignedPlanOutcomeSignal) + { + return GuidanceLanePreference.bHasClosureHistorySignal + ? TEXT("decision + closure-history + aligned-plan-outcome") + : TEXT("decision + aligned-plan-outcome"); + } + return GuidanceLanePreference.bHasClosureHistorySignal + ? TEXT("decision + closure-history") + : TEXT("decision-informed"); + } + if (GuidanceLanePreference.bHasReliableAlignedPlanOutcomeSignal) + { + return TEXT("aligned-plan-outcome + memory"); + } + if (GuidanceLanePreference.bHasClosureHistorySignal) + { + return TEXT("closure-history + memory"); + } + return CachedCoachPanelState.PreferredGuidanceSourceLabel.IsEmpty() + ? TEXT("availability fallback") + : HyperTwistCoachDashboardWidgetInternal::DescribeCoachMemorySourceLabel( + CachedCoachPanelState.PreferredGuidanceSourceLabel); + }(); + Surface.LaunchBiasLabel = + HyperTwistCoachDashboardWidgetInternal::DescribeLaunchBudgetBias( + CachedCoachPanelState.PreferredLaunchBudgetBias); + Surface.LaunchBiasSourceLabel = + HyperTwistCoachDashboardWidgetInternal::DescribeCoachMemorySourceLabel( + CachedCoachPanelState.PreferredLaunchBudgetSourceLabel); + Surface.RecommendedDecisionCount = GuidanceLanePreference.RecommendedDecisionCount; + Surface.FollowUpDecisionCount = GuidanceLanePreference.FollowUpDecisionCount; + Surface.RecommendedContinueBias = GuidanceLanePreference.RecommendedContinueBias; + Surface.FollowUpContinueBias = GuidanceLanePreference.FollowUpContinueBias; + Surface.ClosureContinuationBias = GuidanceLanePreference.ClosureContinuationBias; + Surface.ClosureSuppressionBias = GuidanceLanePreference.ClosureSuppressionBias; + Surface.PreferredLaunchBudgetBias = CachedCoachPanelState.PreferredLaunchBudgetBias; + Surface.BroadenedLaunchHistoryCount = + CachedCoachPanelState.BroadenedLaunchBudgetHistoryCount; + Surface.TightenedLaunchHistoryCount = + CachedCoachPanelState.TightenedLaunchBudgetHistoryCount; + Surface.DeferredTightenedLaunchHistoryCount = + CachedCoachPanelState.DeferredTightenedLaunchHistoryCount; + Surface.DeferredLaunchHistoryCaseCount = + CachedCoachPanelState.DeferredLaunchHistoryCaseCount; + Surface.MethodDrillFollowUpHistoryCount = + CachedCoachPanelState.MethodDrillFollowUpHistoryCount; + Surface.StrongMethodDrillFollowUpHistoryCount = + CachedCoachPanelState.StrongMethodDrillFollowUpHistoryCount; + Surface.WeakMethodDrillFollowUpHistoryCount = + CachedCoachPanelState.WeakMethodDrillFollowUpHistoryCount; + Surface.ReliableAlignedTrustedTightPlanOutcomeHistoryCount = + GuidanceLanePreference.ReliableAlignedTrustedTightPlanOutcomeHistoryCount; + Surface.ReliableAlignedTrustedBroadPlanOutcomeHistoryCount = + GuidanceLanePreference.ReliableAlignedTrustedBroadPlanOutcomeHistoryCount; + Surface.ReliableAlignedTrustedTightContinuationBias = + GuidanceLanePreference.ReliableAlignedTrustedTightContinuationBias; + Surface.ReliableAlignedTrustedBroadRedirectBias = + GuidanceLanePreference.ReliableAlignedTrustedBroadRedirectBias; + Surface.ReliableAlignedTrustedTightFollowUpGuidanceOutcomeHistoryCount = + CachedCoachPanelState.ReliableAlignedTrustedTightFollowUpGuidanceOutcomeHistoryCount; + Surface.ReliableAlignedTrustedBroadRecommendedGuidanceOutcomeHistoryCount = + CachedCoachPanelState.ReliableAlignedTrustedBroadRecommendedGuidanceOutcomeHistoryCount; + Surface.AlignedTightFollowUpPacketStructureOutcomeHistoryCount = + CachedCoachPanelState.AlignedTightFollowUpPacketStructureOutcomeHistoryCount; + Surface.AlignedBroadRecommendedPacketStructureOutcomeHistoryCount = + CachedCoachPanelState.AlignedBroadRecommendedPacketStructureOutcomeHistoryCount; + Surface.AcceptedAlignedTightFollowUpPacketOutcomeHistoryCount = + CachedCoachPanelState.AcceptedAlignedTightFollowUpPacketOutcomeHistoryCount; + Surface.AcceptedAlignedBroadRecommendedPacketOutcomeHistoryCount = + CachedCoachPanelState.AcceptedAlignedBroadRecommendedPacketOutcomeHistoryCount; + Surface.AcceptedAlignedTightFollowUpPacketTrustOutcomeHistoryCount = + CachedCoachPanelState.AcceptedAlignedTightFollowUpPacketTrustOutcomeHistoryCount; + Surface.AcceptedAlignedBroadRecommendedPacketTrustOutcomeHistoryCount = + CachedCoachPanelState.AcceptedAlignedBroadRecommendedPacketTrustOutcomeHistoryCount; + Surface.AcceptedAlignedTightFollowUpPacketTrustReliableHistoryCount = + CachedCoachPanelState.AcceptedAlignedTightFollowUpPacketTrustReliableHistoryCount; + Surface.AcceptedAlignedBroadRecommendedPacketTrustReliableHistoryCount = + CachedCoachPanelState.AcceptedAlignedBroadRecommendedPacketTrustReliableHistoryCount; + Surface.AcceptedAlignedTightFollowUpPacketTrustReliableOutcomeHistoryCount = + CachedCoachPanelState.AcceptedAlignedTightFollowUpPacketTrustReliableOutcomeHistoryCount; + Surface.AcceptedAlignedBroadRecommendedPacketTrustReliableOutcomeHistoryCount = + CachedCoachPanelState.AcceptedAlignedBroadRecommendedPacketTrustReliableOutcomeHistoryCount; + Surface.AcceptedAlignedTightFollowUpPacketTrustReliableOutcomeAcceptedHistoryCount = + CachedCoachPanelState.AcceptedAlignedTightFollowUpPacketTrustReliableOutcomeAcceptedHistoryCount; + Surface.AcceptedAlignedBroadRecommendedPacketTrustReliableOutcomeAcceptedHistoryCount = + CachedCoachPanelState.AcceptedAlignedBroadRecommendedPacketTrustReliableOutcomeAcceptedHistoryCount; + Surface.AcceptedAlignedTightFollowUpPacketTrustReliableLaneOutcomeHistoryCount = + CachedCoachPanelState.AcceptedAlignedTightFollowUpPacketTrustReliableLaneOutcomeHistoryCount; + Surface.AcceptedAlignedBroadRecommendedPacketTrustReliableLaneOutcomeHistoryCount = + CachedCoachPanelState.AcceptedAlignedBroadRecommendedPacketTrustReliableLaneOutcomeHistoryCount; + Surface.RecommendedAverageSuccessRate = + GuidanceLanePreference.RecommendedAverageSuccessRate; + Surface.FollowUpAverageSuccessRate = + GuidanceLanePreference.FollowUpAverageSuccessRate; + Surface.MethodDrillFollowUpAverageOutcomeScore = + CachedCoachPanelState.MethodDrillFollowUpAverageOutcomeScore; + Surface.ReliableAlignedTrustedTightPlanOutcomeAverageScore = + GuidanceLanePreference.ReliableAlignedTrustedTightPlanOutcomeAverageScore; + Surface.ReliableAlignedTrustedBroadPlanOutcomeAverageScore = + GuidanceLanePreference.ReliableAlignedTrustedBroadPlanOutcomeAverageScore; + Surface.ReliableAlignedTrustedTightFollowUpGuidanceOutcomeAverageScore = + CachedCoachPanelState.ReliableAlignedTrustedTightFollowUpGuidanceOutcomeAverageScore; + Surface.ReliableAlignedTrustedBroadRecommendedGuidanceOutcomeAverageScore = + CachedCoachPanelState.ReliableAlignedTrustedBroadRecommendedGuidanceOutcomeAverageScore; + Surface.AlignedTightFollowUpPacketStructureOutcomeAverageScore = + CachedCoachPanelState.AlignedTightFollowUpPacketStructureOutcomeAverageScore; + Surface.AlignedBroadRecommendedPacketStructureOutcomeAverageScore = + CachedCoachPanelState.AlignedBroadRecommendedPacketStructureOutcomeAverageScore; + Surface.AcceptedAlignedTightFollowUpPacketOutcomeAverageScore = + CachedCoachPanelState.AcceptedAlignedTightFollowUpPacketOutcomeAverageScore; + Surface.AcceptedAlignedBroadRecommendedPacketOutcomeAverageScore = + CachedCoachPanelState.AcceptedAlignedBroadRecommendedPacketOutcomeAverageScore; + Surface.AcceptedAlignedTightFollowUpPacketTrustOutcomeAverageScore = + CachedCoachPanelState.AcceptedAlignedTightFollowUpPacketTrustOutcomeAverageScore; + Surface.AcceptedAlignedBroadRecommendedPacketTrustOutcomeAverageScore = + CachedCoachPanelState.AcceptedAlignedBroadRecommendedPacketTrustOutcomeAverageScore; + Surface.AcceptedAlignedTightFollowUpPacketTrustReliableAverageOutcomeScore = + CachedCoachPanelState.AcceptedAlignedTightFollowUpPacketTrustReliableAverageOutcomeScore; + Surface.AcceptedAlignedBroadRecommendedPacketTrustReliableAverageOutcomeScore = + CachedCoachPanelState.AcceptedAlignedBroadRecommendedPacketTrustReliableAverageOutcomeScore; + Surface.AcceptedAlignedTightFollowUpPacketTrustReliableOutcomeAverageScore = + CachedCoachPanelState.AcceptedAlignedTightFollowUpPacketTrustReliableOutcomeAverageScore; + Surface.AcceptedAlignedBroadRecommendedPacketTrustReliableOutcomeAverageScore = + CachedCoachPanelState.AcceptedAlignedBroadRecommendedPacketTrustReliableOutcomeAverageScore; + Surface.AcceptedAlignedTightFollowUpPacketTrustReliableOutcomeAcceptedAverageScore = + CachedCoachPanelState.AcceptedAlignedTightFollowUpPacketTrustReliableOutcomeAcceptedAverageScore; + Surface.AcceptedAlignedBroadRecommendedPacketTrustReliableOutcomeAcceptedAverageScore = + CachedCoachPanelState.AcceptedAlignedBroadRecommendedPacketTrustReliableOutcomeAcceptedAverageScore; + Surface.AcceptedAlignedTightFollowUpPacketTrustReliableLaneOutcomeAverageScore = + CachedCoachPanelState.AcceptedAlignedTightFollowUpPacketTrustReliableLaneOutcomeAverageScore; + Surface.AcceptedAlignedBroadRecommendedPacketTrustReliableLaneOutcomeAverageScore = + CachedCoachPanelState.AcceptedAlignedBroadRecommendedPacketTrustReliableLaneOutcomeAverageScore; + Surface.bHasDecisionSignal = GuidanceLanePreference.bHasDecisionSignal; + Surface.bHasClosureHistorySignal = GuidanceLanePreference.bHasClosureHistorySignal; + Surface.bHasReliableAlignedPlanOutcomeSignal = + GuidanceLanePreference.bHasReliableAlignedPlanOutcomeSignal; + Surface.bDeferredOverflowSteeringLane = + CachedCoachPanelState.PreferredLaunchBudgetSourceLabel + == TEXT("recommendation-history-deferred-tightened-launch"); + Surface.bMethodDrillUpstreamStrongSource = + CachedCoachPanelState.PreferredGuidanceSourceLabel + == TEXT("coach-memory-method-drill-follow-up-strong") + || CachedCoachPanelState.PreferredCoachHandoffSourceLabel + == TEXT("coach-memory-method-drill-follow-up-strong"); + Surface.bMethodDrillUpstreamWeakSource = + CachedCoachPanelState.PreferredGuidanceSourceLabel + == TEXT("coach-memory-method-drill-follow-up-weak") + || CachedCoachPanelState.PreferredCoachHandoffSourceLabel + == TEXT("coach-memory-method-drill-follow-up-weak"); + Surface.bClosedLoopIdleDashboard = + IsCoachLoopActionabilityClosed() + && ( + HyperTwistCoachDashboardWidgetInternal::IsQueueRecoveryMemorySource( + CachedCoachPanelState.PreferredGuidanceSourceLabel) + || !CachedCoachPanelState.PreferredGuidanceSourceLabel.IsEmpty() + || DisplayedCoachHandoffRecommendationKind != EHyperTwistTrainingCoachHandoffKind::None); + + const FString MethodDrillUpstreamMemoryLine = + CachedCoachPanelState.MethodDrillFollowUpHistoryCount > 0 + ? FString::Printf( + TEXT(" | Upstream drill memory count %d | strong %d | weak %d | avg outcome %.1f%s%s"), + CachedCoachPanelState.MethodDrillFollowUpHistoryCount, + CachedCoachPanelState.StrongMethodDrillFollowUpHistoryCount, + CachedCoachPanelState.WeakMethodDrillFollowUpHistoryCount, + CachedCoachPanelState.MethodDrillFollowUpAverageOutcomeScore, + Surface.bMethodDrillUpstreamStrongSource + ? TEXT(" | Successful drill follow-up history is actively reinforcing narrow continuation.") + : TEXT(""), + Surface.bMethodDrillUpstreamWeakSource + ? TEXT(" | Weak drill follow-up history is actively pushing control back toward broader coach guidance.") + : TEXT("")) + : FString(); + + Surface.StatusLine = GuidanceLanePreference.IsStructurallyValid() + ? FString::Printf( + TEXT("Preference: next surfaced lane %s | Active preview: %s | Source: %s"), + *Surface.PreferredGuidanceLaneLabel, + *Surface.ActivePreviewLaneLabel, + *Surface.GuidancePreferenceSourceLabel) + : TEXT("Preference: no coach preview lane is currently available."); + Surface.DetailLine = GuidanceLanePreference.IsStructurallyValid() + ? FString::Printf( + TEXT("Recommended lane: %d decisions | Continue bias %d | Avg success %.2f | Closure suppress bias %d || Follow-up lane: %d decisions | Continue bias %d | Avg success %.2f | Closure continuation bias %d | Launch bias: %s from %s | broadened/tightened history %d/%d | deferred tightened launches %d | deferred launch cases %d%s | The dashboard adopts this preferred lane whenever it needs to surface the next guidance preview."), + GuidanceLanePreference.RecommendedDecisionCount, + GuidanceLanePreference.RecommendedContinueBias, + GuidanceLanePreference.RecommendedAverageSuccessRate, + GuidanceLanePreference.ClosureSuppressionBias, + GuidanceLanePreference.FollowUpDecisionCount, + GuidanceLanePreference.FollowUpContinueBias, + GuidanceLanePreference.FollowUpAverageSuccessRate, + GuidanceLanePreference.ClosureContinuationBias, + *Surface.LaunchBiasLabel, + *Surface.LaunchBiasSourceLabel, + Surface.BroadenedLaunchHistoryCount, + Surface.TightenedLaunchHistoryCount, + Surface.DeferredTightenedLaunchHistoryCount, + Surface.DeferredLaunchHistoryCaseCount, + Surface.bDeferredOverflowSteeringLane + ? TEXT(" | Deferred overflow memory is actively steering the surfaced lane.") + : TEXT("")) + : TEXT("Preference detail: build recommended or follow-up guidance to let the dashboard choose a next surfaced lane."); + if (!MethodDrillUpstreamMemoryLine.IsEmpty()) + { + Surface.DetailLine += MethodDrillUpstreamMemoryLine; + } + if (GuidanceLanePreference.ReliableAlignedTrustedTightPlanOutcomeHistoryCount > 0 + || GuidanceLanePreference.ReliableAlignedTrustedBroadPlanOutcomeHistoryCount > 0 + || GuidanceLanePreference.ReliableAlignedTrustedTightContinuationBias > 0 + || GuidanceLanePreference.ReliableAlignedTrustedBroadRedirectBias > 0) + { + Surface.DetailLine += FString::Printf( + TEXT(" | Aligned launched-plan trust: tight history %d (avg %.2f, continuation bias %d) | broad history %d (avg %.2f, redirect bias %d)%s"), + GuidanceLanePreference.ReliableAlignedTrustedTightPlanOutcomeHistoryCount, + GuidanceLanePreference.ReliableAlignedTrustedTightPlanOutcomeAverageScore, + GuidanceLanePreference.ReliableAlignedTrustedTightContinuationBias, + GuidanceLanePreference.ReliableAlignedTrustedBroadPlanOutcomeHistoryCount, + GuidanceLanePreference.ReliableAlignedTrustedBroadPlanOutcomeAverageScore, + GuidanceLanePreference.ReliableAlignedTrustedBroadRedirectBias, + GuidanceLanePreference.ReliableAlignedTrustedTightContinuationBias + > GuidanceLanePreference.ReliableAlignedTrustedBroadRedirectBias + ? TEXT(" | Tight launched-plan trust is currently reinforcing the follow-up lane.") + : (GuidanceLanePreference.ReliableAlignedTrustedBroadRedirectBias + > GuidanceLanePreference.ReliableAlignedTrustedTightContinuationBias + ? TEXT(" | Broad launched-plan redirect trust is currently reinforcing the recommended lane.") + : TEXT(""))); + } + if (CachedCoachPanelState.ReliableAlignedTrustedTightFollowUpGuidanceOutcomeHistoryCount > 0 + || CachedCoachPanelState.ReliableAlignedTrustedBroadRecommendedGuidanceOutcomeHistoryCount > 0) + { + Surface.DetailLine += FString::Printf( + TEXT(" | Aligned launched-plan lane outcomes: tight->follow-up %d (avg %.2f) | broad->recommended %d (avg %.2f)%s"), + CachedCoachPanelState.ReliableAlignedTrustedTightFollowUpGuidanceOutcomeHistoryCount, + CachedCoachPanelState.ReliableAlignedTrustedTightFollowUpGuidanceOutcomeAverageScore, + CachedCoachPanelState.ReliableAlignedTrustedBroadRecommendedGuidanceOutcomeHistoryCount, + CachedCoachPanelState.ReliableAlignedTrustedBroadRecommendedGuidanceOutcomeAverageScore, + HyperTwistCoachDashboardWidgetInternal::IsAlignedTightFollowUpGuidanceSourceLabel( + CachedCoachPanelState.PreferredGuidanceSourceLabel) + ? TEXT(" | Follow-up is currently being reinforced by aligned tight launched-plan lane outcomes.") + : (HyperTwistCoachDashboardWidgetInternal::IsAlignedBroadRecommendedGuidanceSourceLabel( + CachedCoachPanelState.PreferredGuidanceSourceLabel) + ? TEXT(" | Recommended is currently being reinforced by aligned broad launched-plan lane outcomes.") + : TEXT(""))); + } + if (CachedCoachPanelState.AlignedTightFollowUpPacketStructureOutcomeHistoryCount > 0 + || CachedCoachPanelState.AlignedBroadRecommendedPacketStructureOutcomeHistoryCount > 0) + { + Surface.DetailLine += FString::Printf( + TEXT(" | Aligned retained packet outcomes: tight follow-up-first %d (avg %.2f) | broad recommended-first %d (avg %.2f)%s"), + CachedCoachPanelState.AlignedTightFollowUpPacketStructureOutcomeHistoryCount, + CachedCoachPanelState.AlignedTightFollowUpPacketStructureOutcomeAverageScore, + CachedCoachPanelState.AlignedBroadRecommendedPacketStructureOutcomeHistoryCount, + CachedCoachPanelState.AlignedBroadRecommendedPacketStructureOutcomeAverageScore, + CachedCoachPanelState.PreferredGuidanceSourceLabel + == TEXT("coach-memory-aligned-follow-up-packet-structure-tight-follow-up") + ? TEXT(" | Follow-up is currently being reinforced by retained aligned tight packet outcomes.") + : (CachedCoachPanelState.PreferredGuidanceSourceLabel + == TEXT("coach-memory-aligned-follow-up-packet-structure-broad-recommended") + ? TEXT(" | Recommended is currently being reinforced by retained aligned broad packet outcomes.") + : TEXT(""))); + } + if (CachedCoachPanelState.AcceptedAlignedTightFollowUpPacketOutcomeHistoryCount > 0 + || CachedCoachPanelState.AcceptedAlignedBroadRecommendedPacketOutcomeHistoryCount > 0) + { + Surface.DetailLine += FString::Printf( + TEXT(" | Accepted aligned packet outcomes: tight follow-up-first %d (avg %.2f) | broad recommended-first %d (avg %.2f)%s"), + CachedCoachPanelState.AcceptedAlignedTightFollowUpPacketOutcomeHistoryCount, + CachedCoachPanelState.AcceptedAlignedTightFollowUpPacketOutcomeAverageScore, + CachedCoachPanelState.AcceptedAlignedBroadRecommendedPacketOutcomeHistoryCount, + CachedCoachPanelState.AcceptedAlignedBroadRecommendedPacketOutcomeAverageScore, + CachedCoachPanelState.PreferredGuidanceSourceLabel + == TEXT("recommendation-history-accepted-aligned-tight-follow-up-packet-outcome") + ? TEXT(" | Follow-up is currently being reinforced by accepted aligned tight packet outcomes.") + : (CachedCoachPanelState.PreferredGuidanceSourceLabel + == TEXT("recommendation-history-accepted-aligned-broad-recommended-packet-outcome") + ? TEXT(" | Recommended is currently being reinforced by accepted aligned broad packet outcomes.") + : TEXT(""))); + } + if (CachedCoachPanelState.AcceptedAlignedTightFollowUpPacketTrustOutcomeHistoryCount > 0 + || CachedCoachPanelState.AcceptedAlignedBroadRecommendedPacketTrustOutcomeHistoryCount > 0) + { + Surface.DetailLine += FString::Printf( + TEXT(" | Accepted aligned packet trust outcomes: tight follow-up-first %d (avg %.2f) | broad recommended-first %d (avg %.2f)%s"), + CachedCoachPanelState.AcceptedAlignedTightFollowUpPacketTrustOutcomeHistoryCount, + CachedCoachPanelState.AcceptedAlignedTightFollowUpPacketTrustOutcomeAverageScore, + CachedCoachPanelState.AcceptedAlignedBroadRecommendedPacketTrustOutcomeHistoryCount, + CachedCoachPanelState.AcceptedAlignedBroadRecommendedPacketTrustOutcomeAverageScore, + CachedCoachPanelState.PreferredGuidanceSourceLabel.StartsWith( + TEXT("coach-memory-dashboard-accepted-aligned-follow-up-packet-tight-")) + ? TEXT(" | Follow-up is currently being reinforced by retained accepted aligned tight packet trust.") + : (CachedCoachPanelState.PreferredGuidanceSourceLabel.StartsWith( + TEXT("coach-memory-dashboard-accepted-aligned-follow-up-packet-broad-")) + ? TEXT(" | Recommended is currently being reinforced by retained accepted aligned broad packet trust.") + : TEXT(""))); + } + if (CachedCoachPanelState.AcceptedAlignedTightFollowUpPacketTrustReliableHistoryCount > 0 + || CachedCoachPanelState.AcceptedAlignedBroadRecommendedPacketTrustReliableHistoryCount > 0) + { + Surface.DetailLine += FString::Printf( + TEXT(" | Reliable accepted aligned packet trust: tight follow-up-first %d (avg %.2f) | broad recommended-first %d (avg %.2f)%s"), + CachedCoachPanelState.AcceptedAlignedTightFollowUpPacketTrustReliableHistoryCount, + CachedCoachPanelState.AcceptedAlignedTightFollowUpPacketTrustReliableAverageOutcomeScore, + CachedCoachPanelState.AcceptedAlignedBroadRecommendedPacketTrustReliableHistoryCount, + CachedCoachPanelState.AcceptedAlignedBroadRecommendedPacketTrustReliableAverageOutcomeScore, + CachedCoachPanelState.PreferredGuidanceSourceLabel.StartsWith( + TEXT("coach-memory-dashboard-accepted-aligned-follow-up-packet-tight-reliable-")) + ? TEXT(" | Follow-up is currently being reinforced by reliable accepted aligned tight packet trust.") + : (CachedCoachPanelState.PreferredGuidanceSourceLabel.StartsWith( + TEXT("coach-memory-dashboard-accepted-aligned-follow-up-packet-broad-reliable-")) + ? TEXT(" | Recommended is currently being reinforced by reliable accepted aligned broad packet trust.") + : TEXT(""))); + } + if (CachedCoachPanelState.AcceptedAlignedTightFollowUpPacketTrustReliableOutcomeHistoryCount > 0 + || CachedCoachPanelState.AcceptedAlignedBroadRecommendedPacketTrustReliableOutcomeHistoryCount + > 0) + { + Surface.DetailLine += FString::Printf( + TEXT(" | Reliable accepted aligned packet launched-plan outcomes: tight follow-up-first %d (avg %.2f) | broad recommended-first %d (avg %.2f)"), + CachedCoachPanelState.AcceptedAlignedTightFollowUpPacketTrustReliableOutcomeHistoryCount, + CachedCoachPanelState.AcceptedAlignedTightFollowUpPacketTrustReliableOutcomeAverageScore, + CachedCoachPanelState.AcceptedAlignedBroadRecommendedPacketTrustReliableOutcomeHistoryCount, + CachedCoachPanelState.AcceptedAlignedBroadRecommendedPacketTrustReliableOutcomeAverageScore); + } + if (CachedCoachPanelState.AcceptedAlignedTightFollowUpPacketTrustReliableOutcomeAcceptedHistoryCount + > 0 + || CachedCoachPanelState + .AcceptedAlignedBroadRecommendedPacketTrustReliableOutcomeAcceptedHistoryCount > 0) + { + Surface.DetailLine += FString::Printf( + TEXT(" | Reliable accepted aligned packet handoff completion: tight follow-up-first %d (avg %.2f) | broad recommended-first %d (avg %.2f)"), + CachedCoachPanelState.AcceptedAlignedTightFollowUpPacketTrustReliableOutcomeAcceptedHistoryCount, + CachedCoachPanelState.AcceptedAlignedTightFollowUpPacketTrustReliableOutcomeAcceptedAverageScore, + CachedCoachPanelState.AcceptedAlignedBroadRecommendedPacketTrustReliableOutcomeAcceptedHistoryCount, + CachedCoachPanelState.AcceptedAlignedBroadRecommendedPacketTrustReliableOutcomeAcceptedAverageScore); + } + if (CachedCoachPanelState.AcceptedAlignedTightFollowUpPacketTrustReliableLaneOutcomeHistoryCount + > 0 + || CachedCoachPanelState.AcceptedAlignedBroadRecommendedPacketTrustReliableLaneOutcomeHistoryCount + > 0) + { + Surface.DetailLine += FString::Printf( + TEXT(" | Reliable accepted aligned packet exact lane outcomes: tight follow-up-first %d (avg %.2f) | broad recommended-first %d (avg %.2f)"), + CachedCoachPanelState.AcceptedAlignedTightFollowUpPacketTrustReliableLaneOutcomeHistoryCount, + CachedCoachPanelState.AcceptedAlignedTightFollowUpPacketTrustReliableLaneOutcomeAverageScore, + CachedCoachPanelState.AcceptedAlignedBroadRecommendedPacketTrustReliableLaneOutcomeHistoryCount, + CachedCoachPanelState.AcceptedAlignedBroadRecommendedPacketTrustReliableLaneOutcomeAverageScore); + } + return Surface; +} + bool UHyperTwistCoachDashboardWidget::SelectPreviousMethodDrillFollowUpHistoryEntry() { if (MethodDrillFollowUpHistoryEntries.Num() <= 0) diff --git a/UnrealHyperTwist/Source/UnrealHyperTwist/Public/HyperTwistTraining/HyperTwistCoachDashboardWidget.h b/UnrealHyperTwist/Source/UnrealHyperTwist/Public/HyperTwistTraining/HyperTwistCoachDashboardWidget.h index d3d422f..d526e58 100644 --- a/UnrealHyperTwist/Source/UnrealHyperTwist/Public/HyperTwistTraining/HyperTwistCoachDashboardWidget.h +++ b/UnrealHyperTwist/Source/UnrealHyperTwist/Public/HyperTwistTraining/HyperTwistCoachDashboardWidget.h @@ -775,6 +775,22 @@ public: FHyperTwistTrainingCoachDashboardGuidanceDecisionWeightingInspectSurface GetDisplayedGuidanceDecisionWeightingInspectSurface() const; + UFUNCTION(BlueprintPure, Category = "HyperTwist|Training|Coach|Dashboard") + FHyperTwistTrainingCoachDashboardGuidancePreviewSelectionInspectSurface + GetDisplayedGuidancePreviewSelectionInspectSurface() const; + + UFUNCTION(BlueprintPure, Category = "HyperTwist|Training|Coach|Dashboard") + FHyperTwistTrainingCoachDashboardGuidancePreviewCaseDetailInspectSurface + GetDisplayedGuidancePreviewCaseDetailInspectSurface() const; + + UFUNCTION(BlueprintPure, Category = "HyperTwist|Training|Coach|Dashboard") + FHyperTwistTrainingCoachDashboardGuidanceRationaleInspectSurface + GetDisplayedGuidanceRationaleInspectSurface() const; + + UFUNCTION(BlueprintPure, Category = "HyperTwist|Training|Coach|Dashboard") + FHyperTwistTrainingCoachDashboardGuidancePreferenceInspectSurface + GetDisplayedGuidancePreferenceInspectSurface() const; + UFUNCTION(BlueprintCallable, Category = "HyperTwist|Training|Coach|Dashboard") bool SelectPreviousMethodDrillFollowUpHistoryEntry(); diff --git a/UnrealHyperTwist/Source/UnrealHyperTwist/Public/HyperTwistTraining/HyperTwistTrainingTypes.h b/UnrealHyperTwist/Source/UnrealHyperTwist/Public/HyperTwistTraining/HyperTwistTrainingTypes.h index c54056a..ef6be93 100644 --- a/UnrealHyperTwist/Source/UnrealHyperTwist/Public/HyperTwistTraining/HyperTwistTrainingTypes.h +++ b/UnrealHyperTwist/Source/UnrealHyperTwist/Public/HyperTwistTraining/HyperTwistTrainingTypes.h @@ -10091,6 +10091,474 @@ struct FHyperTwistTrainingCoachDashboardGuidanceDecisionWeightingInspectSurface } }; +USTRUCT(BlueprintType) +struct FHyperTwistTrainingCoachDashboardGuidancePreviewSelectionInspectSurface +{ + GENERATED_BODY() + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist") + FString Headline; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist") + FString StatusLine; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist") + FString DetailLine; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist") + FString ActivePreviewLaneLabel; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist") + FString DeckId; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist") + FString DeckTitle; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist") + FString DeckLabel; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist") + FString SelectionPolicyLabel; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist") + FString DifficultyBand; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist") + FString SubsetId; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist") + FString SelectedCaseId; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist") + FString SelectedCasePromptLabel; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist") + int32 SelectedCaseIndex = INDEX_NONE; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist") + int32 TotalCaseCount = 0; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist") + bool bHasActivePreviewDeck = false; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist") + bool bHasSelectedCase = false; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist") + bool bClosedLoopIdleDashboard = false; + + bool IsStructurallyValid() const + { + return !StatusLine.IsEmpty() + || !DetailLine.IsEmpty() + || bHasActivePreviewDeck + || bHasSelectedCase; + } +}; + +USTRUCT(BlueprintType) +struct FHyperTwistTrainingCoachDashboardGuidancePreviewCaseDetailInspectSurface +{ + GENERATED_BODY() + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist") + FString Headline; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist") + FString StatusLine; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist") + FString DetailLine; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist") + FString ActivePreviewLaneLabel; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist") + FString DeckLabel; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist") + FString CaseId; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist") + FString PromptLabel; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist") + FString PromptKindLabel; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist") + FString SubsetId; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist") + FString ScrambleNotation; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist") + FString CanonicalNotation; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist") + int32 TimeTargetMs = 0; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist") + int32 SelectedCaseIndex = INDEX_NONE; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist") + int32 TotalCaseCount = 0; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist") + bool bHasActivePreviewDeck = false; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist") + bool bHasSelectedCase = false; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist") + bool bClosedLoopIdleDashboard = false; + + bool IsStructurallyValid() const + { + return !StatusLine.IsEmpty() + || !DetailLine.IsEmpty() + || bHasSelectedCase + || bHasActivePreviewDeck; + } +}; + +USTRUCT(BlueprintType) +struct FHyperTwistTrainingCoachDashboardGuidanceRationaleInspectSurface +{ + GENERATED_BODY() + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist") + FString Headline; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist") + FString StatusLine; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist") + FString DetailLine; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist") + FString ActivePreviewLaneLabel; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist") + FString PriorityLabel; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist") + FString FocusLaneLabel; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist") + FString SuggestedModeLabel; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist") + FString SuggestedSelectionLabel; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist") + FString BriefHeadline; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist") + FString PrimaryActionLabel; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist") + FString FocusDeckId; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist") + FString FocusMethodSegmentId; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist") + FString GuidanceSourceLabel; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist") + FString LaunchBiasLabel; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist") + FString LaunchBiasSourceLabel; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist") + FString SelectedCaseId; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist") + FString SelectedPreviewCaseSignalLine; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist") + FString TopSignalSummaryLine; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist") + int32 FocusCaseCount = 0; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist") + int32 SignalCount = 0; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist") + int32 SelectedPreviewCaseSignalCount = 0; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist") + int32 BroadenedLaunchHistoryCount = 0; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist") + int32 TightenedLaunchHistoryCount = 0; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist") + int32 DeferredTightenedLaunchHistoryCount = 0; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist") + int32 DeferredLaunchHistoryCaseCount = 0; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist") + float PriorityScore = 0.0f; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist") + bool bHasActivePreviewBrief = false; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist") + bool bNeedsCoachReview = false; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist") + bool bNeedsCadenceRecovery = false; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist") + bool bNeedsVarietyRotation = false; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist") + bool bSelectedPreviewCaseIsExplicitFocus = false; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist") + bool bDeferredOverflowShaping = false; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist") + bool bClosedLoopIdleDashboard = false; + + bool IsStructurallyValid() const + { + return !StatusLine.IsEmpty() + || !DetailLine.IsEmpty() + || bHasActivePreviewBrief; + } +}; + +USTRUCT(BlueprintType) +struct FHyperTwistTrainingCoachDashboardGuidancePreferenceInspectSurface +{ + GENERATED_BODY() + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist") + FString Headline; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist") + FString StatusLine; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist") + FString DetailLine; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist") + FString PreferredGuidanceLaneLabel; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist") + FString ActivePreviewLaneLabel; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist") + FString GuidancePreferenceSourceLabel; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist") + FString LaunchBiasLabel; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist") + FString LaunchBiasSourceLabel; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist") + int32 RecommendedDecisionCount = 0; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist") + int32 FollowUpDecisionCount = 0; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist") + int32 RecommendedContinueBias = 0; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist") + int32 FollowUpContinueBias = 0; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist") + int32 ClosureContinuationBias = 0; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist") + int32 ClosureSuppressionBias = 0; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist") + int32 PreferredLaunchBudgetBias = 0; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist") + int32 BroadenedLaunchHistoryCount = 0; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist") + int32 TightenedLaunchHistoryCount = 0; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist") + int32 DeferredTightenedLaunchHistoryCount = 0; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist") + int32 DeferredLaunchHistoryCaseCount = 0; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist") + int32 MethodDrillFollowUpHistoryCount = 0; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist") + int32 StrongMethodDrillFollowUpHistoryCount = 0; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist") + int32 WeakMethodDrillFollowUpHistoryCount = 0; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist") + int32 ReliableAlignedTrustedTightPlanOutcomeHistoryCount = 0; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist") + int32 ReliableAlignedTrustedBroadPlanOutcomeHistoryCount = 0; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist") + int32 ReliableAlignedTrustedTightContinuationBias = 0; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist") + int32 ReliableAlignedTrustedBroadRedirectBias = 0; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist") + int32 ReliableAlignedTrustedTightFollowUpGuidanceOutcomeHistoryCount = 0; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist") + int32 ReliableAlignedTrustedBroadRecommendedGuidanceOutcomeHistoryCount = 0; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist") + int32 AlignedTightFollowUpPacketStructureOutcomeHistoryCount = 0; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist") + int32 AlignedBroadRecommendedPacketStructureOutcomeHistoryCount = 0; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist") + int32 AcceptedAlignedTightFollowUpPacketOutcomeHistoryCount = 0; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist") + int32 AcceptedAlignedBroadRecommendedPacketOutcomeHistoryCount = 0; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist") + int32 AcceptedAlignedTightFollowUpPacketTrustOutcomeHistoryCount = 0; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist") + int32 AcceptedAlignedBroadRecommendedPacketTrustOutcomeHistoryCount = 0; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist") + int32 AcceptedAlignedTightFollowUpPacketTrustReliableHistoryCount = 0; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist") + int32 AcceptedAlignedBroadRecommendedPacketTrustReliableHistoryCount = 0; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist") + int32 AcceptedAlignedTightFollowUpPacketTrustReliableOutcomeHistoryCount = 0; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist") + int32 AcceptedAlignedBroadRecommendedPacketTrustReliableOutcomeHistoryCount = 0; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist") + int32 AcceptedAlignedTightFollowUpPacketTrustReliableOutcomeAcceptedHistoryCount = 0; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist") + int32 AcceptedAlignedBroadRecommendedPacketTrustReliableOutcomeAcceptedHistoryCount = 0; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist") + int32 AcceptedAlignedTightFollowUpPacketTrustReliableLaneOutcomeHistoryCount = 0; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist") + int32 AcceptedAlignedBroadRecommendedPacketTrustReliableLaneOutcomeHistoryCount = 0; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist") + float RecommendedAverageSuccessRate = 0.0f; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist") + float FollowUpAverageSuccessRate = 0.0f; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist") + float MethodDrillFollowUpAverageOutcomeScore = 0.0f; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist") + float ReliableAlignedTrustedTightPlanOutcomeAverageScore = 0.0f; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist") + float ReliableAlignedTrustedBroadPlanOutcomeAverageScore = 0.0f; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist") + float ReliableAlignedTrustedTightFollowUpGuidanceOutcomeAverageScore = 0.0f; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist") + float ReliableAlignedTrustedBroadRecommendedGuidanceOutcomeAverageScore = 0.0f; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist") + float AlignedTightFollowUpPacketStructureOutcomeAverageScore = 0.0f; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist") + float AlignedBroadRecommendedPacketStructureOutcomeAverageScore = 0.0f; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist") + float AcceptedAlignedTightFollowUpPacketOutcomeAverageScore = 0.0f; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist") + float AcceptedAlignedBroadRecommendedPacketOutcomeAverageScore = 0.0f; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist") + float AcceptedAlignedTightFollowUpPacketTrustOutcomeAverageScore = 0.0f; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist") + float AcceptedAlignedBroadRecommendedPacketTrustOutcomeAverageScore = 0.0f; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist") + float AcceptedAlignedTightFollowUpPacketTrustReliableAverageOutcomeScore = 0.0f; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist") + float AcceptedAlignedBroadRecommendedPacketTrustReliableAverageOutcomeScore = 0.0f; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist") + float AcceptedAlignedTightFollowUpPacketTrustReliableOutcomeAverageScore = 0.0f; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist") + float AcceptedAlignedBroadRecommendedPacketTrustReliableOutcomeAverageScore = 0.0f; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist") + float AcceptedAlignedTightFollowUpPacketTrustReliableOutcomeAcceptedAverageScore = 0.0f; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist") + float AcceptedAlignedBroadRecommendedPacketTrustReliableOutcomeAcceptedAverageScore = 0.0f; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist") + float AcceptedAlignedTightFollowUpPacketTrustReliableLaneOutcomeAverageScore = 0.0f; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist") + float AcceptedAlignedBroadRecommendedPacketTrustReliableLaneOutcomeAverageScore = 0.0f; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist") + bool bHasPreference = false; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist") + bool bHasDecisionSignal = false; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist") + bool bHasClosureHistorySignal = false; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist") + bool bHasReliableAlignedPlanOutcomeSignal = false; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist") + bool bDeferredOverflowSteeringLane = false; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist") + bool bMethodDrillUpstreamStrongSource = false; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist") + bool bMethodDrillUpstreamWeakSource = false; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist") + bool bClosedLoopIdleDashboard = false; + + bool IsStructurallyValid() const + { + return !StatusLine.IsEmpty() + || !DetailLine.IsEmpty() + || bHasPreference; + } +}; + USTRUCT(BlueprintType) struct FHyperTwistTrainingCoachGeneratedModeLaunchExecutionContextSurface { diff --git a/docs/HYPERTWIST_ROADMAP_OVERHAUL_EXPANSION_GUIDE.md b/docs/HYPERTWIST_ROADMAP_OVERHAUL_EXPANSION_GUIDE.md index 2669def..1a313d7 100644 --- a/docs/HYPERTWIST_ROADMAP_OVERHAUL_EXPANSION_GUIDE.md +++ b/docs/HYPERTWIST_ROADMAP_OVERHAUL_EXPANSION_GUIDE.md @@ -69,8 +69,8 @@ Current correction call from the source-exposed audit and current execution refr - the latest landed bounded `Phase 4` packet closes the retained-idle comparison/outcome actionability gap at the end of the recognition-assisted coach-to-review continuity lane, and the final retained-surface confirmation pass now leaves that closure lane functionally complete - the retained idle widget surface now keeps retained comparison and decision history inspectable without continuing to advertise live launch or guidance-outcome actions once the coach-to-review loop has already collapsed to truthful closed-loop idle - the now-complete deliberate `UHyperTwistTrainingRuntimeLibrary` world-context consumer lane reaches through active generated-mode selector option owned-execution split-phase current-selection merged ordered roster phase-id lookup, normalized-order lookup, and evaluation-order lookup inspect surfaces, so gameplay/Blueprint callers can inspect one retained merged-roster row directly by phase id, normalized order, or evaluation order without scanning the merged roster array or re-running inspect derivation details directly - - the latest landed bounded `Phase 4` packet pivots deliberately off that now-closed `UHyperTwistCoachDashboardWidget` retained-history inspect lane and adds displayed guidance comparison, displayed guidance outcome, and displayed guidance decision-weighting inspect surfaces over the live dashboard recap/comparison state and cached coach actionability state, so gameplay/Blueprint callers can inspect the active comparison target, current outcome action posture, and current authored weighting posture without scraping dashboard text blocks or reopening comparison/outcome derivation - - the next clean move is to stay on that same live dashboard guidance-consumer lane and land the active guidance preview selection, preview-case detail, rationale, and guidance-preference inspect surface group rather than drifting back into backend continuity or reopening the already-complete retained-history seam + - the latest landed bounded `Phase 4` packet stays on that same live `UHyperTwistCoachDashboardWidget` guidance-consumer lane and adds displayed guidance preview selection, displayed preview-case detail, displayed guidance rationale, and displayed guidance-preference inspect surfaces over already-derived preview brief/deck state and cached coach preference state, so gameplay/Blueprint callers can inspect the surfaced preview target, case detail, rationale signal posture, and lane-preference bias without scraping dashboard text blocks or reopening preview/preference derivation + - the next clean move is to stay on that same live dashboard guidance-consumer lane and land the displayed recommended guidance deck preview, displayed follow-up guidance deck preview, and live coach handoff recommendation inspect surface group rather than drifting back into backend continuity or reopening the already-complete retained-history seam - the current execution-discipline rule that broad refactor / monolith-splitting work should not interrupt the active bounded roadmap packet unless structure is actually blocking it ## Current execution-reality references diff --git a/docs/arch/HYPERTWIST_PHASE4_DASHBOARD_LIVE_GUIDANCE_PREVIEW_SELECTION_CASE_DETAIL_RATIONALE_PREFERENCE_INSPECT_SURFACE_PACKET_2026-05-09.md b/docs/arch/HYPERTWIST_PHASE4_DASHBOARD_LIVE_GUIDANCE_PREVIEW_SELECTION_CASE_DETAIL_RATIONALE_PREFERENCE_INSPECT_SURFACE_PACKET_2026-05-09.md new file mode 100644 index 0000000..191e4f6 --- /dev/null +++ b/docs/arch/HYPERTWIST_PHASE4_DASHBOARD_LIVE_GUIDANCE_PREVIEW_SELECTION_CASE_DETAIL_RATIONALE_PREFERENCE_INSPECT_SURFACE_PACKET_2026-05-09.md @@ -0,0 +1,58 @@ +# HyperTwist Phase 4 dashboard live guidance preview, rationale, and preference inspect surface packet + +- bounded Phase `4` dashboard-consumer slice +- date: `2026-05-09` + +## Intent + +Stay on the deliberate live `UHyperTwistCoachDashboardWidget` guidance-consumer lane and expose the remaining surfaced preview-selection, preview-case, rationale, and guidance-preference state directly to gameplay and Blueprint callers. + +## Why this packet exists + +The dashboard already derived: + +- the currently surfaced preview lane and selected preview case +- the selected preview case prompt, subset, and canonical/scramble detail +- the current coach rationale summary and selected-case signal posture +- the current preferred next guidance lane and the retained lane-bias memory behind it + +But that live state still only surfaced through dashboard text blocks. Callers still had to scrape widget presentation or reopen preview/rationale/preference derivation to inspect what the dashboard was currently showing. + +## What changed + +- added `FHyperTwistTrainingCoachDashboardGuidancePreviewSelectionInspectSurface` +- added `FHyperTwistTrainingCoachDashboardGuidancePreviewCaseDetailInspectSurface` +- added `FHyperTwistTrainingCoachDashboardGuidanceRationaleInspectSurface` +- added `FHyperTwistTrainingCoachDashboardGuidancePreferenceInspectSurface` +- added `GetDisplayedGuidancePreviewSelectionInspectSurface()` +- added `GetDisplayedGuidancePreviewCaseDetailInspectSurface()` +- added `GetDisplayedGuidanceRationaleInspectSurface()` +- added `GetDisplayedGuidancePreferenceInspectSurface()` +- kept the packet bounded to `UHyperTwistCoachDashboardWidget` plus shared surface types, with no dashboard redesign and no backend continuity changes + +## Files + +- `C:\HyperTwist\UnrealHyperTwist\Source\UnrealHyperTwist\Public\HyperTwistTraining\HyperTwistTrainingTypes.h` +- `C:\HyperTwist\UnrealHyperTwist\Source\UnrealHyperTwist\Public\HyperTwistTraining\HyperTwistCoachDashboardWidget.h` +- `C:\HyperTwist\UnrealHyperTwist\Source\UnrealHyperTwist\Private\HyperTwistTraining\HyperTwistCoachDashboardWidget.cpp` +- `C:\HyperTwist\docs\HYPERTWIST_ROADMAP_OVERHAUL_EXPANSION_GUIDE.md` + +## Outcome + +Gameplay and Blueprint callers can now inspect: + +- the surfaced preview lane, deck, and current selected preview case +- the selected preview case prompt, subset, target time, scramble, and canonical notation +- the live rationale summary, selected-case signal posture, and top signal summary for the surfaced preview +- the live next-lane preference summary plus retained lane-bias, deferred-overflow, method-drill, aligned-plan, and accepted-packet reinforcement posture + +without scraping dashboard text blocks or reopening preview/rationale/preference derivation. + +## Validation + +- full `Development Editor | Win64` MSBuild on `UnrealHyperTwist.sln` + - passed with `0 Warning(s), 0 Error(s)` + +## Next clean slice + +Stay on the same live dashboard guidance-consumer lane and land the displayed recommended guidance deck preview, displayed follow-up guidance deck preview, and live coach handoff recommendation inspect surface group.