diff --git a/UnrealHyperTwist/Source/UnrealHyperTwist/Private/HyperTwistTraining/HyperTwistCoachDashboardWidget.cpp b/UnrealHyperTwist/Source/UnrealHyperTwist/Private/HyperTwistTraining/HyperTwistCoachDashboardWidget.cpp index 829526f..18a888f 100644 --- a/UnrealHyperTwist/Source/UnrealHyperTwist/Private/HyperTwistTraining/HyperTwistCoachDashboardWidget.cpp +++ b/UnrealHyperTwist/Source/UnrealHyperTwist/Private/HyperTwistTraining/HyperTwistCoachDashboardWidget.cpp @@ -14268,6 +14268,85 @@ UHyperTwistCoachDashboardWidget::GetDisplayedRunActionLabelsInspectSurface() con return Surface; } +FHyperTwistTrainingCoachDashboardHandoffTransitionBandInspectSurface +UHyperTwistCoachDashboardWidget::GetDisplayedHandoffTransitionBandInspectSurface() const +{ + FHyperTwistTrainingCoachDashboardHandoffTransitionBandInspectSurface Surface; + Surface.Headline = TEXT("Handoff transition band"); + + const FHyperTwistTrainingCoachDashboardHandoffRecommendationInspectSurface HandoffRecommendationSurface = + GetDisplayedCoachHandoffRecommendationInspectSurface(); + const FHyperTwistTrainingCoachDashboardHandoffStatusInspectSurface HandoffStatusSurface = + GetDisplayedCoachHandoffStatusInspectSurface(); + const FHyperTwistTrainingCoachDashboardTransitionStatusInspectSurface TransitionSurface = + GetDisplayedTransitionStatusInspectSurface(); + const FHyperTwistTrainingCoachDashboardRunActionLabelsInspectSurface RunActionSurface = + GetDisplayedRunActionLabelsInspectSurface(); + + Surface.HandoffRecommendationStatusLine = HandoffRecommendationSurface.StatusLine.IsEmpty() + ? TEXT("Handoff recommendation: unavailable.") + : HandoffRecommendationSurface.StatusLine; + Surface.HandoffStatusLine = HandoffStatusSurface.StatusLine.IsEmpty() + ? TEXT("Handoff status: unavailable.") + : HandoffStatusSurface.StatusLine; + Surface.TransitionStatusLine = TransitionSurface.StatusLine.IsEmpty() + ? TEXT("Transition status: unavailable.") + : TransitionSurface.StatusLine; + Surface.RunActionLabelsStatusLine = RunActionSurface.StatusLine.IsEmpty() + ? TEXT("Run action labels: unavailable.") + : RunActionSurface.StatusLine; + Surface.RecommendationKindLabel = HandoffRecommendationSurface.RecommendationKindLabel.IsEmpty() + ? TEXT("none") + : HandoffRecommendationSurface.RecommendationKindLabel; + Surface.QueueStatusLabel = HandoffStatusSurface.QueueStatusLabel.IsEmpty() + ? TEXT("queue not ready") + : HandoffStatusSurface.QueueStatusLabel; + Surface.FollowUpStatusLabel = HandoffStatusSurface.FollowUpStatusLabel.IsEmpty() + ? TEXT("follow-up not ready") + : HandoffStatusSurface.FollowUpStatusLabel; + Surface.RecommendedStatusLabel = HandoffStatusSurface.RecommendedStatusLabel.IsEmpty() + ? TEXT("recommended not ready") + : HandoffStatusSurface.RecommendedStatusLabel; + Surface.TransitionLaunchLabel = !TransitionSurface.TransitionLaunchLabel.IsEmpty() + ? TransitionSurface.TransitionLaunchLabel + : (RunActionSurface.TransitionLaunchLabel.IsEmpty() ? TEXT("Launch Coach Run") : RunActionSurface.TransitionLaunchLabel); + Surface.ContinueRunLabel = RunActionSurface.ContinueRunLabel.IsEmpty() ? TEXT("Continue") : RunActionSurface.ContinueRunLabel; + Surface.QueuedRunLabel = RunActionSurface.QueuedRunLabel.IsEmpty() ? TEXT("Start Queue") : RunActionSurface.QueuedRunLabel; + Surface.FollowUpRunLabel = RunActionSurface.FollowUpRunLabel.IsEmpty() ? TEXT("Start Follow-Up") : RunActionSurface.FollowUpRunLabel; + Surface.RecommendedRunLabel = RunActionSurface.RecommendedRunLabel.IsEmpty() ? TEXT("Start Recommended") : RunActionSurface.RecommendedRunLabel; + Surface.ActiveCaseId = TransitionSurface.ActiveCaseId.IsEmpty() ? TEXT("n/a") : TransitionSurface.ActiveCaseId; + Surface.AttemptCount = TransitionSurface.AttemptCount; + Surface.bHasRecommendation = HandoffRecommendationSurface.bHasRecommendation; + Surface.bHasActiveRun = HandoffStatusSurface.bHasActiveRun || TransitionSurface.bHasActiveRun; + Surface.bHasLiveAttemptTimer = HandoffStatusSurface.bHasLiveAttemptTimer || TransitionSurface.bHasLiveAttemptTimer; + Surface.bQueueReady = HandoffStatusSurface.bQueueReady || HandoffRecommendationSurface.bQueueReady; + Surface.bFollowUpReady = HandoffStatusSurface.bFollowUpReady || HandoffRecommendationSurface.bFollowUpReady; + Surface.bRecommendedReady = HandoffStatusSurface.bRecommendedReady || HandoffRecommendationSurface.bRecommendedReady; + Surface.bCanContinueCurrentRun = TransitionSurface.bCanContinueCurrentRun; + Surface.bCanLaunchCoachRun = TransitionSurface.bCanLaunchCoachRun; + Surface.bClosedLoopIdleDashboard = HandoffRecommendationSurface.bClosedLoopIdleDashboard || HandoffStatusSurface.bClosedLoopIdleDashboard || TransitionSurface.bClosedLoopIdleDashboard || RunActionSurface.bClosedLoopIdleDashboard; + Surface.StatusLine = FString::Printf( + TEXT("Handoff-transition band: recommendation %s | continue %s | launch %s | queue/follow-up/recommended %s/%s/%s"), + *Surface.RecommendationKindLabel, + Surface.bCanContinueCurrentRun ? TEXT("enabled") : TEXT("disabled"), + Surface.bCanLaunchCoachRun ? TEXT("enabled") : TEXT("disabled"), + Surface.bQueueReady ? TEXT("ready") : TEXT("not-ready"), + Surface.bFollowUpReady ? TEXT("ready") : TEXT("not-ready"), + Surface.bRecommendedReady ? TEXT("ready") : TEXT("not-ready")); + Surface.DetailLine = FString::Printf( + TEXT("%s | %s | %s | %s | active case %s | attempts %d | live timer %s | active run %s | closed-loop idle %s"), + *Surface.HandoffRecommendationStatusLine, + *Surface.HandoffStatusLine, + *Surface.TransitionStatusLine, + *Surface.RunActionLabelsStatusLine, + *Surface.ActiveCaseId, + Surface.AttemptCount, + Surface.bHasLiveAttemptTimer ? TEXT("yes") : TEXT("no"), + Surface.bHasActiveRun ? TEXT("yes") : TEXT("no"), + Surface.bClosedLoopIdleDashboard ? TEXT("yes") : TEXT("no")); + return Surface; +} + FHyperTwistTrainingCoachDashboardActiveRunStatusInspectSurface UHyperTwistCoachDashboardWidget::GetDisplayedActiveRunStatusInspectSurface() const { diff --git a/UnrealHyperTwist/Source/UnrealHyperTwist/Public/HyperTwistTraining/HyperTwistCoachDashboardWidget.h b/UnrealHyperTwist/Source/UnrealHyperTwist/Public/HyperTwistTraining/HyperTwistCoachDashboardWidget.h index 70a5809..f556f56 100644 --- a/UnrealHyperTwist/Source/UnrealHyperTwist/Public/HyperTwistTraining/HyperTwistCoachDashboardWidget.h +++ b/UnrealHyperTwist/Source/UnrealHyperTwist/Public/HyperTwistTraining/HyperTwistCoachDashboardWidget.h @@ -967,6 +967,10 @@ public: FHyperTwistTrainingCoachDashboardRunActionLabelsInspectSurface GetDisplayedRunActionLabelsInspectSurface() const; + UFUNCTION(BlueprintPure, Category = "HyperTwist|Training|Coach|Dashboard") + FHyperTwistTrainingCoachDashboardHandoffTransitionBandInspectSurface + GetDisplayedHandoffTransitionBandInspectSurface() const; + UFUNCTION(BlueprintPure, Category = "HyperTwist|Training|Coach|Dashboard") FHyperTwistTrainingCoachDashboardActiveRunStatusInspectSurface GetDisplayedActiveRunStatusInspectSurface() const; diff --git a/UnrealHyperTwist/Source/UnrealHyperTwist/Public/HyperTwistTraining/HyperTwistTrainingTypes.h b/UnrealHyperTwist/Source/UnrealHyperTwist/Public/HyperTwistTraining/HyperTwistTrainingTypes.h index 5693645..030a564 100644 --- a/UnrealHyperTwist/Source/UnrealHyperTwist/Public/HyperTwistTraining/HyperTwistTrainingTypes.h +++ b/UnrealHyperTwist/Source/UnrealHyperTwist/Public/HyperTwistTraining/HyperTwistTrainingTypes.h @@ -17528,6 +17528,104 @@ struct FHyperTwistTrainingCoachDashboardRunActionLabelsInspectSurface } }; +USTRUCT(BlueprintType) +struct FHyperTwistTrainingCoachDashboardHandoffTransitionBandInspectSurface +{ + 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 HandoffRecommendationStatusLine; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist") + FString HandoffStatusLine; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist") + FString TransitionStatusLine; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist") + FString RunActionLabelsStatusLine; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist") + FString RecommendationKindLabel; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist") + FString QueueStatusLabel; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist") + FString FollowUpStatusLabel; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist") + FString RecommendedStatusLabel; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist") + FString TransitionLaunchLabel; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist") + FString ContinueRunLabel; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist") + FString QueuedRunLabel; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist") + FString FollowUpRunLabel; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist") + FString RecommendedRunLabel; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist") + FString ActiveCaseId; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist") + int32 AttemptCount = 0; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist") + bool bHasRecommendation = false; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist") + bool bHasActiveRun = false; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist") + bool bHasLiveAttemptTimer = 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 bCanContinueCurrentRun = false; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist") + bool bCanLaunchCoachRun = false; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist") + bool bClosedLoopIdleDashboard = false; + + bool IsStructurallyValid() const + { + return !StatusLine.IsEmpty() + || !DetailLine.IsEmpty() + || bHasRecommendation + || bHasActiveRun + || bHasLiveAttemptTimer + || bCanContinueCurrentRun + || bCanLaunchCoachRun; + } +}; + USTRUCT(BlueprintType) struct FHyperTwistTrainingCoachGeneratedModeLaunchExecutionContextSurface { diff --git a/docs/HYPERTWIST_ROADMAP_OVERHAUL_EXPANSION_GUIDE.md b/docs/HYPERTWIST_ROADMAP_OVERHAUL_EXPANSION_GUIDE.md index e64f272..22b4c69 100644 --- a/docs/HYPERTWIST_ROADMAP_OVERHAUL_EXPANSION_GUIDE.md +++ b/docs/HYPERTWIST_ROADMAP_OVERHAUL_EXPANSION_GUIDE.md @@ -77,8 +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 - - the latest landed bounded `Phase 4` packet deliberately chooses the next adjacent live dashboard consumer band in the run-state / recap neighborhood and adds a single run-state-recap seam over the already-landed active-run status plus run-recap status/detail/action-control surfaces, so gameplay/Blueprint callers can inspect that whole run-state recap dashboard cluster without stitching four 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, the handoff-history band, the guidance-decision-history band, the template-launch-history band, the method-drill recovery-outcome-history band, the method-drill recovery-memory-history band, the method-drill follow-up-history band, the method-drill operational band, the guidance-preview band, the guidance-reasoning band, and the run-state recap 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 the next adjacent live dashboard consumer band in the compact handoff/transition neighborhood and adds a single handoff-transition seam over the already-landed handoff recommendation, handoff status, transition status, and run-action-label surfaces, so gameplay/Blueprint callers can inspect that whole compact live handoff/transition dashboard cluster without stitching four 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, the handoff-history band, the guidance-decision-history band, the template-launch-history band, the method-drill recovery-outcome-history band, the method-drill recovery-memory-history band, the method-drill follow-up-history band, the method-drill operational band, the guidance-preview band, the guidance-reasoning band, the run-state recap band, and the handoff-transition 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_TRANSITION_BAND_INSPECT_SURFACE_PACKET_2026-05-11.md b/docs/arch/HYPERTWIST_PHASE4_DASHBOARD_HANDOFF_TRANSITION_BAND_INSPECT_SURFACE_PACKET_2026-05-11.md new file mode 100644 index 0000000..10bd58d --- /dev/null +++ b/docs/arch/HYPERTWIST_PHASE4_DASHBOARD_HANDOFF_TRANSITION_BAND_INSPECT_SURFACE_PACKET_2026-05-11.md @@ -0,0 +1,52 @@ +# HyperTwist Phase 4 dashboard handoff transition band inspect surface packet + +- bounded Phase `4` dashboard-consumer slice +- date: `2026-05-11` + +## Intent + +Deliberately choose the next adjacent live dashboard consumer band in the compact handoff/transition neighborhood and expose the handoff recommendation, handoff status, transition status, and run-action-label cluster as one inspectable gameplay and Blueprint seam. + +## Why this packet exists + +`UHyperTwistCoachDashboardWidget` already exposed four adjacent compact handoff/transition surfaces: + +- `GetDisplayedCoachHandoffRecommendationInspectSurface()` +- `GetDisplayedCoachHandoffStatusInspectSurface()` +- `GetDisplayedTransitionStatusInspectSurface()` +- `GetDisplayedRunActionLabelsInspectSurface()` + +But callers that wanted to reason about that whole compact live handoff/transition dashboard cluster still had to stitch four adjacent getters together manually. + +## What changed + +- added `FHyperTwistTrainingCoachDashboardHandoffTransitionBandInspectSurface` +- added `GetDisplayedHandoffTransitionBandInspectSurface()` +- composed the new surface entirely over the already-landed handoff recommendation, handoff status, transition status, and run-action-label 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 compact handoff/transition dashboard band through one surface +- handoff recommendation, handoff status, transition status, and run-action-label lines together +- handoff recommendation kind, queue/follow-up/recommended readiness posture, transition launch posture, continue/run-action labels, active-case context, and transition readiness posture + +without stitching four 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, the handoff-history band, the guidance-decision-history band, the template-launch-history band, the method-drill recovery-outcome-history band, the method-drill recovery-memory-history band, the method-drill follow-up-history band, the method-drill operational band, the guidance-preview band, the guidance-reasoning band, the run-state recap band, and the compact handoff-transition band as landed baseline, then deliberately choose another adjacent live dashboard consumer band instead of reopening already-landed surfaces by drift.