diff --git a/UnrealHyperTwist/Source/UnrealHyperTwist/Private/HyperTwistTraining/HyperTwistCoachDashboardWidget.cpp b/UnrealHyperTwist/Source/UnrealHyperTwist/Private/HyperTwistTraining/HyperTwistCoachDashboardWidget.cpp index 6466222..b43aa8a 100644 --- a/UnrealHyperTwist/Source/UnrealHyperTwist/Private/HyperTwistTraining/HyperTwistCoachDashboardWidget.cpp +++ b/UnrealHyperTwist/Source/UnrealHyperTwist/Private/HyperTwistTraining/HyperTwistCoachDashboardWidget.cpp @@ -10067,6 +10067,114 @@ UHyperTwistCoachDashboardWidget::GetSelectedGuidanceDecisionHistoryInspectSurfac return Surface; } +FHyperTwistTrainingCoachDashboardHandoffHistoryBandInspectSurface +UHyperTwistCoachDashboardWidget::GetDisplayedHandoffHistoryBandInspectSurface() const +{ + FHyperTwistTrainingCoachDashboardHandoffHistoryBandInspectSurface Surface; + Surface.Headline = TEXT("Handoff-history band"); + + const FHyperTwistTrainingCoachDashboardHandoffHistoryStatusInspectSurface StatusSurface = + GetDisplayedHandoffHistoryStatusInspectSurface(); + const FHyperTwistTrainingCoachDashboardHandoffHistoryDetailInspectSurface DetailSurface = + GetDisplayedHandoffHistoryDetailInspectSurface(); + const FHyperTwistTrainingCoachDashboardHandoffHistoryNavigationInspectSurface NavigationSurface = + GetDisplayedHandoffHistoryNavigationInspectSurface(); + + Surface.HandoffHistoryStatusLine = StatusSurface.StatusLine.IsEmpty() + ? TEXT("Handoff history status: unavailable.") + : StatusSurface.StatusLine; + Surface.HandoffHistoryDetailLine = DetailSurface.DetailLine.IsEmpty() + ? TEXT("Handoff history detail: unavailable.") + : DetailSurface.DetailLine; + Surface.HandoffHistoryNavigationStatusLine = NavigationSurface.StatusLine.IsEmpty() + ? TEXT("Handoff history navigation: unavailable.") + : NavigationSurface.StatusLine; + Surface.HandoffHistoryNavigationDetailLine = NavigationSurface.DetailLine.IsEmpty() + ? TEXT("Handoff history navigation detail: unavailable.") + : NavigationSurface.DetailLine; + Surface.SelectedEntryOrdinal = NavigationSurface.SelectedEntryOrdinal.IsEmpty() + ? TEXT("none") + : NavigationSurface.SelectedEntryOrdinal; + Surface.RecordedAtUtc = NavigationSurface.RecordedAtUtc.IsEmpty() ? TEXT("n/a") : NavigationSurface.RecordedAtUtc; + Surface.RecommendedHandoffKindLabel = !NavigationSurface.RecommendedHandoffKindLabel.IsEmpty() + ? NavigationSurface.RecommendedHandoffKindLabel + : (StatusSurface.RecommendedHandoffKindLabel.IsEmpty() + ? TEXT("none") + : StatusSurface.RecommendedHandoffKindLabel); + Surface.RecommendationDetailLine = !NavigationSurface.RecommendationDetailLine.IsEmpty() + ? NavigationSurface.RecommendationDetailLine + : (DetailSurface.RecommendationDetailLine.IsEmpty() + ? TEXT("n/a") + : DetailSurface.RecommendationDetailLine); + Surface.QueueSourceLabel = !NavigationSurface.QueueSourceLabel.IsEmpty() + ? NavigationSurface.QueueSourceLabel + : (DetailSurface.QueueSourceLabel.IsEmpty() ? TEXT("n/a") : DetailSurface.QueueSourceLabel); + Surface.PreferredLaneLine = !NavigationSurface.PreferredLaneLine.IsEmpty() + ? NavigationSurface.PreferredLaneLine + : (DetailSurface.PreferredLaneLine.IsEmpty() ? TEXT("none") : DetailSurface.PreferredLaneLine); + Surface.PreferredGuidanceSourceDescription = DetailSurface.PreferredGuidanceSourceDescription.IsEmpty() + ? TEXT("n/a") + : DetailSurface.PreferredGuidanceSourceDescription; + Surface.PreferredRecoveryActionLabel = !NavigationSurface.PreferredRecoveryActionLabel.IsEmpty() + ? NavigationSurface.PreferredRecoveryActionLabel + : (DetailSurface.PreferredRecoveryActionLabel.IsEmpty() + ? TEXT("n/a") + : DetailSurface.PreferredRecoveryActionLabel); + Surface.PreferredRecoveryActionSourceDescription = + DetailSurface.PreferredRecoveryActionSourceDescription.IsEmpty() + ? TEXT("n/a") + : DetailSurface.PreferredRecoveryActionSourceDescription; + Surface.RetainedPostureLine = !NavigationSurface.RetainedPostureLine.IsEmpty() + ? NavigationSurface.RetainedPostureLine + : (DetailSurface.RetainedPostureLine.IsEmpty() + ? TEXT("n/a") + : DetailSurface.RetainedPostureLine); + Surface.ReliablePlanLine = !NavigationSurface.ReliablePlanLine.IsEmpty() + ? NavigationSurface.ReliablePlanLine + : (DetailSurface.ReliablePlanLine.IsEmpty() + ? TEXT("none") + : DetailSurface.ReliablePlanLine); + Surface.PreviousLabel = NavigationSurface.PreviousLabel.IsEmpty() ? TEXT("Prev Handoff") : NavigationSurface.PreviousLabel; + Surface.NextLabel = NavigationSurface.NextLabel.IsEmpty() ? TEXT("Next Handoff") : NavigationSurface.NextLabel; + Surface.SelectedEntryIndex = NavigationSurface.SelectedEntryIndex; + Surface.HistoryEntryCount = NavigationSurface.HistoryEntryCount; + Surface.AcceptedQueuedHandoffCount = DetailSurface.AcceptedQueuedHandoffCount; + Surface.AcceptedFollowUpHandoffCount = DetailSurface.AcceptedFollowUpHandoffCount; + Surface.AcceptedRecommendedHandoffCount = DetailSurface.AcceptedRecommendedHandoffCount; + Surface.ClosureContinuationBias = DetailSurface.ClosureContinuationBias; + Surface.ClosureSuppressionBias = DetailSurface.ClosureSuppressionBias; + Surface.bHasSelectedEntry = StatusSurface.bHasSelectedEntry || DetailSurface.bHasSelectedEntry || NavigationSurface.bHasSelectedEntry; + Surface.bSelectedEntryIsLatest = StatusSurface.bSelectedEntryIsLatest || NavigationSurface.bSelectedEntryIsLatest; + Surface.bPreviousEnabled = NavigationSurface.bPreviousEnabled; + Surface.bNextEnabled = NavigationSurface.bNextEnabled; + Surface.bQueueReady = DetailSurface.bQueueReady || NavigationSurface.bQueueReady; + Surface.bFollowUpReady = DetailSurface.bFollowUpReady || NavigationSurface.bFollowUpReady; + Surface.bRecommendedReady = DetailSurface.bRecommendedReady || NavigationSurface.bRecommendedReady; + Surface.bUsedDeferredFirstSuppressionSignal = DetailSurface.bUsedDeferredFirstSuppressionSignal; + Surface.bUsedMethodDrillWeighting = DetailSurface.bUsedMethodDrillWeighting; + Surface.StatusLine = FString::Printf( + TEXT("Handoff-history band: selected %s | kind %s | navigation %s/%s | queue ready %s"), + *Surface.SelectedEntryOrdinal, + *Surface.RecommendedHandoffKindLabel, + Surface.bPreviousEnabled ? TEXT("enabled") : TEXT("disabled"), + Surface.bNextEnabled ? TEXT("enabled") : TEXT("disabled"), + Surface.bQueueReady ? TEXT("yes") : TEXT("no")); + Surface.DetailLine = FString::Printf( + TEXT("%s | %s | %s | %s | queue source %s | preferred lane %s | recovery %s | retained posture %s | reliable plan %s | recorded %s | latest %s"), + *Surface.HandoffHistoryStatusLine, + *Surface.HandoffHistoryDetailLine, + *Surface.HandoffHistoryNavigationStatusLine, + *Surface.HandoffHistoryNavigationDetailLine, + *Surface.QueueSourceLabel, + *Surface.PreferredLaneLine, + *Surface.PreferredRecoveryActionLabel, + *Surface.RetainedPostureLine, + *Surface.ReliablePlanLine, + *Surface.RecordedAtUtc, + Surface.bSelectedEntryIsLatest ? TEXT("yes") : TEXT("no")); + return Surface; +} + FHyperTwistTrainingCoachDashboardGuidanceDecisionHistoryStatusInspectSurface UHyperTwistCoachDashboardWidget::GetDisplayedGuidanceDecisionHistoryStatusInspectSurface() const { diff --git a/UnrealHyperTwist/Source/UnrealHyperTwist/Public/HyperTwistTraining/HyperTwistCoachDashboardWidget.h b/UnrealHyperTwist/Source/UnrealHyperTwist/Public/HyperTwistTraining/HyperTwistCoachDashboardWidget.h index 97180b7..fbd1dff 100644 --- a/UnrealHyperTwist/Source/UnrealHyperTwist/Public/HyperTwistTraining/HyperTwistCoachDashboardWidget.h +++ b/UnrealHyperTwist/Source/UnrealHyperTwist/Public/HyperTwistTraining/HyperTwistCoachDashboardWidget.h @@ -831,6 +831,10 @@ public: FHyperTwistTrainingCoachDashboardHandoffHistoryNavigationInspectSurface GetDisplayedHandoffHistoryNavigationInspectSurface() const; + UFUNCTION(BlueprintPure, Category = "HyperTwist|Training|Coach|Dashboard") + FHyperTwistTrainingCoachDashboardHandoffHistoryBandInspectSurface + GetDisplayedHandoffHistoryBandInspectSurface() const; + UFUNCTION(BlueprintPure, Category = "HyperTwist|Training|Coach|Dashboard") FHyperTwistTrainingCoachDashboardGuidanceDecisionHistoryInspectSurface GetSelectedGuidanceDecisionHistoryInspectSurface() const; diff --git a/UnrealHyperTwist/Source/UnrealHyperTwist/Public/HyperTwistTraining/HyperTwistTrainingTypes.h b/UnrealHyperTwist/Source/UnrealHyperTwist/Public/HyperTwistTraining/HyperTwistTrainingTypes.h index d60ea34..3f082b4 100644 --- a/UnrealHyperTwist/Source/UnrealHyperTwist/Public/HyperTwistTraining/HyperTwistTrainingTypes.h +++ b/UnrealHyperTwist/Source/UnrealHyperTwist/Public/HyperTwistTraining/HyperTwistTrainingTypes.h @@ -11565,6 +11565,129 @@ struct FHyperTwistTrainingCoachDashboardGuidanceDecisionHistoryNavigationInspect } }; +USTRUCT(BlueprintType) +struct FHyperTwistTrainingCoachDashboardHandoffHistoryBandInspectSurface +{ + 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 HandoffHistoryStatusLine; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist") + FString HandoffHistoryDetailLine; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist") + FString HandoffHistoryNavigationStatusLine; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist") + FString HandoffHistoryNavigationDetailLine; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist") + FString SelectedEntryOrdinal; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist") + FString RecordedAtUtc; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist") + FString RecommendedHandoffKindLabel; + + 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 PreferredGuidanceSourceDescription; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist") + FString PreferredRecoveryActionLabel; + + 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") + FString PreviousLabel; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist") + FString NextLabel; + + 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 ClosureContinuationBias = 0; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist") + int32 ClosureSuppressionBias = 0; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist") + bool bHasSelectedEntry = false; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist") + bool bSelectedEntryIsLatest = false; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist") + bool bPreviousEnabled = false; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist") + bool bNextEnabled = 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; + + bool IsStructurallyValid() const + { + return !StatusLine.IsEmpty() + || !DetailLine.IsEmpty() + || bHasSelectedEntry + || bPreviousEnabled + || bNextEnabled; + } +}; + USTRUCT(BlueprintType) struct FHyperTwistTrainingCoachDashboardGuidanceDecisionHistoryInspectSurface { diff --git a/docs/HYPERTWIST_ROADMAP_OVERHAUL_EXPANSION_GUIDE.md b/docs/HYPERTWIST_ROADMAP_OVERHAUL_EXPANSION_GUIDE.md index f88ed67..0375fbd 100644 --- a/docs/HYPERTWIST_ROADMAP_OVERHAUL_EXPANSION_GUIDE.md +++ b/docs/HYPERTWIST_ROADMAP_OVERHAUL_EXPANSION_GUIDE.md @@ -77,7 +77,8 @@ Current correction call from the source-exposed audit and current execution refr - the latest landed bounded `Phase 4` packet deliberately chooses another adjacent live dashboard consumer band and adds a single queue scheduling / recovery seam over the already-landed queue counts / status, schedule horizon, schedule policy / friction, and queue recovery live status/detail surfaces, so gameplay/Blueprint callers can inspect that whole scheduling-and-recovery dashboard cluster without stitching five adjacent getters together - the latest landed bounded `Phase 4` packet deliberately chooses another adjacent live dashboard consumer band and adds a single closure-recovery seam over the already-landed closure-recovery live status/detail and closure-recovery history navigation surfaces, so gameplay/Blueprint callers can inspect that whole closure-recovery dashboard cluster without stitching three adjacent getters together - the latest landed bounded `Phase 4` packet deliberately chooses another adjacent live dashboard consumer band and adds a single queue-suppression seam over the already-landed queue-suppression live summary/detail and queue-suppression history navigation surfaces, so gameplay/Blueprint callers can inspect that whole queue-suppression dashboard cluster without stitching three adjacent getters together - - with the retained-history text-band lane, the template-launch / preview action-control band, the execution-action-control band, the verification / recognition / review-policy status band, the selected-queue band, the queue scheduling / recovery band, the closure-recovery band, and the queue-suppression band now all closed baseline, the next best clean move is to deliberately choose another adjacent live dashboard consumer band rather than reopen already-landed surfaces by drift + - the latest landed bounded `Phase 4` packet deliberately chooses another adjacent live dashboard consumer band and adds a single handoff-history seam over the already-landed handoff-history status/detail and handoff-history navigation surfaces, so gameplay/Blueprint callers can inspect that whole handoff-history dashboard cluster without stitching three adjacent getters together + - with the retained-history text-band lane, the template-launch / preview action-control band, the execution-action-control band, the verification / recognition / review-policy status band, the selected-queue band, the queue scheduling / recovery band, the closure-recovery band, the queue-suppression band, and the handoff-history band now all closed baseline, the next best clean move is to deliberately choose another adjacent live dashboard consumer band rather than reopen already-landed surfaces by 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 ## Donor portfolio phase taxonomy diff --git a/docs/arch/HYPERTWIST_PHASE4_DASHBOARD_HANDOFF_HISTORY_BAND_INSPECT_SURFACE_PACKET_2026-05-11.md b/docs/arch/HYPERTWIST_PHASE4_DASHBOARD_HANDOFF_HISTORY_BAND_INSPECT_SURFACE_PACKET_2026-05-11.md new file mode 100644 index 0000000..235688d --- /dev/null +++ b/docs/arch/HYPERTWIST_PHASE4_DASHBOARD_HANDOFF_HISTORY_BAND_INSPECT_SURFACE_PACKET_2026-05-11.md @@ -0,0 +1,52 @@ +# HyperTwist Phase 4 dashboard handoff-history band inspect surface packet + +- bounded Phase `4` dashboard-consumer slice +- date: `2026-05-11` + +## Intent + +Deliberately choose another adjacent live dashboard consumer band and expose the handoff-history status, handoff-history detail, and handoff-history navigation cluster as one inspectable gameplay and Blueprint seam. + +## Why this packet exists + +`UHyperTwistCoachDashboardWidget` already exposed three adjacent handoff-history surfaces: + +- `GetDisplayedHandoffHistoryStatusInspectSurface()` +- `GetDisplayedHandoffHistoryDetailInspectSurface()` +- `GetDisplayedHandoffHistoryNavigationInspectSurface()` + +But callers that wanted to reason about that whole handoff-history dashboard cluster still had to stitch those adjacent getters together manually. + +## What changed + +- added `FHyperTwistTrainingCoachDashboardHandoffHistoryBandInspectSurface` +- added `GetDisplayedHandoffHistoryBandInspectSurface()` +- composed the new surface entirely over the already-landed handoff-history status, handoff-history detail, and handoff-history navigation surfaces +- kept the packet bounded by avoiding any new backend derivation or new widget-state caching + +## 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 whole adjacent handoff-history dashboard band through one surface +- handoff-history live status/detail plus navigation status/detail lines together +- selected entry ordinal, recorded time, recommended handoff kind, recommendation detail, queue source, preferred lane, recovery/source context, retained posture, and reliable-plan context +- accepted queued/follow-up/recommended counts, closure continuation/suppression bias, readiness posture, and navigation enablement posture + +without stitching three separate adjacent getters together manually. + +## Validation + +- full `Development Editor | Win64` MSBuild on `UnrealHyperTwist.sln` + - passed with `0 Warning(s), 0 Error(s)` + +## Next clean slice + +Treat the retained-history text-band lane, the template-launch / preview action-control band, the execution-action-control band, the verification / recognition / review-policy status band, the selected-queue band, the queue scheduling / recovery band, the closure-recovery band, the queue-suppression band, and the handoff-history band as landed baseline, then deliberately choose another adjacent live dashboard consumer band instead of reopening already-landed surfaces by drift.