From 0c16748821e1b0dcc91a44daa06c2fc436bb7b22 Mon Sep 17 00:00:00 2001 From: axiomlogicnexus Date: Sat, 9 May 2026 17:56:33 +0200 Subject: [PATCH] Expose dashboard follow-up and handoff history inspect surfaces --- .../HyperTwistCoachDashboardWidget.cpp | 345 ++++++++++++++++ .../HyperTwistCoachDashboardWidget.h | 8 + .../HyperTwistTrainingTypes.h | 378 ++++++++++++++++++ ...RTWIST_ROADMAP_OVERHAUL_EXPANSION_GUIDE.md | 4 +- ...STORY_INSPECT_SURFACE_PACKET_2026-05-09.md | 50 +++ 5 files changed, 783 insertions(+), 2 deletions(-) create mode 100644 docs/arch/HYPERTWIST_PHASE4_DASHBOARD_METHOD_DRILL_FOLLOW_UP_HANDOFF_HISTORY_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 7bf3181..958a7a4 100644 --- a/UnrealHyperTwist/Source/UnrealHyperTwist/Private/HyperTwistTraining/HyperTwistCoachDashboardWidget.cpp +++ b/UnrealHyperTwist/Source/UnrealHyperTwist/Private/HyperTwistTraining/HyperTwistCoachDashboardWidget.cpp @@ -7828,6 +7828,351 @@ UHyperTwistCoachDashboardWidget::GetSelectedMethodDrillRecoveryMemoryHistoryInsp return Surface; } +FHyperTwistTrainingCoachDashboardMethodDrillFollowUpHistoryInspectSurface +UHyperTwistCoachDashboardWidget::GetSelectedMethodDrillFollowUpHistoryInspectSurface() const +{ + FHyperTwistTrainingCoachDashboardMethodDrillFollowUpHistoryInspectSurface Surface; + Surface.Headline = TEXT("Method-drill follow-up history"); + Surface.SelectedEntryIndex = SelectedMethodDrillFollowUpHistoryIndex; + Surface.HistoryEntryCount = MethodDrillFollowUpHistoryEntries.Num(); + + const FHyperTwistCoachDashboardMethodDrillFollowUpWeighting Weighting = + BuildMethodDrillFollowUpWeighting(); + Surface.MatchingHistoryCount = Weighting.MatchingHistoryCount; + Surface.UpstreamPacketStructureHistoryCount = Weighting.UpstreamPacketStructureHistoryCount; + Surface.UpstreamNarrowPacketStructureHistoryCount = + Weighting.UpstreamNarrowPacketStructureHistoryCount; + Surface.UpstreamBroadPacketStructureHistoryCount = + Weighting.UpstreamBroadPacketStructureHistoryCount; + Surface.StrongOutcomeCount = Weighting.StrongOutcomeCount; + Surface.WeakOutcomeCount = Weighting.WeakOutcomeCount; + Surface.ContinueNarrowBias = Weighting.ContinueNarrowBias; + Surface.RedirectCoachBias = Weighting.RedirectCoachBias; + Surface.StrongPacketContinuationCount = Weighting.StrongPacketContinuationCount; + Surface.WeakPacketRedirectCount = Weighting.WeakPacketRedirectCount; + Surface.QueueEntryFirstStructureCount = Weighting.QueueEntryFirstStructureCount; + Surface.FollowUpPacketFirstStructureCount = Weighting.FollowUpPacketFirstStructureCount; + Surface.RecommendedBriefFirstStructureCount = Weighting.RecommendedBriefFirstStructureCount; + Surface.RecommendedRedirectStructureCount = Weighting.RecommendedRedirectStructureCount; + Surface.AverageSuccessRate = Weighting.AverageSuccessRate; + Surface.AverageMistakes = Weighting.AverageMistakes; + Surface.UpstreamNarrowPacketStructureAverageOutcomeScore = + Weighting.UpstreamNarrowPacketStructureAverageOutcomeScore; + Surface.UpstreamBroadPacketStructureAverageOutcomeScore = + Weighting.UpstreamBroadPacketStructureAverageOutcomeScore; + Surface.bHasHistoryWeighting = Weighting.IsStructurallyValid(); + Surface.bPreferDrillFollowUp = Weighting.bPreferDrillFollowUp; + Surface.bPreferCoachHandoff = Weighting.bPreferCoachHandoff; + Surface.bHasUpstreamStructureSignal = Weighting.bHasUpstreamStructureSignal; + Surface.bUsedUpstreamNarrowStructureSignal = Weighting.bUsedUpstreamNarrowStructureSignal; + Surface.bUsedUpstreamBroadStructureSignal = Weighting.bUsedUpstreamBroadStructureSignal; + Surface.OutcomePreferenceLine = !Weighting.IsStructurallyValid() + ? TEXT("no retained drill follow-up history yet") + : (Weighting.bPreferDrillFollowUp + ? (Weighting.bUsedUpstreamNarrowStructureSignal + ? TEXT("retained drill-follow-up packet structure history favors staying narrow with drill follow-up") + : TEXT("retained drill history favors staying narrow with drill follow-up")) + : (Weighting.bPreferCoachHandoff + ? (Weighting.bUsedUpstreamBroadStructureSignal + ? TEXT("retained drill-follow-up packet structure history favors handing control back to broader coach guidance") + : TEXT("retained drill history favors handing control back to broader coach guidance")) + : TEXT("retained drill history is balanced"))); + + const FHyperTwistCoachDashboardMethodDrillFollowUpHistoryEntry* SelectedEntry = + SelectedMethodDrillFollowUpHistoryIndex >= 0 + && SelectedMethodDrillFollowUpHistoryIndex < MethodDrillFollowUpHistoryEntries.Num() + ? &MethodDrillFollowUpHistoryEntries[SelectedMethodDrillFollowUpHistoryIndex] + : nullptr; + Surface.bHasSelectedEntry = + SelectedEntry != nullptr && SelectedEntry->IsStructurallyValid(); + if (!Surface.bHasSelectedEntry) + { + Surface.StatusLine = + TEXT("Drill follow-up history: no retained drill follow-up outcomes recorded yet."); + Surface.DetailLine = + TEXT("Drill follow-up history detail: once drill-derived follow-up runs complete, their recap outcomes will accumulate here and feed later drill-vs-handoff judgment."); + return Surface; + } + + Surface.RecordedAtUtc = SelectedEntry->RecordedAtUtc; + Surface.SourceRunId = SelectedEntry->SourceRunId; + Surface.SourceDrillId = SelectedEntry->SourceDrillId; + Surface.SourceSessionId = SelectedEntry->SourceSessionId; + Surface.StageLabel = + SelectedEntry->StageLabel.IsEmpty() ? TEXT("n/a") : SelectedEntry->StageLabel; + Surface.DiagnosticState = SelectedEntry->DiagnosticState; + Surface.DiagnosticStateLabel = + HyperTwistCoachDashboardWidgetInternal::EnumDisplayName( + SelectedEntry->DiagnosticState); + Surface.RecommendedReviewGrade = SelectedEntry->RecommendedReviewGrade; + Surface.RecommendedReviewGradeLabel = + HyperTwistCoachDashboardWidgetInternal::EnumDisplayName( + SelectedEntry->RecommendedReviewGrade); + Surface.TemplateKind = SelectedEntry->TemplateKind; + Surface.TemplateKindLabel = + HyperTwistCoachDashboardWidgetInternal::EnumDisplayName( + SelectedEntry->TemplateKind); + Surface.SuggestedMode = SelectedEntry->SuggestedMode; + Surface.SuggestedModeLabel = + HyperTwistCoachDashboardWidgetInternal::EnumDisplayName( + SelectedEntry->SuggestedMode); + Surface.SuggestedSelectionPolicy = SelectedEntry->SuggestedSelectionPolicy; + Surface.SuggestedSelectionLabel = + HyperTwistCoachDashboardWidgetInternal::EnumDisplayName( + SelectedEntry->SuggestedSelectionPolicy); + Surface.PacketStructureLabel = + SelectedEntry->PacketStructureLabel.IsEmpty() + ? TEXT("default") + : SelectedEntry->PacketStructureLabel; + Surface.PacketLaneLabel = + SelectedEntry->PacketLaneLabel.IsEmpty() + ? TEXT("none") + : SelectedEntry->PacketLaneLabel; + Surface.PacketStanceLabel = + SelectedEntry->PacketStanceLabel.IsEmpty() + ? TEXT("none") + : SelectedEntry->PacketStanceLabel; + Surface.FocusCaseCount = SelectedEntry->FocusCaseCount; + Surface.LaunchedCaseCount = SelectedEntry->LaunchedCaseCount; + Surface.CompletedAttemptCount = SelectedEntry->CompletedAttemptCount; + Surface.TotalMistakes = SelectedEntry->TotalMistakes; + Surface.SuccessRate = SelectedEntry->SuccessRate; + Surface.bBoundaryPending = SelectedEntry->bBoundaryPending; + Surface.bBoundaryRepeatBurden = SelectedEntry->bBoundaryRepeatBurden; + Surface.bBoundaryAssistance = SelectedEntry->bBoundaryAssistance; + Surface.bPacketProvenStrongContinuation = + SelectedEntry->bPacketProvenStrongContinuation; + Surface.bPacketProvenWeakRedirect = SelectedEntry->bPacketProvenWeakRedirect; + Surface.StatusLine = FString::Printf( + TEXT("Drill follow-up history: %d entries | selected %d/%d | Stage: %s | review %s | Recorded: %s"), + MethodDrillFollowUpHistoryEntries.Num(), + SelectedMethodDrillFollowUpHistoryIndex + 1, + MethodDrillFollowUpHistoryEntries.Num(), + *Surface.StageLabel, + *Surface.RecommendedReviewGradeLabel, + *SelectedEntry->RecordedAtUtc); + Surface.DetailLine = FString::Printf( + TEXT("State: %s | template: %s | mode: %s | selection: %s | focus %d | launched %d | success %.2f | attempts %d | mistakes %d | packet structure: %s | packet lane: %s | packet stance: %s | pending: %s | repeat burden: %s | assistance: %s"), + *Surface.DiagnosticStateLabel, + *Surface.TemplateKindLabel, + *Surface.SuggestedModeLabel, + *Surface.SuggestedSelectionLabel, + SelectedEntry->FocusCaseCount, + SelectedEntry->LaunchedCaseCount, + SelectedEntry->SuccessRate, + SelectedEntry->CompletedAttemptCount, + SelectedEntry->TotalMistakes, + *Surface.PacketStructureLabel, + *Surface.PacketLaneLabel, + *Surface.PacketStanceLabel, + SelectedEntry->bBoundaryPending ? TEXT("yes") : TEXT("no"), + SelectedEntry->bBoundaryRepeatBurden ? TEXT("yes") : TEXT("no"), + SelectedEntry->bBoundaryAssistance ? TEXT("yes") : TEXT("no")); + return Surface; +} + +FHyperTwistTrainingCoachDashboardHandoffHistoryInspectSurface +UHyperTwistCoachDashboardWidget::GetSelectedHandoffHistoryInspectSurface() const +{ + FHyperTwistTrainingCoachDashboardHandoffHistoryInspectSurface Surface; + Surface.Headline = TEXT("Handoff history"); + Surface.SelectedEntryIndex = SelectedHandoffHistoryIndex; + Surface.HistoryEntryCount = HandoffHistoryEntries.Num(); + + const FHyperTwistCoachDashboardHandoffHistoryEntry* SelectedEntry = + SelectedHandoffHistoryIndex >= 0 + && SelectedHandoffHistoryIndex < HandoffHistoryEntries.Num() + ? &HandoffHistoryEntries[SelectedHandoffHistoryIndex] + : nullptr; + Surface.bHasSelectedEntry = + SelectedEntry != nullptr && SelectedEntry->IsStructurallyValid(); + if (!Surface.bHasSelectedEntry) + { + Surface.StatusLine = + TEXT("Handoff history: no retained handoff-pattern shifts recorded yet."); + Surface.DetailLine = + TEXT("Handoff history detail: retained recommendation shifts and accepted queued/follow-up/recommended handoff patterns will accumulate here over time."); + return Surface; + } + + Surface.RecordedAtUtc = SelectedEntry->RecordedAtUtc; + Surface.RecommendedHandoffKindLabel = + SelectedEntry->RecommendedHandoffKindLabel.IsEmpty() + ? TEXT("none") + : SelectedEntry->RecommendedHandoffKindLabel; + Surface.RecommendationStatusLine = SelectedEntry->RecommendationStatusLine; + Surface.RecommendationDetailLine = + SelectedEntry->RecommendationDetailLine.IsEmpty() + ? SelectedEntry->RecommendationStatusLine + : SelectedEntry->RecommendationDetailLine; + Surface.QueueSourceLabel = + SelectedEntry->QueueSourceLabel.IsEmpty() + ? TEXT("n/a") + : SelectedEntry->QueueSourceLabel; + Surface.PreferredGuidanceLane = SelectedEntry->PreferredGuidanceLane; + Surface.PreferredLaneLine = + HyperTwistCoachDashboardWidgetInternal::DescribeGuidanceLane( + SelectedEntry->PreferredGuidanceLane); + Surface.PreferredGuidanceSourceLabel = SelectedEntry->PreferredGuidanceSourceLabel; + Surface.PreferredGuidanceSourceDescription = + SelectedEntry->PreferredGuidanceSourceLabel.IsEmpty() + ? TEXT("n/a") + : HyperTwistCoachDashboardWidgetInternal::DescribeCoachMemorySourceLabel( + SelectedEntry->PreferredGuidanceSourceLabel); + Surface.PreferredRecoveryAction = SelectedEntry->PreferredRecoveryAction; + Surface.PreferredRecoveryActionLabel = + SelectedEntry->PreferredRecoveryAction + == EHyperTwistTrainingQueueRecoveryAction::None + ? TEXT("none") + : HyperTwistCoachDashboardWidgetInternal::EnumDisplayName( + SelectedEntry->PreferredRecoveryAction); + Surface.PreferredRecoveryActionSourceLabel = + SelectedEntry->PreferredRecoveryActionSourceLabel; + Surface.PreferredRecoveryActionSourceDescription = + SelectedEntry->PreferredRecoveryActionSourceLabel.IsEmpty() + ? TEXT("n/a") + : HyperTwistCoachDashboardWidgetInternal::DescribeCoachMemorySourceLabel( + SelectedEntry->PreferredRecoveryActionSourceLabel); + Surface.RetainedPostureLine = + HyperTwistCoachDashboardWidgetInternal::DescribeRetainedMethodDrillRecoveryPosture( + SelectedEntry->bUsedStrongRetainedMethodDrillRecoveryPosture, + SelectedEntry->bUsedWeakRetainedMethodDrillRecoveryPosture); + Surface.ReliablePlanLine = [&]() -> FString + { + if (SelectedEntry->bUsedReliableAlignedTrustedTightStructurePlanOutcomeHistory) + { + return TEXT("aligned trusted tight launched-plan continuation"); + } + if (SelectedEntry->bUsedReliableAlignedTrustedBroadStructurePlanOutcomeHistory) + { + return TEXT("aligned trusted broad launched-plan redirect"); + } + if (SelectedEntry->bUsedReliableAlignedTrustedTightStructurePlanHistory) + { + return TEXT("aligned trusted tight continuation"); + } + if (SelectedEntry->bUsedReliableAlignedTrustedBroadStructurePlanHistory) + { + return TEXT("aligned trusted broad redirect"); + } + if (SelectedEntry->bUsedReliableTrustedTightStructurePlanHistory) + { + return TEXT("trusted tight continuation"); + } + if (SelectedEntry->bUsedReliableTrustedBroadStructurePlanHistory) + { + return TEXT("trusted broad redirect"); + } + return TEXT("none"); + }(); + Surface.AcceptedQueuedHandoffCount = SelectedEntry->AcceptedQueuedHandoffCount; + Surface.AcceptedFollowUpHandoffCount = SelectedEntry->AcceptedFollowUpHandoffCount; + Surface.AcceptedRecommendedHandoffCount = + SelectedEntry->AcceptedRecommendedHandoffCount; + Surface.AcceptedDeferredOverflowQueuedHandoffCount = + SelectedEntry->AcceptedDeferredOverflowQueuedHandoffCount; + Surface.AcceptedDeferredOverflowFollowUpHandoffCount = + SelectedEntry->AcceptedDeferredOverflowFollowUpHandoffCount; + Surface.AcceptedDeferredOverflowRecommendedHandoffCount = + SelectedEntry->AcceptedDeferredOverflowRecommendedHandoffCount; + Surface.AcceptedMethodDrillQueuedHandoffCount = + SelectedEntry->AcceptedMethodDrillQueuedHandoffCount; + Surface.AcceptedMethodDrillFollowUpHandoffCount = + SelectedEntry->AcceptedMethodDrillFollowUpHandoffCount; + Surface.AcceptedMethodDrillRecommendedHandoffCount = + SelectedEntry->AcceptedMethodDrillRecommendedHandoffCount; + Surface.AcceptedAlignedTightFollowUpOutcomeHandoffCount = + SelectedEntry->AcceptedAlignedTightFollowUpOutcomeHandoffCount; + Surface.AcceptedAlignedBroadRecommendedOutcomeHandoffCount = + SelectedEntry->AcceptedAlignedBroadRecommendedOutcomeHandoffCount; + Surface.AcceptedAlignedTightFollowUpPacketHandoffCount = + SelectedEntry->AcceptedAlignedTightFollowUpPacketHandoffCount; + Surface.AcceptedAlignedBroadRecommendedPacketHandoffCount = + SelectedEntry->AcceptedAlignedBroadRecommendedPacketHandoffCount; + Surface.ReliableAcceptedAlignedTightFollowUpPacketOutcomeHandoffCount = + SelectedEntry->ReliableAcceptedAlignedTightFollowUpPacketOutcomeHandoffCount; + Surface.ReliableAcceptedAlignedBroadRecommendedPacketOutcomeHandoffCount = + SelectedEntry->ReliableAcceptedAlignedBroadRecommendedPacketOutcomeHandoffCount; + Surface.ReliableAlignedTrustedTightPlanOutcomeHistoryCount = + SelectedEntry->ReliableAlignedTrustedTightPlanOutcomeHistoryCount; + Surface.ReliableAlignedTrustedBroadPlanOutcomeHistoryCount = + SelectedEntry->ReliableAlignedTrustedBroadPlanOutcomeHistoryCount; + Surface.ReliableAlignedTrustedTightPlanOutcomeAverageScore = + SelectedEntry->ReliableAlignedTrustedTightPlanOutcomeAverageScore; + Surface.ReliableAlignedTrustedBroadPlanOutcomeAverageScore = + SelectedEntry->ReliableAlignedTrustedBroadPlanOutcomeAverageScore; + Surface.ClosureContinuationBias = SelectedEntry->ClosureContinuationBias; + Surface.ClosureSuppressionBias = SelectedEntry->ClosureSuppressionBias; + Surface.bQueueReady = SelectedEntry->bQueueReady; + Surface.bFollowUpReady = SelectedEntry->bFollowUpReady; + Surface.bRecommendedReady = SelectedEntry->bRecommendedReady; + Surface.bUsedDeferredFirstSuppressionSignal = + SelectedEntry->bUsedDeferredFirstSuppressionSignal; + Surface.bUsedMethodDrillWeighting = SelectedEntry->bUsedMethodDrillWeighting; + Surface.bUsedStrongRetainedMethodDrillRecoveryPosture = + SelectedEntry->bUsedStrongRetainedMethodDrillRecoveryPosture; + Surface.bUsedWeakRetainedMethodDrillRecoveryPosture = + SelectedEntry->bUsedWeakRetainedMethodDrillRecoveryPosture; + Surface.bUsedReliableTrustedTightStructurePlanHistory = + SelectedEntry->bUsedReliableTrustedTightStructurePlanHistory; + Surface.bUsedReliableTrustedBroadStructurePlanHistory = + SelectedEntry->bUsedReliableTrustedBroadStructurePlanHistory; + Surface.bUsedReliableAlignedTrustedTightStructurePlanHistory = + SelectedEntry->bUsedReliableAlignedTrustedTightStructurePlanHistory; + Surface.bUsedReliableAlignedTrustedBroadStructurePlanHistory = + SelectedEntry->bUsedReliableAlignedTrustedBroadStructurePlanHistory; + Surface.bUsedReliableAlignedTrustedTightStructurePlanOutcomeHistory = + SelectedEntry->bUsedReliableAlignedTrustedTightStructurePlanOutcomeHistory; + Surface.bUsedReliableAlignedTrustedBroadStructurePlanOutcomeHistory = + SelectedEntry->bUsedReliableAlignedTrustedBroadStructurePlanOutcomeHistory; + Surface.StatusLine = FString::Printf( + TEXT("Handoff history: %d entries | selected %d/%d | Recommendation: %s | Stance: %s | Reliable plan: %s | Recorded: %s"), + HandoffHistoryEntries.Num(), + SelectedHandoffHistoryIndex + 1, + HandoffHistoryEntries.Num(), + *Surface.RecommendedHandoffKindLabel, + *Surface.RetainedPostureLine, + *Surface.ReliablePlanLine, + *SelectedEntry->RecordedAtUtc); + Surface.DetailLine = FString::Printf( + TEXT("Accepted queued/follow-up/recommended: %d/%d/%d | aligned guidance accepted follow-up/recommended: %d/%d | aligned packet accepted follow-up/recommended: %d/%d | reliable accepted aligned packet handoff follow-up/recommended: %d/%d | deferred-overflow queued/follow-up/recommended: %d/%d/%d | drill-driven queued/follow-up/recommended: %d/%d/%d | aligned reliable handoff outcomes tight/broad %d/%d avg %.1f/%.1f | deferred-first suppression recommendation used: %s | drill weighting used: %s | reliable trusted plan: %s | retained posture: %s | queue source: %s | preferred lane: %s | memory source: %s | recovery action: %s | recovery source: %s | closure continuation bias %d | closure suppression bias %d | readiness queue/follow-up/recommended: %s/%s/%s || %s"), + SelectedEntry->AcceptedQueuedHandoffCount, + SelectedEntry->AcceptedFollowUpHandoffCount, + SelectedEntry->AcceptedRecommendedHandoffCount, + SelectedEntry->AcceptedAlignedTightFollowUpOutcomeHandoffCount, + SelectedEntry->AcceptedAlignedBroadRecommendedOutcomeHandoffCount, + SelectedEntry->AcceptedAlignedTightFollowUpPacketHandoffCount, + SelectedEntry->AcceptedAlignedBroadRecommendedPacketHandoffCount, + SelectedEntry->ReliableAcceptedAlignedTightFollowUpPacketOutcomeHandoffCount, + SelectedEntry->ReliableAcceptedAlignedBroadRecommendedPacketOutcomeHandoffCount, + SelectedEntry->AcceptedDeferredOverflowQueuedHandoffCount, + SelectedEntry->AcceptedDeferredOverflowFollowUpHandoffCount, + SelectedEntry->AcceptedDeferredOverflowRecommendedHandoffCount, + SelectedEntry->AcceptedMethodDrillQueuedHandoffCount, + SelectedEntry->AcceptedMethodDrillFollowUpHandoffCount, + SelectedEntry->AcceptedMethodDrillRecommendedHandoffCount, + SelectedEntry->ReliableAlignedTrustedTightPlanOutcomeHistoryCount, + SelectedEntry->ReliableAlignedTrustedBroadPlanOutcomeHistoryCount, + SelectedEntry->ReliableAlignedTrustedTightPlanOutcomeAverageScore, + SelectedEntry->ReliableAlignedTrustedBroadPlanOutcomeAverageScore, + SelectedEntry->bUsedDeferredFirstSuppressionSignal ? TEXT("yes") : TEXT("no"), + SelectedEntry->bUsedMethodDrillWeighting ? TEXT("yes") : TEXT("no"), + *Surface.ReliablePlanLine, + *Surface.RetainedPostureLine, + *Surface.QueueSourceLabel, + *Surface.PreferredLaneLine, + *Surface.PreferredGuidanceSourceDescription, + *Surface.PreferredRecoveryActionLabel, + *Surface.PreferredRecoveryActionSourceDescription, + SelectedEntry->ClosureContinuationBias, + SelectedEntry->ClosureSuppressionBias, + SelectedEntry->bQueueReady ? TEXT("yes") : TEXT("no"), + SelectedEntry->bFollowUpReady ? TEXT("yes") : TEXT("no"), + SelectedEntry->bRecommendedReady ? TEXT("yes") : TEXT("no"), + *Surface.RecommendationDetailLine); + 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 604928b..f4e835f 100644 --- a/UnrealHyperTwist/Source/UnrealHyperTwist/Public/HyperTwistTraining/HyperTwistCoachDashboardWidget.h +++ b/UnrealHyperTwist/Source/UnrealHyperTwist/Public/HyperTwistTraining/HyperTwistCoachDashboardWidget.h @@ -747,6 +747,14 @@ public: FHyperTwistTrainingCoachDashboardMethodDrillRecoveryMemoryHistoryInspectSurface GetSelectedMethodDrillRecoveryMemoryHistoryInspectSurface() const; + UFUNCTION(BlueprintPure, Category = "HyperTwist|Training|Coach|Dashboard") + FHyperTwistTrainingCoachDashboardMethodDrillFollowUpHistoryInspectSurface + GetSelectedMethodDrillFollowUpHistoryInspectSurface() const; + + UFUNCTION(BlueprintPure, Category = "HyperTwist|Training|Coach|Dashboard") + FHyperTwistTrainingCoachDashboardHandoffHistoryInspectSurface + GetSelectedHandoffHistoryInspectSurface() 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 70db915..53f2059 100644 --- a/UnrealHyperTwist/Source/UnrealHyperTwist/Public/HyperTwistTraining/HyperTwistTrainingTypes.h +++ b/UnrealHyperTwist/Source/UnrealHyperTwist/Public/HyperTwistTraining/HyperTwistTrainingTypes.h @@ -9037,6 +9037,384 @@ struct FHyperTwistTrainingCoachDashboardMethodDrillRecoveryMemoryHistoryInspectS } }; +USTRUCT(BlueprintType) +struct FHyperTwistTrainingCoachDashboardMethodDrillFollowUpHistoryInspectSurface +{ + 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 RecordedAtUtc; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist") + FString SourceRunId; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist") + FString SourceDrillId; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist") + FString SourceSessionId; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist") + FString StageLabel; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist") + FString DiagnosticStateLabel; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist") + FString RecommendedReviewGradeLabel; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist") + FString TemplateKindLabel; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist") + FString SuggestedModeLabel; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist") + FString SuggestedSelectionLabel; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist") + FString OutcomePreferenceLine; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist") + FString PacketStructureLabel; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist") + FString PacketLaneLabel; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist") + FString PacketStanceLabel; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist") + int32 SelectedEntryIndex = INDEX_NONE; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist") + int32 HistoryEntryCount = 0; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist") + int32 MatchingHistoryCount = 0; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist") + int32 UpstreamPacketStructureHistoryCount = 0; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist") + int32 UpstreamNarrowPacketStructureHistoryCount = 0; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist") + int32 UpstreamBroadPacketStructureHistoryCount = 0; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist") + int32 StrongOutcomeCount = 0; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist") + int32 WeakOutcomeCount = 0; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist") + int32 ContinueNarrowBias = 0; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist") + int32 RedirectCoachBias = 0; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist") + int32 StrongPacketContinuationCount = 0; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist") + int32 WeakPacketRedirectCount = 0; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist") + int32 QueueEntryFirstStructureCount = 0; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist") + int32 FollowUpPacketFirstStructureCount = 0; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist") + int32 RecommendedBriefFirstStructureCount = 0; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist") + int32 RecommendedRedirectStructureCount = 0; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist") + int32 FocusCaseCount = 0; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist") + int32 LaunchedCaseCount = 0; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist") + int32 CompletedAttemptCount = 0; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist") + int32 TotalMistakes = 0; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist") + float SuccessRate = 0.0f; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist") + float AverageSuccessRate = 0.0f; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist") + float AverageMistakes = 0.0f; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist") + float UpstreamNarrowPacketStructureAverageOutcomeScore = 0.0f; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist") + float UpstreamBroadPacketStructureAverageOutcomeScore = 0.0f; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist") + EHyperTwistTrainingMethodDrillDiagnosticState DiagnosticState = + EHyperTwistTrainingMethodDrillDiagnosticState::Unknown; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist") + EHyperTwistTrainingReviewGrade RecommendedReviewGrade = + EHyperTwistTrainingReviewGrade::Good; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist") + EHyperTwistTrainingSessionTemplateKind TemplateKind = + EHyperTwistTrainingSessionTemplateKind::ReviewPlan; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist") + EHyperTwistTrainingDeliveryMode SuggestedMode = + EHyperTwistTrainingDeliveryMode::Timer; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist") + EHyperTwistTrainingSelectionPolicy SuggestedSelectionPolicy = + EHyperTwistTrainingSelectionPolicy::Weighted; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist") + bool bHasSelectedEntry = false; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist") + bool bHasHistoryWeighting = false; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist") + bool bBoundaryPending = false; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist") + bool bBoundaryRepeatBurden = false; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist") + bool bBoundaryAssistance = false; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist") + bool bPacketProvenStrongContinuation = false; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist") + bool bPacketProvenWeakRedirect = false; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist") + bool bPreferDrillFollowUp = false; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist") + bool bPreferCoachHandoff = false; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist") + bool bHasUpstreamStructureSignal = false; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist") + bool bUsedUpstreamNarrowStructureSignal = false; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist") + bool bUsedUpstreamBroadStructureSignal = false; + + bool IsStructurallyValid() const + { + return !StatusLine.IsEmpty() + || !DetailLine.IsEmpty() + || bHasSelectedEntry + || bHasHistoryWeighting + || HistoryEntryCount > 0; + } +}; + +USTRUCT(BlueprintType) +struct FHyperTwistTrainingCoachDashboardHandoffHistoryInspectSurface +{ + 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 RecordedAtUtc; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist") + FString RecommendedHandoffKindLabel; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist") + FString RecommendationStatusLine; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist") + FString RecommendationDetailLine; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist") + FString QueueSourceLabel; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist") + FString PreferredLaneLine; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist") + FString PreferredGuidanceSourceLabel; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist") + FString PreferredGuidanceSourceDescription; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist") + FString PreferredRecoveryActionLabel; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist") + FString PreferredRecoveryActionSourceLabel; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist") + FString PreferredRecoveryActionSourceDescription; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist") + FString RetainedPostureLine; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist") + FString ReliablePlanLine; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist") + int32 SelectedEntryIndex = INDEX_NONE; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist") + int32 HistoryEntryCount = 0; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist") + int32 AcceptedQueuedHandoffCount = 0; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist") + int32 AcceptedFollowUpHandoffCount = 0; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist") + int32 AcceptedRecommendedHandoffCount = 0; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist") + int32 AcceptedDeferredOverflowQueuedHandoffCount = 0; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist") + int32 AcceptedDeferredOverflowFollowUpHandoffCount = 0; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist") + int32 AcceptedDeferredOverflowRecommendedHandoffCount = 0; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist") + int32 AcceptedMethodDrillQueuedHandoffCount = 0; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist") + int32 AcceptedMethodDrillFollowUpHandoffCount = 0; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist") + int32 AcceptedMethodDrillRecommendedHandoffCount = 0; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist") + int32 AcceptedAlignedTightFollowUpOutcomeHandoffCount = 0; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist") + int32 AcceptedAlignedBroadRecommendedOutcomeHandoffCount = 0; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist") + int32 AcceptedAlignedTightFollowUpPacketHandoffCount = 0; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist") + int32 AcceptedAlignedBroadRecommendedPacketHandoffCount = 0; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist") + int32 ReliableAcceptedAlignedTightFollowUpPacketOutcomeHandoffCount = 0; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist") + int32 ReliableAcceptedAlignedBroadRecommendedPacketOutcomeHandoffCount = 0; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist") + int32 ReliableAlignedTrustedTightPlanOutcomeHistoryCount = 0; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist") + int32 ReliableAlignedTrustedBroadPlanOutcomeHistoryCount = 0; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist") + int32 ClosureContinuationBias = 0; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist") + int32 ClosureSuppressionBias = 0; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist") + float ReliableAlignedTrustedTightPlanOutcomeAverageScore = 0.0f; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist") + float ReliableAlignedTrustedBroadPlanOutcomeAverageScore = 0.0f; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist") + EHyperTwistTrainingCoachGuidanceLane PreferredGuidanceLane = + EHyperTwistTrainingCoachGuidanceLane::None; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist") + EHyperTwistTrainingQueueRecoveryAction PreferredRecoveryAction = + EHyperTwistTrainingQueueRecoveryAction::None; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist") + bool bHasSelectedEntry = false; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist") + bool bQueueReady = false; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist") + bool bFollowUpReady = false; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist") + bool bRecommendedReady = false; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist") + bool bUsedDeferredFirstSuppressionSignal = false; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist") + bool bUsedMethodDrillWeighting = false; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist") + bool bUsedStrongRetainedMethodDrillRecoveryPosture = false; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist") + bool bUsedWeakRetainedMethodDrillRecoveryPosture = false; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist") + bool bUsedReliableTrustedTightStructurePlanHistory = false; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist") + bool bUsedReliableTrustedBroadStructurePlanHistory = false; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist") + bool bUsedReliableAlignedTrustedTightStructurePlanHistory = false; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist") + bool bUsedReliableAlignedTrustedBroadStructurePlanHistory = false; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist") + bool bUsedReliableAlignedTrustedTightStructurePlanOutcomeHistory = false; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist") + bool bUsedReliableAlignedTrustedBroadStructurePlanOutcomeHistory = false; + + bool IsStructurallyValid() const + { + return !StatusLine.IsEmpty() + || !DetailLine.IsEmpty() + || bHasSelectedEntry + || HistoryEntryCount > 0; + } +}; + USTRUCT(BlueprintType) struct FHyperTwistTrainingCoachGeneratedModeLaunchExecutionContextSurface { diff --git a/docs/HYPERTWIST_ROADMAP_OVERHAUL_EXPANSION_GUIDE.md b/docs/HYPERTWIST_ROADMAP_OVERHAUL_EXPANSION_GUIDE.md index fbad88e..8576bd0 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 stays on that same deliberate `UHyperTwistCoachDashboardWidget` retained-history inspect lane and adds selected method-drill recovery outcome history and selected method-drill recovery memory history inspect surfaces over already-retained dashboard state, so gameplay/Blueprint callers can inspect retained drill-recovery outcome shifts and upstream recovery-memory posture without scraping dashboard text blocks or reopening recovery-memory comparison derivation - - the current next bounded packet should stay on that same dashboard retained-history inspect lane only while a real gameplay or Blueprint caller still needs one more thin inspect contract over already-retained dashboard history state; the next clean move inside that lane is the method-drill follow-up history and handoff history inspect pair rather than widening back into backend continuity or runtime-library drift + - the latest landed bounded `Phase 4` packet stays on that same deliberate `UHyperTwistCoachDashboardWidget` retained-history inspect lane and adds selected method-drill follow-up history and selected handoff history inspect surfaces over already-retained dashboard state, so gameplay/Blueprint callers can inspect retained drill follow-up recap posture and retained handoff-pattern shifts without scraping dashboard text blocks or reopening follow-up weighting or handoff-memory derivation + - the current next bounded packet should stay on that same dashboard retained-history inspect lane only while a real gameplay or Blueprint caller still needs one more thin inspect contract over already-retained dashboard history state; the next clean move inside that lane is the guidance decision history and template launch history inspect pair rather than widening back into backend continuity or runtime-library drift - 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_METHOD_DRILL_FOLLOW_UP_HANDOFF_HISTORY_INSPECT_SURFACE_PACKET_2026-05-09.md b/docs/arch/HYPERTWIST_PHASE4_DASHBOARD_METHOD_DRILL_FOLLOW_UP_HANDOFF_HISTORY_INSPECT_SURFACE_PACKET_2026-05-09.md new file mode 100644 index 0000000..a101a7a --- /dev/null +++ b/docs/arch/HYPERTWIST_PHASE4_DASHBOARD_METHOD_DRILL_FOLLOW_UP_HANDOFF_HISTORY_INSPECT_SURFACE_PACKET_2026-05-09.md @@ -0,0 +1,50 @@ +# HyperTwist Phase 4 dashboard method-drill follow-up and handoff history inspect surface packet + +- bounded Phase `4` dashboard-consumer slice +- date: `2026-05-09` + +## Intent + +Stay on the deliberate `UHyperTwistCoachDashboardWidget` retained-history inspect lane and expose the next two retained dashboard history families directly to gameplay and Blueprint callers. + +## Why this packet exists + +The dashboard already retained: + +- selected method-drill follow-up history entries and their current drill-vs-handoff weighting posture +- selected handoff history entries and their retained recommendation-shift memory + +But that state still only surfaced through dashboard text blocks and selection actions. Callers still had to scrape widget presentation or reopen follow-up weighting and handoff-memory derivation to inspect retained orchestration posture directly. + +## What changed + +- added `FHyperTwistTrainingCoachDashboardMethodDrillFollowUpHistoryInspectSurface` +- added `FHyperTwistTrainingCoachDashboardHandoffHistoryInspectSurface` +- added `GetSelectedMethodDrillFollowUpHistoryInspectSurface()` +- added `GetSelectedHandoffHistoryInspectSurface()` +- 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 selected retained method-drill follow-up history entry with drill source ids, stage, diagnostic/review/template posture, launch shape, packet posture, boundary state, and retained follow-up weighting summary +- the selected retained handoff history entry with recommendation label, reliable-plan posture, retained drill-recovery stance, queue/guidance/recovery source attribution, readiness posture, and retained accepted-handoff counts + +without scraping dashboard text blocks or reopening follow-up weighting or handoff-memory derivation. + +## Validation + +- full `Development Editor | Win64` MSBuild on `UnrealHyperTwist.sln` + - passed with `0 Warning(s), 0 Error(s)` + +## Next clean slice + +Stay on this dashboard retained-history inspect lane only while a real gameplay or Blueprint caller still needs one more thin inspect contract over already-retained dashboard history state. The next clean move is the guidance decision history and template launch history inspect pair.