From e09f3c66ee44b4e4ac24f91afe62a56bff750aa1 Mon Sep 17 00:00:00 2001 From: axiomlogicnexus Date: Sat, 9 May 2026 23:42:50 +0200 Subject: [PATCH] Expose dashboard schedule horizon and policy friction surfaces --- .../HyperTwistCoachDashboardWidget.cpp | 161 +++++++++++++++- .../HyperTwistCoachDashboardWidget.h | 10 + .../HyperTwistTrainingTypes.h | 178 ++++++++++++++++++ ...RTWIST_ROADMAP_OVERHAUL_EXPANSION_GUIDE.md | 18 +- ...CTION_INSPECT_SURFACE_PACKET_2026-05-09.md | 52 +++++ 5 files changed, 413 insertions(+), 6 deletions(-) create mode 100644 docs/arch/HYPERTWIST_PHASE4_DASHBOARD_LIVE_SCHEDULE_HORIZON_POLICY_FRICTION_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 39bdaeb..c437ab9 100644 --- a/UnrealHyperTwist/Source/UnrealHyperTwist/Private/HyperTwistTraining/HyperTwistCoachDashboardWidget.cpp +++ b/UnrealHyperTwist/Source/UnrealHyperTwist/Private/HyperTwistTraining/HyperTwistCoachDashboardWidget.cpp @@ -11729,6 +11729,157 @@ UHyperTwistCoachDashboardWidget::GetDisplayedSelectedQueueEntryDetailInspectSurf return Surface; } +FHyperTwistTrainingCoachDashboardScheduleHorizonStatusInspectSurface +UHyperTwistCoachDashboardWidget::GetDisplayedScheduleHorizonStatusInspectSurface() const +{ + FHyperTwistTrainingCoachDashboardScheduleHorizonStatusInspectSurface Surface; + Surface.Headline = TEXT("Schedule horizon status"); + + Surface.QueueId = CachedCoachScheduleHorizonSummary.QueueId.IsEmpty() + ? TEXT("n/a") + : CachedCoachScheduleHorizonSummary.QueueId; + Surface.FocusDeckId = CachedCoachScheduleHorizonSummary.FocusDeckId.IsEmpty() + ? TEXT("n/a") + : CachedCoachScheduleHorizonSummary.FocusDeckId; + Surface.FocusMethodSegmentId = + CachedCoachScheduleHorizonSummary.FocusMethodSegmentId.IsEmpty() + ? TEXT("n/a") + : CachedCoachScheduleHorizonSummary.FocusMethodSegmentId; + Surface.ActiveEntryId = CachedCoachScheduleHorizonSummary.ActiveEntryId.IsEmpty() + ? TEXT("none") + : CachedCoachScheduleHorizonSummary.ActiveEntryId; + Surface.NextReadyEntryId = CachedCoachScheduleHorizonSummary.NextReadyEntryId.IsEmpty() + ? TEXT("none") + : CachedCoachScheduleHorizonSummary.NextReadyEntryId; + Surface.NextDeferredEntryId = + CachedCoachScheduleHorizonSummary.NextDeferredEntryId.IsEmpty() + ? TEXT("none") + : CachedCoachScheduleHorizonSummary.NextDeferredEntryId; + Surface.NextArchiveEntryId = CachedCoachScheduleHorizonSummary.NextArchiveEntryId.IsEmpty() + ? TEXT("none") + : CachedCoachScheduleHorizonSummary.NextArchiveEntryId; + Surface.NextFollowUpEntryId = + CachedCoachScheduleHorizonSummary.NextFollowUpEntryId.IsEmpty() + ? TEXT("none") + : CachedCoachScheduleHorizonSummary.NextFollowUpEntryId; + Surface.CurrentHorizonLabel = + CachedCoachScheduleHorizonSummary.CurrentHorizonLabel.IsEmpty() + ? TEXT("n/a") + : CachedCoachScheduleHorizonSummary.CurrentHorizonLabel; + Surface.ImmediateEntryCount = CachedCoachScheduleHorizonSummary.ImmediateEntryCount; + Surface.DeferredEntryCount = CachedCoachScheduleHorizonSummary.DeferredEntryCount; + Surface.ArchiveAwareEntryCount = CachedCoachScheduleHorizonSummary.ArchiveAwareEntryCount; + Surface.FollowUpEntryCount = CachedCoachScheduleHorizonSummary.FollowUpEntryCount; + Surface.PinnedEntryCount = CachedCoachScheduleHorizonSummary.PinnedEntryCount; + Surface.bHasImmediateWindow = CachedCoachScheduleHorizonSummary.bHasImmediateWindow; + Surface.bHasDeferredWindow = CachedCoachScheduleHorizonSummary.bHasDeferredWindow; + Surface.bNeedsArchiveWindow = CachedCoachScheduleHorizonSummary.bNeedsArchiveWindow; + Surface.bHasBlockedFollowUp = CachedCoachScheduleHorizonSummary.bHasBlockedFollowUp; + Surface.bHasInProgressEntry = CachedCoachScheduleHorizonSummary.bHasInProgressEntry; + Surface.StatusLine = !DisplayedScheduleStatusLine.IsEmpty() + ? DisplayedScheduleStatusLine + : FString::Printf( + TEXT("Horizon: %s | Immediate %d | Deferred %d | Archive-aware %d | Follow-up %d | Pinned %d | Immediate window: %s | Deferred window: %s | Blocked follow-up: %s"), + *Surface.CurrentHorizonLabel, + Surface.ImmediateEntryCount, + Surface.DeferredEntryCount, + Surface.ArchiveAwareEntryCount, + Surface.FollowUpEntryCount, + Surface.PinnedEntryCount, + Surface.bHasImmediateWindow ? TEXT("yes") : TEXT("no"), + Surface.bHasDeferredWindow ? TEXT("yes") : TEXT("no"), + Surface.bHasBlockedFollowUp ? TEXT("yes") : TEXT("no")); + return Surface; +} + +FHyperTwistTrainingCoachDashboardSchedulePolicyFrictionInspectSurface +UHyperTwistCoachDashboardWidget::GetDisplayedSchedulePolicyFrictionInspectSurface() const +{ + FHyperTwistTrainingCoachDashboardSchedulePolicyFrictionInspectSurface Surface; + Surface.Headline = TEXT("Schedule policy / friction"); + + Surface.QueueId = CachedCoachSchedulePolicySummary.QueueId.IsEmpty() + ? TEXT("n/a") + : CachedCoachSchedulePolicySummary.QueueId; + Surface.FocusDeckId = CachedCoachSchedulePolicySummary.FocusDeckId.IsEmpty() + ? TEXT("n/a") + : CachedCoachSchedulePolicySummary.FocusDeckId; + Surface.FocusMethodSegmentId = + CachedCoachSchedulePolicySummary.FocusMethodSegmentId.IsEmpty() + ? TEXT("n/a") + : CachedCoachSchedulePolicySummary.FocusMethodSegmentId; + Surface.NextImmediateEntryId = + CachedCoachSchedulePolicySummary.NextImmediateEntryId.IsEmpty() + ? TEXT("none") + : CachedCoachSchedulePolicySummary.NextImmediateEntryId; + Surface.NextPendingEntryId = CachedCoachSchedulePolicySummary.NextPendingEntryId.IsEmpty() + ? TEXT("none") + : CachedCoachSchedulePolicySummary.NextPendingEntryId; + Surface.NextDeferredEntryId = + CachedCoachSchedulePolicySummary.NextDeferredEntryId.IsEmpty() + ? TEXT("none") + : CachedCoachSchedulePolicySummary.NextDeferredEntryId; + Surface.NextManualRescheduleEntryId = + CachedCoachSchedulePolicySummary.NextManualRescheduleEntryId.IsEmpty() + ? TEXT("none") + : CachedCoachSchedulePolicySummary.NextManualRescheduleEntryId; + Surface.EarliestDeferredUntilUtc = + CachedCoachSchedulePolicySummary.EarliestDeferredUntilUtc.IsEmpty() + ? TEXT("n/a") + : CachedCoachSchedulePolicySummary.EarliestDeferredUntilUtc; + Surface.DominantDeferralReasonLabel = + CachedCoachSchedulePolicySummary.DominantDeferralReasonLabel.IsEmpty() + ? TEXT("n/a") + : CachedCoachSchedulePolicySummary.DominantDeferralReasonLabel; + Surface.ClosurePolicyLine = CachedCoachSchedulePolicySummary.ClosurePolicyLine.IsEmpty() + ? TEXT("n/a") + : CachedCoachSchedulePolicySummary.ClosurePolicyLine; + Surface.HistoricalFollowUpContinuationCount = + CachedCoachSchedulePolicySummary.HistoricalFollowUpContinuationCount; + Surface.HistoricalBorderlineFollowUpSuppressionCount = + CachedCoachSchedulePolicySummary.HistoricalBorderlineFollowUpSuppressionCount; + Surface.ImmediateEntryCount = CachedCoachSchedulePolicySummary.ImmediateEntryCount; + Surface.PendingEntryCount = CachedCoachSchedulePolicySummary.PendingEntryCount; + Surface.DeferredEntryCount = CachedCoachSchedulePolicySummary.DeferredEntryCount; + Surface.ManualRescheduleEntryCount = + CachedCoachSchedulePolicySummary.ManualRescheduleEntryCount; + Surface.ArchiveAwareDeferredEntryCount = + CachedCoachSchedulePolicySummary.ArchiveAwareDeferredEntryCount; + Surface.BlockedFollowUpDeferredEntryCount = + CachedCoachSchedulePolicySummary.BlockedFollowUpDeferredEntryCount; + Surface.ReschedulePressureScore = CachedCoachSchedulePolicySummary.ReschedulePressureScore; + Surface.bAllowsManualReschedule = CachedCoachSchedulePolicySummary.bAllowsManualReschedule; + Surface.bHasExpiredDeferrals = CachedCoachSchedulePolicySummary.bHasExpiredDeferrals; + Surface.bNeedsManualRescheduleReview = + CachedCoachSchedulePolicySummary.bNeedsManualRescheduleReview; + Surface.bHasArchiveAwareDeferrals = + CachedCoachSchedulePolicySummary.bHasArchiveAwareDeferrals; + Surface.bHasBlockedFollowUpDeferrals = + CachedCoachSchedulePolicySummary.bHasBlockedFollowUpDeferrals; + Surface.bFollowUpContinuationFromRecoveryHistory = + CachedCoachSchedulePolicySummary.bFollowUpContinuationFromRecoveryHistory; + Surface.bBorderlineFollowUpSuppressedByRecoveryHistory = + CachedCoachSchedulePolicySummary.bBorderlineFollowUpSuppressedByRecoveryHistory; + Surface.PolicyLine = !DisplayedSchedulePolicyLine.IsEmpty() + ? DisplayedSchedulePolicyLine + : FString::Printf( + TEXT("Policy: immediate %d | pending %d | deferred %d | manual %d | earliest deferred: %s | dominant reason: %s | pressure %.2f | manual allowed: %s | expired deferrals: %s | review needed: %s | archive-aware: %s | blocked follow-up: %s | closure: %s"), + Surface.ImmediateEntryCount, + Surface.PendingEntryCount, + Surface.DeferredEntryCount, + Surface.ManualRescheduleEntryCount, + *Surface.EarliestDeferredUntilUtc, + *Surface.DominantDeferralReasonLabel, + Surface.ReschedulePressureScore, + Surface.bAllowsManualReschedule ? TEXT("yes") : TEXT("no"), + Surface.bHasExpiredDeferrals ? TEXT("yes") : TEXT("no"), + Surface.bNeedsManualRescheduleReview ? TEXT("yes") : TEXT("no"), + Surface.bHasArchiveAwareDeferrals ? TEXT("yes") : TEXT("no"), + Surface.bHasBlockedFollowUpDeferrals ? TEXT("yes") : TEXT("no"), + *Surface.ClosurePolicyLine); + return Surface; +} + FHyperTwistTrainingCoachDashboardLastAttemptReviewSummaryInspectSurface UHyperTwistCoachDashboardWidget::GetDisplayedLastAttemptReviewSummaryInspectSurface() const { @@ -24132,7 +24283,7 @@ void UHyperTwistCoachDashboardWidget::UpdateDashboardPresentation() } if (ScheduleStatusTextBlock != nullptr) { - ScheduleStatusTextBlock->SetText(FText::FromString(FString::Printf( + DisplayedScheduleStatusLine = FString::Printf( TEXT("Horizon: %s | Immediate %d | Deferred %d | Archive-aware %d | Follow-up %d | Pinned %d | Immediate window: %s | Deferred window: %s | Blocked follow-up: %s"), CachedCoachScheduleHorizonSummary.CurrentHorizonLabel.IsEmpty() ? TEXT("n/a") @@ -24145,11 +24296,12 @@ void UHyperTwistCoachDashboardWidget::UpdateDashboardPresentation() CachedCoachScheduleHorizonSummary.bHasImmediateWindow ? TEXT("yes") : TEXT("no"), CachedCoachScheduleHorizonSummary.bHasDeferredWindow ? TEXT("yes") : TEXT("no"), CachedCoachScheduleHorizonSummary.bHasBlockedFollowUp ? TEXT("yes") : TEXT("no") - ))); + ); + ScheduleStatusTextBlock->SetText(FText::FromString(DisplayedScheduleStatusLine)); } if (SchedulePolicyTextBlock != nullptr) { - SchedulePolicyTextBlock->SetText(FText::FromString(FString::Printf( + DisplayedSchedulePolicyLine = FString::Printf( TEXT("Policy: immediate %d | pending %d | deferred %d | manual %d | earliest deferred: %s | dominant reason: %s | pressure %.2f | manual allowed: %s | expired deferrals: %s | review needed: %s | archive-aware: %s | blocked follow-up: %s | closure: %s"), CachedCoachSchedulePolicySummary.ImmediateEntryCount, CachedCoachSchedulePolicySummary.PendingEntryCount, @@ -24170,7 +24322,8 @@ void UHyperTwistCoachDashboardWidget::UpdateDashboardPresentation() CachedCoachSchedulePolicySummary.ClosurePolicyLine.IsEmpty() ? TEXT("n/a") : *CachedCoachSchedulePolicySummary.ClosurePolicyLine - ))); + ); + SchedulePolicyTextBlock->SetText(FText::FromString(DisplayedSchedulePolicyLine)); } const int32 ClosureKeepHistoryCount = CachedCoachSchedulePolicySummary.HistoricalFollowUpContinuationCount; diff --git a/UnrealHyperTwist/Source/UnrealHyperTwist/Public/HyperTwistTraining/HyperTwistCoachDashboardWidget.h b/UnrealHyperTwist/Source/UnrealHyperTwist/Public/HyperTwistTraining/HyperTwistCoachDashboardWidget.h index f358967..e60625b 100644 --- a/UnrealHyperTwist/Source/UnrealHyperTwist/Public/HyperTwistTraining/HyperTwistCoachDashboardWidget.h +++ b/UnrealHyperTwist/Source/UnrealHyperTwist/Public/HyperTwistTraining/HyperTwistCoachDashboardWidget.h @@ -875,6 +875,14 @@ public: FHyperTwistTrainingCoachDashboardSelectedQueueEntryDetailInspectSurface GetDisplayedSelectedQueueEntryDetailInspectSurface() const; + UFUNCTION(BlueprintPure, Category = "HyperTwist|Training|Coach|Dashboard") + FHyperTwistTrainingCoachDashboardScheduleHorizonStatusInspectSurface + GetDisplayedScheduleHorizonStatusInspectSurface() const; + + UFUNCTION(BlueprintPure, Category = "HyperTwist|Training|Coach|Dashboard") + FHyperTwistTrainingCoachDashboardSchedulePolicyFrictionInspectSurface + GetDisplayedSchedulePolicyFrictionInspectSurface() const; + UFUNCTION(BlueprintPure, Category = "HyperTwist|Training|Coach|Dashboard") FHyperTwistTrainingCoachDashboardLastAttemptReviewSummaryInspectSurface GetDisplayedLastAttemptReviewSummaryInspectSurface() const; @@ -1967,6 +1975,8 @@ private: FString DisplayedQueueExecutionLine; FString DisplayedSelectedQueueSummaryLine; FString DisplayedSelectedQueueEntryDetailLine; + FString DisplayedScheduleStatusLine; + FString DisplayedSchedulePolicyLine; FString DisplayedPreviousQueueNavigationLabel; FString DisplayedStartSelectedQueueActionLabel; FString DisplayedNextQueueNavigationLabel; diff --git a/UnrealHyperTwist/Source/UnrealHyperTwist/Public/HyperTwistTraining/HyperTwistTrainingTypes.h b/UnrealHyperTwist/Source/UnrealHyperTwist/Public/HyperTwistTraining/HyperTwistTrainingTypes.h index 0d1f013..71dc4d3 100644 --- a/UnrealHyperTwist/Source/UnrealHyperTwist/Public/HyperTwistTraining/HyperTwistTrainingTypes.h +++ b/UnrealHyperTwist/Source/UnrealHyperTwist/Public/HyperTwistTraining/HyperTwistTrainingTypes.h @@ -11553,6 +11553,184 @@ struct FHyperTwistTrainingCoachDashboardSelectedQueueEntryDetailInspectSurface } }; +USTRUCT(BlueprintType) +struct FHyperTwistTrainingCoachDashboardScheduleHorizonStatusInspectSurface +{ + GENERATED_BODY() + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist") + FString Headline; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist") + FString StatusLine; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist") + FString QueueId; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist") + FString FocusDeckId; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist") + FString FocusMethodSegmentId; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist") + FString ActiveEntryId; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist") + FString NextReadyEntryId; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist") + FString NextDeferredEntryId; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist") + FString NextArchiveEntryId; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist") + FString NextFollowUpEntryId; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist") + FString CurrentHorizonLabel; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist") + int32 ImmediateEntryCount = 0; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist") + int32 DeferredEntryCount = 0; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist") + int32 ArchiveAwareEntryCount = 0; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist") + int32 FollowUpEntryCount = 0; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist") + int32 PinnedEntryCount = 0; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist") + bool bHasImmediateWindow = false; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist") + bool bHasDeferredWindow = false; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist") + bool bNeedsArchiveWindow = false; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist") + bool bHasBlockedFollowUp = false; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist") + bool bHasInProgressEntry = false; + + bool IsStructurallyValid() const + { + return !StatusLine.IsEmpty() + || !CurrentHorizonLabel.IsEmpty() + || ImmediateEntryCount > 0 + || DeferredEntryCount > 0 + || bHasInProgressEntry; + } +}; + +USTRUCT(BlueprintType) +struct FHyperTwistTrainingCoachDashboardSchedulePolicyFrictionInspectSurface +{ + GENERATED_BODY() + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist") + FString Headline; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist") + FString PolicyLine; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist") + FString QueueId; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist") + FString FocusDeckId; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist") + FString FocusMethodSegmentId; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist") + FString NextImmediateEntryId; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist") + FString NextPendingEntryId; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist") + FString NextDeferredEntryId; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist") + FString NextManualRescheduleEntryId; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist") + FString EarliestDeferredUntilUtc; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist") + FString DominantDeferralReasonLabel; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist") + FString ClosurePolicyLine; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist") + int32 HistoricalFollowUpContinuationCount = 0; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist") + int32 HistoricalBorderlineFollowUpSuppressionCount = 0; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist") + int32 ImmediateEntryCount = 0; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist") + int32 PendingEntryCount = 0; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist") + int32 DeferredEntryCount = 0; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist") + int32 ManualRescheduleEntryCount = 0; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist") + int32 ArchiveAwareDeferredEntryCount = 0; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist") + int32 BlockedFollowUpDeferredEntryCount = 0; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist") + float ReschedulePressureScore = 0.0f; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist") + bool bAllowsManualReschedule = false; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist") + bool bHasExpiredDeferrals = false; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist") + bool bNeedsManualRescheduleReview = false; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist") + bool bHasArchiveAwareDeferrals = false; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist") + bool bHasBlockedFollowUpDeferrals = false; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist") + bool bFollowUpContinuationFromRecoveryHistory = false; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist") + bool bBorderlineFollowUpSuppressedByRecoveryHistory = false; + + bool IsStructurallyValid() const + { + return !PolicyLine.IsEmpty() + || ReschedulePressureScore > 0.0f + || DeferredEntryCount > 0 + || ManualRescheduleEntryCount > 0 + || bHasArchiveAwareDeferrals + || bHasBlockedFollowUpDeferrals; + } +}; + USTRUCT(BlueprintType) struct FHyperTwistTrainingCoachDashboardLastAttemptReviewSummaryInspectSurface { diff --git a/docs/HYPERTWIST_ROADMAP_OVERHAUL_EXPANSION_GUIDE.md b/docs/HYPERTWIST_ROADMAP_OVERHAUL_EXPANSION_GUIDE.md index 8e55285..7f93fec 100644 --- a/docs/HYPERTWIST_ROADMAP_OVERHAUL_EXPANSION_GUIDE.md +++ b/docs/HYPERTWIST_ROADMAP_OVERHAUL_EXPANSION_GUIDE.md @@ -69,10 +69,24 @@ 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 live `UHyperTwistCoachDashboardWidget` guidance-consumer lane and adds queue counts/status, selected-queue summary, and selected queue-entry detail inspect surfaces over already-derived live dashboard queue overview and selected-entry presentation state, so gameplay/Blueprint callers can inspect the live queue status line, counts/execution posture, current selected-entry summary, and selected-entry detail without scraping widget text or reopening queue-state derivation - - the next clean move is to stay on that same live dashboard guidance-consumer lane and land the schedule horizon status and schedule policy / friction inspect surface pair rather than drifting back into backend continuity or reopening the already-complete retained-history seam + - the latest landed bounded `Phase 4` packet stays on that same live `UHyperTwistCoachDashboardWidget` guidance-consumer lane and adds schedule horizon status and schedule policy / friction inspect surfaces over already-derived live dashboard schedule presentation state, so gameplay/Blueprint callers can inspect the live horizon posture, queue-window summary, policy/friction line, and reschedule/closure posture without scraping widget text or reopening schedule derivation + - the next clean move is to stay on that same live dashboard guidance-consumer lane and land the closure-recovery live status and closure-recovery detail inspect surface pair rather than drifting back into backend continuity or reopening the already-complete retained-history seam - 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 + +- repo-portfolio intake/classification, mirror custody boundaries, model allowlists, and first-pass donor evaluation belong primarily to Phase `0` and are materially established already +- owned contract extraction from chosen donors belongs primarily to Phase `1` and is already reflected in the first-party notation, replay, training-content, provenance, vision-sidecar, and speech-sidecar contracts +- deep source-level audit of the wider donor corpus is not globally closed; it remains selective ongoing work anchored by the late-Phase-`4` manifest-reconciliation / custody-governance reservation and by later phase-specific donor decisions +- clean-room work belongs first to Phase `0` governance and Phase `1` contract shaping, then executes only for selected restrictive repos when a bounded first-party lane needs it; several restrictive donors already have scrubbed Model A handoff files, but not every restrictive mirror has or needs a full clean-room implementation yet +- implementation of valuable donor ideas is intentionally distributed by domain across later phases rather than treated as one giant repo-import pass: + - Phase `3` / `4`: coaching, runtime, orchestration, recognition continuity, and live consumers + - Phase `5`: speech-sidecar and embodied-coach donors + - Phase `6`: hypercube/simulation donors + - Phase `7`: XR/immersive donors + - Phase `8`: benchmark-oracle, correctness, and release-hardening donors +- do not treat the mirror portfolio as an instruction to deep-audit or reimplement every repo before product work can continue; only the active and justified donor lanes should be pulled forward + ## Current execution-reality references For the current code-reality synthesis and active phase-discipline note, also read: diff --git a/docs/arch/HYPERTWIST_PHASE4_DASHBOARD_LIVE_SCHEDULE_HORIZON_POLICY_FRICTION_INSPECT_SURFACE_PACKET_2026-05-09.md b/docs/arch/HYPERTWIST_PHASE4_DASHBOARD_LIVE_SCHEDULE_HORIZON_POLICY_FRICTION_INSPECT_SURFACE_PACKET_2026-05-09.md new file mode 100644 index 0000000..01d1297 --- /dev/null +++ b/docs/arch/HYPERTWIST_PHASE4_DASHBOARD_LIVE_SCHEDULE_HORIZON_POLICY_FRICTION_INSPECT_SURFACE_PACKET_2026-05-09.md @@ -0,0 +1,52 @@ +# HyperTwist Phase 4 dashboard live schedule horizon status and schedule policy / friction inspect surface packet + +- bounded Phase `4` dashboard-consumer slice +- date: `2026-05-09` + +## Intent + +Stay on the deliberate live `UHyperTwistCoachDashboardWidget` guidance-consumer lane and expose the remaining live schedule horizon and schedule policy / friction presentation state directly to gameplay and Blueprint callers. + +## Why this packet exists + +The dashboard already derived: + +- the live schedule horizon status line +- the live schedule policy / friction line + +But that state still only surfaced through widget text blocks. Callers still had to scrape dashboard text to inspect the current queue-window posture, reschedule pressure, deferral reason, and closure policy presentation. + +## What changed + +- added `FHyperTwistTrainingCoachDashboardScheduleHorizonStatusInspectSurface` +- added `FHyperTwistTrainingCoachDashboardSchedulePolicyFrictionInspectSurface` +- added `GetDisplayedScheduleHorizonStatusInspectSurface()` +- added `GetDisplayedSchedulePolicyFrictionInspectSurface()` +- retained the exact displayed schedule horizon and schedule policy lines inside the widget so the new inspect surfaces report the same live strings the dashboard is already presenting +- refreshed the roadmap docs to record the donor-portfolio phase taxonomy, including where deep donor source audit, selective restrictive clean-room work, and phase-specific donor implementation belong in the live roadmap +- 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 live schedule horizon label, queue-window posture, active/next entry routing, and horizon counts +- the live schedule policy / friction line, reschedule pressure, deferred-window posture, dominant deferral reason, and closure-policy context + +without scraping dashboard text blocks or reopening schedule derivation. + +## Validation + +- full `Development Editor | Win64` MSBuild on `UnrealHyperTwist.sln` + - passed with `0 Warning(s), 0 Error(s)` + +## Next clean slice + +Stay on the same live dashboard guidance-consumer lane and land the closure-recovery live status and closure-recovery detail inspect surface pair.