diff --git a/UnrealHyperTwist/Source/UnrealHyperTwist/Private/HyperTwistTraining/HyperTwistTrainingCoachLibrary.cpp b/UnrealHyperTwist/Source/UnrealHyperTwist/Private/HyperTwistTraining/HyperTwistTrainingCoachLibrary.cpp index a45b668..a170f71 100644 --- a/UnrealHyperTwist/Source/UnrealHyperTwist/Private/HyperTwistTraining/HyperTwistTrainingCoachLibrary.cpp +++ b/UnrealHyperTwist/Source/UnrealHyperTwist/Private/HyperTwistTraining/HyperTwistTrainingCoachLibrary.cpp @@ -11276,6 +11276,245 @@ UHyperTwistTrainingCoachLibrary:: return Surface; } +FHyperTwistTrainingCoachGeneratedModeSelectorOptionOwnedExecutionSplitPhaseCurrentSelectionDroppedRowAuditInspectSurface +UHyperTwistTrainingCoachLibrary:: + DeriveCoachGeneratedModeSelectorOptionOwnedExecutionSplitPhaseCurrentSelectionDroppedRowAuditInspectSurface( + const FHyperTwistTrainingRunState& RunState, + const FString& SelectorId, + const FHyperTwistTrainingCoachGeneratedModeSelectorOptionMenuSurface& OptionMenuSurface, + const FHyperTwistTrainingCoachGeneratedModeSelectorOptionLaunchRequestPreviewSurface& + OptionLaunchRequestPreviewSurface + ) +{ + const FHyperTwistTrainingCoachGeneratedModeSelectorOptionOwnedExecutionSplitPhaseCurrentSelectionCanonicalInspectSurface + CanonicalInspectSurface = + DeriveCoachGeneratedModeSelectorOptionOwnedExecutionSplitPhaseCurrentSelectionCanonicalInspectSurface( + RunState, + SelectorId, + OptionMenuSurface, + OptionLaunchRequestPreviewSurface + ); + + FHyperTwistTrainingCoachGeneratedModeSelectorOptionOwnedExecutionSplitPhaseCurrentSelectionDroppedRowAuditInspectSurface + Surface; + Surface.SelectorId = CanonicalInspectSurface.SelectorId; + Surface.SelectorLabel = CanonicalInspectSurface.SelectorLabel; + Surface.BindingLabel = CanonicalInspectSurface.BindingLabel; + Surface.Headline = + TEXT("Generated Mode Selector Option Owned-Execution Split-Phase Current-Selection Dropped-Row Audit Inspect"); + Surface.bHasSelector = CanonicalInspectSurface.bHasSelector; + Surface.bHasSelection = CanonicalInspectSurface.bHasSelection; + Surface.bSelectionMatchesAvailableOption = + CanonicalInspectSurface.bSelectionMatchesAvailableOption; + Surface.CurrentSelectionSelectionLine = + CanonicalInspectSurface.CurrentSelectionSelectionLine; + Surface.CurrentSelectionOptionId = + CanonicalInspectSurface.CurrentSelectionOptionId; + Surface.CurrentSelectionOptionLabel = + CanonicalInspectSurface.CurrentSelectionOptionLabel; + Surface.CurrentSelectionOptionValue = + CanonicalInspectSurface.CurrentSelectionOptionValue; + Surface.LaunchRequestPreviewKind = + CanonicalInspectSurface.LaunchRequestPreviewKind; + Surface.DuplicatePruningLine = + CanonicalInspectSurface.DuplicatePruningLine; + Surface.InvalidDefinitionLine = + CanonicalInspectSurface.InvalidDefinitionLine; + Surface.PreviewPostureLine = + CanonicalInspectSurface.PreviewPostureLine; + Surface.bStartsOwnedCaseImmediately = + CanonicalInspectSurface.bStartsOwnedCaseImmediately; + Surface.bHasExactCurrentSelectionDroppedRowAudit = + CanonicalInspectSurface.bHasExactCurrentSelectionCanonicalInspect; + Surface.bRetainsActiveDeckSplitPhaseFusion = + CanonicalInspectSurface.bRetainsActiveDeckSplitPhaseFusion; + Surface.bHasDuplicatePrunedRows = + CanonicalInspectSurface.bHasDuplicatePrunedPhases; + Surface.bHasInvalidRawRows = + CanonicalInspectSurface.bHasInvalidRawDefinitions; + Surface.bPreviewBlocked = CanonicalInspectSurface.bPreviewBlocked; + Surface.bCanPreview = CanonicalInspectSurface.bCanPreview; + + if (!SelectorId.IsEmpty()) + { + Surface.Headline = OptionMenuSurface.SelectorLabel.IsEmpty() + ? FString::Printf( + TEXT("Generated Mode Selector Option Owned-Execution Split-Phase Current-Selection Dropped-Row Audit Inspect: %s"), + *SelectorId + ) + : FString::Printf( + TEXT("Generated Mode Selector Option Owned-Execution Split-Phase Current-Selection Dropped-Row Audit Inspect: %s"), + *OptionMenuSurface.SelectorLabel + ); + } + + for (const FHyperTwistTrainingCoachGeneratedModeSelectorOptionOwnedExecutionSplitPhaseRawRowNormalizedPhaseFusionPreviewRowSurface& + FusedRow : CanonicalInspectSurface.FusedRows) + { + if (!FusedRow.bDroppedBecauseDuplicate && !FusedRow.bDroppedBecauseInvalid) + { + continue; + } + + FHyperTwistTrainingCoachGeneratedModeSelectorOptionOwnedExecutionSplitPhaseCurrentSelectionDroppedRowAuditInspectRowSurface + RowSurface; + RowSurface.PhaseId = FusedRow.PhaseId; + RowSurface.SourceLabel = FusedRow.SourceLabel; + RowSurface.RawOrder = FusedRow.RawOrder; + RowSurface.EvaluationOrder = FusedRow.EvaluationOrder; + RowSurface.RawDefinitionLine = FusedRow.RawDefinitionLine; + RowSurface.NormalizationOutcomeLine = FusedRow.NormalizationOutcomeLine; + RowSurface.DuplicatePruningProvenanceLine = + FusedRow.DuplicatePruningProvenanceLine; + RowSurface.LabelProvenanceLine = FusedRow.LabelProvenanceLine; + RowSurface.bSourceLabelWasExplicit = FusedRow.bSourceLabelWasExplicit; + RowSurface.bDroppedBecauseDuplicate = + FusedRow.bDroppedBecauseDuplicate; + RowSurface.bDroppedBecauseInvalid = + FusedRow.bDroppedBecauseInvalid; + RowSurface.bCanPreview = FusedRow.bCanPreview; + + if (RowSurface.bDroppedBecauseDuplicate) + { + RowSurface.DroppedRowAuditLine = FString::Printf( + TEXT("Current-selection dropped-row audit on execute: evaluation #%d for phase id %s is duplicate-pruned before normalized phase detail is retained."), + RowSurface.EvaluationOrder, + *RowSurface.PhaseId + ); + } + else + { + RowSurface.DroppedRowAuditLine = FString::Printf( + TEXT("Current-selection dropped-row audit on execute: evaluation #%d never reaches normalized phase detail because the raw row is structurally invalid."), + RowSurface.EvaluationOrder + ); + } + + RowSurface.DetailLine = FString::Printf( + TEXT("%s | %s | %s"), + *RowSurface.NormalizationOutcomeLine, + *RowSurface.LabelProvenanceLine, + *RowSurface.DroppedRowAuditLine + ); + Surface.DroppedRows.Add(MoveTemp(RowSurface)); + } + + Surface.DroppedRowCount = Surface.DroppedRows.Num(); + Surface.bHasCurrentSelectionDroppedRowAudit = + Surface.DroppedRowCount > 0; + + for (const FHyperTwistTrainingCoachGeneratedModeSelectorOptionOwnedExecutionSplitPhaseCurrentSelectionDroppedRowAuditInspectRowSurface& + RowSurface : Surface.DroppedRows) + { + if (RowSurface.bDroppedBecauseDuplicate) + { + ++Surface.DuplicatePrunedRowCount; + } + if (RowSurface.bDroppedBecauseInvalid) + { + ++Surface.InvalidRawRowCount; + } + } + + Surface.DroppedRowCountLine = Surface.bHasCurrentSelectionDroppedRowAudit + ? FString::Printf( + TEXT("Current-selection dropped raw rows on execute: %d row%s"), + Surface.DroppedRowCount, + Surface.DroppedRowCount == 1 ? TEXT("") : TEXT("s") + ) + : (CanonicalInspectSurface.bHasCurrentSelectionCanonicalInspectEntry + && !CanonicalInspectSurface.bPreviewBlocked + ? TEXT("Current-selection dropped raw rows on execute: none") + : TEXT("Current-selection dropped raw rows on execute: unavailable")); + + if (Surface.DroppedRows.Num() > 0) + { + Surface.CurrentSelectionDroppedRowAuditLine = FString::Printf( + TEXT("%s | %d duplicate-pruned | %d invalid"), + *Surface.DroppedRowCountLine, + Surface.DuplicatePrunedRowCount, + Surface.InvalidRawRowCount + ); + } + else if (OptionMenuSurface.bHasUnresolvedSelectionDetail) + { + Surface.CurrentSelectionDroppedRowAuditLine = + OptionMenuSurface.UnresolvedSelectionLine; + } + else if (CanonicalInspectSurface.bPreviewBlocked) + { + Surface.CurrentSelectionDroppedRowAuditLine = + CanonicalInspectSurface.CurrentSelectionCanonicalInspectLine; + } + else if (CanonicalInspectSurface.bHasCurrentSelectionCanonicalInspectEntry) + { + Surface.CurrentSelectionDroppedRowAuditLine = + TEXT("Current-selection dropped-row audit on execute: none"); + } + else if (OptionMenuSurface.bHasSelection) + { + Surface.CurrentSelectionDroppedRowAuditLine = + TEXT("Current selection has no additional owned-execution split-phase dropped-row audit preview."); + } + else if (OptionMenuSurface.bHasSelector) + { + Surface.CurrentSelectionDroppedRowAuditLine = + TEXT("Current selection: unresolved"); + } + else + { + Surface.CurrentSelectionDroppedRowAuditLine = + TEXT("Current selection: n/a"); + } + + if (Surface.bHasCurrentSelectionDroppedRowAudit) + { + Surface.StatusLine = FString::Printf( + TEXT("Generated-mode selector option owned-execution split-phase current-selection dropped-row audit inspect exposes %d dropped raw row%s for the active selection."), + Surface.DroppedRowCount, + Surface.DroppedRowCount == 1 ? TEXT("") : TEXT("s") + ); + } + else if (OptionMenuSurface.bHasSelector && OptionMenuSurface.bHasUnresolvedSelectionDetail) + { + Surface.StatusLine = + TEXT("Generated-mode selector option owned-execution split-phase current-selection dropped-row audit inspect is active, but the cached selection no longer matches an imported option."); + } + else if (CanonicalInspectSurface.bPreviewBlocked) + { + Surface.StatusLine = + TEXT("Generated-mode selector option owned-execution split-phase current-selection dropped-row audit inspect resolves the active selection, but execute-time dropped-row inspection remains blocked."); + } + else if (CanonicalInspectSurface.bHasCurrentSelectionCanonicalInspectEntry) + { + Surface.StatusLine = + TEXT("Generated-mode selector option owned-execution split-phase current-selection dropped-row audit inspect resolves the active selection, and no dropped raw rows are currently retained."); + } + else if (OptionMenuSurface.bHasSelector && OptionMenuSurface.bHasSelection) + { + Surface.StatusLine = + TEXT("Generated-mode selector option owned-execution split-phase current-selection dropped-row audit inspect is active, but the current selection does not expose dropped-row detail."); + } + else if (OptionMenuSurface.bHasSelector) + { + Surface.StatusLine = + TEXT("Generated-mode selector option owned-execution split-phase current-selection dropped-row audit inspect is active, but this selector is currently unresolved."); + } + else + { + Surface.StatusLine = CanonicalInspectSurface.StatusLine; + } + + Surface.DetailLine = FString::Printf( + TEXT("%s | %s | %s"), + *Surface.CurrentSelectionSelectionLine, + *Surface.CurrentSelectionDroppedRowAuditLine, + *Surface.DroppedRowCountLine + ); + + return Surface; +} + FHyperTwistTrainingCoachQueueControlSurface UHyperTwistTrainingCoachLibrary::DeriveCoachQueueControlSurface( const FHyperTwistTrainingCoachSessionQueueState& QueueState, diff --git a/UnrealHyperTwist/Source/UnrealHyperTwist/Private/HyperTwistTraining/HyperTwistTrainingPanelWidget.cpp b/UnrealHyperTwist/Source/UnrealHyperTwist/Private/HyperTwistTraining/HyperTwistTrainingPanelWidget.cpp index 00077f1..97469d5 100644 --- a/UnrealHyperTwist/Source/UnrealHyperTwist/Private/HyperTwistTraining/HyperTwistTrainingPanelWidget.cpp +++ b/UnrealHyperTwist/Source/UnrealHyperTwist/Private/HyperTwistTraining/HyperTwistTrainingPanelWidget.cpp @@ -1195,6 +1195,25 @@ UHyperTwistTrainingPanelWidget::GetDisplayedCoachGeneratedModeSelectorOptionOwne ); } +FHyperTwistTrainingCoachGeneratedModeSelectorOptionOwnedExecutionSplitPhaseCurrentSelectionDroppedRowAuditInspectSurface +UHyperTwistTrainingPanelWidget::GetDisplayedCoachGeneratedModeSelectorOptionOwnedExecutionSplitPhaseCurrentSelectionDroppedRowAuditInspectSurface( + const FString& SelectorId +) const +{ + const FHyperTwistTrainingCoachGeneratedModeSelectorOptionMenuSurface OptionMenuSurface = + GetDisplayedCoachGeneratedModeSelectorOptionMenuSurface(SelectorId); + const FHyperTwistTrainingCoachGeneratedModeSelectorOptionLaunchRequestPreviewSurface + OptionLaunchRequestPreviewSurface = + GetDisplayedCoachGeneratedModeSelectorOptionLaunchRequestPreviewSurface(SelectorId); + return UHyperTwistTrainingCoachLibrary:: + DeriveCoachGeneratedModeSelectorOptionOwnedExecutionSplitPhaseCurrentSelectionDroppedRowAuditInspectSurface( + CachedRunState, + SelectorId, + OptionMenuSurface, + OptionLaunchRequestPreviewSurface + ); +} + FHyperTwistTrainingRunState UHyperTwistTrainingPanelWidget::StartCoachRecommendedRun( const int32 MaxCases, const FString& StartActionSourceLabel diff --git a/UnrealHyperTwist/Source/UnrealHyperTwist/Private/HyperTwistTraining/HyperTwistTrainingSessionActor.cpp b/UnrealHyperTwist/Source/UnrealHyperTwist/Private/HyperTwistTraining/HyperTwistTrainingSessionActor.cpp index 1eb40ec..cd9b43b 100644 --- a/UnrealHyperTwist/Source/UnrealHyperTwist/Private/HyperTwistTraining/HyperTwistTrainingSessionActor.cpp +++ b/UnrealHyperTwist/Source/UnrealHyperTwist/Private/HyperTwistTraining/HyperTwistTrainingSessionActor.cpp @@ -1176,6 +1176,25 @@ AHyperTwistTrainingSessionActor::GetDisplayedCoachGeneratedModeSelectorOptionOwn ); } +FHyperTwistTrainingCoachGeneratedModeSelectorOptionOwnedExecutionSplitPhaseCurrentSelectionDroppedRowAuditInspectSurface +AHyperTwistTrainingSessionActor::GetDisplayedCoachGeneratedModeSelectorOptionOwnedExecutionSplitPhaseCurrentSelectionDroppedRowAuditInspectSurface( + const FString& SelectorId +) const +{ + const FHyperTwistTrainingCoachGeneratedModeSelectorOptionMenuSurface OptionMenuSurface = + GetDisplayedCoachGeneratedModeSelectorOptionMenuSurface(SelectorId); + const FHyperTwistTrainingCoachGeneratedModeSelectorOptionLaunchRequestPreviewSurface + OptionLaunchRequestPreviewSurface = + GetDisplayedCoachGeneratedModeSelectorOptionLaunchRequestPreviewSurface(SelectorId); + return UHyperTwistTrainingCoachLibrary:: + DeriveCoachGeneratedModeSelectorOptionOwnedExecutionSplitPhaseCurrentSelectionDroppedRowAuditInspectSurface( + CachedRunState, + SelectorId, + OptionMenuSurface, + OptionLaunchRequestPreviewSurface + ); +} + FHyperTwistTrainingRunState AHyperTwistTrainingSessionActor::StartCoachRecommendedTrainingRun( const int32 MaxCases ) diff --git a/UnrealHyperTwist/Source/UnrealHyperTwist/Public/HyperTwistTraining/HyperTwistTrainingCoachLibrary.h b/UnrealHyperTwist/Source/UnrealHyperTwist/Public/HyperTwistTraining/HyperTwistTrainingCoachLibrary.h index 7014c31..485bab9 100644 --- a/UnrealHyperTwist/Source/UnrealHyperTwist/Public/HyperTwistTraining/HyperTwistTrainingCoachLibrary.h +++ b/UnrealHyperTwist/Source/UnrealHyperTwist/Public/HyperTwistTraining/HyperTwistTrainingCoachLibrary.h @@ -947,4 +947,14 @@ public: const FHyperTwistTrainingCoachGeneratedModeSelectorOptionLaunchRequestPreviewSurface& OptionLaunchRequestPreviewSurface ); + + UFUNCTION(BlueprintPure, Category = "HyperTwist|Training|Coach") + static FHyperTwistTrainingCoachGeneratedModeSelectorOptionOwnedExecutionSplitPhaseCurrentSelectionDroppedRowAuditInspectSurface + DeriveCoachGeneratedModeSelectorOptionOwnedExecutionSplitPhaseCurrentSelectionDroppedRowAuditInspectSurface( + const FHyperTwistTrainingRunState& RunState, + const FString& SelectorId, + const FHyperTwistTrainingCoachGeneratedModeSelectorOptionMenuSurface& OptionMenuSurface, + const FHyperTwistTrainingCoachGeneratedModeSelectorOptionLaunchRequestPreviewSurface& + OptionLaunchRequestPreviewSurface + ); }; diff --git a/UnrealHyperTwist/Source/UnrealHyperTwist/Public/HyperTwistTraining/HyperTwistTrainingPanelWidget.h b/UnrealHyperTwist/Source/UnrealHyperTwist/Public/HyperTwistTraining/HyperTwistTrainingPanelWidget.h index d4ddce5..43b3101 100644 --- a/UnrealHyperTwist/Source/UnrealHyperTwist/Public/HyperTwistTraining/HyperTwistTrainingPanelWidget.h +++ b/UnrealHyperTwist/Source/UnrealHyperTwist/Public/HyperTwistTraining/HyperTwistTrainingPanelWidget.h @@ -398,6 +398,12 @@ public: const FString& SelectorId ) const; + UFUNCTION(BlueprintPure, Category = "HyperTwist|Training|Coach") + FHyperTwistTrainingCoachGeneratedModeSelectorOptionOwnedExecutionSplitPhaseCurrentSelectionDroppedRowAuditInspectSurface + GetDisplayedCoachGeneratedModeSelectorOptionOwnedExecutionSplitPhaseCurrentSelectionDroppedRowAuditInspectSurface( + const FString& SelectorId + ) const; + UFUNCTION(BlueprintCallable, Category = "HyperTwist|Training|Coach") FHyperTwistTrainingRunState StartCoachRecommendedRun( int32 MaxCases, diff --git a/UnrealHyperTwist/Source/UnrealHyperTwist/Public/HyperTwistTraining/HyperTwistTrainingSessionActor.h b/UnrealHyperTwist/Source/UnrealHyperTwist/Public/HyperTwistTraining/HyperTwistTrainingSessionActor.h index 75d4de1..4ba1efd 100644 --- a/UnrealHyperTwist/Source/UnrealHyperTwist/Public/HyperTwistTraining/HyperTwistTrainingSessionActor.h +++ b/UnrealHyperTwist/Source/UnrealHyperTwist/Public/HyperTwistTraining/HyperTwistTrainingSessionActor.h @@ -379,6 +379,12 @@ public: const FString& SelectorId ) const; + UFUNCTION(BlueprintPure, Category = "HyperTwist|Training|Coach") + FHyperTwistTrainingCoachGeneratedModeSelectorOptionOwnedExecutionSplitPhaseCurrentSelectionDroppedRowAuditInspectSurface + GetDisplayedCoachGeneratedModeSelectorOptionOwnedExecutionSplitPhaseCurrentSelectionDroppedRowAuditInspectSurface( + const FString& SelectorId + ) const; + UFUNCTION(BlueprintCallable, Category = "HyperTwist|Training|Coach") FHyperTwistTrainingRunState StartCoachRecommendedTrainingRun(int32 MaxCases); diff --git a/UnrealHyperTwist/Source/UnrealHyperTwist/Public/HyperTwistTraining/HyperTwistTrainingTypes.h b/UnrealHyperTwist/Source/UnrealHyperTwist/Public/HyperTwistTraining/HyperTwistTrainingTypes.h index b6b7b16..d01c865 100644 --- a/UnrealHyperTwist/Source/UnrealHyperTwist/Public/HyperTwistTraining/HyperTwistTrainingTypes.h +++ b/UnrealHyperTwist/Source/UnrealHyperTwist/Public/HyperTwistTraining/HyperTwistTrainingTypes.h @@ -13640,3 +13640,171 @@ struct FHyperTwistTrainingCoachGeneratedModeSelectorOptionOwnedExecutionSplitPha || bHasCurrentSelectionSurvivorPhaseRoster; } }; + +USTRUCT(BlueprintType) +struct FHyperTwistTrainingCoachGeneratedModeSelectorOptionOwnedExecutionSplitPhaseCurrentSelectionDroppedRowAuditInspectRowSurface +{ + GENERATED_BODY() + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist") + FString PhaseId; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist") + FString SourceLabel; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist") + int32 RawOrder = 0; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist") + int32 EvaluationOrder = -1; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist") + FString RawDefinitionLine; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist") + FString NormalizationOutcomeLine; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist") + FString DuplicatePruningProvenanceLine; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist") + FString LabelProvenanceLine; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist") + FString DroppedRowAuditLine; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist") + FString DetailLine; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist") + bool bSourceLabelWasExplicit = false; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist") + bool bDroppedBecauseDuplicate = false; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist") + bool bDroppedBecauseInvalid = false; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist") + bool bCanPreview = false; + + bool IsStructurallyValid() const + { + return !PhaseId.IsEmpty() + || !RawDefinitionLine.IsEmpty() + || !DroppedRowAuditLine.IsEmpty() + || bCanPreview; + } +}; + +USTRUCT(BlueprintType) +struct FHyperTwistTrainingCoachGeneratedModeSelectorOptionOwnedExecutionSplitPhaseCurrentSelectionDroppedRowAuditInspectSurface +{ + GENERATED_BODY() + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist") + FString SelectorId; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist") + FString SelectorLabel; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist") + FString BindingLabel; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist") + FString Headline; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist") + FString StatusLine; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist") + FString CurrentSelectionSelectionLine; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist") + FString CurrentSelectionDroppedRowAuditLine; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist") + FString DroppedRowCountLine; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist") + FString DuplicatePruningLine; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist") + FString InvalidDefinitionLine; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist") + FString PreviewPostureLine; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist") + FString DetailLine; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist") + TArray + DroppedRows; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist") + FString CurrentSelectionOptionId; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist") + FString CurrentSelectionOptionLabel; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist") + FString CurrentSelectionOptionValue; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist") + EHyperTwistTrainingCoachGeneratedModeOptionLaunchRequestPreviewKind LaunchRequestPreviewKind = + EHyperTwistTrainingCoachGeneratedModeOptionLaunchRequestPreviewKind::None; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist") + int32 DroppedRowCount = 0; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist") + int32 DuplicatePrunedRowCount = 0; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist") + int32 InvalidRawRowCount = 0; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist") + bool bHasSelector = false; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist") + bool bHasSelection = false; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist") + bool bSelectionMatchesAvailableOption = false; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist") + bool bHasCurrentSelectionDroppedRowAudit = false; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist") + bool bStartsOwnedCaseImmediately = false; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist") + bool bHasExactCurrentSelectionDroppedRowAudit = false; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist") + bool bRetainsActiveDeckSplitPhaseFusion = false; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist") + bool bHasDuplicatePrunedRows = false; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist") + bool bHasInvalidRawRows = false; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist") + bool bPreviewBlocked = false; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist") + bool bCanPreview = false; + + bool IsStructurallyValid() const + { + return !StatusLine.IsEmpty() + || !SelectorId.IsEmpty() + || !CurrentSelectionDroppedRowAuditLine.IsEmpty() + || DroppedRows.Num() > 0 + || bHasSelector + || bHasSelection + || bHasCurrentSelectionDroppedRowAudit; + } +}; diff --git a/docs/HYPERTWIST_ROADMAP_OVERHAUL_EXPANSION_GUIDE.md b/docs/HYPERTWIST_ROADMAP_OVERHAUL_EXPANSION_GUIDE.md index 886b2cd..b203d06 100644 --- a/docs/HYPERTWIST_ROADMAP_OVERHAUL_EXPANSION_GUIDE.md +++ b/docs/HYPERTWIST_ROADMAP_OVERHAUL_EXPANSION_GUIDE.md @@ -68,8 +68,8 @@ Current correction call from the source-exposed audit and current execution refr - the imported generated-mode gap is closed; request/config/selection plumbing and the bounded clean-room executor are already landed in first-party code - 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 latest landed bounded `Phase 4` packet stays on that same gameplay-facing consumer lane and adds one thin generated-mode selector option owned execution split-phase current-selection survivor-phase roster inspect surface over the already-cached selector/runtime/request state, so gameplay/Blueprint callers can render only the normalized surviving phases for the active selection without filtering duplicate-pruned and invalid raw rows out of the fused canonical inspect surface themselves - - the current next bounded packet is to expose one thin generated-mode selector option owned execution split-phase current-selection dropped-row audit inspect surface on those same two consumer surfaces so gameplay/Blueprint callers can inspect only duplicate-pruned and invalid raw rows for the active selection without scanning the full fused canonical inspect surface themselves + - the latest landed bounded `Phase 4` packet stays on that same gameplay-facing consumer lane and adds one thin generated-mode selector option owned execution split-phase current-selection dropped-row audit inspect surface over the already-cached selector/runtime/request state, so gameplay/Blueprint callers can inspect only duplicate-pruned and invalid raw rows for the active selection without scanning the full fused canonical inspect surface themselves + - the current next bounded packet is to expose one thin generated-mode selector option owned execution split-phase current-selection phase-id fallback roster inspect surface on those same two consumer surfaces so gameplay/Blueprint callers can inspect only surviving phases whose visible labels fall back to phase id without filtering the broader survivor-phase roster themselves - 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 ## Current execution-reality references diff --git a/docs/arch/HYPERTWIST_PHASE4_GAMEPLAY_GENERATED_MODE_SELECTOR_OPTION_OWNED_EXECUTION_SPLIT_PHASE_CURRENT_SELECTION_DROPPED_ROW_AUDIT_INSPECT_SURFACE_PACKET_2026-05-08.md b/docs/arch/HYPERTWIST_PHASE4_GAMEPLAY_GENERATED_MODE_SELECTOR_OPTION_OWNED_EXECUTION_SPLIT_PHASE_CURRENT_SELECTION_DROPPED_ROW_AUDIT_INSPECT_SURFACE_PACKET_2026-05-08.md new file mode 100644 index 0000000..8344625 --- /dev/null +++ b/docs/arch/HYPERTWIST_PHASE4_GAMEPLAY_GENERATED_MODE_SELECTOR_OPTION_OWNED_EXECUTION_SPLIT_PHASE_CURRENT_SELECTION_DROPPED_ROW_AUDIT_INSPECT_SURFACE_PACKET_2026-05-08.md @@ -0,0 +1,33 @@ +# HyperTwist Phase 4 gameplay generated-mode selector option owned execution split-phase current-selection dropped-row audit inspect surface packet + +## Goal + +Close the next thin gameplay-facing consumer seam above the current-selection canonical inspect surface by exposing one current-selection dropped-row audit inspect surface for a chosen selector id. + +## Why this packet exists + +The current-selection canonical inspect surface already exposed the active selection's full fused split-phase normalization state, including surviving rows, duplicate-pruned rows, and invalid rows. Gameplay and Blueprint callers that only need the dropped-row audit still had to scan and filter the full fused row array themselves. + +This packet removes that caller-side filtering step. It exposes one thin current-selection dropped-row audit inspect surface that projects only duplicate-pruned and invalid raw rows for the active selection while preserving unresolved-selection and blocked-preview posture from the already-landed canonical inspect surface. + +## What changed + +- add a first-party owned execution split-phase current-selection dropped-row audit inspect surface in shared training types +- derive that surface in the coach library by projecting the already-landed current-selection canonical inspect surface instead of reimplementing split-phase normalization logic +- expose the current-selection dropped-row audit inspect surface on both gameplay-facing consumers: + - `UHyperTwistTrainingPanelWidget` + - `AHyperTwistTrainingSessionActor` +- preserve exact duplicate-pruned and invalid-row provenance for the active selection +- preserve unresolved cached-selection and blocked-preview posture when the active selection cannot yet expose dropped-row audit detail + +## Validation + +- full `Development Editor|Win64` solution build for `C:\HyperTwist\UnrealHyperTwist\UnrealHyperTwist.sln` + +## Result + +Gameplay and Blueprint callers can now inspect only the active selection's duplicate-pruned and invalid raw rows from one dedicated dropped-row audit surface without scanning the full fused canonical inspect surface first. + +## Next bounded slice + +Stay on the same gameplay-facing consumer lane and expose one thin generated-mode selector option owned execution split-phase current-selection phase-id fallback roster inspect surface so callers can inspect only surviving phases whose visible labels fall back to phase id without filtering the broader survivor-phase roster themselves.