Expose dashboard handoff history status and detail surfaces

This commit is contained in:
axiomlogicnexus 2026-05-10 19:29:39 +02:00
parent 9fdd090d28
commit 3adfb010f5
5 changed files with 285 additions and 2 deletions

View file

@ -9034,6 +9034,96 @@ UHyperTwistCoachDashboardWidget::GetSelectedHandoffHistoryInspectSurface() const
return Surface;
}
FHyperTwistTrainingCoachDashboardHandoffHistoryStatusInspectSurface
UHyperTwistCoachDashboardWidget::GetDisplayedHandoffHistoryStatusInspectSurface() const
{
FHyperTwistTrainingCoachDashboardHandoffHistoryStatusInspectSurface Surface;
Surface.Headline = TEXT("Handoff history status");
const FHyperTwistTrainingCoachDashboardHandoffHistoryInspectSurface HistorySurface =
GetSelectedHandoffHistoryInspectSurface();
const FHyperTwistTrainingCoachDashboardHandoffHistoryNavigationInspectSurface NavigationSurface =
GetDisplayedHandoffHistoryNavigationInspectSurface();
Surface.StatusLine = !DisplayedHandoffHistoryStatusLine.IsEmpty()
? DisplayedHandoffHistoryStatusLine
: HistorySurface.StatusLine;
Surface.SelectedEntryOrdinal = NavigationSurface.SelectedEntryOrdinal.IsEmpty()
? TEXT("none")
: NavigationSurface.SelectedEntryOrdinal;
Surface.RecordedAtUtc =
HistorySurface.RecordedAtUtc.IsEmpty() ? TEXT("n/a") : HistorySurface.RecordedAtUtc;
Surface.RecommendedHandoffKindLabel = HistorySurface.RecommendedHandoffKindLabel.IsEmpty()
? TEXT("none")
: HistorySurface.RecommendedHandoffKindLabel;
Surface.RetainedPostureLine = HistorySurface.RetainedPostureLine.IsEmpty()
? TEXT("n/a")
: HistorySurface.RetainedPostureLine;
Surface.ReliablePlanLine = HistorySurface.ReliablePlanLine.IsEmpty()
? TEXT("none")
: HistorySurface.ReliablePlanLine;
Surface.SelectedEntryIndex = HistorySurface.SelectedEntryIndex;
Surface.HistoryEntryCount = HistorySurface.HistoryEntryCount;
Surface.bHasSelectedEntry = HistorySurface.bHasSelectedEntry;
Surface.bSelectedEntryIsLatest = NavigationSurface.bSelectedEntryIsLatest;
return Surface;
}
FHyperTwistTrainingCoachDashboardHandoffHistoryDetailInspectSurface
UHyperTwistCoachDashboardWidget::GetDisplayedHandoffHistoryDetailInspectSurface() const
{
FHyperTwistTrainingCoachDashboardHandoffHistoryDetailInspectSurface Surface;
Surface.Headline = TEXT("Handoff history detail");
const FHyperTwistTrainingCoachDashboardHandoffHistoryInspectSurface HistorySurface =
GetSelectedHandoffHistoryInspectSurface();
Surface.DetailLine = !DisplayedHandoffHistoryDetailLine.IsEmpty()
? DisplayedHandoffHistoryDetailLine
: HistorySurface.DetailLine;
Surface.RecommendationDetailLine = HistorySurface.RecommendationDetailLine.IsEmpty()
? TEXT("n/a")
: HistorySurface.RecommendationDetailLine;
Surface.QueueSourceLabel =
HistorySurface.QueueSourceLabel.IsEmpty() ? TEXT("n/a") : HistorySurface.QueueSourceLabel;
Surface.PreferredLaneLine =
HistorySurface.PreferredLaneLine.IsEmpty() ? TEXT("none") : HistorySurface.PreferredLaneLine;
Surface.PreferredGuidanceSourceDescription =
HistorySurface.PreferredGuidanceSourceDescription.IsEmpty()
? TEXT("n/a")
: HistorySurface.PreferredGuidanceSourceDescription;
Surface.PreferredRecoveryActionLabel =
HistorySurface.PreferredRecoveryActionLabel.IsEmpty()
? TEXT("n/a")
: HistorySurface.PreferredRecoveryActionLabel;
Surface.PreferredRecoveryActionSourceDescription =
HistorySurface.PreferredRecoveryActionSourceDescription.IsEmpty()
? TEXT("n/a")
: HistorySurface.PreferredRecoveryActionSourceDescription;
Surface.ReliablePlanLine = HistorySurface.ReliablePlanLine.IsEmpty()
? TEXT("none")
: HistorySurface.ReliablePlanLine;
Surface.RetainedPostureLine = HistorySurface.RetainedPostureLine.IsEmpty()
? TEXT("n/a")
: HistorySurface.RetainedPostureLine;
Surface.SelectedEntryIndex = HistorySurface.SelectedEntryIndex;
Surface.HistoryEntryCount = HistorySurface.HistoryEntryCount;
Surface.AcceptedQueuedHandoffCount = HistorySurface.AcceptedQueuedHandoffCount;
Surface.AcceptedFollowUpHandoffCount = HistorySurface.AcceptedFollowUpHandoffCount;
Surface.AcceptedRecommendedHandoffCount =
HistorySurface.AcceptedRecommendedHandoffCount;
Surface.ClosureContinuationBias = HistorySurface.ClosureContinuationBias;
Surface.ClosureSuppressionBias = HistorySurface.ClosureSuppressionBias;
Surface.bHasSelectedEntry = HistorySurface.bHasSelectedEntry;
Surface.bQueueReady = HistorySurface.bQueueReady;
Surface.bFollowUpReady = HistorySurface.bFollowUpReady;
Surface.bRecommendedReady = HistorySurface.bRecommendedReady;
Surface.bUsedDeferredFirstSuppressionSignal =
HistorySurface.bUsedDeferredFirstSuppressionSignal;
Surface.bUsedMethodDrillWeighting = HistorySurface.bUsedMethodDrillWeighting;
return Surface;
}
FHyperTwistTrainingCoachDashboardHandoffHistoryNavigationInspectSurface
UHyperTwistCoachDashboardWidget::GetDisplayedHandoffHistoryNavigationInspectSurface() const
{
@ -26519,10 +26609,12 @@ void UHyperTwistCoachDashboardWidget::UpdateDashboardPresentation()
{
HandoffHistoryHeaderTextBlock->SetText(FText::FromString(TEXT("[Handoff History]")));
}
DisplayedHandoffHistoryStatusLine = HandoffHistoryStatusLine;
if (HandoffHistoryStatusTextBlock != nullptr)
{
HandoffHistoryStatusTextBlock->SetText(FText::FromString(HandoffHistoryStatusLine));
}
DisplayedHandoffHistoryDetailLine = HandoffHistoryDetailLine;
if (HandoffHistoryDetailTextBlock != nullptr)
{
HandoffHistoryDetailTextBlock->SetText(FText::FromString(HandoffHistoryDetailLine));

View file

@ -791,6 +791,14 @@ public:
FHyperTwistTrainingCoachDashboardHandoffHistoryInspectSurface
GetSelectedHandoffHistoryInspectSurface() const;
UFUNCTION(BlueprintPure, Category = "HyperTwist|Training|Coach|Dashboard")
FHyperTwistTrainingCoachDashboardHandoffHistoryStatusInspectSurface
GetDisplayedHandoffHistoryStatusInspectSurface() const;
UFUNCTION(BlueprintPure, Category = "HyperTwist|Training|Coach|Dashboard")
FHyperTwistTrainingCoachDashboardHandoffHistoryDetailInspectSurface
GetDisplayedHandoffHistoryDetailInspectSurface() const;
UFUNCTION(BlueprintPure, Category = "HyperTwist|Training|Coach|Dashboard")
FHyperTwistTrainingCoachDashboardHandoffHistoryNavigationInspectSurface
GetDisplayedHandoffHistoryNavigationInspectSurface() const;
@ -2128,6 +2136,8 @@ private:
FString DisplayedSchedulePolicyLine;
FString DisplayedClosureRecoveryStatusLine;
FString DisplayedClosureRecoveryDetailLine;
FString DisplayedHandoffHistoryStatusLine;
FString DisplayedHandoffHistoryDetailLine;
FString DisplayedPreviousQueueNavigationLabel;
FString DisplayedStartSelectedQueueActionLabel;
FString DisplayedNextQueueNavigationLabel;

View file

@ -10073,6 +10073,134 @@ struct FHyperTwistTrainingCoachDashboardMethodDrillFollowUpHistoryInspectSurface
}
};
USTRUCT(BlueprintType)
struct FHyperTwistTrainingCoachDashboardHandoffHistoryStatusInspectSurface
{
GENERATED_BODY()
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
FString Headline;
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
FString StatusLine;
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 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")
bool bHasSelectedEntry = false;
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
bool bSelectedEntryIsLatest = false;
bool IsStructurallyValid() const
{
return !StatusLine.IsEmpty()
|| bHasSelectedEntry
|| HistoryEntryCount > 0;
}
};
USTRUCT(BlueprintType)
struct FHyperTwistTrainingCoachDashboardHandoffHistoryDetailInspectSurface
{
GENERATED_BODY()
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
FString Headline;
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
FString DetailLine;
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 ReliablePlanLine;
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
FString RetainedPostureLine;
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 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 !DetailLine.IsEmpty()
|| bHasSelectedEntry
|| HistoryEntryCount > 0;
}
};
USTRUCT(BlueprintType)
struct FHyperTwistTrainingCoachDashboardHandoffHistoryNavigationInspectSurface
{

View file

@ -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 adjacent in that same live dashboard consumer lane and adds the dedicated template-launch history status/detail inspect pair over the exact displayed retained-history lines already shown by the widget, so gameplay/Blueprint callers can inspect the current retained template-launch history text band directly without scraping text blocks or routing only through the broader selected-history and navigation surfaces
- the retained template-launch history band is now functionally complete enough to stop widening it by drift; the next best clean move is to stay adjacent in the same retained-history dashboard neighborhood and expose the displayed handoff history status/detail pair over the current handoff-history text band
- the latest landed bounded `Phase 4` packet stays adjacent in that same retained-history dashboard lane and adds the dedicated handoff history status/detail inspect pair over the exact displayed retained-history lines already shown by the widget, so gameplay/Blueprint callers can inspect the current retained handoff-history text band directly without scraping text blocks or routing only through the broader selected-history and navigation surfaces
- the retained handoff-history band is now functionally complete enough to stop widening it by drift; the next best clean move is to stay in that same retained-history dashboard neighborhood and expose the displayed guidance-decision history status/detail pair over the current guidance-decision-history text band
- 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

View file

@ -0,0 +1,53 @@
# HyperTwist Phase 4 dashboard handoff history status detail inspect surface packet
- bounded Phase `4` dashboard-consumer slice
- date: `2026-05-10`
## Intent
Stay adjacent in the retained-history dashboard lane and expose the dedicated handoff-history text band directly to gameplay and Blueprint callers.
## Why this packet exists
`UHyperTwistCoachDashboardWidget` already displayed:
- the current `Handoff history` status line
- the current `Handoff history` detail line
But those two lines only surfaced through `HandoffHistoryStatusTextBlock` and `HandoffHistoryDetailTextBlock`. Callers could inspect the selected retained handoff entry and the prev/next navigation posture separately, but there was still no dedicated inspect surface for the exact retained-history text band the dashboard was already presenting.
## What changed
- added `FHyperTwistTrainingCoachDashboardHandoffHistoryStatusInspectSurface`
- added `FHyperTwistTrainingCoachDashboardHandoffHistoryDetailInspectSurface`
- added `GetDisplayedHandoffHistoryStatusInspectSurface()`
- added `GetDisplayedHandoffHistoryDetailInspectSurface()`
- retained the exact displayed handoff-history status/detail lines inside the widget so the new surfaces report the same live strings the dashboard is already presenting
- composed both surfaces over the already-landed selected-handoff-history and handoff-history-navigation surfaces so the packet stayed bounded and reused the same retained-history derivation
## 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 exact displayed handoff-history status line
- the exact displayed handoff-history detail line
- selected retained entry ordinal, recommendation kind, retained posture, and reliable-plan context
- queue source, preferred lane/source, preferred recovery action/source, readiness posture, and closure-bias context
without scraping widget text blocks or stitching together the selected-history and navigation wrappers manually.
## Validation
- full `Development Editor | Win64` MSBuild on `UnrealHyperTwist.sln`
- passed with `0 Warning(s), 0 Error(s)`
## Next clean slice
Treat the retained handoff-history band as functionally complete enough and stay in the same retained-history dashboard neighborhood to expose the displayed guidance-decision history status/detail pair over the current guidance-decision-history text band.