Expose dashboard closure recovery band

This commit is contained in:
axiomlogicnexus 2026-05-11 15:27:11 +02:00
parent 1357b91115
commit 5b99bc83b3
5 changed files with 285 additions and 1 deletions

View file

@ -15782,6 +15782,107 @@ UHyperTwistCoachDashboardWidget::GetDisplayedClosureRecoveryDetailInspectSurface
return Surface;
}
FHyperTwistTrainingCoachDashboardClosureRecoveryBandInspectSurface
UHyperTwistCoachDashboardWidget::GetDisplayedClosureRecoveryBandInspectSurface() const
{
FHyperTwistTrainingCoachDashboardClosureRecoveryBandInspectSurface Surface;
Surface.Headline = TEXT("Closure-recovery band");
const FHyperTwistTrainingCoachDashboardClosureRecoveryStatusInspectSurface StatusSurface =
GetDisplayedClosureRecoveryStatusInspectSurface();
const FHyperTwistTrainingCoachDashboardClosureRecoveryDetailInspectSurface DetailSurface =
GetDisplayedClosureRecoveryDetailInspectSurface();
const FHyperTwistTrainingCoachDashboardClosureRecoveryHistoryNavigationInspectSurface NavigationSurface =
GetDisplayedClosureRecoveryHistoryNavigationInspectSurface();
Surface.ClosureRecoveryStatusLine = StatusSurface.StatusLine.IsEmpty()
? TEXT("Closure recovery status: unavailable.")
: StatusSurface.StatusLine;
Surface.ClosureRecoveryDetailLine = DetailSurface.DetailLine.IsEmpty()
? TEXT("Closure recovery detail: unavailable.")
: DetailSurface.DetailLine;
Surface.ClosureRecoveryNavigationStatusLine = NavigationSurface.StatusLine.IsEmpty()
? TEXT("Closure recovery navigation: unavailable.")
: NavigationSurface.StatusLine;
Surface.ClosureRecoveryNavigationDetailLine = NavigationSurface.DetailLine.IsEmpty()
? TEXT("Closure recovery navigation detail: unavailable.")
: NavigationSurface.DetailLine;
Surface.ClosureRecoveryHistoryLabel = StatusSurface.ClosureRecoveryHistoryLabel.IsEmpty()
? TEXT("n/a")
: StatusSurface.ClosureRecoveryHistoryLabel;
Surface.ClosurePolicyLine = !DetailSurface.ClosurePolicyLine.IsEmpty()
? DetailSurface.ClosurePolicyLine
: (StatusSurface.ClosurePolicyLine.IsEmpty() ? TEXT("n/a") : StatusSurface.ClosurePolicyLine);
Surface.GuidanceLaneLabel = !DetailSurface.GuidanceLaneLabel.IsEmpty()
? DetailSurface.GuidanceLaneLabel
: (StatusSurface.GuidanceLaneLabel.IsEmpty() ? TEXT("none") : StatusSurface.GuidanceLaneLabel);
Surface.PreferredGuidanceSourceLabel = DetailSurface.PreferredGuidanceSourceLabel.IsEmpty()
? TEXT("none")
: DetailSurface.PreferredGuidanceSourceLabel;
Surface.PreferredGuidanceSourceDescription = !DetailSurface.PreferredGuidanceSourceDescription.IsEmpty()
? DetailSurface.PreferredGuidanceSourceDescription
: NavigationSurface.PreferredGuidanceSourceDescription;
Surface.ActiveSignalId = !DetailSurface.ActiveSignalId.IsEmpty()
? DetailSurface.ActiveSignalId
: (StatusSurface.ActiveSignalId.IsEmpty() ? TEXT("none") : StatusSurface.ActiveSignalId);
Surface.ActiveSignalHeadline = StatusSurface.ActiveSignalHeadline.IsEmpty()
? TEXT("n/a")
: StatusSurface.ActiveSignalHeadline;
Surface.ActiveSignalPriorityLabel = StatusSurface.ActiveSignalPriorityLabel.IsEmpty()
? TEXT("n/a")
: StatusSurface.ActiveSignalPriorityLabel;
Surface.ActiveSignalDetail = DetailSurface.ActiveSignalDetail.IsEmpty()
? TEXT("")
: DetailSurface.ActiveSignalDetail;
Surface.PreviousLabel = NavigationSurface.PreviousLabel.IsEmpty() ? TEXT("Prev Closure Recovery") : NavigationSurface.PreviousLabel;
Surface.NextLabel = NavigationSurface.NextLabel.IsEmpty() ? TEXT("Next Closure Recovery") : NavigationSurface.NextLabel;
Surface.SelectedEntryOrdinal = NavigationSurface.SelectedEntryOrdinal.IsEmpty()
? TEXT("none")
: NavigationSurface.SelectedEntryOrdinal;
Surface.RecordedAtUtc = NavigationSurface.RecordedAtUtc.IsEmpty() ? TEXT("n/a") : NavigationSurface.RecordedAtUtc;
Surface.SelectedLaneLabel = NavigationSurface.SelectedLaneLabel.IsEmpty() ? TEXT("none") : NavigationSurface.SelectedLaneLabel;
Surface.SelectedEntryIndex = NavigationSurface.SelectedEntryIndex;
Surface.HistoryEntryCount = NavigationSurface.HistoryEntryCount;
Surface.HistoricalFollowUpContinuationCount = StatusSurface.HistoricalFollowUpContinuationCount;
Surface.HistoricalBorderlineFollowUpSuppressionCount =
StatusSurface.HistoricalBorderlineFollowUpSuppressionCount;
Surface.ActiveSignalScore = StatusSurface.ActiveSignalScore;
Surface.PreferredGuidanceLane = StatusSurface.PreferredGuidanceLane;
Surface.bHasClosureRecoveryHistory =
StatusSurface.bHasClosureRecoveryHistory || DetailSurface.bHasClosureRecoveryHistory;
Surface.bHasActiveSignal = StatusSurface.bHasActiveSignal || DetailSurface.bHasActiveSignal;
Surface.bActiveSignalPromoted = StatusSurface.bActiveSignalPromoted;
Surface.bFollowUpContinuationFromRecoveryHistory =
DetailSurface.bFollowUpContinuationFromRecoveryHistory;
Surface.bBorderlineFollowUpSuppressedByRecoveryHistory =
DetailSurface.bBorderlineFollowUpSuppressedByRecoveryHistory;
Surface.bHasSelectedEntry = NavigationSurface.bHasSelectedEntry;
Surface.bSelectedEntryIsLatest = NavigationSurface.bSelectedEntryIsLatest;
Surface.bPreviousEnabled = NavigationSurface.bPreviousEnabled;
Surface.bNextEnabled = NavigationSurface.bNextEnabled;
Surface.StatusLine = FString::Printf(
TEXT("Closure-recovery band: %s | lane %s | selected %s | signal %s | navigation %s/%s"),
*Surface.ClosureRecoveryHistoryLabel,
*Surface.GuidanceLaneLabel,
*Surface.SelectedEntryOrdinal,
*Surface.ActiveSignalId,
Surface.bPreviousEnabled ? TEXT("enabled") : TEXT("disabled"),
Surface.bNextEnabled ? TEXT("enabled") : TEXT("disabled"));
Surface.DetailLine = FString::Printf(
TEXT("%s | %s | %s | %s | policy %s | source %s | signal headline %s | signal priority %s | recorded %s | latest %s"),
*Surface.ClosureRecoveryStatusLine,
*Surface.ClosureRecoveryDetailLine,
*Surface.ClosureRecoveryNavigationStatusLine,
*Surface.ClosureRecoveryNavigationDetailLine,
*Surface.ClosurePolicyLine,
*Surface.PreferredGuidanceSourceDescription,
*Surface.ActiveSignalHeadline,
*Surface.ActiveSignalPriorityLabel,
*Surface.RecordedAtUtc,
Surface.bSelectedEntryIsLatest ? TEXT("yes") : TEXT("no"));
return Surface;
}
FHyperTwistTrainingCoachDashboardLastAttemptReviewSummaryInspectSurface
UHyperTwistCoachDashboardWidget::GetDisplayedLastAttemptReviewSummaryInspectSurface() const
{

View file

@ -1067,6 +1067,10 @@ public:
FHyperTwistTrainingCoachDashboardClosureRecoveryDetailInspectSurface
GetDisplayedClosureRecoveryDetailInspectSurface() const;
UFUNCTION(BlueprintPure, Category = "HyperTwist|Training|Coach|Dashboard")
FHyperTwistTrainingCoachDashboardClosureRecoveryBandInspectSurface
GetDisplayedClosureRecoveryBandInspectSurface() const;
UFUNCTION(BlueprintPure, Category = "HyperTwist|Training|Coach|Dashboard")
FHyperTwistTrainingCoachDashboardLastAttemptReviewSummaryInspectSurface
GetDisplayedLastAttemptReviewSummaryInspectSurface() const;

View file

@ -14808,6 +14808,132 @@ struct FHyperTwistTrainingCoachDashboardClosureRecoveryDetailInspectSurface
}
};
USTRUCT(BlueprintType)
struct FHyperTwistTrainingCoachDashboardClosureRecoveryBandInspectSurface
{
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 ClosureRecoveryStatusLine;
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
FString ClosureRecoveryDetailLine;
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
FString ClosureRecoveryNavigationStatusLine;
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
FString ClosureRecoveryNavigationDetailLine;
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
FString ClosureRecoveryHistoryLabel;
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
FString ClosurePolicyLine;
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
FString GuidanceLaneLabel;
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
FString PreferredGuidanceSourceLabel;
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
FString PreferredGuidanceSourceDescription;
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
FString ActiveSignalId;
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
FString ActiveSignalHeadline;
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
FString ActiveSignalPriorityLabel;
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
FString ActiveSignalDetail;
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
FString PreviousLabel;
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
FString NextLabel;
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
FString SelectedEntryOrdinal;
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
FString RecordedAtUtc;
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
FString SelectedLaneLabel;
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
int32 SelectedEntryIndex = INDEX_NONE;
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
int32 HistoryEntryCount = 0;
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
int32 HistoricalFollowUpContinuationCount = 0;
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
int32 HistoricalBorderlineFollowUpSuppressionCount = 0;
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
float ActiveSignalScore = 0.0f;
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
EHyperTwistTrainingCoachGuidanceLane PreferredGuidanceLane =
EHyperTwistTrainingCoachGuidanceLane::None;
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
bool bHasClosureRecoveryHistory = false;
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
bool bHasActiveSignal = false;
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
bool bActiveSignalPromoted = false;
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
bool bFollowUpContinuationFromRecoveryHistory = false;
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
bool bBorderlineFollowUpSuppressedByRecoveryHistory = false;
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;
bool IsStructurallyValid() const
{
return !StatusLine.IsEmpty()
|| !DetailLine.IsEmpty()
|| bHasClosureRecoveryHistory
|| bHasActiveSignal
|| bHasSelectedEntry
|| bPreviousEnabled
|| bNextEnabled;
}
};
USTRUCT(BlueprintType)
struct FHyperTwistTrainingCoachDashboardLastAttemptReviewSummaryInspectSurface
{

View file

@ -75,7 +75,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 composite verification / recognition / review-policy seam over the already-landed verification action, repository verification status, recognition status, and review-policy status surfaces, so gameplay/Blueprint callers can inspect that whole status cluster without stitching four adjacent getters together
- the latest landed bounded `Phase 4` packet deliberately chooses another adjacent live dashboard consumer band and adds a single composite selected-queue seam over the already-landed selected-queue navigation, start-selected action, selected-queue summary, and selected queue-entry detail surfaces, so gameplay/Blueprint callers can inspect that whole queue-focused dashboard cluster without stitching four adjacent getters together
- 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
- 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, and the queue scheduling / recovery 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 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
- 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, and the closure-recovery 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

View file

@ -0,0 +1,52 @@
# HyperTwist Phase 4 dashboard closure recovery 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 closure-recovery status, closure-recovery detail, and closure-recovery history navigation cluster as one inspectable gameplay and Blueprint seam.
## Why this packet exists
`UHyperTwistCoachDashboardWidget` already exposed three adjacent closure-recovery surfaces:
- `GetDisplayedClosureRecoveryStatusInspectSurface()`
- `GetDisplayedClosureRecoveryDetailInspectSurface()`
- `GetDisplayedClosureRecoveryHistoryNavigationInspectSurface()`
But callers that wanted to reason about that whole closure-recovery dashboard cluster still had to stitch those adjacent getters together manually.
## What changed
- added `FHyperTwistTrainingCoachDashboardClosureRecoveryBandInspectSurface`
- added `GetDisplayedClosureRecoveryBandInspectSurface()`
- composed the new surface entirely over the already-landed closure-recovery live status, closure-recovery detail, and closure-recovery 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 closure-recovery dashboard band through one surface
- closure-recovery live status/detail plus history-navigation status/detail lines together
- closure history label, closure policy, guidance lane, preferred guidance source, active signal context, entry ordinal, recorded time, and selected lane context
- closure-recovery history posture, active-signal posture, follow-up continuation/suppression 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, and the closure-recovery band as landed baseline, then deliberately choose another adjacent live dashboard consumer band instead of reopening already-landed surfaces by drift.