Add native control profile roster diagnostics

This commit is contained in:
axiomlogicnexus 2026-06-24 03:43:53 +00:00
parent ee7b525393
commit f664f099f5
10 changed files with 599 additions and 1 deletions

View file

@ -12809,6 +12809,15 @@ UHyperTwistCoachDashboardWidget::GetDisplayedControlSettingsOwnershipInspectSurf
return Surface;
}
FHyperTwistTrainingControlProfileRosterInspectSurface
UHyperTwistCoachDashboardWidget::GetDisplayedControlProfileRosterInspectSurface() const
{
FHyperTwistTrainingControlProfileRosterInspectSurface Surface =
UHyperTwistTrainingPanelWidget::GetDisplayedControlProfileRosterInspectSurface();
Surface.Headline = TEXT("Selectable control and profile roster");
return Surface;
}
FHyperTwistTrainingCoachDashboardGuidanceRationaleInspectSurface
UHyperTwistCoachDashboardWidget::GetDisplayedGuidanceRationaleInspectSurface() const
{
@ -19163,6 +19172,24 @@ void UHyperTwistCoachDashboardWidget::EnsureDefaultDashboardBuilt()
TEXT("CoachControlSettingsOwnershipDetail"),
8
);
ControlProfileRosterHeaderTextBlock = HyperTwistCoachDashboardWidgetInternal::AddTextRow(
WidgetTree,
RootLayout,
TEXT("CoachControlProfileRosterHeader"),
2
);
ControlProfileRosterStatusTextBlock = HyperTwistCoachDashboardWidgetInternal::AddTextRow(
WidgetTree,
RootLayout,
TEXT("CoachControlProfileRosterStatus"),
2
);
ControlProfileRosterDetailTextBlock = HyperTwistCoachDashboardWidgetInternal::AddTextRow(
WidgetTree,
RootLayout,
TEXT("CoachControlProfileRosterDetail"),
8
);
RecognitionStatusTextBlock = HyperTwistCoachDashboardWidgetInternal::AddTextRow(
WidgetTree,
RootLayout,
@ -30251,6 +30278,23 @@ void UHyperTwistCoachDashboardWidget::UpdateDashboardPresentation()
ControlSettingsOwnershipDetailTextBlock->SetText(
FText::FromString(ControlSettingsSurface.DetailLine));
}
const FHyperTwistTrainingControlProfileRosterInspectSurface ControlProfileRosterSurface =
GetDisplayedControlProfileRosterInspectSurface();
if (ControlProfileRosterHeaderTextBlock != nullptr)
{
ControlProfileRosterHeaderTextBlock->SetText(
FText::FromString(TEXT("[Selectable Control and Profile Roster]")));
}
if (ControlProfileRosterStatusTextBlock != nullptr)
{
ControlProfileRosterStatusTextBlock->SetText(
FText::FromString(ControlProfileRosterSurface.StatusLine));
}
if (ControlProfileRosterDetailTextBlock != nullptr)
{
ControlProfileRosterDetailTextBlock->SetText(
FText::FromString(ControlProfileRosterSurface.DetailLine));
}
if (VerificationStatusTextBlock != nullptr)
{
DisplayedVerificationStatusLine = CachedCoachPanelState.VerificationStatusLine;

View file

@ -1081,6 +1081,231 @@ UHyperTwistTrainingPanelWidget::GetDisplayedControlSettingsOwnershipInspectSurfa
return Surface;
}
FHyperTwistTrainingControlProfileRosterInspectSurface
UHyperTwistTrainingPanelWidget::GetDisplayedControlProfileRosterInspectSurface() const
{
FHyperTwistTrainingControlProfileRosterInspectSurface Surface;
Surface.Headline = TEXT("Selectable control and profile roster");
const FHyperTwistAlgorithmKeyboardProfile ClassicKeyboardProfile =
UHyperTwistAlgorithmKeyboardLibrary::GetClassicWcaKeyboardProfile();
Surface.ClassicKeyboardProfileName = ClassicKeyboardProfile.ProfileName;
Surface.ClassicKeyboardBindingCount = ClassicKeyboardProfile.Bindings.Num();
Surface.bClassicKeyboardProfileReady =
!Surface.ClassicKeyboardProfileName.IsEmpty() && Surface.ClassicKeyboardBindingCount > 0;
FHyperTwistTrainingImmersivePresenceControlContract PresenceContract;
Surface.bImmersivePresenceProfileReady =
UHyperTwistTrainingRuntimeLibrary::TryGetBundledImmersivePresenceControlContract(
TEXT("immersive-training-presence-control-contract"),
PresenceContract
) && PresenceContract.IsStructurallyValid();
if (Surface.bImmersivePresenceProfileReady)
{
Surface.ImmersivePresenceContractId = PresenceContract.ContractId;
Surface.ImmersionIntensityPresetCount = PresenceContract.ImmersionIntensityIds.Num();
Surface.ReducedDistractionPresetCount =
PresenceContract.ReducedDistractionPresetIds.Num();
}
const FHyperTwistTrainingMagic120CellReferenceBundle Magic120CellBundle =
UHyperTwistTrainingRuntimeLibrary::GetBundledMagic120CellReferenceBundle();
Surface.Magic120CellRuntimeProfileContractId =
Magic120CellBundle.PrimaryRuntimeProfileContractId;
Surface.Magic120CellViewProfileContractId = Magic120CellBundle.PrimaryViewProfileContractId;
FHyperTwistTrainingMagic120CellRuntimeProfileContract Magic120CellRuntimeProfile;
const bool bMagic120CellRuntimeProfileReady =
UHyperTwistTrainingRuntimeLibrary::TryGetBundledMagic120CellRuntimeProfileContract(
Surface.Magic120CellRuntimeProfileContractId,
Magic120CellRuntimeProfile
) && Magic120CellRuntimeProfile.IsStructurallyValid();
FHyperTwistTrainingMagic120CellViewProfileContract Magic120CellViewProfile;
const bool bMagic120CellViewProfileReady =
UHyperTwistTrainingRuntimeLibrary::TryGetBundledMagic120CellViewProfileContract(
Surface.Magic120CellViewProfileContractId,
Magic120CellViewProfile
) && Magic120CellViewProfile.IsStructurallyValid();
FHyperTwistTrainingHigherDimensionalRuntimeViewContextSurface Magic120CellViewContextSurface;
const bool bMagic120CellViewContextReady =
UHyperTwistTrainingRuntimeLibrary::TryGetBundledHigherDimensionalRuntimeViewContextSurfaceByActivationProfileId(
TEXT("magic120cell-cleanroom-runtime-activation"),
Magic120CellViewContextSurface
) && Magic120CellViewContextSurface.IsStructurallyValid();
Surface.Magic120CellSelectorCount = Magic120CellViewContextSurface.Selectors.Num();
Surface.bMagic120CellProfileReady =
bMagic120CellRuntimeProfileReady
&& bMagic120CellViewProfileReady
&& bMagic120CellViewContextReady
&& Surface.Magic120CellSelectorCount > 0;
const FHyperTwistTrainingMagicCube5DReferenceBundle MagicCube5DBundle =
UHyperTwistTrainingRuntimeLibrary::GetBundledMagicCube5DReferenceBundle();
Surface.MagicCube5DRuntimeProfileContractId =
MagicCube5DBundle.PrimaryRuntimeProfileContractId;
Surface.MagicCube5DViewProfileContractId = MagicCube5DBundle.PrimaryViewProfileContractId;
FHyperTwistTrainingMagicCube5DRuntimeProfileContract MagicCube5DRuntimeProfile;
const bool bMagicCube5DRuntimeProfileReady =
UHyperTwistTrainingRuntimeLibrary::TryGetBundledMagicCube5DRuntimeProfileContract(
Surface.MagicCube5DRuntimeProfileContractId,
MagicCube5DRuntimeProfile
) && MagicCube5DRuntimeProfile.IsStructurallyValid();
FHyperTwistTrainingMagicCube5DViewProfileContract MagicCube5DViewProfile;
const bool bMagicCube5DViewProfileReady =
UHyperTwistTrainingRuntimeLibrary::TryGetBundledMagicCube5DViewProfileContract(
Surface.MagicCube5DViewProfileContractId,
MagicCube5DViewProfile
) && MagicCube5DViewProfile.IsStructurallyValid();
FHyperTwistTrainingHigherDimensionalRuntimeViewContextSurface MagicCube5DViewContextSurface;
const bool bMagicCube5DViewContextReady =
UHyperTwistTrainingRuntimeLibrary::TryGetBundledHigherDimensionalRuntimeViewContextSurfaceByActivationProfileId(
TEXT("magiccube5d-cleanroom-runtime-activation"),
MagicCube5DViewContextSurface
) && MagicCube5DViewContextSurface.IsStructurallyValid();
Surface.MagicCube5DSelectorCount = MagicCube5DViewContextSurface.Selectors.Num();
Surface.bMagicCube5DProfileReady =
bMagicCube5DRuntimeProfileReady
&& bMagicCube5DViewProfileReady
&& bMagicCube5DViewContextReady
&& Surface.MagicCube5DSelectorCount > 0;
const FHyperTwistTrainingHigherDimensionalRuntimeActivationProfile ActiveActivationProfile =
HasDisplayedHigherDimensionalRuntimeActivationProfile()
? GetDisplayedHigherDimensionalRuntimeActivationProfile()
: FHyperTwistTrainingHigherDimensionalRuntimeActivationProfile();
const FHyperTwistTrainingHigherDimensionalRuntimeViewContextSurface ActiveViewContextSurface =
HasDisplayedHigherDimensionalRuntimeViewContextSurface()
? GetDisplayedHigherDimensionalRuntimeViewContextSurface()
: FHyperTwistTrainingHigherDimensionalRuntimeViewContextSurface();
const FHyperTwistTrainingHigherDimensionalRuntimeSessionSurface ActiveSessionSurface =
HasDisplayedHigherDimensionalRuntimeSessionSurface()
? GetDisplayedHigherDimensionalRuntimeSessionSurface()
: FHyperTwistTrainingHigherDimensionalRuntimeSessionSurface();
Surface.bActiveHigherDimensionalProfileVisible = ActiveActivationProfile.IsStructurallyValid();
Surface.ActiveHigherDimensionalActivationProfileId =
Surface.bActiveHigherDimensionalProfileVisible
? ActiveActivationProfile.ActivationProfileId
: TEXT("none");
Surface.ActiveHigherDimensionalViewContextId = ActiveViewContextSurface.IsStructurallyValid()
? ActiveViewContextSurface.ViewContextSurfaceId
: TEXT("none");
Surface.ActiveHigherDimensionalSessionSurfaceId = ActiveSessionSurface.IsStructurallyValid()
? ActiveSessionSurface.SessionSurfaceId
: TEXT("none");
Surface.ActiveHigherDimensionalSelectorCount = ActiveViewContextSurface.IsStructurallyValid()
? ActiveViewContextSurface.Selectors.Num()
: 0;
Surface.bFinishedControllerRebindingReady = false;
const FString ClassicKeyboardProfileName =
!Surface.ClassicKeyboardProfileName.IsEmpty()
? Surface.ClassicKeyboardProfileName
: TEXT("n/a");
const FString PresenceContractId =
!Surface.ImmersivePresenceContractId.IsEmpty()
? Surface.ImmersivePresenceContractId
: TEXT("n/a");
const FString Magic120CellRuntimeProfileId =
!Surface.Magic120CellRuntimeProfileContractId.IsEmpty()
? Surface.Magic120CellRuntimeProfileContractId
: TEXT("n/a");
const FString Magic120CellViewProfileId =
!Surface.Magic120CellViewProfileContractId.IsEmpty()
? Surface.Magic120CellViewProfileContractId
: TEXT("n/a");
const FString MagicCube5DRuntimeProfileId =
!Surface.MagicCube5DRuntimeProfileContractId.IsEmpty()
? Surface.MagicCube5DRuntimeProfileContractId
: TEXT("n/a");
const FString MagicCube5DViewProfileId =
!Surface.MagicCube5DViewProfileContractId.IsEmpty()
? Surface.MagicCube5DViewProfileContractId
: TEXT("n/a");
const FString ActiveActivationProfileId =
!Surface.ActiveHigherDimensionalActivationProfileId.IsEmpty()
? Surface.ActiveHigherDimensionalActivationProfileId
: TEXT("none");
const FString ActiveViewContextId =
!Surface.ActiveHigherDimensionalViewContextId.IsEmpty()
? Surface.ActiveHigherDimensionalViewContextId
: TEXT("none");
const FString ActiveSessionSurfaceId =
!Surface.ActiveHigherDimensionalSessionSurfaceId.IsEmpty()
? Surface.ActiveHigherDimensionalSessionSurfaceId
: TEXT("none");
Surface.SummaryLine =
TEXT("The shipped selectable roster currently covers the classic keyboard mapping, scenic immersive presets, and dedicated 120-cell/5D view-selector families, while controller rebinding still remains unfinished.");
Surface.ClassicKeyboardProfileLine = FString::Printf(
TEXT("Classic keyboard profile: %s | bindings %d | ctrl suppressed %s | alt suppressed %s | meta suppressed %s | repeat suppressed %s."),
*ClassicKeyboardProfileName,
Surface.ClassicKeyboardBindingCount,
*HyperTwistTrainingPanelWidgetInternal::DescribeBool(
ClassicKeyboardProfile.Policy.bSuppressCtrl),
*HyperTwistTrainingPanelWidgetInternal::DescribeBool(
ClassicKeyboardProfile.Policy.bSuppressAlt),
*HyperTwistTrainingPanelWidgetInternal::DescribeBool(
ClassicKeyboardProfile.Policy.bSuppressMeta),
*HyperTwistTrainingPanelWidgetInternal::DescribeBool(
ClassicKeyboardProfile.Policy.bSuppressRepeat)
);
Surface.ImmersivePresenceProfileLine = FString::Printf(
TEXT("Immersive presence presets: %s | contract %s | intensity presets %d | reduced-distraction presets %d."),
*HyperTwistTrainingPanelWidgetInternal::DescribeReadyState(
Surface.bImmersivePresenceProfileReady),
*PresenceContractId,
Surface.ImmersionIntensityPresetCount,
Surface.ReducedDistractionPresetCount
);
Surface.Magic120CellProfileLine = FString::Printf(
TEXT("Magic120Cell selectable family: %s | runtime %s | view %s | selectors %d."),
*HyperTwistTrainingPanelWidgetInternal::DescribeReadyState(
Surface.bMagic120CellProfileReady),
*Magic120CellRuntimeProfileId,
*Magic120CellViewProfileId,
Surface.Magic120CellSelectorCount
);
Surface.MagicCube5DProfileLine = FString::Printf(
TEXT("MagicCube5D selectable family: %s | runtime %s | view %s | selectors %d."),
*HyperTwistTrainingPanelWidgetInternal::DescribeReadyState(
Surface.bMagicCube5DProfileReady),
*MagicCube5DRuntimeProfileId,
*MagicCube5DViewProfileId,
Surface.MagicCube5DSelectorCount
);
Surface.ActiveHigherDimensionalProfileLine =
Surface.bActiveHigherDimensionalProfileVisible
? FString::Printf(
TEXT("Active higher-dimensional selection: activation %s | view context %s | session %s | visible selectors %d."),
*ActiveActivationProfileId,
*ActiveViewContextId,
*ActiveSessionSurfaceId,
Surface.ActiveHigherDimensionalSelectorCount
)
: TEXT("Active higher-dimensional selection: none currently displayed in this widget.");
Surface.PreferencesGapLine =
TEXT("Controller rebinding: not yet shipped; the current native roster ends at keyboard, scenic presence presets, and dedicated family selector/view profiles.");
Surface.StatusLine = FString::Printf(
TEXT("classic keyboard %s | immersive presets %s | 120-cell family %s | 5D family %s | active selection %s | controller rebinding not yet shipped"),
Surface.bClassicKeyboardProfileReady ? TEXT("ready") : TEXT("missing"),
Surface.bImmersivePresenceProfileReady ? TEXT("ready") : TEXT("missing"),
Surface.bMagic120CellProfileReady ? TEXT("ready") : TEXT("missing"),
Surface.bMagicCube5DProfileReady ? TEXT("ready") : TEXT("missing"),
Surface.bActiveHigherDimensionalProfileVisible ? TEXT("visible") : TEXT("not loaded")
);
Surface.DetailLine = FString::Printf(
TEXT("%s | %s | %s | %s | %s | %s"),
*Surface.ClassicKeyboardProfileLine,
*Surface.ImmersivePresenceProfileLine,
*Surface.Magic120CellProfileLine,
*Surface.MagicCube5DProfileLine,
*Surface.ActiveHigherDimensionalProfileLine,
*Surface.PreferencesGapLine
);
return Surface;
}
FHyperTwistTrainingDeck UHyperTwistTrainingPanelWidget::BuildActiveCoachRecommendedDeck(const int32 MaxCases)
{
CachedCoachRecommendedDeck = UHyperTwistTrainingRuntimeLibrary::BuildActiveCoachRecommendedDeck(

View file

@ -941,6 +941,9 @@ public:
FHyperTwistTrainingControlSettingsOwnershipInspectSurface
GetDisplayedControlSettingsOwnershipInspectSurface() const override;
FHyperTwistTrainingControlProfileRosterInspectSurface
GetDisplayedControlProfileRosterInspectSurface() const override;
UFUNCTION(BlueprintPure, Category = "HyperTwist|Training|Coach|Dashboard")
FHyperTwistTrainingCoachDashboardGuidanceRationaleInspectSurface
GetDisplayedGuidanceRationaleInspectSurface() const;
@ -1670,6 +1673,15 @@ protected:
UPROPERTY(Transient)
TObjectPtr<UTextBlock> ControlSettingsOwnershipDetailTextBlock = nullptr;
UPROPERTY(Transient)
TObjectPtr<UTextBlock> ControlProfileRosterHeaderTextBlock = nullptr;
UPROPERTY(Transient)
TObjectPtr<UTextBlock> ControlProfileRosterStatusTextBlock = nullptr;
UPROPERTY(Transient)
TObjectPtr<UTextBlock> ControlProfileRosterDetailTextBlock = nullptr;
UPROPERTY(Transient)
TObjectPtr<UTextBlock> RecognitionStatusTextBlock = nullptr;

View file

@ -299,6 +299,10 @@ public:
virtual FHyperTwistTrainingControlSettingsOwnershipInspectSurface
GetDisplayedControlSettingsOwnershipInspectSurface() const;
UFUNCTION(BlueprintPure, Category = "HyperTwist|Training|Input")
virtual FHyperTwistTrainingControlProfileRosterInspectSurface
GetDisplayedControlProfileRosterInspectSurface() const;
UFUNCTION(BlueprintCallable, Category = "HyperTwist|Training|Coach")
FHyperTwistTrainingDeck BuildActiveCoachRecommendedDeck(int32 MaxCases);

View file

@ -10160,6 +10160,119 @@ struct FHyperTwistTrainingControlSettingsOwnershipInspectSurface
}
};
USTRUCT(BlueprintType)
struct FHyperTwistTrainingControlProfileRosterInspectSurface
{
GENERATED_BODY()
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
FString Headline;
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
FString SummaryLine;
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
FString StatusLine;
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
FString DetailLine;
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
FString ClassicKeyboardProfileLine;
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
FString ImmersivePresenceProfileLine;
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
FString Magic120CellProfileLine;
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
FString MagicCube5DProfileLine;
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
FString ActiveHigherDimensionalProfileLine;
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
FString PreferencesGapLine;
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
FString ClassicKeyboardProfileName;
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
FString ImmersivePresenceContractId;
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
FString Magic120CellRuntimeProfileContractId;
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
FString Magic120CellViewProfileContractId;
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
FString MagicCube5DRuntimeProfileContractId;
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
FString MagicCube5DViewProfileContractId;
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
FString ActiveHigherDimensionalActivationProfileId;
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
FString ActiveHigherDimensionalViewContextId;
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
FString ActiveHigherDimensionalSessionSurfaceId;
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
int32 ClassicKeyboardBindingCount = 0;
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
int32 ImmersionIntensityPresetCount = 0;
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
int32 ReducedDistractionPresetCount = 0;
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
int32 Magic120CellSelectorCount = 0;
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
int32 MagicCube5DSelectorCount = 0;
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
int32 ActiveHigherDimensionalSelectorCount = 0;
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
bool bClassicKeyboardProfileReady = false;
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
bool bImmersivePresenceProfileReady = false;
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
bool bMagic120CellProfileReady = false;
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
bool bMagicCube5DProfileReady = false;
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
bool bActiveHigherDimensionalProfileVisible = false;
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
bool bFinishedControllerRebindingReady = false;
bool IsStructurallyValid() const
{
return !SummaryLine.IsEmpty()
|| !StatusLine.IsEmpty()
|| !ClassicKeyboardProfileLine.IsEmpty()
|| !ImmersivePresenceProfileLine.IsEmpty()
|| !Magic120CellProfileLine.IsEmpty()
|| !MagicCube5DProfileLine.IsEmpty()
|| bClassicKeyboardProfileReady
|| bImmersivePresenceProfileReady
|| bMagic120CellProfileReady
|| bMagicCube5DProfileReady;
}
};
USTRUCT(BlueprintType)
struct FHyperTwistTrainingCoachDashboardQueueRecoveryStatusInspectSurface
{

View file

@ -1217,6 +1217,117 @@ bool FHyperTwistCoachDashboardControlSettingsOwnershipInspectSurfaceTest::RunTes
return true;
}
IMPLEMENT_SIMPLE_AUTOMATION_TEST(
FHyperTwistTrainingPanelControlProfileRosterInspectSurfaceTest,
"HyperTwist.Browser.TrainingPanel.ControlProfileRosterInspectSurface",
EAutomationTestFlags::EditorContext | EAutomationTestFlags::EngineFilter
)
bool FHyperTwistTrainingPanelControlProfileRosterInspectSurfaceTest::RunTest(
const FString& Parameters
)
{
UHyperTwistTrainingPanelWidget* TrainingPanel = NewObject<UHyperTwistTrainingPanelWidget>();
TestNotNull(TEXT("The training panel widget must be constructible."), TrainingPanel);
if (TrainingPanel == nullptr)
{
return false;
}
const FHyperTwistTrainingControlProfileRosterInspectSurface Surface =
TrainingPanel->GetDisplayedControlProfileRosterInspectSurface();
TestTrue(
TEXT("The control/profile roster surface must be structurally valid."),
Surface.IsStructurallyValid()
);
TestEqual(
TEXT("The control/profile roster surface must keep a stable headline."),
Surface.Headline,
TEXT("Selectable control and profile roster")
);
TestTrue(
TEXT("The control/profile roster surface must report the current shipped classic keyboard profile."),
Surface.bClassicKeyboardProfileReady
&& Surface.ClassicKeyboardProfileName == TEXT("classic-wca-keyboard/v1")
&& Surface.ClassicKeyboardBindingCount == 18
);
TestTrue(
TEXT("The control/profile roster surface must report the immersive presence preset roster."),
Surface.bImmersivePresenceProfileReady
&& Surface.ImmersivePresenceContractId
== TEXT("immersive-training-presence-control-contract")
&& Surface.ImmersionIntensityPresetCount == 3
&& Surface.ReducedDistractionPresetCount == 3
);
TestTrue(
TEXT("The control/profile roster surface must report the shipped dedicated-family profile ids and selector counts."),
Surface.bMagic120CellProfileReady
&& Surface.bMagicCube5DProfileReady
&& Surface.Magic120CellRuntimeProfileContractId
== TEXT("magic120cell-runtime-profile")
&& Surface.Magic120CellViewProfileContractId
== TEXT("magic120cell-focus-view-profile")
&& Surface.MagicCube5DRuntimeProfileContractId
== TEXT("magiccube5d-runtime-profile")
&& Surface.MagicCube5DViewProfileContractId
== TEXT("magiccube5d-projection-view-profile")
&& Surface.Magic120CellSelectorCount == 4
&& Surface.MagicCube5DSelectorCount == 4
);
TestFalse(
TEXT("The control/profile roster surface must keep unfinished controller rebinding truth explicit."),
Surface.bFinishedControllerRebindingReady
);
TestTrue(
TEXT("The control/profile roster surface must say plainly that controller rebinding is not yet shipped."),
Surface.DetailLine.Contains(TEXT("not yet shipped"))
);
return true;
}
IMPLEMENT_SIMPLE_AUTOMATION_TEST(
FHyperTwistCoachDashboardControlProfileRosterInspectSurfaceTest,
"HyperTwist.Browser.CoachDashboard.ControlProfileRosterInspectSurface",
EAutomationTestFlags::EditorContext | EAutomationTestFlags::EngineFilter
)
bool FHyperTwistCoachDashboardControlProfileRosterInspectSurfaceTest::RunTest(
const FString& Parameters
)
{
UHyperTwistCoachDashboardWidget* CoachDashboard = NewObject<UHyperTwistCoachDashboardWidget>();
TestNotNull(TEXT("The coach dashboard widget must be constructible."), CoachDashboard);
if (CoachDashboard == nullptr)
{
return false;
}
CoachDashboard->RefreshCoachDashboardView();
const FHyperTwistTrainingControlProfileRosterInspectSurface Surface =
CoachDashboard->GetDisplayedControlProfileRosterInspectSurface();
TestTrue(
TEXT("The coach dashboard control/profile roster surface must stay structurally valid after a view refresh."),
Surface.IsStructurallyValid()
);
TestEqual(
TEXT("The coach dashboard control/profile roster surface must preserve the diagnostics headline."),
Surface.Headline,
TEXT("Selectable control and profile roster")
);
TestTrue(
TEXT("The coach dashboard control/profile roster surface must retain the shipped dedicated-family runtime/view profile references in its detail line."),
Surface.DetailLine.Contains(TEXT("magic120cell-runtime-profile"))
&& Surface.DetailLine.Contains(TEXT("magic120cell-focus-view-profile"))
&& Surface.DetailLine.Contains(TEXT("magiccube5d-runtime-profile"))
&& Surface.DetailLine.Contains(TEXT("magiccube5d-projection-view-profile"))
);
TestTrue(
TEXT("The coach dashboard control/profile roster surface must retain the classic keyboard profile fact in its detail line."),
Surface.DetailLine.Contains(TEXT("classic-wca-keyboard/v1"))
);
return true;
}
IMPLEMENT_SIMPLE_AUTOMATION_TEST(
FHyperTwistBrowserWidgetAuthoritativeShellArtifactsTest,
"HyperTwist.Browser.Widget.AuthoritativeShellArtifacts",

View file

@ -190,6 +190,25 @@ Use these as the current governing docs:
`TrainingPanel.ControlSettingsOwnershipInspectSurface`,
`CoachDashboard.ControlInputReadinessInspectSurface`, and
`TrainingPanel.ControlInputReadinessInspectSurface`
- that same shipping/browser posture now also carries a native selectable
control/profile roster inspect surface through
`UHyperTwistTrainingPanelWidget` and `UHyperTwistCoachDashboardWidget`, so
the operator can see the shipped classic keyboard profile and binding count,
scenic immersive preset roster, dedicated-family `Magic120Cell` /
`MagicCube5D` runtime/view profile ids plus selector counts, and explicit
unfinished controller rebinding truth without opening the browser shell
- Validation evidence on `2026-06-24`: after hash-syncing the touched type,
training-panel, coach-dashboard, and browser-test files into maintained
isolated worktree `C:\HyperTwist_worktrees\phase10validate`, the same
primary reverse-SSH `localhost:22022` lane rebuilt that widened slice with
`Result: Succeeded` and UnrealBuildTool `Total execution time: 3606.23
seconds`, then `Automation RunTests HyperTwist.Browser` exported
`Saved\AutomationReports\Browser-ControlProfileRoster-Verify\index.json`
with `20` `HyperTwist.Browser.*` tests succeeded and `0` failed, including
`CoachDashboard.ControlProfileRosterInspectSurface`,
`TrainingPanel.ControlProfileRosterInspectSurface`,
`CoachDashboard.ControlSettingsOwnershipInspectSurface`,
and `TrainingPanel.ControlSettingsOwnershipInspectSurface`
- the same optional full-browser-client branch is now also tightened by a backend-contract matrix packet that fixes transport-neutral operation labels, minimum session or host or bridge identity facts, request or result correlation posture, freshness or reconnect rules, and the owned state/runtime payload anchors a later browser-client implementation must preserve
- `MagicTile` `Phase 7C` is now landed separately through the bundled tiling native-behavior
proof contract/probe seam, runtime-library proof helpers, and focused Windows validation on

View file

@ -493,6 +493,31 @@ Latest dependency and validation hardening follow-up later on `2026-06-23`:
- the repo now also owns a single bounded validation command for that same
browser/public/auth-server surface:
- `scripts/run-hypertwist-web-surface-validation.sh`
Latest native roster and toolchain follow-up on `2026-06-24`:
- `scripts/run-hypertwist-gitnexus-analyze.sh` re-indexed the bounded
source-only mirror successfully at `16,159` nodes, `37,724` edges,
`666` clusters, and `300` flows
- `scripts/run-hypertwist-gitnexus-status.sh` again reported the bounded
mirror `Status: up-to-date`
- `scripts/run-hypertwist-sentrux-source-only.sh` improved again to
`Quality: 6137` with all `7` checked rules passing
- that same pass confirmed the new native control/profile roster inspect
surface did not reopen cycle debt or browser/website structural violations
- after hash-syncing the touched type, training-panel, coach-dashboard, and
browser-test files into maintained validation root
`C:\HyperTwist_worktrees\phase10validate`, the authoritative Windows Unreal
lane stayed green under:
- `scripts/run-hypertwist-remote-unreal-build.sh`
- `Result: Succeeded`
- `Total time in Parallel executor: 3586.44 seconds`
- `Total execution time: 3606.23 seconds`
- the same maintained lane then exported
`Saved\AutomationReports\Browser-ControlProfileRoster-Verify\index.json`
with `20` green `HyperTwist.Browser.*` tests, including:
- `HyperTwist.Browser.CoachDashboard.ControlProfileRosterInspectSurface`
- `HyperTwist.Browser.TrainingPanel.ControlProfileRosterInspectSurface`
- it runs the current website type-check or focused auth-route tests or
website build or website/server type-check or server tests or
`Content/Browser` verify/build sequence in one reproducible packet

View file

@ -117,6 +117,43 @@ truthfully claim:
- `CoachDashboard.ControlInputReadinessInspectSurface`
- `TrainingPanel.ControlInputReadinessInspectSurface`
### Native selectable control/profile roster is now real
- `FHyperTwistTrainingControlProfileRosterInspectSurface` now also exists in
`UnrealHyperTwist/Source/UnrealHyperTwist/Public/HyperTwistTraining/HyperTwistTrainingTypes.h`
- `UHyperTwistTrainingPanelWidget` and `UHyperTwistCoachDashboardWidget` now
expose that third inspect surface and keep the actually shipped selectable
roster visible without pretending controller rebinding or headset runtime
completion
- the current roster surface explicitly reports:
- shipped classic keyboard profile `classic-wca-keyboard/v1`
- the current `18` shipped classic keyboard bindings
- immersive-presence contract
`immersive-training-presence-control-contract`
- the current `3` immersive-intensity presets and `3`
reduced-distraction presets
- `Magic120Cell` runtime/profile ownership through
`magic120cell-runtime-profile` and
`magic120cell-focus-view-profile`
- `MagicCube5D` runtime/profile ownership through
`magiccube5d-runtime-profile` and
`magiccube5d-projection-view-profile`
- the current `4` selector options in each dedicated-family roster
- explicit unfinished XR/controller rebinding truth
- Windows validation on `2026-06-24` hash-synced the touched training, coach,
type, and browser-test files into maintained validation root
`C:\HyperTwist_worktrees\phase10validate`, rebuilt the widened slice with
`Result: Succeeded`, UnrealBuildTool `Total execution time: 3606.23
seconds`, then exported
`Saved\AutomationReports\Browser-ControlProfileRoster-Verify\index.json`
with all `20` `HyperTwist.Browser.*` tests green, including:
- `CoachDashboard.ControlProfileRosterInspectSurface`
- `TrainingPanel.ControlProfileRosterInspectSurface`
- `CoachDashboard.ControlSettingsOwnershipInspectSurface`
- `TrainingPanel.ControlSettingsOwnershipInspectSurface`
- `CoachDashboard.ControlInputReadinessInspectSurface`
- `TrainingPanel.ControlInputReadinessInspectSurface`
### Finished XR runtime ownership is not yet proven
- `UnrealHyperTwist/UnrealHyperTwist.uproject` currently enables
@ -141,6 +178,9 @@ Current truthful product wording should say:
- desktop Unreal simulator: real and shipping
- classic input and higher-dimensional keyboard interaction: real and shipping
- native operator/training diagnostics already surface current input truth
- the currently shipped selectable native roster is visible inside Unreal:
classic keyboard, scenic immersive presets, and dedicated 120-cell/5D view
selectors
- camera, immersive, and dedicated-family view settings already have bounded
first-party ownership
- immersive/scenic training direction: first-party owned and source-backed
@ -154,6 +194,9 @@ manual:
- docs/resources/support surfaces should explicitly distinguish current keyboard
and higher-dimensional control ownership from unfinished VR/controller claims
- docs/resources/support surfaces may truthfully describe the current shipped
roster of keyboard, scenic immersive, and dedicated-family selector/view
options, but they must not collapse that into finished controller rebinding
- docs/resources/support surfaces may truthfully describe current camera or
immersive or dedicated-family view settings ownership, but they must not
inflate that into full controller rebinding or headset-runtime completion
@ -176,6 +219,7 @@ first clean implementation packet should be:
1. a bounded native plugin/runtime-owner slice above the current desktop-hosted
immersive lane
2. finished controller-specific rebinding/preferences ownership above the
already-landed camera/immersive/view settings surfaces
already-landed camera/immersive/view settings surfaces and the current
shipped roster inspect surface
3. packaged validation on the Windows Unreal lane with headset/controller truth
kept explicit

View file

@ -147,6 +147,7 @@ Do not collapse those three tiers into one undifferentiated "features" voice.
| Browser/spatial/media adjunct surfaces | Implemented now | landed `three.js`, `react-three-fiber`, `xr`, `model-viewer`, `remotion` packets | These are implemented bounded families, and the current Phase 1 browser-runtime landing now includes a first-party authoritative `Content/Browser/index.html` shell, bundled-runtime upgrade path, committed clean-checkout plain-JS fallback runtime, embedded `UHyperTwistBrowserWidget` bridge, the `2026-06-19` runtime-ready queue hardening that retains outbound Unreal shell traffic until the browser runtime is ready, a same-day first-party `Browser Runtime Status` surface with shared boot-state ownership across bundled and fallback shells, a follow-on typed Unreal-side `browser-runtime-status` capture seam that retains the last valid runtime snapshot across unrelated later envelope traffic until explicit reset, a second follow-on typed Unreal-side `hypertwist-runtime-ready` capture seam that raises the original handshake payload out of raw JSON-only handling without changing queue flush behavior, a third same-day native/operator-facing status surface that consumes those typed seams inside Unreal while clearing retained runtime ownership on shell-authority change, a fourth same-day native training/operator diagnostics-panel continuation that wires that typed status ownership into `UHyperTwistTrainingPanelWidget` and the coach dashboard without making the dashboard inspect seam depend on stale rendered strings, a fifth same-day diagnostics-fidelity continuation that now carries bootstrap/runtime-ready timestamps, last command/shell-state receipt timestamps, and fallback reason through the same native operator/training seams, and a later `2026-06-23` control/input readiness continuation that projects shipped keyboard/input truth and unfinished XR/preferences truth through the same native training/operator surfaces. This still is not proof of unlimited browser-shell parity. |
| Native control/input readiness inspect surface | Implemented now | landed first-party `2026-06-23` browser/native operator continuation | `UHyperTwistTrainingPanelWidget` and `UHyperTwistCoachDashboardWidget` now expose `FHyperTwistTrainingControlInputReadinessInspectSurface`, including the shipped `classic-wca-keyboard/v1` mapping, classic-cube mouse/touch/shortcut readiness, higher-dimensional dedicated-family runtime-catalog truth, project-level `EnhancedInput` plus motion-controller groundwork facts, immersive-presence contract presence, and explicit unfinished XR/runtime plus preferences truth. The recovered primary reverse-SSH `localhost:22022` lane rebuilt maintained validation worktree `C:\HyperTwist_worktrees\phase10validate` on `2026-06-23` with `Result: Succeeded`, UnrealBuildTool `Total execution time: 1563.53 seconds`, and exported `Saved\AutomationReports\Browser-ControlInputReadiness-Verify\index.json` with all `16` `HyperTwist.Browser.*` tests passing, including `CoachDashboard.ControlInputReadinessInspectSurface` and `TrainingPanel.ControlInputReadinessInspectSurface`. A later same-day quality follow-up then moved the project-input-groundwork inspection behind that surface from raw text scanning into structured Unreal config reads, rebuilt the same maintained validation worktree again with `Result: Succeeded`, UnrealBuildTool `Total execution time: 158.13 seconds`, and re-exported focused browser proof to `Saved\AutomationReports\Browser-ControlInputReadiness-StructuredConfig-Verify` with all `16` `HyperTwist.Browser.*` tests green again. |
| Native control/settings ownership inspect surface | Implemented now | landed first-party `2026-06-24` browser/native operator continuation | `UHyperTwistTrainingPanelWidget` and `UHyperTwistCoachDashboardWidget` now expose `FHyperTwistTrainingControlSettingsOwnershipInspectSurface`, including the shipped viewer camera-settings owner `tool/camera-settings`, the immersive-presence control contract, dedicated-family `magic120cell-focus-view-profile` and `magiccube5d-projection-view-profile` view ownership, higher-dimensional selector ownership, and explicit unfinished XR/controller rebinding truth. The same primary reverse-SSH `localhost:22022` lane rebuilt maintained validation worktree `C:\HyperTwist_worktrees\phase10validate` on `2026-06-24` with `Result: Succeeded`, UnrealBuildTool `Total execution time: 4331.11 seconds`, and then exported `Saved\AutomationReports\Browser-ControlSettingsOwnership-Verify\index.json` with all `18` `HyperTwist.Browser.*` tests passing, including `CoachDashboard.ControlSettingsOwnershipInspectSurface`, `TrainingPanel.ControlSettingsOwnershipInspectSurface`, and the previously landed runtime plus control/input inspect seams. |
| Native control/profile roster inspect surface | Implemented now | landed first-party `2026-06-24` browser/native operator continuation | `UHyperTwistTrainingPanelWidget` and `UHyperTwistCoachDashboardWidget` now expose `FHyperTwistTrainingControlProfileRosterInspectSurface`, keeping the actually shipped selectable native roster visible: classic keyboard profile `classic-wca-keyboard/v1` with `18` bindings, immersive-presence contract `immersive-training-presence-control-contract` with `3` intensity plus `3` reduced-distraction presets, dedicated-family `Magic120Cell` runtime/view ids `magic120cell-runtime-profile` and `magic120cell-focus-view-profile`, dedicated-family `MagicCube5D` runtime/view ids `magiccube5d-runtime-profile` and `magiccube5d-projection-view-profile`, the current `4` selectors in each dedicated-family roster, and explicit unfinished controller rebinding truth. After hash-syncing the touched type/training/dashboard/test files into maintained validation worktree `C:\HyperTwist_worktrees\phase10validate`, the same primary reverse-SSH `localhost:22022` lane rebuilt the widened slice on `2026-06-24` with `Result: Succeeded`, UnrealBuildTool `Total execution time: 3606.23 seconds`, then exported `Saved\AutomationReports\Browser-ControlProfileRoster-Verify\index.json` with all `20` `HyperTwist.Browser.*` tests passing, including `CoachDashboard.ControlProfileRosterInspectSurface` and `TrainingPanel.ControlProfileRosterInspectSurface`. |
| Optional full-browser client path above Unreal backend authority | Deep-source grounded retained | landed first-party `Phase 8B` preparation packet + spec/evidence continuation + backend-contract continuation | This branch remains a spec-only first-party option: a browser-owned rendering and input shell may sit above explicit Unreal backend seams while Unreal remains authoritative for puzzle, training, timer, replay, and persistence state. The current continuation now fixes the allowed seam families to catalog, session, action, state, continuity push, replay, persistence status, and runtime health, then further fixes transport-neutral operation labels, minimum identity or freshness requirements, and the owned state/runtime payload anchors that any later browser-client backend implementation must preserve. The landed embedded browser/CEF shell remains the current shipping posture, and this branch stays separate from any native `MagicTile` behavior or renderer widening. |
| Rewritten browser spatial scene and renderer reference grounding | Implemented now | `mrdoob/three.js` retained permissive lane + first-party current code | Current live `Browser 3D and XR Support` reference side includes one rewritten first-party target grounded in retained `mrdoob/three.js`: the browser spatial scene and renderer contract. This does not displace the landed `Phase 3R-F` first-party browser spatial owner trio or absorb the adjacent `react-three-fiber` renderer-bridge and `xr` session slices. |
| Rewritten React-side browser renderer and event-bridge grounding | Implemented now | `pmndrs/react-three-fiber` retained permissive lane + first-party current code | Current live `Browser 3D and XR Support` reference side includes one rewritten first-party target grounded in retained `react-three-fiber`: the React scene renderer and event bridge. This does not displace the landed `Phase 3R-F` first-party browser spatial owner trio or absorb the adjacent `three.js` scene substrate and `xr` session slices. |