diff --git a/.sentrux/source-only-baseline.json b/.sentrux/source-only-baseline.json new file mode 100644 index 0000000..96c49a5 --- /dev/null +++ b/.sentrux/source-only-baseline.json @@ -0,0 +1,12 @@ +{ + "timestamp": 1782739148.1063952, + "quality_signal": 0.623355968371853, + "coupling_score": 0.1492204899777283, + "cycle_count": 0, + "god_file_count": 1, + "hotspot_count": 0, + "complex_fn_count": 15, + "max_depth": 11, + "total_import_edges": 898, + "cross_module_edges": 134 +} \ No newline at end of file diff --git a/Content/Browser/vite.config.ts b/Content/Browser/vite.config.ts index 20e11bb..3ea3e75 100644 --- a/Content/Browser/vite.config.ts +++ b/Content/Browser/vite.config.ts @@ -1,7 +1,42 @@ import { defineConfig } from 'vite'; import { resolve } from 'path'; +function annotateGltfViewerMikktspaceFallback() +{ + const OriginalFallbackExpression = + "new URL('mikktspace_bg.wasm', import.meta.url)"; + const AnnotatedFallbackExpression = + "new URL(/* @vite-ignore */ 'mikktspace_bg.wasm', import.meta.url)"; + + return { + name: 'annotate-gltf-viewer-mikktspace-fallback', + transform(Code: string, Id: string) + { + if (!Id.includes('@khronosgroup/gltf-viewer/dist/gltf-viewer.module.js')) + { + return null; + } + + if (!Code.includes(OriginalFallbackExpression)) + { + return null; + } + + return { + code: Code.replaceAll( + OriginalFallbackExpression, + AnnotatedFallbackExpression + ), + map: null + }; + } + }; +} + export default defineConfig({ + plugins: [ + annotateGltfViewerMikktspaceFallback() + ], build: { outDir: 'dist', emptyOutDir: true, diff --git a/UnrealHyperTwist/Source/UnrealHyperTwist/Private/HyperTwistTraining/HyperTwistCoachDashboardWidget.cpp b/UnrealHyperTwist/Source/UnrealHyperTwist/Private/HyperTwistTraining/HyperTwistCoachDashboardWidget.cpp index 66ce758..1354320 100644 --- a/UnrealHyperTwist/Source/UnrealHyperTwist/Private/HyperTwistTraining/HyperTwistCoachDashboardWidget.cpp +++ b/UnrealHyperTwist/Source/UnrealHyperTwist/Private/HyperTwistTraining/HyperTwistCoachDashboardWidget.cpp @@ -19383,6 +19383,14 @@ void UHyperTwistCoachDashboardWidget::EnsureDefaultDashboardBuilt() 4 ) ); + ControlProfileRosterStructuredTextBlocks.Add( + HyperTwistCoachDashboardWidgetInternal::AddTextRow( + WidgetTree, + RootLayout, + TEXT("CoachControlProfileRosterPreferencesContinuity"), + 4 + ) + ); ControlProfileRosterStructuredTextBlocks.Add( HyperTwistCoachDashboardWidgetInternal::AddTextRow( WidgetTree, @@ -30546,6 +30554,7 @@ void UHyperTwistCoachDashboardWidget::UpdateDashboardPresentation() ControlProfileRosterSurface.MagicCube5DProfileLine, ControlProfileRosterSurface.ActiveHigherDimensionalProfileLine, ControlProfileRosterSurface.SelectorRecallLine, + ControlProfileRosterSurface.PreferencesContinuityLine, ControlProfileRosterSurface.PreferencesGapLine, } ); diff --git a/UnrealHyperTwist/Source/UnrealHyperTwist/Private/HyperTwistTraining/HyperTwistTrainingControlSurfaceFormatting.h b/UnrealHyperTwist/Source/UnrealHyperTwist/Private/HyperTwistTraining/HyperTwistTrainingControlSurfaceFormatting.h new file mode 100644 index 0000000..e8a497a --- /dev/null +++ b/UnrealHyperTwist/Source/UnrealHyperTwist/Private/HyperTwistTraining/HyperTwistTrainingControlSurfaceFormatting.h @@ -0,0 +1,257 @@ +// Copyright HyperTwist, Inc. All Rights Reserved. + +#pragma once + +#include "CoreMinimal.h" + +namespace HyperTwistTrainingControlSurfaceFormatting +{ + inline FString DescribeBool(const bool bValue) + { + return bValue ? TEXT("yes") : TEXT("no"); + } + + inline FString DescribeReadyState(const bool bValue) + { + return bValue ? TEXT("ready") : TEXT("not ready"); + } + + inline FString DescribeAggregateReadyState( + const bool bPrimaryReady, + const bool bSecondaryReady + ) + { + if (bPrimaryReady && bSecondaryReady) + { + return TEXT("ready"); + } + + if (bPrimaryReady || bSecondaryReady) + { + return TEXT("partial"); + } + + return TEXT("missing"); + } + + inline FString DescribeOwnedContinuityState( + const bool bOwnershipReady, + const bool bContinuityReady + ) + { + if (!bOwnershipReady) + { + return TEXT("missing"); + } + + return bContinuityReady ? TEXT("ready") : TEXT("partial"); + } + + inline FString DescribeIdOrFallback(const FString& Value) + { + return !Value.IsEmpty() ? Value : FString(TEXT("n/a")); + } + + inline FString DescribeIdIfReady( + const bool bReady, + const FString& Value + ) + { + return DescribeIdOrFallback(bReady ? Value : FString()); + } + + inline int32 DescribeCountIfReady( + const bool bReady, + const int32 Count + ) + { + return bReady ? Count : 0; + } + + inline FString BuildControlInputPreferencesStatusLine( + const bool bCameraSettingsContinuityReady, + const FString& CameraExportArtifactId, + const bool bImmersiveSessionRecallReady, + const FString& ImmersiveSessionRecallBoundaryId, + const int32 ImmersiveSessionRecallScopeCount, + const int32 ImmersiveSessionRecallPreferenceFieldTagCount + ) + { + return FString::Printf( + TEXT("Preferences continuity: %s | camera export %s | immersive recall %s | recall scopes %d | preference fields %d | polished rebinding and broader control-settings UI are not yet shipped."), + *DescribeAggregateReadyState( + bCameraSettingsContinuityReady, + bImmersiveSessionRecallReady), + *DescribeIdIfReady( + bCameraSettingsContinuityReady, + CameraExportArtifactId), + *DescribeIdIfReady( + bImmersiveSessionRecallReady, + ImmersiveSessionRecallBoundaryId), + DescribeCountIfReady( + bImmersiveSessionRecallReady, + ImmersiveSessionRecallScopeCount), + DescribeCountIfReady( + bImmersiveSessionRecallReady, + ImmersiveSessionRecallPreferenceFieldTagCount) + ); + } + + inline FString BuildControlSettingsCameraSettingsLine( + const bool bCameraSettingsReady, + const bool bCameraSettingsContinuityReady, + const FString& CameraSettingsToolId, + const FString& CameraSettingsExportArtifactId, + const int32 CameraSettingsWorkflowTagCount, + const int32 CameraSettingsPreviewStateTagCount, + const int32 CameraSettingsExportArtifactCount + ) + { + return FString::Printf( + TEXT("Viewer camera settings: %s | tool %s | camera export %s | workflow tags %d | preview states %d | export artifacts %d | orbit/framing/export surface is owned."), + *DescribeOwnedContinuityState( + bCameraSettingsReady, + bCameraSettingsContinuityReady), + *DescribeIdIfReady( + bCameraSettingsReady, + CameraSettingsToolId), + *DescribeIdIfReady( + bCameraSettingsContinuityReady, + CameraSettingsExportArtifactId), + DescribeCountIfReady( + bCameraSettingsReady, + CameraSettingsWorkflowTagCount), + DescribeCountIfReady( + bCameraSettingsReady, + CameraSettingsPreviewStateTagCount), + DescribeCountIfReady( + bCameraSettingsReady, + CameraSettingsExportArtifactCount) + ); + } + + inline FString BuildControlSettingsImmersiveSettingsLine( + const bool bImmersivePresenceSettingsReady, + const bool bImmersiveSessionRecallReady, + const FString& ImmersivePresenceContractId, + const FString& ImmersiveSessionRecallBoundaryId, + const int32 ImmersionIntensityPresetCount, + const int32 ReducedDistractionPresetCount, + const int32 ImmersivePresenceSurfaceTagCount, + const int32 ImmersiveSessionRecallScopeCount, + const int32 ImmersiveSessionRecallPreferenceFieldTagCount, + const int32 ImmersiveSessionRecallResetSurfaceTagCount + ) + { + return FString::Printf( + TEXT("Immersive presence settings: %s | contract %s | session recall %s | intensity presets %d | reduced-distraction presets %d | presence tags %d | recall scopes %d | preference fields %d | reset surfaces %d."), + *DescribeOwnedContinuityState( + bImmersivePresenceSettingsReady, + bImmersiveSessionRecallReady), + *DescribeIdIfReady( + bImmersivePresenceSettingsReady, + ImmersivePresenceContractId), + *DescribeIdIfReady( + bImmersiveSessionRecallReady, + ImmersiveSessionRecallBoundaryId), + DescribeCountIfReady( + bImmersivePresenceSettingsReady, + ImmersionIntensityPresetCount), + DescribeCountIfReady( + bImmersivePresenceSettingsReady, + ReducedDistractionPresetCount), + DescribeCountIfReady( + bImmersivePresenceSettingsReady, + ImmersivePresenceSurfaceTagCount), + DescribeCountIfReady( + bImmersiveSessionRecallReady, + ImmersiveSessionRecallScopeCount), + DescribeCountIfReady( + bImmersiveSessionRecallReady, + ImmersiveSessionRecallPreferenceFieldTagCount), + DescribeCountIfReady( + bImmersiveSessionRecallReady, + ImmersiveSessionRecallResetSurfaceTagCount) + ); + } + + inline FString BuildControlSettingsStatusLine( + const bool bCameraSettingsReady, + const bool bCameraSettingsContinuityReady, + const bool bImmersivePresenceSettingsReady, + const bool bImmersiveSessionRecallReady, + const bool bMagic120CellOwnedSettingsReady, + const bool bMagicCube5DOwnedSettingsReady, + const bool bHigherDimensionalSelectorSettingsReady, + const bool bRepositoryBackedSelectorRecallReady + ) + { + return FString::Printf( + TEXT("camera %s | immersive %s | 120-cell owned settings %s | 5D owned settings %s | selectors %s | selector recall %s | XR rebinding not yet shipped"), + *DescribeOwnedContinuityState( + bCameraSettingsReady, + bCameraSettingsContinuityReady), + *DescribeOwnedContinuityState( + bImmersivePresenceSettingsReady, + bImmersiveSessionRecallReady), + bMagic120CellOwnedSettingsReady ? TEXT("ready") : TEXT("partial"), + bMagicCube5DOwnedSettingsReady ? TEXT("ready") : TEXT("partial"), + bHigherDimensionalSelectorSettingsReady ? TEXT("ready") : TEXT("partial"), + bRepositoryBackedSelectorRecallReady ? TEXT("ready") : TEXT("unavailable") + ); + } + + inline FString BuildControlProfilePreferencesContinuityLine( + const bool bCameraSettingsContinuityReady, + const FString& CameraSettingsExportArtifactId, + const bool bImmersiveSessionRecallReady, + const FString& ImmersiveSessionRecallBoundaryId, + const int32 ImmersiveSessionRecallScopeCount, + const int32 ImmersiveSessionRecallPreferenceFieldTagCount + ) + { + return FString::Printf( + TEXT("Profile continuity: %s | camera export %s | immersive recall %s | recall scopes %d | preference fields %d."), + *DescribeAggregateReadyState( + bCameraSettingsContinuityReady, + bImmersiveSessionRecallReady), + *DescribeIdIfReady( + bCameraSettingsContinuityReady, + CameraSettingsExportArtifactId), + *DescribeIdIfReady( + bImmersiveSessionRecallReady, + ImmersiveSessionRecallBoundaryId), + DescribeCountIfReady( + bImmersiveSessionRecallReady, + ImmersiveSessionRecallScopeCount), + DescribeCountIfReady( + bImmersiveSessionRecallReady, + ImmersiveSessionRecallPreferenceFieldTagCount) + ); + } + + inline FString BuildControlProfileStatusLine( + const bool bClassicKeyboardProfileReady, + const bool bImmersivePresenceProfileReady, + const bool bMagic120CellProfileReady, + const bool bMagicCube5DProfileReady, + const bool bActiveHigherDimensionalProfileVisible, + const bool bRepositoryBackedSelectorRecallReady, + const bool bCameraSettingsContinuityReady, + const bool bImmersiveSessionRecallReady + ) + { + return FString::Printf( + TEXT("classic keyboard %s | immersive presets %s | 120-cell family %s | 5D family %s | active selection %s | selector recall %s | profile continuity %s | controller rebinding not yet shipped"), + bClassicKeyboardProfileReady ? TEXT("ready") : TEXT("missing"), + bImmersivePresenceProfileReady ? TEXT("ready") : TEXT("missing"), + bMagic120CellProfileReady ? TEXT("ready") : TEXT("missing"), + bMagicCube5DProfileReady ? TEXT("ready") : TEXT("missing"), + bActiveHigherDimensionalProfileVisible ? TEXT("visible") : TEXT("not loaded"), + bRepositoryBackedSelectorRecallReady ? TEXT("ready") : TEXT("unavailable"), + *DescribeAggregateReadyState( + bCameraSettingsContinuityReady, + bImmersiveSessionRecallReady) + ); + } +} diff --git a/UnrealHyperTwist/Source/UnrealHyperTwist/Private/HyperTwistTraining/HyperTwistTrainingPanelWidget.cpp b/UnrealHyperTwist/Source/UnrealHyperTwist/Private/HyperTwistTraining/HyperTwistTrainingPanelWidget.cpp index 8a4517f..583cc11 100644 --- a/UnrealHyperTwist/Source/UnrealHyperTwist/Private/HyperTwistTraining/HyperTwistTrainingPanelWidget.cpp +++ b/UnrealHyperTwist/Source/UnrealHyperTwist/Private/HyperTwistTraining/HyperTwistTrainingPanelWidget.cpp @@ -1,10 +1,12 @@ #include "HyperTwistTraining/HyperTwistTrainingPanelWidget.h" #include "HyperTwistAlgorithm/HyperTwistAlgorithmKeyboard.h" +#include "HyperTwistAlgorithm/HyperTwistAlgorithmSerializer.h" #include "HyperTwistBrowser/HyperTwistBrowserWidget.h" #include "HyperTwistSimulation/HyperTwistClassicCubeOrbitPawn.h" #include "HyperTwistSimulation/HyperTwistClassicCubePlayerController.h" #include "HyperTwistSimulation/HyperTwistVirtual3333ProjectionPlayerController.h" +#include "HyperTwistTraining/HyperTwistTrainingControlSurfaceFormatting.h" #include "HyperTwistTraining/HyperTwistTrainingImmersiveEnvironmentLibrary.h" #include "HyperTwistTraining/HyperTwistTrainingMagic120CellLibrary.h" #include "HyperTwistTraining/HyperTwistTrainingMagicCube5DLibrary.h" @@ -62,14 +64,28 @@ namespace HyperTwistTrainingPanelWidgetInternal } }; + struct FViewerCameraSettingsFacts + { + FHyperTwistTrainingViewerEditorToolReference Tool; + FString ExportArtifactId; + bool bToolReady = false; + bool bExportArtifactReady = false; + }; + + struct FImmersiveSessionRecallFacts + { + FHyperTwistTrainingImmersiveSessionRecallBoundary Boundary; + bool bReady = false; + }; + FString DescribeBool(const bool bValue) { - return bValue ? TEXT("yes") : TEXT("no"); + return HyperTwistTrainingControlSurfaceFormatting::DescribeBool(bValue); } FString DescribeReadyState(const bool bValue) { - return bValue ? TEXT("ready") : TEXT("not ready"); + return HyperTwistTrainingControlSurfaceFormatting::DescribeReadyState(bValue); } FString DescribeAggregateReadyState( @@ -77,17 +93,9 @@ namespace HyperTwistTrainingPanelWidgetInternal const bool bSecondaryReady ) { - if (bPrimaryReady && bSecondaryReady) - { - return TEXT("ready"); - } - - if (bPrimaryReady || bSecondaryReady) - { - return TEXT("partial"); - } - - return TEXT("missing"); + return HyperTwistTrainingControlSurfaceFormatting::DescribeAggregateReadyState( + bPrimaryReady, + bSecondaryReady); } FString DescribeOwnedContinuityState( @@ -95,17 +103,14 @@ namespace HyperTwistTrainingPanelWidgetInternal const bool bContinuityReady ) { - if (!bOwnershipReady) - { - return TEXT("missing"); - } - - return bContinuityReady ? TEXT("ready") : TEXT("partial"); + return HyperTwistTrainingControlSurfaceFormatting::DescribeOwnedContinuityState( + bOwnershipReady, + bContinuityReady); } FString DescribeIdOrFallback(const FString& Value) { - return !Value.IsEmpty() ? Value : FString(TEXT("n/a")); + return HyperTwistTrainingControlSurfaceFormatting::DescribeIdOrFallback(Value); } FString DescribeKeyForRoster(const FKey& Key) @@ -120,17 +125,16 @@ namespace HyperTwistTrainingPanelWidgetInternal return TEXT("n/a"); } - FString Text = Move.Family; - if (Move.Amount < 0) - { - Text += TEXT("'"); - } - else if (FMath::Abs(Move.Amount) > 1) - { - Text += FString::FromInt(FMath::Abs(Move.Amount)); - } + FHyperTwistAlgorithmNode Node; + Node.NodeType = EHyperTwistAlgorithmNodeType::BlockMove; + Node.BlockMove = Move; - return Text; + FHyperTwistAlgorithmSequence Sequence; + Sequence.Nodes.Add(Node); + + const FString CanonicalText = + UHyperTwistAlgorithmSerializer::SerializeAlgorithm(Sequence); + return !CanonicalText.IsEmpty() ? CanonicalText : TEXT("n/a"); } FString BuildClassicKeyboardMoveRosterLine( @@ -286,6 +290,43 @@ namespace HyperTwistTrainingPanelWidgetInternal return false; } + FViewerCameraSettingsFacts BuildViewerCameraSettingsFacts() + { + FViewerCameraSettingsFacts Facts; + const FHyperTwistTrainingViewerReferenceBundle Bundle = + UHyperTwistTrainingViewerLibrary::BuildBundledBrowserViewerReferenceBundle(); + Facts.bToolReady = + Bundle.IsStructurallyValid() + && TryFindViewerEditorToolById( + Bundle, + TEXT("tool/camera-settings"), + Facts.Tool + ); + if (Facts.bToolReady) + { + FHyperTwistTrainingViewerQaArtifactReference ExportArtifact; + Facts.bExportArtifactReady = TryFindFirstViewerQaArtifactByIds( + Bundle, + Facts.Tool.ExportArtifactIds, + Facts.ExportArtifactId, + ExportArtifact + ); + } + + return Facts; + } + + FImmersiveSessionRecallFacts BuildImmersiveSessionRecallFacts() + { + FImmersiveSessionRecallFacts Facts; + Facts.bReady = + UHyperTwistTrainingRuntimeLibrary::TryGetBundledImmersiveSessionRecallBoundary( + TEXT("immersive-training-session-recall-boundary"), + Facts.Boundary + ) && Facts.Boundary.IsStructurallyValid(); + return Facts; + } + bool AxisConfigEntriesContainToken( const TArray& AxisConfigEntries, const TCHAR* Token @@ -1253,29 +1294,17 @@ UHyperTwistTrainingPanelWidget::GetDisplayedControlInputReadinessInspectSurface( TEXT("immersive-training-presence-control-contract"), PresenceControlContract ); - const FHyperTwistTrainingViewerReferenceBundle ViewerBundle = - UHyperTwistTrainingViewerLibrary::BuildBundledBrowserViewerReferenceBundle(); - FHyperTwistTrainingViewerEditorToolReference CameraSettingsTool; - FHyperTwistTrainingViewerQaArtifactReference CameraExportArtifact; - FString CameraExportArtifactId; + const HyperTwistTrainingPanelWidgetInternal::FViewerCameraSettingsFacts + CameraSettingsFacts = + HyperTwistTrainingPanelWidgetInternal::BuildViewerCameraSettingsFacts(); const bool bCameraSettingsContinuityReady = - ViewerBundle.IsStructurallyValid() - && HyperTwistTrainingPanelWidgetInternal::TryFindViewerEditorToolById( - ViewerBundle, - TEXT("tool/camera-settings"), - CameraSettingsTool - ) && HyperTwistTrainingPanelWidgetInternal::TryFindFirstViewerQaArtifactByIds( - ViewerBundle, - CameraSettingsTool.ExportArtifactIds, - CameraExportArtifactId, - CameraExportArtifact - ); - FHyperTwistTrainingImmersiveSessionRecallBoundary ImmersiveSessionRecallBoundary; + CameraSettingsFacts.bExportArtifactReady; + const FString CameraExportArtifactId = CameraSettingsFacts.ExportArtifactId; + const HyperTwistTrainingPanelWidgetInternal::FImmersiveSessionRecallFacts + ImmersiveSessionRecallFacts = + HyperTwistTrainingPanelWidgetInternal::BuildImmersiveSessionRecallFacts(); const bool bImmersiveSessionRecallReady = - UHyperTwistTrainingRuntimeLibrary::TryGetBundledImmersiveSessionRecallBoundary( - TEXT("immersive-training-session-recall-boundary"), - ImmersiveSessionRecallBoundary - ) && ImmersiveSessionRecallBoundary.IsStructurallyValid(); + ImmersiveSessionRecallFacts.bReady; const bool bBoundedPreferencesContinuityReady = bCameraSettingsContinuityReady && bImmersiveSessionRecallReady; @@ -1347,24 +1376,15 @@ UHyperTwistTrainingPanelWidget::GetDisplayedControlInputReadinessInspectSurface( *HyperTwistTrainingPanelWidgetInternal::DescribeBool( Surface.bImmersivePresenceContractReady) ); - Surface.PreferencesStatusLine = FString::Printf( - TEXT("Preferences continuity: %s | camera export %s | immersive recall %s | recall scopes %d | preference fields %d | polished rebinding and broader control-settings UI are not yet shipped."), - *HyperTwistTrainingPanelWidgetInternal::DescribeAggregateReadyState( + Surface.PreferencesStatusLine = + HyperTwistTrainingControlSurfaceFormatting::BuildControlInputPreferencesStatusLine( bCameraSettingsContinuityReady, - bImmersiveSessionRecallReady), - *HyperTwistTrainingPanelWidgetInternal::DescribeIdOrFallback( - bCameraSettingsContinuityReady ? CameraExportArtifactId : FString()), - *HyperTwistTrainingPanelWidgetInternal::DescribeIdOrFallback( - bImmersiveSessionRecallReady - ? ImmersiveSessionRecallBoundary.BoundaryId - : FString()), - bImmersiveSessionRecallReady - ? ImmersiveSessionRecallBoundary.RecallScopeIds.Num() - : 0, - bImmersiveSessionRecallReady - ? ImmersiveSessionRecallBoundary.PreferenceFieldTags.Num() - : 0 - ); + CameraExportArtifactId, + bImmersiveSessionRecallReady, + ImmersiveSessionRecallFacts.Boundary.BoundaryId, + ImmersiveSessionRecallFacts.Boundary.RecallScopeIds.Num(), + ImmersiveSessionRecallFacts.Boundary.PreferenceFieldTags.Num() + ); Surface.NextPacketLine = HyperTwistTrainingPanelWidgetInternal::BuildControlInputXrBoundaryLine(); Surface.StatusLine = FString::Printf( @@ -1404,36 +1424,23 @@ UHyperTwistTrainingPanelWidget::GetDisplayedControlSettingsOwnershipInspectSurfa FHyperTwistTrainingControlSettingsOwnershipInspectSurface Surface; Surface.Headline = TEXT("Control settings ownership"); - const FHyperTwistTrainingViewerReferenceBundle ViewerBundle = - UHyperTwistTrainingViewerLibrary::BuildBundledBrowserViewerReferenceBundle(); - FHyperTwistTrainingViewerEditorToolReference CameraSettingsTool; - Surface.bCameraSettingsReady = - ViewerBundle.IsStructurallyValid() - && HyperTwistTrainingPanelWidgetInternal::TryFindViewerEditorToolById( - ViewerBundle, - TEXT("tool/camera-settings"), - CameraSettingsTool - ); + const HyperTwistTrainingPanelWidgetInternal::FViewerCameraSettingsFacts + CameraSettingsFacts = + HyperTwistTrainingPanelWidgetInternal::BuildViewerCameraSettingsFacts(); + Surface.bCameraSettingsReady = CameraSettingsFacts.bToolReady; if (Surface.bCameraSettingsReady) { - Surface.CameraSettingsToolId = CameraSettingsTool.ToolId; - Surface.CameraSettingsWorkflowTagCount = CameraSettingsTool.WorkflowTags.Num(); + Surface.CameraSettingsToolId = CameraSettingsFacts.Tool.ToolId; + Surface.CameraSettingsWorkflowTagCount = + CameraSettingsFacts.Tool.WorkflowTags.Num(); Surface.CameraSettingsPreviewStateTagCount = - CameraSettingsTool.PreviewStateTags.Num(); + CameraSettingsFacts.Tool.PreviewStateTags.Num(); Surface.CameraSettingsExportArtifactCount = - CameraSettingsTool.ExportArtifactIds.Num(); + CameraSettingsFacts.Tool.ExportArtifactIds.Num(); } - FHyperTwistTrainingViewerQaArtifactReference CameraExportArtifact; - FString CameraExportArtifactId; Surface.bCameraSettingsContinuityReady = - Surface.bCameraSettingsReady - && HyperTwistTrainingPanelWidgetInternal::TryFindFirstViewerQaArtifactByIds( - ViewerBundle, - CameraSettingsTool.ExportArtifactIds, - CameraExportArtifactId, - CameraExportArtifact - ); - Surface.CameraSettingsExportArtifactId = CameraExportArtifactId; + CameraSettingsFacts.bExportArtifactReady; + Surface.CameraSettingsExportArtifactId = CameraSettingsFacts.ExportArtifactId; FHyperTwistTrainingImmersivePresenceControlContract ImmersivePresenceContract; Surface.bImmersivePresenceSettingsReady = @@ -1447,22 +1454,20 @@ UHyperTwistTrainingPanelWidget::GetDisplayedControlSettingsOwnershipInspectSurfa Surface.ImmersivePresenceSurfaceTagCount = ImmersivePresenceContract.PresenceSurfaceTags.Num(); } - FHyperTwistTrainingImmersiveSessionRecallBoundary ImmersiveSessionRecallBoundary; - Surface.bImmersiveSessionRecallReady = - UHyperTwistTrainingRuntimeLibrary::TryGetBundledImmersiveSessionRecallBoundary( - TEXT("immersive-training-session-recall-boundary"), - ImmersiveSessionRecallBoundary - ) && ImmersiveSessionRecallBoundary.IsStructurallyValid(); + const HyperTwistTrainingPanelWidgetInternal::FImmersiveSessionRecallFacts + ImmersiveSessionRecallFacts = + HyperTwistTrainingPanelWidgetInternal::BuildImmersiveSessionRecallFacts(); + Surface.bImmersiveSessionRecallReady = ImmersiveSessionRecallFacts.bReady; if (Surface.bImmersiveSessionRecallReady) { Surface.ImmersiveSessionRecallBoundaryId = - ImmersiveSessionRecallBoundary.BoundaryId; + ImmersiveSessionRecallFacts.Boundary.BoundaryId; Surface.ImmersiveSessionRecallScopeCount = - ImmersiveSessionRecallBoundary.RecallScopeIds.Num(); + ImmersiveSessionRecallFacts.Boundary.RecallScopeIds.Num(); Surface.ImmersiveSessionRecallPreferenceFieldTagCount = - ImmersiveSessionRecallBoundary.PreferenceFieldTags.Num(); + ImmersiveSessionRecallFacts.Boundary.PreferenceFieldTags.Num(); Surface.ImmersiveSessionRecallResetSurfaceTagCount = - ImmersiveSessionRecallBoundary.ResetSurfaceTags.Num(); + ImmersiveSessionRecallFacts.Boundary.ResetSurfaceTags.Num(); } FHyperTwistTrainingHigherDimensionalRuntimeViewContextSurface Magic120CellViewContextSurface; @@ -1622,8 +1627,6 @@ UHyperTwistTrainingPanelWidget::GetDisplayedControlSettingsOwnershipInspectSurfa Surface.bRequiresWindowsPackagedControllerValidationForReopen = XrBoundaryFacts.bRequiresWindowsPackagedControllerValidationForReopen; - const FString CameraSettingsToolId = - !Surface.CameraSettingsToolId.IsEmpty() ? Surface.CameraSettingsToolId : TEXT("n/a"); const FString ActiveViewContextId = !Surface.ActiveHigherDimensionalViewContextId.IsEmpty() ? Surface.ActiveHigherDimensionalViewContextId @@ -1682,51 +1685,32 @@ UHyperTwistTrainingPanelWidget::GetDisplayedControlSettingsOwnershipInspectSurfa const bool bMagicCube5DOwnedSettingsReady = Surface.bMagicCube5DViewSettingsReady && Surface.bMagicCube5DPersistenceSettingsReady; - const bool bCameraSettingsOwnedContinuityReady = - Surface.bCameraSettingsReady && Surface.bCameraSettingsContinuityReady; - const bool bImmersiveOwnedContinuityReady = - Surface.bImmersivePresenceSettingsReady - && Surface.bImmersiveSessionRecallReady; - const FString DisplayCameraExportArtifactId = - !Surface.CameraSettingsExportArtifactId.IsEmpty() - ? Surface.CameraSettingsExportArtifactId - : TEXT("n/a"); - const FString ImmersivePresenceContractId = - !Surface.ImmersivePresenceContractId.IsEmpty() - ? Surface.ImmersivePresenceContractId - : TEXT("n/a"); - const FString ImmersiveSessionRecallBoundaryId = - !Surface.ImmersiveSessionRecallBoundaryId.IsEmpty() - ? Surface.ImmersiveSessionRecallBoundaryId - : TEXT("n/a"); Surface.SummaryLine = TEXT("Camera, immersive, and dedicated-family projection, selector, continuity, and persistence settings are already first-party owned, while XR/controller rebinding still remains unfinished."); - Surface.CameraSettingsLine = FString::Printf( - TEXT("Viewer camera settings: %s | tool %s | camera export %s | workflow tags %d | preview states %d | export artifacts %d | orbit/framing/export surface is owned."), - *HyperTwistTrainingPanelWidgetInternal::DescribeOwnedContinuityState( + Surface.CameraSettingsLine = + HyperTwistTrainingControlSurfaceFormatting::BuildControlSettingsCameraSettingsLine( Surface.bCameraSettingsReady, - Surface.bCameraSettingsContinuityReady), - *CameraSettingsToolId, - *DisplayCameraExportArtifactId, - Surface.CameraSettingsWorkflowTagCount, - Surface.CameraSettingsPreviewStateTagCount, - Surface.CameraSettingsExportArtifactCount - ); - Surface.ImmersiveSettingsLine = FString::Printf( - TEXT("Immersive presence settings: %s | contract %s | session recall %s | intensity presets %d | reduced-distraction presets %d | presence tags %d | recall scopes %d | preference fields %d | reset surfaces %d."), - *HyperTwistTrainingPanelWidgetInternal::DescribeOwnedContinuityState( + Surface.bCameraSettingsContinuityReady, + Surface.CameraSettingsToolId, + Surface.CameraSettingsExportArtifactId, + Surface.CameraSettingsWorkflowTagCount, + Surface.CameraSettingsPreviewStateTagCount, + Surface.CameraSettingsExportArtifactCount + ); + Surface.ImmersiveSettingsLine = + HyperTwistTrainingControlSurfaceFormatting::BuildControlSettingsImmersiveSettingsLine( Surface.bImmersivePresenceSettingsReady, - Surface.bImmersiveSessionRecallReady), - *ImmersivePresenceContractId, - *ImmersiveSessionRecallBoundaryId, - ImmersivePresenceContract.ImmersionIntensityIds.Num(), - ImmersivePresenceContract.ReducedDistractionPresetIds.Num(), - Surface.ImmersivePresenceSurfaceTagCount, - Surface.ImmersiveSessionRecallScopeCount, - Surface.ImmersiveSessionRecallPreferenceFieldTagCount, - Surface.ImmersiveSessionRecallResetSurfaceTagCount - ); + Surface.bImmersiveSessionRecallReady, + Surface.ImmersivePresenceContractId, + Surface.ImmersiveSessionRecallBoundaryId, + ImmersivePresenceContract.ImmersionIntensityIds.Num(), + ImmersivePresenceContract.ReducedDistractionPresetIds.Num(), + Surface.ImmersivePresenceSurfaceTagCount, + Surface.ImmersiveSessionRecallScopeCount, + Surface.ImmersiveSessionRecallPreferenceFieldTagCount, + Surface.ImmersiveSessionRecallResetSurfaceTagCount + ); Surface.Magic120CellSettingsLine = FString::Printf( TEXT("Magic120Cell owned settings: %s | profile %s | session %s | scene %s | persistence %s | semantics %s | selectors %d | projection tags %d | symmetry presets %d | visibility presets %d | focus surfaces %d."), *HyperTwistTrainingPanelWidgetInternal::DescribeReadyState( @@ -1774,19 +1758,17 @@ UHyperTwistTrainingPanelWidget::GetDisplayedControlSettingsOwnershipInspectSurfa HyperTwistTrainingPanelWidgetInternal::BuildControlSettingsXrBoundaryLine( Surface.bOpenXrProjectPluginEnabled ); - Surface.StatusLine = FString::Printf( - TEXT("camera %s | immersive %s | 120-cell owned settings %s | 5D owned settings %s | selectors %s | selector recall %s | XR rebinding not yet shipped"), - *HyperTwistTrainingPanelWidgetInternal::DescribeOwnedContinuityState( + Surface.StatusLine = + HyperTwistTrainingControlSurfaceFormatting::BuildControlSettingsStatusLine( Surface.bCameraSettingsReady, - Surface.bCameraSettingsContinuityReady), - *HyperTwistTrainingPanelWidgetInternal::DescribeOwnedContinuityState( + Surface.bCameraSettingsContinuityReady, Surface.bImmersivePresenceSettingsReady, - Surface.bImmersiveSessionRecallReady), - bMagic120CellOwnedSettingsReady ? TEXT("ready") : TEXT("partial"), - bMagicCube5DOwnedSettingsReady ? TEXT("ready") : TEXT("partial"), - Surface.bHigherDimensionalSelectorSettingsReady ? TEXT("ready") : TEXT("partial"), - Surface.bRepositoryBackedSelectorRecallReady ? TEXT("ready") : TEXT("unavailable") - ); + Surface.bImmersiveSessionRecallReady, + bMagic120CellOwnedSettingsReady, + bMagicCube5DOwnedSettingsReady, + Surface.bHigherDimensionalSelectorSettingsReady, + Surface.bRepositoryBackedSelectorRecallReady + ); Surface.DetailLine = FString::Printf( TEXT("%s | %s | %s | %s | %s | %s | %s"), *Surface.CameraSettingsLine, @@ -1827,6 +1809,25 @@ UHyperTwistTrainingPanelWidget::GetDisplayedControlProfileRosterInspectSurface() Surface.ReducedDistractionPresetCount = PresenceContract.ReducedDistractionPresetIds.Num(); } + const HyperTwistTrainingPanelWidgetInternal::FViewerCameraSettingsFacts + CameraSettingsFacts = + HyperTwistTrainingPanelWidgetInternal::BuildViewerCameraSettingsFacts(); + Surface.bCameraSettingsContinuityReady = + CameraSettingsFacts.bExportArtifactReady; + Surface.CameraSettingsExportArtifactId = CameraSettingsFacts.ExportArtifactId; + const HyperTwistTrainingPanelWidgetInternal::FImmersiveSessionRecallFacts + ImmersiveSessionRecallFacts = + HyperTwistTrainingPanelWidgetInternal::BuildImmersiveSessionRecallFacts(); + Surface.bImmersiveSessionRecallReady = ImmersiveSessionRecallFacts.bReady; + if (Surface.bImmersiveSessionRecallReady) + { + Surface.ImmersiveSessionRecallBoundaryId = + ImmersiveSessionRecallFacts.Boundary.BoundaryId; + Surface.ImmersiveSessionRecallScopeCount = + ImmersiveSessionRecallFacts.Boundary.RecallScopeIds.Num(); + Surface.ImmersiveSessionRecallPreferenceFieldTagCount = + ImmersiveSessionRecallFacts.Boundary.PreferenceFieldTags.Num(); + } const FHyperTwistTrainingMagic120CellReferenceBundle Magic120CellBundle = UHyperTwistTrainingRuntimeLibrary::GetBundledMagic120CellReferenceBundle(); @@ -1900,6 +1901,10 @@ UHyperTwistTrainingPanelWidget::GetDisplayedControlProfileRosterInspectSurface() HasDisplayedHigherDimensionalRuntimeSessionSurface() ? GetDisplayedHigherDimensionalRuntimeSessionSurface() : FHyperTwistTrainingHigherDimensionalRuntimeSessionSurface(); + const FHyperTwistTrainingHigherDimensionalInteractiveSceneSurface ActiveSceneSurface = + HasDisplayedHigherDimensionalInteractiveSceneSurface() + ? GetDisplayedHigherDimensionalInteractiveSceneSurface() + : FHyperTwistTrainingHigherDimensionalInteractiveSceneSurface(); Surface.bActiveHigherDimensionalProfileVisible = ActiveActivationProfile.IsStructurallyValid(); Surface.ActiveHigherDimensionalActivationProfileId = Surface.bActiveHigherDimensionalProfileVisible @@ -1911,6 +1916,10 @@ UHyperTwistTrainingPanelWidget::GetDisplayedControlProfileRosterInspectSurface() Surface.ActiveHigherDimensionalSessionSurfaceId = ActiveSessionSurface.IsStructurallyValid() ? ActiveSessionSurface.SessionSurfaceId : TEXT("none"); + Surface.ActiveHigherDimensionalInteractiveSceneSurfaceId = + ActiveSceneSurface.IsStructurallyValid() + ? ActiveSceneSurface.SceneSurfaceId + : TEXT("none"); Surface.ActiveHigherDimensionalSelectorCount = ActiveViewContextSurface.IsStructurallyValid() ? ActiveViewContextSurface.Selectors.Num() : 0; @@ -1975,9 +1984,12 @@ UHyperTwistTrainingPanelWidget::GetDisplayedControlProfileRosterInspectSurface() !Surface.ActiveHigherDimensionalSessionSurfaceId.IsEmpty() ? Surface.ActiveHigherDimensionalSessionSurfaceId : TEXT("none"); - + const FString ActiveSceneSurfaceId = + !Surface.ActiveHigherDimensionalInteractiveSceneSurfaceId.IsEmpty() + ? Surface.ActiveHigherDimensionalInteractiveSceneSurfaceId + : 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."); + TEXT("The shipped selectable roster currently covers the classic keyboard mapping, scenic immersive presets, bounded camera or immersive continuity, 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, @@ -2022,10 +2034,11 @@ UHyperTwistTrainingPanelWidget::GetDisplayedControlProfileRosterInspectSurface() Surface.ActiveHigherDimensionalProfileLine = Surface.bActiveHigherDimensionalProfileVisible ? FString::Printf( - TEXT("Active higher-dimensional selection: activation %s | view context %s | session %s | visible selectors %d."), + TEXT("Active higher-dimensional selection: activation %s | view context %s | session %s | scene %s | visible selectors %d."), *ActiveActivationProfileId, *ActiveViewContextId, *ActiveSessionSurfaceId, + *ActiveSceneSurfaceId, Surface.ActiveHigherDimensionalSelectorCount ) : TEXT("Active higher-dimensional selection: none currently displayed in this widget."); @@ -2033,21 +2046,32 @@ UHyperTwistTrainingPanelWidget::GetDisplayedControlProfileRosterInspectSurface() HyperTwistTrainingPanelWidgetInternal::BuildSelectorRecallLine( SelectorRecallFacts ); + Surface.PreferencesContinuityLine = + HyperTwistTrainingControlSurfaceFormatting::BuildControlProfilePreferencesContinuityLine( + Surface.bCameraSettingsContinuityReady, + Surface.CameraSettingsExportArtifactId, + Surface.bImmersiveSessionRecallReady, + Surface.ImmersiveSessionRecallBoundaryId, + Surface.ImmersiveSessionRecallScopeCount, + Surface.ImmersiveSessionRecallPreferenceFieldTagCount + ); Surface.PreferencesGapLine = HyperTwistTrainingPanelWidgetInternal::BuildControlProfileRosterXrBoundaryLine( Surface.bOpenXrProjectPluginEnabled ); - Surface.StatusLine = FString::Printf( - TEXT("classic keyboard %s | immersive presets %s | 120-cell family %s | 5D family %s | active selection %s | selector recall %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.bRepositoryBackedSelectorRecallReady ? TEXT("ready") : TEXT("unavailable") - ); + Surface.StatusLine = + HyperTwistTrainingControlSurfaceFormatting::BuildControlProfileStatusLine( + Surface.bClassicKeyboardProfileReady, + Surface.bImmersivePresenceProfileReady, + Surface.bMagic120CellProfileReady, + Surface.bMagicCube5DProfileReady, + Surface.bActiveHigherDimensionalProfileVisible, + Surface.bRepositoryBackedSelectorRecallReady, + Surface.bCameraSettingsContinuityReady, + Surface.bImmersiveSessionRecallReady + ); Surface.DetailLine = FString::Printf( - TEXT("%s | %s | %s | %s | %s | %s | %s | %s"), + TEXT("%s | %s | %s | %s | %s | %s | %s | %s | %s"), *Surface.ClassicKeyboardProfileLine, *Surface.ClassicKeyboardMoveRosterLine, *Surface.ImmersivePresenceProfileLine, @@ -2055,6 +2079,7 @@ UHyperTwistTrainingPanelWidget::GetDisplayedControlProfileRosterInspectSurface() *Surface.MagicCube5DProfileLine, *Surface.ActiveHigherDimensionalProfileLine, *Surface.SelectorRecallLine, + *Surface.PreferencesContinuityLine, *Surface.PreferencesGapLine ); diff --git a/UnrealHyperTwist/Source/UnrealHyperTwist/Public/HyperTwistTraining/HyperTwistTrainingTypes.h b/UnrealHyperTwist/Source/UnrealHyperTwist/Public/HyperTwistTraining/HyperTwistTrainingTypes.h index de125b4..1b34481 100644 --- a/UnrealHyperTwist/Source/UnrealHyperTwist/Public/HyperTwistTraining/HyperTwistTrainingTypes.h +++ b/UnrealHyperTwist/Source/UnrealHyperTwist/Public/HyperTwistTraining/HyperTwistTrainingTypes.h @@ -10353,6 +10353,9 @@ struct FHyperTwistTrainingControlProfileRosterInspectSurface UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist") FString SelectorRecallLine; + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist") + FString PreferencesContinuityLine; + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist") FString PreferencesGapLine; @@ -10365,6 +10368,12 @@ struct FHyperTwistTrainingControlProfileRosterInspectSurface UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist") FString ImmersivePresenceContractId; + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist") + FString CameraSettingsExportArtifactId; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist") + FString ImmersiveSessionRecallBoundaryId; + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist") FString Magic120CellRuntimeProfileContractId; @@ -10386,6 +10395,9 @@ struct FHyperTwistTrainingControlProfileRosterInspectSurface UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist") FString ActiveHigherDimensionalSessionSurfaceId; + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist") + FString ActiveHigherDimensionalInteractiveSceneSurfaceId; + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist") int32 ClassicKeyboardBindingCount = 0; @@ -10407,12 +10419,24 @@ struct FHyperTwistTrainingControlProfileRosterInspectSurface UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist") int32 RecalledHigherDimensionalSelectorCount = 0; + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist") + int32 ImmersiveSessionRecallScopeCount = 0; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist") + int32 ImmersiveSessionRecallPreferenceFieldTagCount = 0; + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist") bool bClassicKeyboardProfileReady = false; UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist") bool bImmersivePresenceProfileReady = false; + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist") + bool bCameraSettingsContinuityReady = false; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist") + bool bImmersiveSessionRecallReady = false; + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist") bool bMagic120CellProfileReady = false; @@ -10454,8 +10478,11 @@ struct FHyperTwistTrainingControlProfileRosterInspectSurface || !MagicCube5DProfileLine.IsEmpty() || !ActiveHigherDimensionalProfileLine.IsEmpty() || !SelectorRecallLine.IsEmpty() + || !PreferencesContinuityLine.IsEmpty() || bClassicKeyboardProfileReady || bImmersivePresenceProfileReady + || bCameraSettingsContinuityReady + || bImmersiveSessionRecallReady || bMagic120CellProfileReady || bMagicCube5DProfileReady || bActiveHigherDimensionalProfileVisible diff --git a/UnrealHyperTwist/Source/UnrealHyperTwist/Tests/HyperTwistControlProfileContinuityParityTest.cpp b/UnrealHyperTwist/Source/UnrealHyperTwist/Tests/HyperTwistControlProfileContinuityParityTest.cpp new file mode 100644 index 0000000..e827bb4 --- /dev/null +++ b/UnrealHyperTwist/Source/UnrealHyperTwist/Tests/HyperTwistControlProfileContinuityParityTest.cpp @@ -0,0 +1,492 @@ +// Copyright HyperTwist, Inc. All Rights Reserved. + +#include "Misc/AutomationTest.h" + +#include "Blueprint/WidgetTree.h" +#include "Components/TextBlock.h" +#include "HyperTwistTraining/HyperTwistCoachDashboardWidget.h" +#include "HyperTwistTraining/HyperTwistTrainingControlSurfaceFormatting.h" +#include "HyperTwistTraining/HyperTwistTrainingPanelWidget.h" +#include "HyperTwistTraining/HyperTwistTrainingRuntimeLibrary.h" + +#if WITH_AUTOMATION_TESTS + +namespace HyperTwistControlProfileContinuityParityTestInternal +{ + UTextBlock* FindDashboardTextBlock( + const UHyperTwistCoachDashboardWidget* CoachDashboard, + const TCHAR* WidgetName + ) + { + if (CoachDashboard == nullptr) + { + return nullptr; + } + + UWidgetTree* WidgetTree = CoachDashboard->WidgetTree; + if (WidgetTree == nullptr) + { + return nullptr; + } + + return Cast(WidgetTree->FindWidget(FName(WidgetName))); + } +} + +IMPLEMENT_SIMPLE_AUTOMATION_TEST( + FHyperTwistControlInputContinuityStateFormattingTest, + "HyperTwist.Browser.ControlInputContinuityStateFormatting", + EAutomationTestFlags::EditorContext | EAutomationTestFlags::EngineFilter +) + +bool FHyperTwistControlInputContinuityStateFormattingTest::RunTest( + const FString& Parameters +) +{ + const FString MissingLine = + HyperTwistTrainingControlSurfaceFormatting::BuildControlInputPreferencesStatusLine( + false, + FString(), + false, + FString(), + 7, + 9 + ); + TestTrue( + TEXT("The control/input continuity formatter must render a fully absent continuity lane as missing with explicit fallback ids and zero recall counts."), + MissingLine.Contains(TEXT("Preferences continuity: missing")) + && MissingLine.Contains(TEXT("camera export n/a")) + && MissingLine.Contains(TEXT("immersive recall n/a")) + && MissingLine.Contains(TEXT("recall scopes 0")) + && MissingLine.Contains(TEXT("preference fields 0")) + ); + + const FString PartialLine = + HyperTwistTrainingControlSurfaceFormatting::BuildControlInputPreferencesStatusLine( + true, + TEXT("artifact/camera-export-json"), + false, + FString(), + 7, + 9 + ); + TestTrue( + TEXT("The control/input continuity formatter must render a one-sided continuity lane as partial while preserving the ready id and withholding the missing one."), + PartialLine.Contains(TEXT("Preferences continuity: partial")) + && PartialLine.Contains(TEXT("camera export artifact/camera-export-json")) + && PartialLine.Contains(TEXT("immersive recall n/a")) + && PartialLine.Contains(TEXT("recall scopes 0")) + && PartialLine.Contains(TEXT("preference fields 0")) + ); + + const FString ReadyLine = + HyperTwistTrainingControlSurfaceFormatting::BuildControlInputPreferencesStatusLine( + true, + TEXT("artifact/camera-export-json"), + true, + TEXT("immersive-training-session-recall-boundary"), + 3, + 5 + ); + TestTrue( + TEXT("The control/input continuity formatter must render a fully ready continuity lane with the shipped ids and live recall counts."), + ReadyLine.Contains(TEXT("Preferences continuity: ready")) + && ReadyLine.Contains(TEXT("camera export artifact/camera-export-json")) + && ReadyLine.Contains(TEXT("immersive recall immersive-training-session-recall-boundary")) + && ReadyLine.Contains(TEXT("recall scopes 3")) + && ReadyLine.Contains(TEXT("preference fields 5")) + ); + + return true; +} + +IMPLEMENT_SIMPLE_AUTOMATION_TEST( + FHyperTwistControlSettingsContinuityStateFormattingTest, + "HyperTwist.Browser.ControlSettingsContinuityStateFormatting", + EAutomationTestFlags::EditorContext | EAutomationTestFlags::EngineFilter +) + +bool FHyperTwistControlSettingsContinuityStateFormattingTest::RunTest( + const FString& Parameters +) +{ + const FString MissingCameraLine = + HyperTwistTrainingControlSurfaceFormatting::BuildControlSettingsCameraSettingsLine( + false, + false, + TEXT("tool/camera-settings"), + TEXT("artifact/camera-export-json"), + 3, + 2, + 1 + ); + TestTrue( + TEXT("The control/settings camera continuity formatter must render a fully absent camera lane as missing with fallback ids and zero out stale tool counts."), + MissingCameraLine.Contains(TEXT("Viewer camera settings: missing")) + && MissingCameraLine.Contains(TEXT("tool n/a")) + && MissingCameraLine.Contains(TEXT("camera export n/a")) + && MissingCameraLine.Contains(TEXT("workflow tags 0")) + && MissingCameraLine.Contains(TEXT("preview states 0")) + && MissingCameraLine.Contains(TEXT("export artifacts 0")) + ); + + const FString PartialCameraLine = + HyperTwistTrainingControlSurfaceFormatting::BuildControlSettingsCameraSettingsLine( + true, + false, + TEXT("tool/camera-settings"), + FString(), + 3, + 2, + 1 + ); + TestTrue( + TEXT("The control/settings camera continuity formatter must render owned-but-not-continuous camera state as partial."), + PartialCameraLine.Contains(TEXT("Viewer camera settings: partial")) + && PartialCameraLine.Contains(TEXT("tool tool/camera-settings")) + && PartialCameraLine.Contains(TEXT("camera export n/a")) + ); + + const FString ReadyCameraLine = + HyperTwistTrainingControlSurfaceFormatting::BuildControlSettingsCameraSettingsLine( + true, + true, + TEXT("tool/camera-settings"), + TEXT("artifact/camera-export-json"), + 3, + 2, + 1 + ); + TestTrue( + TEXT("The control/settings camera continuity formatter must render a fully ready camera lane with the shipped export id."), + ReadyCameraLine.Contains(TEXT("Viewer camera settings: ready")) + && ReadyCameraLine.Contains(TEXT("tool tool/camera-settings")) + && ReadyCameraLine.Contains(TEXT("camera export artifact/camera-export-json")) + ); + + const FString MissingImmersiveLine = + HyperTwistTrainingControlSurfaceFormatting::BuildControlSettingsImmersiveSettingsLine( + false, + false, + TEXT("immersive-training-presence-control-contract"), + TEXT("immersive-training-session-recall-boundary"), + 3, + 3, + 4, + 7, + 9, + 11 + ); + TestTrue( + TEXT("The control/settings immersive continuity formatter must render a fully absent immersive lane as missing with fallback ids and zero out stale presence and recall counts."), + MissingImmersiveLine.Contains(TEXT("Immersive presence settings: missing")) + && MissingImmersiveLine.Contains(TEXT("contract n/a")) + && MissingImmersiveLine.Contains(TEXT("session recall n/a")) + && MissingImmersiveLine.Contains(TEXT("intensity presets 0")) + && MissingImmersiveLine.Contains(TEXT("reduced-distraction presets 0")) + && MissingImmersiveLine.Contains(TEXT("presence tags 0")) + && MissingImmersiveLine.Contains(TEXT("recall scopes 0")) + && MissingImmersiveLine.Contains(TEXT("preference fields 0")) + && MissingImmersiveLine.Contains(TEXT("reset surfaces 0")) + ); + + const FString PartialImmersiveLine = + HyperTwistTrainingControlSurfaceFormatting::BuildControlSettingsImmersiveSettingsLine( + true, + false, + TEXT("immersive-training-presence-control-contract"), + FString(), + 3, + 3, + 4, + 7, + 9, + 11 + ); + TestTrue( + TEXT("The control/settings immersive continuity formatter must render owned-but-not-recalled immersive state as partial while masking stale recall counts."), + PartialImmersiveLine.Contains(TEXT("Immersive presence settings: partial")) + && PartialImmersiveLine.Contains(TEXT("contract immersive-training-presence-control-contract")) + && PartialImmersiveLine.Contains(TEXT("session recall n/a")) + && PartialImmersiveLine.Contains(TEXT("recall scopes 0")) + && PartialImmersiveLine.Contains(TEXT("preference fields 0")) + && PartialImmersiveLine.Contains(TEXT("reset surfaces 0")) + ); + + const FString ReadyImmersiveLine = + HyperTwistTrainingControlSurfaceFormatting::BuildControlSettingsImmersiveSettingsLine( + true, + true, + TEXT("immersive-training-presence-control-contract"), + TEXT("immersive-training-session-recall-boundary"), + 3, + 3, + 4, + 3, + 5, + 3 + ); + TestTrue( + TEXT("The control/settings immersive continuity formatter must render a fully ready immersive lane with the shipped recall id and counts."), + ReadyImmersiveLine.Contains(TEXT("Immersive presence settings: ready")) + && ReadyImmersiveLine.Contains(TEXT("contract immersive-training-presence-control-contract")) + && ReadyImmersiveLine.Contains(TEXT("session recall immersive-training-session-recall-boundary")) + && ReadyImmersiveLine.Contains(TEXT("recall scopes 3")) + && ReadyImmersiveLine.Contains(TEXT("preference fields 5")) + ); + + const FString MixedStatusLine = + HyperTwistTrainingControlSurfaceFormatting::BuildControlSettingsStatusLine( + false, + false, + true, + false, + true, + false, + false, + false + ); + TestTrue( + TEXT("The control/settings status formatter must keep mixed missing-versus-partial continuity truth explicit instead of collapsing it into one generic degraded label."), + MixedStatusLine.Contains(TEXT("camera missing")) + && MixedStatusLine.Contains(TEXT("immersive partial")) + && MixedStatusLine.Contains(TEXT("120-cell owned settings ready")) + && MixedStatusLine.Contains(TEXT("5D owned settings partial")) + && MixedStatusLine.Contains(TEXT("selectors partial")) + && MixedStatusLine.Contains(TEXT("selector recall unavailable")) + ); + + return true; +} + +IMPLEMENT_SIMPLE_AUTOMATION_TEST( + FHyperTwistControlProfileContinuityStateFormattingTest, + "HyperTwist.Browser.ControlProfileContinuityStateFormatting", + EAutomationTestFlags::EditorContext | EAutomationTestFlags::EngineFilter +) + +bool FHyperTwistControlProfileContinuityStateFormattingTest::RunTest( + const FString& Parameters +) +{ + const FString MissingContinuityLine = + HyperTwistTrainingControlSurfaceFormatting::BuildControlProfilePreferencesContinuityLine( + false, + FString(), + false, + FString(), + 0, + 0 + ); + TestTrue( + TEXT("The control/profile continuity formatter must render a fully absent continuity lane as missing with fallback ids."), + MissingContinuityLine.Contains(TEXT("Profile continuity: missing")) + && MissingContinuityLine.Contains(TEXT("camera export n/a")) + && MissingContinuityLine.Contains(TEXT("immersive recall n/a")) + ); + + const FString PartialContinuityLine = + HyperTwistTrainingControlSurfaceFormatting::BuildControlProfilePreferencesContinuityLine( + true, + TEXT("artifact/camera-export-json"), + false, + FString(), + 7, + 9 + ); + TestTrue( + TEXT("The control/profile continuity formatter must render a one-sided continuity lane as partial while preserving the ready id and masking stale recall counts."), + PartialContinuityLine.Contains(TEXT("Profile continuity: partial")) + && PartialContinuityLine.Contains(TEXT("camera export artifact/camera-export-json")) + && PartialContinuityLine.Contains(TEXT("immersive recall n/a")) + && PartialContinuityLine.Contains(TEXT("recall scopes 0")) + && PartialContinuityLine.Contains(TEXT("preference fields 0")) + ); + + const FString ReadyContinuityLine = + HyperTwistTrainingControlSurfaceFormatting::BuildControlProfilePreferencesContinuityLine( + true, + TEXT("artifact/camera-export-json"), + true, + TEXT("immersive-training-session-recall-boundary"), + 3, + 5 + ); + TestTrue( + TEXT("The control/profile continuity formatter must render a fully ready continuity lane with the shipped ids and counts."), + ReadyContinuityLine.Contains(TEXT("Profile continuity: ready")) + && ReadyContinuityLine.Contains(TEXT("camera export artifact/camera-export-json")) + && ReadyContinuityLine.Contains(TEXT("immersive recall immersive-training-session-recall-boundary")) + && ReadyContinuityLine.Contains(TEXT("recall scopes 3")) + && ReadyContinuityLine.Contains(TEXT("preference fields 5")) + ); + + const FString MixedStatusLine = + HyperTwistTrainingControlSurfaceFormatting::BuildControlProfileStatusLine( + true, + true, + true, + true, + false, + false, + true, + false + ); + TestTrue( + TEXT("The control/profile status formatter must keep partial continuity truth explicit alongside unloaded active-selection and unavailable selector-recall posture."), + MixedStatusLine.Contains(TEXT("classic keyboard ready")) + && MixedStatusLine.Contains(TEXT("active selection not loaded")) + && MixedStatusLine.Contains(TEXT("selector recall unavailable")) + && MixedStatusLine.Contains(TEXT("profile continuity partial")) + ); + + return true; +} + +IMPLEMENT_SIMPLE_AUTOMATION_TEST( + FHyperTwistTrainingPanelControlProfileContinuityParityTest, + "HyperTwist.Browser.TrainingPanel.ControlProfileContinuityParity", + EAutomationTestFlags::EditorContext | EAutomationTestFlags::EngineFilter +) + +bool FHyperTwistTrainingPanelControlProfileContinuityParityTest::RunTest( + const FString& Parameters +) +{ + UHyperTwistTrainingPanelWidget* TrainingPanel = NewObject(); + 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 keep bounded camera and immersive continuity explicit in structured form."), + Surface.bCameraSettingsContinuityReady + && Surface.CameraSettingsExportArtifactId + == TEXT("artifact/camera-export-json") + && Surface.bImmersiveSessionRecallReady + && Surface.ImmersiveSessionRecallBoundaryId + == TEXT("immersive-training-session-recall-boundary") + && Surface.ImmersiveSessionRecallScopeCount == 3 + && Surface.ImmersiveSessionRecallPreferenceFieldTagCount == 5 + ); + TestTrue( + TEXT("The control/profile roster surface must keep the bounded continuity ids visible in the rendered detail line."), + Surface.PreferencesContinuityLine.Contains(TEXT("artifact/camera-export-json")) + && Surface.PreferencesContinuityLine.Contains( + TEXT("immersive-training-session-recall-boundary")) + && Surface.DetailLine.Contains(TEXT("artifact/camera-export-json")) + && Surface.DetailLine.Contains( + TEXT("immersive-training-session-recall-boundary")) + ); + + FHyperTwistTrainingHigherDimensionalRuntimeActivationProfile ActiveActivationProfile; + FHyperTwistTrainingHigherDimensionalRuntimeViewContextSurface ActiveViewContextSurface; + FHyperTwistTrainingHigherDimensionalRuntimeSessionSurface ActiveSessionSurface; + FHyperTwistTrainingHigherDimensionalInteractiveSceneSurface ActiveSceneSurface; + const bool bLoadedActiveSelection = + UHyperTwistTrainingRuntimeLibrary::TryGetBundledHigherDimensionalRuntimeActivationProfileById( + TEXT("magic120cell-cleanroom-runtime-activation"), + ActiveActivationProfile + ) && UHyperTwistTrainingRuntimeLibrary::TryGetBundledHigherDimensionalRuntimeViewContextSurfaceByActivationProfileId( + TEXT("magic120cell-cleanroom-runtime-activation"), + ActiveViewContextSurface + ) && UHyperTwistTrainingRuntimeLibrary::TryGetBundledHigherDimensionalRuntimeSessionSurfaceByActivationProfileId( + TEXT("magic120cell-cleanroom-runtime-activation"), + ActiveSessionSurface + ) && UHyperTwistTrainingRuntimeLibrary::TryGetBundledHigherDimensionalInteractiveSceneSurfaceByActivationProfileId( + TEXT("magic120cell-cleanroom-runtime-activation"), + ActiveSceneSurface + ); + TestTrue( + TEXT("The control/profile roster active-selection proof must be able to load the bundled dedicated-family activation, session, and scene surfaces."), + bLoadedActiveSelection + ); + if (bLoadedActiveSelection) + { + TrainingPanel->CachedHigherDimensionalRuntimeActivationProfile = + ActiveActivationProfile; + TrainingPanel->CachedHigherDimensionalRuntimeViewContextSurface = + ActiveViewContextSurface; + TrainingPanel->CachedHigherDimensionalRuntimeSessionSurface = + ActiveSessionSurface; + TrainingPanel->CachedHigherDimensionalInteractiveSceneSurface = + ActiveSceneSurface; + const FHyperTwistTrainingControlProfileRosterInspectSurface ActiveSurface = + TrainingPanel->GetDisplayedControlProfileRosterInspectSurface(); + TestEqual( + TEXT("The control/profile roster surface must keep the active higher-dimensional scene surface id in structured form."), + ActiveSurface.ActiveHigherDimensionalInteractiveSceneSurfaceId, + TEXT("phase6c/magic120cell/interactive-scene-surface") + ); + TestTrue( + TEXT("The control/profile roster surface must keep the active higher-dimensional scene surface visible in the rendered detail line."), + ActiveSurface.ActiveHigherDimensionalProfileLine.Contains( + TEXT("phase6c/magic120cell/interactive-scene-surface")) + ); + } + + return true; +} + +IMPLEMENT_SIMPLE_AUTOMATION_TEST( + FHyperTwistCoachDashboardControlProfileContinuityArtifactsTest, + "HyperTwist.Browser.CoachDashboard.ControlProfileContinuityArtifacts", + EAutomationTestFlags::EditorContext | EAutomationTestFlags::EngineFilter +) + +bool FHyperTwistCoachDashboardControlProfileContinuityArtifactsTest::RunTest( + const FString& Parameters +) +{ + UHyperTwistCoachDashboardWidget* CoachDashboard = NewObject(); + TestNotNull(TEXT("The coach dashboard widget must be constructible."), CoachDashboard); + if (CoachDashboard == nullptr) + { + return false; + } + + CoachDashboard->TakeWidget(); + CoachDashboard->RefreshCoachDashboardView(); + + const FHyperTwistTrainingControlProfileRosterInspectSurface Surface = + CoachDashboard->GetDisplayedControlProfileRosterInspectSurface(); + TestTrue( + TEXT("The coach dashboard control/profile roster surface must retain the bounded continuity ids in its detail line."), + Surface.DetailLine.Contains(TEXT("artifact/camera-export-json")) + && Surface.DetailLine.Contains( + TEXT("immersive-training-session-recall-boundary")) + ); + + UTextBlock* PreferencesContinuityTextBlock = + HyperTwistControlProfileContinuityParityTestInternal::FindDashboardTextBlock( + CoachDashboard, + TEXT("CoachControlProfileRosterPreferencesContinuity") + ); + TestNotNull( + TEXT("The coach dashboard must build the structured preferences-continuity roster row."), + PreferencesContinuityTextBlock + ); + if (PreferencesContinuityTextBlock != nullptr) + { + TestEqual( + TEXT("The structured preferences-continuity roster row must mirror the inspect surface."), + PreferencesContinuityTextBlock->GetText().ToString(), + Surface.PreferencesContinuityLine + ); + TestTrue( + TEXT("The structured preferences-continuity roster row must expose the shipped camera-export and immersive recall ids."), + PreferencesContinuityTextBlock->GetText().ToString().Contains( + TEXT("artifact/camera-export-json")) + && PreferencesContinuityTextBlock->GetText().ToString().Contains( + TEXT("immersive-training-session-recall-boundary")) + ); + } + + return true; +} + +#endif diff --git a/docs/ops/HYPERTWIST_OVERNIGHT_MODE_CLOSEOUT_CONTINUATION_AND_BOUNDARY_SHAPE_2026-06-19.md b/docs/ops/HYPERTWIST_OVERNIGHT_MODE_CLOSEOUT_CONTINUATION_AND_BOUNDARY_SHAPE_2026-06-19.md index 69e5ded..63b9bf3 100644 --- a/docs/ops/HYPERTWIST_OVERNIGHT_MODE_CLOSEOUT_CONTINUATION_AND_BOUNDARY_SHAPE_2026-06-19.md +++ b/docs/ops/HYPERTWIST_OVERNIGHT_MODE_CLOSEOUT_CONTINUATION_AND_BOUNDARY_SHAPE_2026-06-19.md @@ -178,7 +178,7 @@ closeout must now explicitly state one of the following: Required shape example: -- recommendation-adoption status: `continue` may adopt `A D / O:B C E F / X` +- recommendation-adoption status: `continue` may adopt `A D / O:B C E / HO:F` or @@ -203,6 +203,14 @@ The governing interpretation is now explicit: - future instances must not infer adoption from `continue` alone when the closeout does not authorize that adoption +Compact-string note: + +- `HO:` is the canonical hard-omit prefix in new closeouts and prepared + decision packets +- older historical closeouts may still use `X:` for hard omit; read that older form as + legacy shorthand for `HO:` +- `O:` remains the omit-from-current-lane / reroute-later bucket + Expanded closeout-shape repertoire: - recommendation-adoption status: plain `continue` may adopt the displayed diff --git a/docs/ops/HYPERTWIST_PUBLIC_WEBSITE_AUTH_BILLING_AND_DISTRIBUTION_PACKET_2026-06-22.md b/docs/ops/HYPERTWIST_PUBLIC_WEBSITE_AUTH_BILLING_AND_DISTRIBUTION_PACKET_2026-06-22.md index 359f65d..33228cb 100644 --- a/docs/ops/HYPERTWIST_PUBLIC_WEBSITE_AUTH_BILLING_AND_DISTRIBUTION_PACKET_2026-06-22.md +++ b/docs/ops/HYPERTWIST_PUBLIC_WEBSITE_AUTH_BILLING_AND_DISTRIBUTION_PACKET_2026-06-22.md @@ -491,3 +491,41 @@ This packet does not claim any of the following: Those are deployment/runtime configuration tasks, not missing ownership of the public website lane itself. + +Latest authoritative launch-summary consumption alignment follow-up on `2026-06-29`: + +- the current same-family continuation tightened one remaining rollout-truth + seam inside the browser lane instead of widening product scope again +- the shared website launch-status resolver under + `website/src/shared/public-launch.ts` now prefers the auth server's + authoritative `launch` summary from `GET /api/auth/health` when that summary + is present, instead of always reconstructing checklist, blocker, and target + posture only from lower-level booleans on the client +- that matters because the packet authority had already declared that the auth + server-owned `launch` summary exists so public and protected browser surfaces + do not have to duplicate launch-blocker evaluation client-side +- the public `/launch-status` surface and the protected `/app/launch-status` + surface now both keep server-owned blocker labels and checkout-target truth + visible directly when the auth server provides them, while still falling back + to local derived checklist truth if the richer summary is absent +- focused validation for that alignment pass stayed green under: + - `npm --prefix website run type-check` + - `npm --prefix website test -- --run src/__tests__/public-launch.test.ts src/__tests__/public-marketing-pages.test.tsx src/__tests__/protected-app-pages.test.tsx` + - `3` files passed + - `29` tests passed +- the broader owned website/runtime umbrella then also stayed green: + - `scripts/run-hypertwist-web-surface-validation.sh` + - focused website route/auth/release validation: `13` files, `79` tests + passed + - `website/server` suite: `10` files, `36` tests passed + - `Content/Browser` shell verification and production build passed + - `website/` and `Content/Browser/` production audits stayed at + `found 0 vulnerabilities` + - `website/server/` again retained only the already-documented upstream + `supertokens-node -> nodemailer` residual advisory +- current truthful reading after this pass: + - the auth server's launch summary is now not only emitted, but actually + consumed as the preferred browser authority surface + - public and protected launch pages remain conservative because they still + derive bounded local checklist truth whenever the richer server summary is + unavailable diff --git a/docs/ops/HYPERTWIST_PUBLIC_WEBSITE_CONTENT_AND_OPERATOR_MANUAL_PACKET_2026-06-22.md b/docs/ops/HYPERTWIST_PUBLIC_WEBSITE_CONTENT_AND_OPERATOR_MANUAL_PACKET_2026-06-22.md index 05f50a3..eacd09d 100644 --- a/docs/ops/HYPERTWIST_PUBLIC_WEBSITE_CONTENT_AND_OPERATOR_MANUAL_PACKET_2026-06-22.md +++ b/docs/ops/HYPERTWIST_PUBLIC_WEBSITE_CONTENT_AND_OPERATOR_MANUAL_PACKET_2026-06-22.md @@ -835,3 +835,370 @@ Latest shared-release-bundle follow-up on `2026-06-25`: - `16,253` nodes, `38,116` edges, `665` clusters, `300` flows - `scripts/run-hypertwist-gitnexus-status.sh` - bounded mirror `Status: up-to-date` + +Latest onboarding-manual depth follow-up on `2026-06-28`: + +- the canonical public `/getting-started` route was widened again so it no + longer depends on the docs or resources pages alone for the two most + simulator-specific public manual seams: + - the same first-session route now includes the current + higher-dimensional family guide directly, covering the dedicated native + `Magic120Cell` and `MagicCube5D` lanes plus the current embedded-browser + `MagicTile` host posture + - that same route now also includes the public runtime control guide + directly, including the shipped classic desktop control posture, the + current higher-dimensional desktop-control truth, the native diagnostics + check, and the explicit desktop-hosted `No-Go` XR/controller boundary +- this keeps the canonical onboarding page closer to a genuine operator manual + instead of requiring users to reconstruct the real first-session path from + scattered public pages +- focused validation for that follow-up stayed green under: + - `npm --prefix website test -- --run src/__tests__/public-marketing-pages.test.tsx` + - `1` file passed + - `15` tests passed +- the same packet also rechecked the owned structural and graph-analysis + posture so the public-manual widening did not quietly degrade the refactor + baseline: + - `scripts/run-hypertwist-sentrux-source-only.sh` + - `Quality: 6228` + - all `7` rules pass + - `scripts/run-hypertwist-gitnexus-analyze.sh` + - `16,380` nodes, `38,646` edges, `679` clusters, `300` flows + - `scripts/run-hypertwist-gitnexus-status.sh` + - bounded mirror `Status: up-to-date` + +Latest feature-atlas parity follow-up on `2026-06-28`: + +- the public `/features` route then widened again so the feature atlas no + longer stops at capability and roster summaries when the rest of the manual + already carries a more practical desktop-usage seam +- that same atlas now also includes the shared runtime control guide directly, + including: + - the shipped classic desktop control posture + - the current higher-dimensional desktop-control posture + - the native diagnostics check + - the explicit desktop-hosted `No-Go` XR/controller boundary +- this keeps the public feature atlas closer to the broader operator/distribution + manual instead of forcing advanced readers to leave `/features` for docs, + resources, or getting-started just to find the practical control and + diagnostics truth +- focused validation for that atlas-parity follow-up stayed green under: + - `npm --prefix website test -- --run src/__tests__/public-marketing-pages.test.tsx` + - `1` file passed + - `15` tests passed +- the broader owned website/runtime/server umbrella then also stayed green + again under: + - `scripts/run-hypertwist-web-surface-validation.sh` + - focused website route/auth/release validation: `12` files, `74` tests + passed + - `npm --prefix website run build` + - `npm --prefix website/server run type-check` + - `npm --prefix website/server test -- --run` + - `10` website/server files passed, `36` tests passed + - `npm --prefix Content/Browser run verify:shell` + - `npm --prefix Content/Browser run build` + - `website/` and `Content/Browser/` production audits: `found 0 + vulnerabilities` + - `website/server` again retained only the already-documented upstream + `supertokens-node -> nodemailer` residual advisory +- the owned structural loop stayed green on the same continuation: + - `scripts/run-hypertwist-sentrux-source-only.sh` + - `Quality: 6228` + - all `7` rules pass + +Latest responsive manual-route proof expansion on `2026-06-29`: + +- the next same-family production-hardening packet then widened the existing + public responsive Playwright proof so the newer canonical public manual and + launch-authority routes are no longer outside the browser-level viewport + evidence lane +- `website/tests/e2e/responsive-public-pages.spec.ts` now also covers: + - `/features` + - `/docs` + - `/getting-started` + - `/launch-status` +- that means the responsive public-route proof now covers the practical public + operator/distribution surfaces that were widened most heavily in the recent + manual packet, rather than only the older marketing and commerce routes +- current validation truth for that responsive-proof expansion is green: + - `npm --prefix website run test:e2e:responsive` + - responsive public-route Playwright proof: `22` tests passed + - `scripts/run-hypertwist-web-surface-validation.sh --with-responsive-e2e` + - focused website route/auth/release validation: `12` files, `74` tests + passed + - responsive public-route Playwright proof: `22` tests passed + - responsive protected-route Playwright proof: `12` tests passed + - `website/server` suite: `10` files, `36` tests passed + - `Content/Browser` shell verification and production build passed + - `website/` and `Content/Browser/` production audits stayed at + `found 0 vulnerabilities` + - `website/server/` again retained only the already-documented upstream + `supertokens-node -> nodemailer` residual advisory + +Latest commerce/download manual deepening follow-up on `2026-06-29`: + +- the public pricing and download routes were widened again so the commercial + and release-access lanes no longer stop too early at entitlement, package + choice, and browser-to-desktop handoff +- `/pricing` now also carries: + - the practical simulator-use manual for the installed software + - the higher-dimensional family guide covering `Magic120Cell`, + `MagicCube5D`, and the current embedded-browser `MagicTile` posture + - the current input/device plus runtime-control truth, including the + explicit desktop-hosted `No-Go` XR/controller boundary +- `/download` now also carries: + - the practical installed-runtime manual + - the higher-dimensional family guide directly on the package route + - the same current input/device plus runtime-control truth before first + launch +- this keeps the public commerce and package lanes professional and + self-sufficient instead of forcing operators to jump into docs/resources + before they can understand what the entitled desktop software actually does +- current validation truth for that manual-deepening continuation is green: + - `npm --prefix website test -- --run src/__tests__/public-marketing-pages.test.tsx` + - `1` file passed + - `15` tests passed + - `npm --prefix website run build` + - production website build passed + - `scripts/run-hypertwist-web-surface-validation.sh` + - focused website route/auth/release validation: `12` files, `74` tests + passed + - `website/server` suite: `10` files, `36` tests passed + - `Content/Browser` shell verification and production build passed + - `website/` and `Content/Browser/` production audits stayed at + `found 0 vulnerabilities` + - `website/server/` again retained only the already-documented upstream + `supertokens-node -> nodemailer` residual advisory + +Latest shared public-manual refactor follow-up on `2026-06-29`: + +- the same-family continuation then tightened the public-manual ownership + layer itself so the widened page set stays easier to evolve without silent + copy drift +- shared first-party public-manual card sections now live in: + - `website/src/pages/public-page-helpers.tsx` + - `PrincipleCardSection` + - `BulletCardSection` + - `StepCardSection` + - `FaqCardSection` +- the current public/manual consumers now route through those shared helpers + instead of each page re-implementing the same card-grid structure: + - `website/src/pages/public-pages-marketing.tsx` + - `website/src/pages/public-pages-features.tsx` + - `website/src/pages/public-pages-commerce.tsx` +- this does not widen product scope or alter the browser-versus-desktop truth; + it keeps the existing operator-manual packet more coherent and less likely to + diverge across the public route family +- current validation truth for that shared-ownership follow-up is green: + - `npm --prefix website run type-check` + - `npm --prefix website test -- --run src/__tests__/public-marketing-pages.test.tsx` + - `1` file passed + - `15` tests passed + - `npm --prefix website run build` + - production website build passed + +Latest responsive-proof revalidation after the shared-manual continuation on `2026-06-29`: + +- the current same-family continuation then re-proved the widened public and + protected browser lanes at real browser viewport sizes after the newer + shared-section and commerce/manual deepening work +- this did not widen product claims; it re-validated that the now-richer page + set still behaves like a production operator/distribution surface on mobile + and tablet breakpoints +- the owned responsive route proof stayed green under: + - `scripts/run-hypertwist-web-surface-validation.sh --with-responsive-e2e` + - focused website route/auth/release validation: `12` files, `74` tests + passed + - responsive public-route Playwright proof: `22` tests passed + - responsive protected-route Playwright proof: `12` tests passed + - `website/server` suite: `10` files, `36` tests passed + - `Content/Browser` shell verification and production build passed + - `website/` and `Content/Browser/` production audits stayed at + `found 0 vulnerabilities` + - `website/server/` again retained only the already-documented upstream + `supertokens-node -> nodemailer` residual advisory +- the responsive public-route proof still covers the heavier manual and + authority routes that matter most to this packet: + - `/features` + - `/docs` + - `/getting-started` + - `/launch-status` + - plus the already-covered homepage, about, resources, pricing, download, + support, and register routes +- the responsive protected-route proof also stayed current for: + - `/app` + - `/app/launch-status` + - `/app/downloads` + - `/app/browser-access` + - `/app/account` + - `/app/notices` +- current truthful reading after this revalidation: + - the public/manual website lane remains intentional and professional rather + than brochure-only + - the richer manual/commerce copy introduced by the recent continuations did + not regress the owned browser delivery surfaces + +Latest launch-authority alignment follow-up on `2026-06-29`: + +- the next same-family continuation then closed a remaining authority-gap seam + between the documented auth-server launch summary and the browser surfaces + that read it +- `website/src/shared/public-launch.ts` now prefers the richer server-provided + `launch` summary from `GET /api/auth/health` when available, including its + explicit blocker labels, checklist truth, and operator/studio checkout + targets, instead of always reconstructing launch posture only from lower + rollout booleans on the client +- that keeps the public `/launch-status` route and the protected + `/app/launch-status` route better aligned with the intended server-owned + rollout authority while still preserving bounded local derivation as a safe + fallback if the richer summary is absent +- current validation truth for that authority-alignment continuation is green: + - `npm --prefix website run type-check` + - `npm --prefix website test -- --run src/__tests__/public-launch.test.ts src/__tests__/public-marketing-pages.test.tsx src/__tests__/protected-app-pages.test.tsx` + - `3` files passed + - `29` tests passed + - `scripts/run-hypertwist-web-surface-validation.sh` + - focused website route/auth/release validation: `13` files, `79` tests + passed + - `website/server` suite: `10` files, `36` tests passed + - `Content/Browser` shell verification and production build passed + - `website/` and `Content/Browser/` production audits stayed at + `found 0 vulnerabilities` + - `website/server/` again retained only the already-documented upstream + `supertokens-node -> nodemailer` residual advisory + +Latest shared public-manual section consolidation later on `2026-06-29`: + +- the next same-family continuation stayed inside the owned public-manual lane + and reduced drift risk by moving more repeated section rendering into shared + helper ownership +- `website/src/pages/public-page-helpers.tsx` now also owns reusable public + sections for: + - simulator manual + - higher-dimensional runtime guide + - input and device posture + - control-profile roster + - runtime control guide +- the current page consumers now route those shared sections through: + - `website/src/pages/public-pages-marketing.tsx` + - `website/src/pages/public-pages-commerce.tsx` +- this does not widen product claims; it keeps the public docs/about/resources/ + pricing/download/getting-started family aligned as one professional operator + manual instead of a set of near-copy pages that can drift separately +- validation stayed green on the same consolidation pass: + - `npm --prefix website run type-check` + - `scripts/run-hypertwist-web-surface-validation.sh` + - focused website route/auth/release validation: `13` files, `79` tests + passed + - `website/server` suite: `10` files, `36` tests passed + - `Content/Browser` shell verification and production build passed + - `website/` and `Content/Browser/` production audits stayed at + `found 0 vulnerabilities` + - `website/server/` again retained only the already-documented upstream + `supertokens-node -> nodemailer` residual advisory + +Latest protected responsive recovery follow-up later on `2026-06-29`: + +- the next same-family website quality pass fixed a real protected-route mobile + regression instead of widening scope again +- the affected route was the signed-in `/app/launch-status` surface, where the + stacked action rows could widen the viewport by a couple of pixels on narrow + mobile widths because the button links still sized themselves to long labels +- `website/src/styles/global.css` now hardens the owned small-screen button-row + posture so stacked protected actions fill the available column width and + allow wrapped labels +- this correction stayed entirely inside the existing protected operator shell + and did not alter the browser-versus-desktop truth or release-lane claims +- the full owned browser validation lane then re-ran green under: + - `scripts/run-hypertwist-web-surface-validation.sh --with-responsive-e2e` + - focused website route/auth/release validation: `13` files, `79` tests + passed + - responsive public-route Playwright proof: `22` tests passed + - responsive protected-route Playwright proof: `12` tests passed + - `website/server` suite: `10` files, `36` tests passed + - `Content/Browser` shell verification and production build passed + - `website/` and `Content/Browser/` production audits stayed at + `found 0 vulnerabilities` + - `website/server/` again retained only the already-documented upstream + `supertokens-node -> nodemailer` residual advisory +- current truthful reading after this follow-up: + - the richer public/protected manual lane is not only source-accurate, but + also still behaves like a deliberate operator/distribution surface at real + mobile and tablet breakpoints after the latest content widening + +Latest feature-atlas shared-section completion plus public legal-route responsive expansion later on `2026-06-29`: + +- the next same-family continuation stayed inside the owned public/manual lane + and closed a remaining drift-risk gap instead of widening product scope +- the public feature-atlas route now also routes its repeated manual sections + through the same shared helper ownership already used by the broader + marketing and commerce families: + - `HigherDimensionalRuntimeGuideSection` + - `InputAndDevicePostureSection` + - `ControlProfileRosterSection` + - `RuntimeControlGuideSection` +- that means the higher-dimensional runtime guide, current input/device truth, + selectable roster, and practical runtime-control guidance now share one + first-party rendering path across the main public route family instead of + leaving `/features` on a separate near-copy structure +- the same continuation then widened browser-level responsive proof across the + remaining public legal/reference routes that were already content-complete + but not yet inside the explicit mobile/tablet viewport lane: + - `/changelog` + - `/open-source-notices` + - `/privacy` + - `/terms` + - `/shipping-payment` +- a later adjacent auth-entry parity continuation then also added `/login` to + that same owned responsive public-route matrix so the real browser-entry + surface sits under the same mobile/tablet proof lane as `/register` +- the owned responsive public-route proof therefore now covers the broader + public operator/distribution family rather than only the marketing, + onboarding, support, and core commerce subset +- current validation truth for that continuation is green: + - `scripts/run-hypertwist-web-surface-validation.sh --with-responsive-e2e` + - focused website route/auth/release validation: `13` files, `79` tests + passed + - responsive public-route Playwright proof: `34` tests passed + - responsive protected-route Playwright proof: `12` tests passed + - `website/server` suite: `10` files, `36` tests passed + - `Content/Browser` shell verification and production build passed + - `website/` and `Content/Browser/` production audits stayed at + `found 0 vulnerabilities` + - `website/server/` again retained only the already-documented upstream + `supertokens-node -> nodemailer` residual advisory +- current truthful reading after this continuation: + - the feature atlas now sits on the same shared public-manual ownership path + as the surrounding major public routes + - the broader public legal/reference family now has real browser-level + mobile and tablet overflow proof instead of relying only on route tests and + source-level review + +Latest feature-atlas capability-FAQ continuity follow-up on `2026-06-29`: + +- the next same-family continuation stayed inside the owned public/manual lane + and widened the public `/features` route from a capability matrix plus + runtime-guide surface into a cleaner question-answering route as well +- the feature atlas now also renders a dedicated `Common capability questions` + section backed by the same shared FAQ authority already used on the broader + docs/support family +- those answers now keep the exact product-boundary questions visible directly + on the capability route, including: + - why the browser surface is intentionally narrower than the desktop runtime + - why HyperTwist still keeps the web product surface even though the + simulator is desktop-first + - why XR/controller completion is not yet marketed as finished + - how current control, settings, and bounded higher-dimensional continuity + should be read honestly +- the FAQ wording itself was also tightened so the public manual now states the + key inferiority points explicitly instead of leaving them implicit: + - the browser surface does not own package-validated training behavior, + low-latency native input, higher-dimensional packaged execution, or + device/runtime integration authority + - the current desktop runtime does own real keyboard or mouse or touch plus + settings and higher-dimensional selector posture, but it still does not + claim finished packaged XR/controller proof or polished rebinding +- focused validation for that continuation stayed green under: + - `npm --prefix website test -- --run src/__tests__/public-marketing-pages.test.tsx` + - `1` file passed + - `16` tests passed diff --git a/docs/ops/HYPERTWIST_REFACTORING_TOOLCHAIN_2026-06-22.md b/docs/ops/HYPERTWIST_REFACTORING_TOOLCHAIN_2026-06-22.md index 44ead39..40bb57c 100644 --- a/docs/ops/HYPERTWIST_REFACTORING_TOOLCHAIN_2026-06-22.md +++ b/docs/ops/HYPERTWIST_REFACTORING_TOOLCHAIN_2026-06-22.md @@ -22,6 +22,7 @@ VectorShell. - `.sentrux/rules.toml` - `scripts/bootstrap-hypertwist-sentrux.sh` - `scripts/run-hypertwist-sentrux-source-only.sh` +- `scripts/run-hypertwist-sentrux-gate.sh` - `scripts/run-hypertwist-gitnexus-analyze.sh` - `scripts/run-hypertwist-gitnexus-status.sh` @@ -53,6 +54,24 @@ Run: scripts/run-hypertwist-sentrux-source-only.sh ``` +For the owned regression-gate loop, run: + +```bash +scripts/run-hypertwist-sentrux-gate.sh --save +scripts/run-hypertwist-sentrux-gate.sh +``` + +The gate wrapper uses the same bounded source-only mirror, but it now persists +its baseline at: + +- `.sentrux/source-only-baseline.json` + +That matters because upstream `sentrux gate --save` writes +`.sentrux/baseline.json` inside the scanned root. HyperTwist therefore copies +the repo-owned source-only baseline into and out of the disposable mirror so +the gate remains usable across hygiene-cleaned temp roots instead of forgetting +its own saved state on every run. + Resolution order for the analyzer binary is now HyperTwist-owned first: - `HYPERTWIST_SENTRUX_BINARY` if explicitly provided @@ -114,12 +133,21 @@ Behavior: available or is not runnable - always uses `--skip-agents-md` so HyperTwist authority files are not rewritten just to refresh analysis state +- `scripts/run-hypertwist-gitnexus-status.sh` is now hygiene-aware by default: + - if the disposable `.gitnexus-source-only-root/` mirror has already been + deleted during a correct cleanup pass, the wrapper reports that as an + informational state instead of pretending the repo is corrupted + - if the mirror exists but `.gitnexus/meta.json` is missing, the wrapper now + reports that as an interrupted or rebuilding index state by default + - `HYPERTWIST_GITNEXUS_STATUS_REQUIRE_INDEX=1` restores strict non-zero + failure when a caller truly needs status to fail on those absent/incomplete + disposable-root cases ## Working-reference note The retained HyperTwist `mirrors/GitNexus` working reference already contains -the newer stack-overflow and cycle-hardening work recorded in its -`CHANGELOG.md`, including: +the newer stack-overflow and cycle-hardening work visible in its retained +source tree and tests, including: - iterative stdio newline handling to prevent stack overflow on empty-line bursts @@ -132,11 +160,15 @@ It is not a signal to absorb GitNexus runtime code into the shipped product. 1. run `scripts/run-hypertwist-gitnexus-analyze.sh` 2. review impact/freshness through `scripts/run-hypertwist-gitnexus-status.sh` -3. run `scripts/run-hypertwist-sentrux-source-only.sh` for a structural - baseline -4. make the bounded packet -5. rerun `scripts/run-hypertwist-sentrux-source-only.sh` -6. rerun product tests for the affected lane +3. run `scripts/run-hypertwist-sentrux-gate.sh --save` when you need to stamp + a fresh bounded baseline for the current refactor lane +4. run `scripts/run-hypertwist-sentrux-source-only.sh` for the immediate + structural snapshot +5. make the bounded packet +6. rerun `scripts/run-hypertwist-sentrux-source-only.sh` +7. rerun `scripts/run-hypertwist-sentrux-gate.sh` to compare against the saved + bounded baseline +8. rerun product tests for the affected lane ## Current findings snapshot @@ -1014,3 +1046,371 @@ This note does not: - make `GitNexus` a product runtime dependency - claim `sentrux` replaces product validation - widen HyperTwist into a generic code-intelligence product + +Latest refresh on `2026-06-28`: + +- the current same-family public-manual continuation rechecked the owned + structural loop instead of treating the earlier website/runtime results as + permanently sufficient: + - `scripts/run-hypertwist-sentrux-source-only.sh` + - `Quality: 6228` + - all `7` rules pass +- the HyperTwist-owned graph refresh also completed again on the bounded + source-only mirror: + - `scripts/run-hypertwist-gitnexus-analyze.sh` + - the retained local CLI again failed cleanly on this Linux host because of + the cross-platform `LadybugDB` native payload mismatch, so the wrapper + truthfully fell back to `npx -y gitnexus@latest` + - fallback analyze run completed successfully in `84.5s` + - bounded mirror result: + - `16,380` nodes + - `38,646` edges + - `679` clusters + - `300` flows + - `scripts/run-hypertwist-gitnexus-status.sh` then reported: + - `Indexed commit: a4a50b8` + - `Current commit: a4a50b8` + - `Status: up-to-date` +- current truthful reading after this refresh: + - the broad vanilla-refactor lane is no longer blocked by tool adoption, + broken wrappers, or an active failing structural gate + - HyperTwist now has a stable owned analyzer loop for day-to-day bounded + refactor review even though the retained local GitNexus native payload is + still not runnable on this Linux host + - the next worthwhile refactor work is selective readability or ownership + cleanup driven by product/runtime value, not emergency analyzer setup debt + +Latest refresh on `2026-06-29`: + +- the current public commerce/download manual deepening slice rechecked the + owned analyzer loop instead of assuming the previous refresh was still + sufficient after another website/manual continuation +- the owned structural gate stayed green: + - `scripts/run-hypertwist-sentrux-source-only.sh` + - `Quality: 6228` + - all `7` rules pass +- the HyperTwist-owned graph refresh again completed on the bounded + source-only mirror: + - `scripts/run-hypertwist-gitnexus-analyze.sh` + - the retained local CLI again failed cleanly on this Linux host because of + the cross-platform `LadybugDB` native payload mismatch, so the wrapper + truthfully fell back to `npx -y gitnexus@latest` + - fallback analyze run completed successfully in `87.8s` + - bounded mirror result: + - `16,380` nodes + - `38,646` edges + - `679` clusters + - `300` flows + - `scripts/run-hypertwist-gitnexus-status.sh` then reported: + - `Indexed commit: bbcd877` + - `Current commit: bbcd877` + - `Status: up-to-date` +- the same continuation also stayed green under product-surface validation: + - `npm --prefix website test -- --run src/__tests__/public-marketing-pages.test.tsx` + - `1` file passed + - `15` tests passed + - `npm --prefix website run build` + - production website build passed + - `scripts/run-hypertwist-web-surface-validation.sh` + - focused website route/auth/release validation: `12` files, `74` tests + passed + - `website/server` suite: `10` files, `36` tests passed + - `Content/Browser` shell verification and production build passed + - `website/` and `Content/Browser/` production audits stayed at + `found 0 vulnerabilities` + - `website/server/` again retained only the already-documented upstream + `supertokens-node -> nodemailer` residual advisory +- current truthful reading after this refresh: + - the broad vanilla-refactor lane is complete as a tooling-adoption task + - the current remaining high-value refactor work is product-driven cleanup, + not missing `sentrux` or GitNexus ownership inside HyperTwist + +Latest shared-section refactor follow-up on `2026-06-29`: + +- the current public-manual continuation then spent that already-proven owned + refactor headroom on a bounded maintainability pass instead of widening + product claims again +- shared card-section ownership for the public website now lives in: + - `website/src/pages/public-page-helpers.tsx` + - `PrincipleCardSection` + - `BulletCardSection` + - `StepCardSection` + - `FaqCardSection` +- the current public manual consumers now route through those shared helpers + instead of each page hand-rolling the same grid logic: + - `website/src/pages/public-pages-marketing.tsx` + - `website/src/pages/public-pages-features.tsx` + - `website/src/pages/public-pages-commerce.tsx` +- that keeps the browser-versus-desktop product truth, runtime-boundary copy, + and operator-manual structure less drift-prone across future public-page + continuations +- the owned structural loop stayed green after that refactor packet: + - `scripts/run-hypertwist-sentrux-source-only.sh` + - `Quality: 6228` + - all `7` rules pass +- the HyperTwist-owned graph refresh also stayed healthy: + - `scripts/run-hypertwist-gitnexus-analyze.sh` + - the retained local CLI again failed cleanly on this Linux host because of + the cross-platform `LadybugDB` native payload mismatch, so the wrapper + truthfully fell back to `npx -y gitnexus@latest` + - bounded mirror result: + - `16,387` nodes + - `38,682` edges + - `676` clusters + - `300` flows + - `scripts/run-hypertwist-gitnexus-status.sh` then reported: + - `Indexed commit: 1deca95` + - `Current commit: 1deca95` + - `Status: up-to-date` +- the same refactor packet also stayed green under product-surface validation: + - `npm --prefix website run type-check` + - `npm --prefix website test -- --run src/__tests__/public-marketing-pages.test.tsx` + - `1` file passed + - `15` tests passed + - `npm --prefix website run build` +- current truthful reading after this follow-up: + - the broad refactor/tooling lane remains healthy and HyperTwist-owned + - the next worthwhile refactors should continue to be selected for real + product-surface clarity or native/runtime ownership value, not for missing + analyzer setup or duplicate manual-section scaffolding + +Latest GitNexus status-wrapper hardening plus responsive-proof refresh on `2026-06-29`: + +- the current same-family tooling follow-up tightened operator-facing + GitNexus status truth instead of widening product scope again +- `scripts/run-hypertwist-gitnexus-status.sh` now explicitly distinguishes: + - no bounded analysis root exists yet + - bounded source-only mirror exists but no completed `.gitnexus/meta.json` + index metadata is present yet +- that means a status check during an in-progress bounded-mirror refresh now + reports that the index is not ready yet, rather than looking corrupted or + failing opaquely +- the new pre-index message was exercised directly by temporarily withholding + the disposable `.gitnexus/meta.json` file and rerunning the wrapper: + - reported: + `HyperTwist GitNexus source-only analysis root exists, but no completed index metadata is available yet.` + - follow-up guidance: + `If scripts/run-hypertwist-gitnexus-analyze.sh is currently refreshing the bounded mirror, wait for it to finish and rerun status.` +- the owned structural and graph loop remained healthy on the same pass: + - `scripts/run-hypertwist-sentrux-source-only.sh` + - `Quality: 6228` + - all `7` rules pass + - `scripts/run-hypertwist-gitnexus-analyze.sh` + - retained local CLI again fell back cleanly to `npx -y gitnexus@latest` + on this Linux host because of the cross-platform `LadybugDB` native payload + mismatch + - bounded mirror result: + - `16,387` nodes + - `38,686` edges + - `676` clusters + - `300` flows + - `scripts/run-hypertwist-gitnexus-status.sh` + - `Indexed commit: a41d7ef` + - `Current commit: a41d7ef` + - `Status: up-to-date` +- the adjacent owned web/runtime validation umbrella also stayed green on the + same refresh: + - `scripts/run-hypertwist-web-surface-validation.sh --with-responsive-e2e` + - focused website route/auth/release validation: `12` files, `74` tests + passed + - responsive public-route Playwright proof: `22` tests passed + - responsive protected-route Playwright proof: `12` tests passed + - `website/server` suite: `10` files, `36` tests passed + - `Content/Browser` shell verification and production build passed + - `website/` and `Content/Browser/` production audits stayed at + `found 0 vulnerabilities` + - `website/server/` again retained only the already-documented upstream + `supertokens-node -> nodemailer` residual advisory +- current truthful reading after this hardening pass: + - the HyperTwist-owned refactor/tooling lane is not merely present, but now + gives clearer operator feedback during bounded mirror refresh windows + - the remaining worthwhile work continues to be product or runtime-driven + refinement, not missing analyzer ownership or opaque wrapper behavior + +Latest shared-manual helper consolidation follow-up later on `2026-06-29`: + +- the next same-family quality pass stayed inside the owned public-website + manual lane and removed more repeated section rendering without widening + product scope +- `website/src/pages/public-page-helpers.tsx` now also owns the reusable + simulator-manual, higher-dimensional-runtime, input/device-posture, + control-profile-roster, and runtime-control-guide public-manual sections +- the current public/manual consumers now read those shared sections through: + - `website/src/pages/public-pages-marketing.tsx` + - `website/src/pages/public-pages-commerce.tsx` +- the owned tool and validation loop stayed green on the same pass: + - `scripts/run-hypertwist-sentrux-source-only.sh` + - `Quality: 6227` + - all `7` rules pass + - `scripts/run-hypertwist-gitnexus-analyze.sh` + - retained local CLI again fell back cleanly to `npx -y gitnexus@latest` + on this Linux host because of the cross-platform `LadybugDB` native payload + mismatch + - bounded mirror result: + - `16,389` nodes + - `38,702` edges + - `674` clusters + - `300` flows + - `scripts/run-hypertwist-gitnexus-status.sh` + - `Indexed commit: f1f5cce` + - `Current commit: f1f5cce` + - `Status: up-to-date` + - `scripts/run-hypertwist-web-surface-validation.sh` + - focused website route/auth/release validation: `13` files, `79` tests + passed + - `website/server` suite: `10` files, `36` tests passed + - `Content/Browser` shell verification and production build passed + - `website/` and `Content/Browser/` production audits stayed at + `found 0 vulnerabilities` + - `website/server/` again retained only the already-documented upstream + `supertokens-node -> nodemailer` residual advisory +- current truthful reading after this consolidation: + - vanilla refactoring is healthy and HyperTwist-owned; the next worthwhile + refactors should continue to be chosen for product clarity or native/runtime + value, not because the website manual lane is still drifting by duplication + +Latest browser responsive recovery plus tooling rerun later on `2026-06-29`: + +- the next same-family pass used the owned analyzer and browser-validation loop + to fix a real small-screen regression on protected launch-status instead of + manufacturing a new scope branch +- the current correction lived in `website/src/styles/global.css`, where the + small-screen button-row posture now forces stacked action links to respect + the available column width and allows long labels to wrap +- the owned structural and graph loop then stayed green again under: + - `scripts/run-hypertwist-sentrux-source-only.sh` + - `Quality: 6228` + - all `7` rules pass + - `scripts/run-hypertwist-gitnexus-analyze.sh` + - retained local CLI again fell back cleanly to `npx -y gitnexus@latest` + on this Linux host because of the cross-platform `LadybugDB` native payload + mismatch + - bounded mirror result: + - `16,394` nodes + - `38,737` edges + - `674` clusters + - `300` flows + - `scripts/run-hypertwist-gitnexus-status.sh` + - `Indexed commit: a863f79` + - `Current commit: a863f79` + - `Status: up-to-date` +- the adjacent owned browser/runtime validation umbrella also stayed green + after that recovery: + - `scripts/run-hypertwist-web-surface-validation.sh --with-responsive-e2e` + - focused website route/auth/release validation: `13` files, `79` tests + passed + - responsive public-route Playwright proof: `22` tests passed + - responsive protected-route Playwright proof: `12` tests passed + - `website/server` suite: `10` files, `36` tests passed + - `Content/Browser` shell verification and production build passed + - `website/` and `Content/Browser/` production audits stayed at + `found 0 vulnerabilities` + - `website/server/` again retained only the already-documented upstream + `supertokens-node -> nodemailer` residual advisory +- current truthful reading after this rerun: + - the HyperTwist-owned refactor/tooling lane remains healthy enough to catch + and verify small real product regressions, not just abstract structural + debt + +Latest final auth-entry and authority-sync rerun later on `2026-06-29`: + +- the next same-family quality pass rechecked the owned analyzer loop after the + final public-route authority sync instead of assuming the earlier `2026-06-29` + refreshes were still sufficient +- the owned structural gate stayed green: + - `scripts/run-hypertwist-sentrux-source-only.sh` + - `Quality: 6228` + - all `7` rules pass +- the HyperTwist-owned graph refresh again completed on the bounded + source-only mirror: + - `scripts/run-hypertwist-gitnexus-analyze.sh` + - the retained local CLI again failed cleanly on this Linux host because of + the cross-platform `LadybugDB` native payload mismatch, so the wrapper + truthfully fell back to `npx -y gitnexus@latest` + - fallback analyze run completed successfully in `80.2s` + - bounded mirror result: + - `16,393` nodes + - `38,742` edges + - `673` clusters + - `300` flows + - `scripts/run-hypertwist-gitnexus-status.sh` then reported: + - `Indexed commit: e7f266f` + - `Current commit: e7f266f` + - `Status: up-to-date` +- current truthful reading after this rerun: + - the broad vanilla-refactor lane remains complete as a tooling-adoption and + analyzer-ownership job inside HyperTwist + - the retained GitNexus local native payload still is not runnable on this + Linux host, but the HyperTwist-owned wrapper keeps that host fact explicit + instead of masking it + - the next worthwhile refactor work should keep being chosen for real + simulator, website-manual, or native-ownership value rather than for + missing analyzer setup debt + +Latest hygiene-aware status-wrapper follow-up later on `2026-06-29`: + +- the next bounded refactor-tool pass stayed inside the already-owned + GitNexus wrapper lane and corrected an operator-friction seam that appeared + after proper post-task cleanup +- `scripts/run-hypertwist-gitnexus-status.sh` no longer treats the absence of + the disposable `.gitnexus-source-only-root/` mirror as an automatic repo + failure in default mode; it now states plainly that this is normal after + hygiene and points operators back to + `scripts/run-hypertwist-gitnexus-analyze.sh` to recreate the bounded mirror +- the same wrapper now also distinguishes an interrupted or rebuilding mirror + where `.gitnexus/meta.json` is not yet present, instead of collapsing that + into the same generic missing-root failure +- strict automation can still request the old fail-fast posture explicitly + through: + - `HYPERTWIST_GITNEXUS_STATUS_REQUIRE_INDEX=1` +- this keeps HyperTwist’s refactor-tool posture aligned with the doctrine that + the GitNexus mirror is disposable analysis state, not release evidence or a + committed product artifact + +Latest owned regression-gate and final refresh follow-up later on `2026-06-29`: + +- the next same-family hardening pass then closed the remaining “wrapper is + present” versus “owned regression loop is actually proven” gap +- the HyperTwist-owned `sentrux` baseline loop is now explicitly re-proved: + - `scripts/run-hypertwist-sentrux-gate.sh --save` + - persisted baseline: + `.sentrux/source-only-baseline.json` + - `scripts/run-hypertwist-sentrux-gate.sh` + - comparison result: + - `Quality: 6234 -> 6234` + - `Coupling: 0.15 -> 0.15` + - `Cycles: 0 -> 0` + - `God files: 1 -> 1` + - `No degradation detected` +- the adjacent owned structural snapshot also stayed green: + - `scripts/run-hypertwist-sentrux-source-only.sh` + - `Quality: 6234` + - all `7` rules pass +- the HyperTwist-owned graph refresh again completed successfully on the + bounded source-only mirror: + - `scripts/run-hypertwist-gitnexus-analyze.sh` + - the retained local CLI again failed cleanly on this Linux host because of + the cross-platform `LadybugDB` native payload mismatch, so the wrapper + truthfully fell back to `npx -y gitnexus@latest` + - bounded mirror result: + - `16,397` nodes + - `38,754` edges + - `673` clusters + - `300` flows + - `scripts/run-hypertwist-gitnexus-status.sh` + - `Indexed commit: ab10931` + - `Current commit: ab10931` + - `Status: up-to-date` +- the same owned-refresh pass also kept the current public/protected browser + product surface green under: + - `scripts/run-hypertwist-web-surface-validation.sh --skip-audits` + - focused website route/auth/release validation: `13` files, `79` tests + passed + - `website/server` suite: `10` files, `36` tests passed + - `Content/Browser` shell verification and production build passed +- current truthful reading after this refresh: + - vanilla refactoring is complete as an owned toolchain-adoption and + regression-loop task inside HyperTwist + - the current remaining worthwhile refactors should be product or + runtime-driven improvements, not missing `sentrux`/GitNexus ownership or + an unproven baseline-comparison loop diff --git a/docs/ops/HYPERTWIST_UNREAL_INPUT_AND_XR_COMPLETENESS_AUDIT_2026-06-22.md b/docs/ops/HYPERTWIST_UNREAL_INPUT_AND_XR_COMPLETENESS_AUDIT_2026-06-22.md index 5d08e4c..00a5562 100644 --- a/docs/ops/HYPERTWIST_UNREAL_INPUT_AND_XR_COMPLETENESS_AUDIT_2026-06-22.md +++ b/docs/ops/HYPERTWIST_UNREAL_INPUT_AND_XR_COMPLETENESS_AUDIT_2026-06-22.md @@ -259,9 +259,47 @@ truthfully claim: - `TrainingPanel.ControlSettingsOwnershipInspectSurface` - `CoachDashboard.ControlProfileRosterInspectSurface` - `TrainingPanel.ControlProfileRosterInspectSurface` +- a later interrupted-session recovery proof on `2026-06-29` then treated the + previously detached remote automation run as incomplete instead of assuming + success, repaired a stale remote + `HyperTwistBrowserBridgeObjectTest.cpp` copy on the broader maintained root, + re-synced the exact touched continuity slice into the short-root lane + `C:\HTpp`, rebuilt that exact-source lane cleanly with `Result: Succeeded` + and UnrealBuildTool `Total execution time: 4645.02 seconds`, then + sequentially re-exported fresh exact-source continuity proof with all + `Result={Success}` for: + - `HyperTwist.Browser.ControlProfileContinuityStateFormatting` + - `HyperTwist.Browser.ControlInputContinuityStateFormatting` + - `HyperTwist.Browser.ControlSettingsContinuityStateFormatting` +- that recovery matters for this audit because it keeps the current + desktop-hosted `No-Go` XR/controller boundary and the bounded + camera/immersive continuity wording grounded in fresh Windows evidence after + an interrupted host session rather than leaving the latest packet only on an + assumed-success trail - the unattended run still emitted the already-accepted `Failed to create the web browser window.` message, but that noise did not block report export or any of the focused browser automation proof +- a later exact-source maintained-root hardening follow-up on `2026-06-29` + then tightened the shared continuity formatting itself so stale ids and + counts are masked whenever the corresponding readiness booleans are false, + rather than letting degraded state accidentally render carried-over values: + - the touched training-panel, coach-dashboard, type, shared formatter, and + focused automation-test files were re-synced into maintained validation + root `C:\HyperTwist_worktrees\phase10validate` + - the maintained validation root rebuilt cleanly with `Result: Succeeded` + and UnrealBuildTool `Total execution time: 3325.07 seconds` + - focused browser automation then exported the maintained-root report family + `Continuity-CountMasking-20260629-*` with all `Result={Success}` for: + - `HyperTwist.Browser.ControlInputContinuityStateFormatting` + - `HyperTwist.Browser.ControlSettingsContinuityStateFormatting` + - `HyperTwist.Browser.ControlProfileContinuityStateFormatting` + - `HyperTwist.Browser.TrainingPanel.ControlProfileContinuityParity` + - `HyperTwist.Browser.CoachDashboard.ControlProfileContinuityArtifacts` +- that same follow-up matters for this audit because the current + desktop-hosted `No-Go` XR/controller boundary and the bounded + camera/immersive/profile continuity wording are now grounded not only in + current Windows proof, but also in explicit degraded-state count-masking + behavior instead of merely assuming absent readiness will hide stale values ### Explicit project OpenXR plugin posture now exists diff --git a/docs/v6_5_deep_manual_pack/HyperTwist/DEVELOPMENT.md b/docs/v6_5_deep_manual_pack/HyperTwist/DEVELOPMENT.md index 136ff7b..5d386b1 100644 --- a/docs/v6_5_deep_manual_pack/HyperTwist/DEVELOPMENT.md +++ b/docs/v6_5_deep_manual_pack/HyperTwist/DEVELOPMENT.md @@ -32,6 +32,7 @@ claims over the same capability. HyperTwist now has its own bounded refactor/analyzer entry points: - `scripts/run-hypertwist-sentrux-source-only.sh` +- `scripts/run-hypertwist-sentrux-gate.sh` - `scripts/run-hypertwist-gitnexus-analyze.sh` - `scripts/run-hypertwist-gitnexus-status.sh` - `scripts/run-hypertwist-web-surface-validation.sh` @@ -55,10 +56,29 @@ Use them with this posture: - `HYPERTWIST_GITNEXUS_DEBUG_LOCAL=1` keeps local GitNexus stderr visible so retained-runtime problems can be diagnosed instead of being silently suppressed during the normal fallback path +- `scripts/run-hypertwist-gitnexus-status.sh` is now hygiene-aware in default + mode: + - if the disposable `.gitnexus-source-only-root/` mirror has already been + removed during a correct cleanup pass, the wrapper reports that as normal + disposable-state absence instead of treating it as repo corruption + - if the disposable mirror exists but `.gitnexus/meta.json` is missing, the + wrapper reports an interrupted or rebuilding index state instead of the + same generic failure + - `HYPERTWIST_GITNEXUS_STATUS_REQUIRE_INDEX=1` restores strict non-zero + failure when an automation caller truly requires a completed bounded index - `scripts/run-hypertwist-sentrux-source-only.sh` now prefers a HyperTwist owned entry path first: `HYPERTWIST_SENTRUX_BINARY`, repo-local `./sentrux` or `./sentrux.exe`, then repo-local `tools/sentrux/bin/`, then a bootstrap attempt, then `PATH` +- `scripts/run-hypertwist-sentrux-gate.sh` now gives HyperTwist the same + bounded source-only regression loop as the broader Sentrux doctrine, but + without trusting a disposable temp mirror to remember its own baseline: + - `--save` refreshes the owned baseline at + `.sentrux/source-only-baseline.json` + - comparison runs restore that repo-owned baseline into the disposable + mirror before calling `sentrux gate` + - the wrapper therefore survives normal post-task hygiene that deletes temp + mirrors instead of silently losing the last saved architecture baseline - the current `2026-06-24` wrapper hardening tightens that posture further: - the source-only wrapper now auto-attempts `scripts/bootstrap-hypertwist-sentrux.sh --if-missing` before it gives up @@ -82,9 +102,13 @@ Suggested loop: 1. run `scripts/run-hypertwist-gitnexus-analyze.sh` before a larger rename or subsystem split 2. use `scripts/run-hypertwist-gitnexus-status.sh` to confirm index freshness -3. run `scripts/run-hypertwist-sentrux-source-only.sh` before and after the +3. if the packet needs a before/after regression comparison, stamp the owned + bounded baseline with `scripts/run-hypertwist-sentrux-gate.sh --save` +4. run `scripts/run-hypertwist-sentrux-source-only.sh` before and after the packet -4. treat `sentrux` failures as structural review signals, then confirm with +5. rerun `scripts/run-hypertwist-sentrux-gate.sh` when you want the saved + source-only baseline comparison itself, not just the latest raw score +6. treat `sentrux` failures as structural review signals, then confirm with focused product tests Additional dependency-health loop for the current browser and website family: @@ -1313,10 +1337,14 @@ Current audit note: - `npm --prefix website run test:e2e:responsive:list` - that responsive packet covers the real current HyperTwist public routes for: - homepage + - feature atlas - about - resources + - docs - pricing - download + - getting-started + - launch-status - support - register - each route now has a browser-level proof for: @@ -1353,6 +1381,34 @@ Current audit note: responsive browser proofs when `--with-responsive-e2e` is explicitly requested +Latest same-family responsive public-route expansion follow-up on `2026-06-29`: + +- the responsive public-route browser proof then widened again so the newer + canonical manual and authority routes are no longer outside the production- + shaped viewport evidence lane +- `website/tests/e2e/responsive-public-pages.spec.ts` now also covers: + - `/features` + - `/docs` + - `/getting-started` + - `/launch-status` +- the widened public-route proof therefore now covers `11` public routes + across both mobile and tablet classes instead of the earlier narrower public + shell set +- current validation truth for that widened browser-level packet is green: + - `npm --prefix website run test:e2e:responsive` + - responsive public-route Playwright proof: `22` tests passed + - `scripts/run-hypertwist-web-surface-validation.sh --with-responsive-e2e` + - focused website route/auth/release validation: `12` files, `74` tests + passed + - responsive public-route Playwright proof: `22` tests passed + - responsive protected-route Playwright proof: `12` tests passed + - `website/server` suite: `10` files, `36` tests passed + - `Content/Browser` shell verification and production build passed + - `website/` and `Content/Browser/` production audits stayed at + `found 0 vulnerabilities` + - `website/server/` again retained only the already-documented upstream + `supertokens-node -> nodemailer` residual + ## Latest native/public control-roster parity follow-up (`2026-06-25`) - the same-family native/operator continuity lane then aligned the shipped @@ -1393,3 +1449,627 @@ Current audit note: - `CoachDashboard.ControlProfileRosterInspectSurface` - `TrainingPanel.ControlProfileRosterInspectSurface` - `CoachDashboard.ControlSurfaceStructuredTextArtifacts` + +## Latest control-profile continuity and diagnostics follow-up (`2026-06-28`) + +- the next same-family native/operator continuity packet then tightened the + control-profile roster seam itself instead of leaving the newest continuity + truth stranded only on sibling control-settings surfaces: + - `FHyperTwistTrainingControlProfileRosterInspectSurface` now carries the + active higher-dimensional interactive-scene id alongside the active + activation, view-context, and session ids + - that same roster seam now resolves the first valid viewer camera-export + artifact instead of trusting only the first listed id, and it keeps the + shipped `artifact/camera-export-json` plus + `immersive-training-session-recall-boundary` visible with recall-scope and + preference-field counts + - `UHyperTwistCoachDashboardWidget` now mirrors that same bounded continuity + truth into a dedicated `CoachControlProfileRosterPreferencesContinuity` + structured row instead of collapsing it into broader detail prose only + - `HyperTwistTrainingPanelWidget.cpp` now resolves the bounded camera and + immersive continuity facts through shared local helper builders so the + control-input, control-settings, and control-profile seams do not drift + apart when the same continuity truth changes again later +- the public manual and operator-facing site truth now also reflect that same + native diagnostics reality more directly: + - `website/src/site-data.ts` now adds a dedicated native diagnostics-check + card to the runtime control guide + - the public control-roster copy now explicitly mentions the live scene id + and the continuity-count readout instead of leaving those facts implied +- current local validation for that same packet is green: + - focused public/protected/manual website coverage: + `47` tests passed across `public-marketing-pages`, `public-auth-pages`, + `protected-app-pages`, and `app-route-tree` + - `scripts/run-hypertwist-web-surface-validation.sh` + - website focused suite: `74` tests passed + - website/server suite: `36` tests passed + - `Content/Browser` shell verification and production build passed + - `website/` and `Content/Browser/` production audits stayed at + `found 0 vulnerabilities` + - `website/server/` retained only the already-documented upstream + `supertokens-node -> nodemailer` residual + - `scripts/run-hypertwist-sentrux-source-only.sh` + - `Quality: 6228` + - all `7` rules passing + - `scripts/run-hypertwist-gitnexus-analyze.sh` + - bounded mirror refreshed at: + - `16,382` nodes + - `38,653` edges + - `679` clusters + - `300` flows + - `scripts/run-hypertwist-gitnexus-status.sh` + - bounded mirror `Status: up-to-date` +- the authoritative Windows proof for the exact-source continuity state also + completed cleanly on the short-root recovery lane `C:\HTpp`: + - synced the exact touched Unreal source files through + `scripts/run-hypertwist-remote-windows-file-sync.sh --remote-root 'C:\HTpp'` + - remote Unreal rebuild through + `scripts/run-hypertwist-remote-unreal-build.sh --worktree-root 'C:\HTpp' --max-parallel-actions 8` + - `Result: Succeeded` + - UnrealBuildTool `Total execution time: 2374.44 seconds` + - focused remote automation then exported both report roots with + `Result={Success}`: + - `Browser-ControlProfileContinuityParity-20260628-HyperTwist.Browser.TrainingPanel.ControlProfileContinuityParity` + - `Browser-ControlProfileContinuityParity-20260628-HyperTwist.Browser.CoachDashboard.ControlProfileContinuityArtifacts` + - the accepted unattended `Failed to create the web browser window.` dialog + still appeared on both editor launches, but it remained non-blocking and + the focused automation proofs completed successfully + +## Latest onboarding-manual and refactor-refresh follow-up (`2026-06-28`) + +- the canonical public `/getting-started` route then widened again so the + shortest complete onboarding page now also carries the same + higher-dimensional family guide and runtime control guide already present on + the broader docs/resources lanes +- that means the first-session route now directly teaches: + - the dedicated native `Magic120Cell` and `MagicCube5D` families + - the current embedded-browser `MagicTile` host posture + - the shipped classic desktop control posture + - the current higher-dimensional control posture + - the native diagnostics check + - the explicit desktop-hosted `No-Go` XR/controller boundary +- focused validation for that public-manual continuation stayed green under: + - `npm --prefix website test -- --run src/__tests__/public-marketing-pages.test.tsx` + - `1` file passed + - `15` tests passed +- the same packet also refreshed the owned analyzer loop so the current + refactor posture stayed source-backed instead of inherited from older notes: + - `scripts/run-hypertwist-sentrux-source-only.sh` + - `Quality: 6228` + - all `7` rules pass + - `scripts/run-hypertwist-gitnexus-analyze.sh` + - retained local CLI again fell back cleanly to `npx -y gitnexus@latest` + on this Linux host because of the cross-platform `LadybugDB` native + payload mismatch + - bounded mirror refreshed at: + - `16,380` nodes + - `38,646` edges + - `679` clusters + - `300` flows + - `scripts/run-hypertwist-gitnexus-status.sh` + - `Indexed commit: a4a50b8` + - `Current commit: a4a50b8` + - `Status: up-to-date` +- current truthful reading after that refresh: + - the broad vanilla-refactor lane is no longer blocked by broken wrappers or + a failing structural gate + - the next worthwhile cleanup is selective readability or ownership work + chosen for product value, not emergency analyzer adoption + +## Latest feature-atlas runtime-guide parity follow-up (`2026-06-28`) + +- the public `FeaturesPage` then widened again so the feature atlas no longer + stops at capability tracks, higher-dimensional host posture, and roster + summaries when the broader public manual already carries a more practical + runtime-usage seam +- the same route now also renders the shared runtime control guide directly, + including: + - the shipped classic desktop control posture + - the current higher-dimensional desktop-control posture + - the native diagnostics check + - the explicit desktop-hosted `No-Go` XR/controller boundary +- this keeps the public feature atlas closer to a genuine capability-plus-usage + reference instead of requiring advanced readers to leave the atlas for docs, + resources, or getting-started just to find the current practical control and + diagnostics truth +- focused validation for that continuation stayed green under: + - `npm --prefix website test -- --run src/__tests__/public-marketing-pages.test.tsx` + - `1` file passed + - `15` tests passed +- the broader owned website/runtime/server umbrella then also stayed green + again under: + - `scripts/run-hypertwist-web-surface-validation.sh` + - focused website route/auth/release validation: `12` files, `74` tests + passed + - `npm --prefix website run build` + - `npm --prefix website/server run type-check` + - `npm --prefix website/server test -- --run` + - `10` website/server files passed, `36` tests passed + - `npm --prefix Content/Browser run verify:shell` + - `npm --prefix Content/Browser run build` + - `website/` and `Content/Browser/` production audits stayed at + `found 0 vulnerabilities` + - `website/server/` again retained only the already-documented upstream + `supertokens-node -> nodemailer` residual +- the owned structural gate stayed clean on the same packet: + - `scripts/run-hypertwist-sentrux-source-only.sh` + - `Quality: 6228` + - all `7` rules pass + +## Latest commerce/download manual deepening follow-up (`2026-06-29`) + +- the public commerce and package routes were then widened again so the pages + where operators actually decide to buy access or fetch the build no longer + stop at entitlement, target choice, and browser-to-desktop handoff +- the public `/pricing` route now also carries: + - the practical installed-software simulator manual + - the shared higher-dimensional family guide + - the same current input/device and runtime-control truth, including the + explicit desktop-hosted `No-Go` XR/controller boundary +- the public `/download` route now also carries: + - the installed-runtime manual directly on the package page + - the higher-dimensional family guide before first launch + - the current input/device and runtime-control truth before the operator + leaves the public release lane +- this keeps pricing/download closer to genuine public operator-manual + surfaces instead of leaving the practical product explanation scattered + across docs/resources/getting-started alone +- validation for that continuation stayed green under: + - `npm --prefix website test -- --run src/__tests__/public-marketing-pages.test.tsx` + - `1` file passed + - `15` tests passed + - `npm --prefix website run build` + - production website build passed + - `scripts/run-hypertwist-web-surface-validation.sh` + - focused website route/auth/release validation: `12` files, `74` tests + passed + - `website/server` suite: `10` files, `36` tests passed + - `Content/Browser` shell verification and production build passed + - `website/` and `Content/Browser/` production audits stayed at + `found 0 vulnerabilities` + - `website/server/` again retained only the already-documented upstream + `supertokens-node -> nodemailer` residual advisory + +## Latest shared public-manual plus control-continuity validation follow-up (`2026-06-29`) + +- the same-family continuation then spent its next bounded packet on shared + public-manual ownership plus additional native continuity proof instead of + widening claims +- the public website now centralizes repeated manual-card rendering in: + - `website/src/pages/public-page-helpers.tsx` + - `PrincipleCardSection` + - `BulletCardSection` + - `StepCardSection` + - `FaqCardSection` +- the current public/manual consumers now route through those shared helpers: + - `website/src/pages/public-pages-marketing.tsx` + - `website/src/pages/public-pages-features.tsx` + - `website/src/pages/public-pages-commerce.tsx` +- local public-surface validation for that refactor stayed green under: + - `npm --prefix website run type-check` + - `npm --prefix website test -- --run src/__tests__/public-marketing-pages.test.tsx` + - `1` file passed + - `15` tests passed + - `npm --prefix website run build` + - production website build passed +- the owned structural and graph loop also stayed green on the same packet: + - `scripts/run-hypertwist-sentrux-source-only.sh` + - `Quality: 6228` + - all `7` rules pass + - `scripts/run-hypertwist-gitnexus-analyze.sh` + - retained local CLI again fell back cleanly to `npx -y gitnexus@latest` + on this Linux host because of the cross-platform `LadybugDB` native payload + mismatch + - bounded mirror result: + - `16,387` nodes + - `38,682` edges + - `676` clusters + - `300` flows + - `scripts/run-hypertwist-gitnexus-status.sh` + - `Indexed commit: 1deca95` + - `Current commit: 1deca95` + - `Status: up-to-date` +- the adjacent native continuity-formatting proof also landed successfully on + the exact-source Windows lane `C:\HTpp` after the shared formatter extraction: + - authoritative short-root Unreal rebuild succeeded before the automation + reruns + - `HyperTwist.Browser.ControlInputContinuityStateFormatting` + - `State=Success` + - report: + `Saved\AutomationReports\Browser-ControlInputContinuityStateFormatting-Verify` + - `HyperTwist.Browser.ControlSettingsContinuityStateFormatting` + - `State=Success` + - report: + `Saved\AutomationReports\Browser-ControlSettingsContinuityStateFormatting-Verify` + - `HyperTwist.Browser.ControlProfileContinuityStateFormatting` + - `State=Success` + - report: + `Saved\AutomationReports\Browser-ControlProfileContinuityStateFormatting-Verify` + - the widget-level training-panel integration path also stayed green after + the formatter extraction: + - `HyperTwist.Browser.TrainingPanel.ControlProfileContinuityParity` + - `State=Success` + - report: + `Saved\AutomationReports\Browser-ControlProfileContinuityParity-Rerun` +- this keeps the native training/operator continuity packet honest after the + shared formatter extraction: the browser/public manual side now has lower + drift risk, and the sibling Unreal-side continuity text still has exact-source + proof for input, settings, and profile degraded-state rendering + +## Latest exact-source short-root continuity recovery proof (`2026-06-29`) + +- the next adjacent recovery pass closed one important validation gap instead + of widening scope again: the earlier short-root rerun had only matched the + formatter-name subset, so the exact-source Windows lane was re-proved again + against the broader continuity family on `C:\HTpp` +- the authoritative short-root Unreal rebuild stayed green before the reruns: + - `scripts/run-hypertwist-remote-unreal-build.sh --worktree-root 'C:\HTpp' --max-parallel-actions 8` + - `Result: Succeeded` + - UnrealBuildTool `Total execution time: 78.51 seconds` +- the exact-source formatting-family rerun then passed on the same short-root + lane: + - report: + `Saved\AutomationReports\ContinuityStateFormatting-Rerun` + - `HyperTwist.Browser.ControlInputContinuityStateFormatting` + - `HyperTwist.Browser.ControlProfileContinuityStateFormatting` + - `HyperTwist.Browser.ControlSettingsContinuityStateFormatting` + - all `3` tests completed with `Result={Success}` +- the exact-source broader profile-continuity rerun then also passed on the + same short-root lane: + - report: + `Saved\AutomationReports\ControlProfileContinuity-Rerun` + - `HyperTwist.Browser.CoachDashboard.ControlProfileContinuityArtifacts` + - `HyperTwist.Browser.TrainingPanel.ControlProfileContinuityParity` + - `HyperTwist.Browser.ControlProfileContinuityStateFormatting` + - all `3` tests completed with `Result={Success}` +- the repeated unattended editor dialog `Failed to create the web browser + window.` again remained non-blocking on this Windows automation lane +- this keeps the native continuity packet truthful after recovery: + - the shared formatter extraction is now backed by current exact-source + Windows proof + - the training-panel and coach-dashboard parity seams are explicitly + re-proved, not merely inferred from the narrower formatter-only rerun + +## Latest interrupted-session exact-source continuity completion proof (`2026-06-29`) + +- the next same-family recovery pass then treated the previously detached + remote automation session as incomplete instead of assuming success +- the broader maintained validation root had drifted on one sibling test file: + - remote `C:\HyperTwist_worktrees\phase10validate\UnrealHyperTwist\Source\UnrealHyperTwist\Tests\HyperTwistBrowserBridgeObjectTest.cpp` + still carried stale extra lines and failed the first rebuild with: + `error C2816: invocation of function-like macro 'IMPLEMENT_SIMPLE_AUTOMATION_TEST' is missing terminating ')'` + - the exact local file was re-synced to repair that stale remote source + instead of accepting the older broken copy as current truth +- after that repair, the exact touched continuity slice was re-synced into the + short-root recovery lane `C:\HTpp`, which was then used as the authoritative + exact-source completion lane for the interrupted packet +- the recovered short-root Unreal rebuild stayed green under: + - `scripts/run-hypertwist-remote-unreal-build.sh --worktree-root 'C:\HTpp'` + - `Result: Succeeded` + - UnrealBuildTool `Total execution time: 4645.02 seconds` +- the exact-source recovered continuity reruns then completed sequentially on + the same short-root lane and all stayed green: + - report root: + `Saved\AutomationReports\Continuity-Rerun-20260629-HyperTwist.Browser.ControlProfileContinuity` + - `HyperTwist.Browser.ControlProfileContinuityStateFormatting` + - `Result={Success}` + - report root: + `Saved\AutomationReports\Continuity-Rerun-20260629-HyperTwist.Browser.ControlInputContinuityStateFormatting` + - `HyperTwist.Browser.ControlInputContinuityStateFormatting` + - `Result={Success}` + - report root: + `Saved\AutomationReports\Continuity-Rerun-20260629-HyperTwist.Browser.ControlSettingsContinuityStateFormatting` + - `HyperTwist.Browser.ControlSettingsContinuityStateFormatting` + - `Result={Success}` +- the repeated unattended editor dialog `Failed to create the web browser + window.` again remained a non-blocking Windows editor artifact during these + recovered reruns +- this closes the interrupted-session gap truthfully: + - the prior detached remote session is no longer merely presumed green + - the current exact-source continuity family has fresh post-recovery Windows + proof on the short-root lane + - the stale remote-source issue is recorded as a repaired host-state problem, + not misdescribed as a current repository defect + +## Latest owned regression-gate plus maintained-root continuity-count masking follow-up (`2026-06-29`) + +- the next same-family finish-quality pass then closed two remaining “almost + there” gaps instead of widening scope again: + - the owned `sentrux` baseline-comparison loop was re-proved explicitly + - the broader maintained validation root re-proved degraded-state + continuity/count masking on the exact touched Unreal slice +- the HyperTwist-owned refactor loop is now backed by fresh before/after gate + evidence instead of only wrapper presence: + - `scripts/run-hypertwist-sentrux-gate.sh --save` + - persisted baseline: + `.sentrux/source-only-baseline.json` + - `scripts/run-hypertwist-sentrux-gate.sh` + - comparison result: + - `Quality: 6234 -> 6234` + - `Coupling: 0.15 -> 0.15` + - `Cycles: 0 -> 0` + - `God files: 1 -> 1` + - `No degradation detected` + - `scripts/run-hypertwist-sentrux-source-only.sh` + - `Quality: 6234` + - all `7` rules pass + - `scripts/run-hypertwist-gitnexus-analyze.sh` + - bounded mirror result: + - `16,397` nodes + - `38,754` edges + - `673` clusters + - `300` flows + - `scripts/run-hypertwist-gitnexus-status.sh` + - `Indexed commit: ab10931` + - `Current commit: ab10931` + - `Status: up-to-date` +- the exact touched continuity slice then also stayed green on the maintained + Windows validation root `C:\HyperTwist_worktrees\phase10validate`: + - exact-source rebuild: + - `Result: Succeeded` + - UnrealBuildTool `Total execution time: 3325.07 seconds` + - focused automation report family: + `Continuity-CountMasking-20260629-*` + - successful filters: + - `HyperTwist.Browser.ControlInputContinuityStateFormatting` + - `HyperTwist.Browser.ControlSettingsContinuityStateFormatting` + - `HyperTwist.Browser.ControlProfileContinuityStateFormatting` + - `HyperTwist.Browser.TrainingPanel.ControlProfileContinuityParity` + - `HyperTwist.Browser.CoachDashboard.ControlProfileContinuityArtifacts` +- this keeps the lane honest in two useful ways: + - the owned analyzer/tooling posture is proven as a real regression loop, + not just a documented wrapper set + - the native control/input, control/settings, and control/profile continuity + seams now have fresh maintained-root Windows proof that degraded readiness + masks stale counts and ids instead of overreporting continuity state + +## Latest responsive website revalidation plus GitNexus status hardening follow-up (`2026-06-29`) + +- the next same-family continuation stayed inside the current owned + website/tooling lane instead of reopening any new runtime branch +- the public/protected browser product surface was revalidated at real browser + breakpoints after the recent public-manual widening: + - `scripts/run-hypertwist-web-surface-validation.sh --with-responsive-e2e` + - focused website route/auth/release validation: `12` files, `74` tests + passed + - responsive public-route Playwright proof: `22` tests passed + - responsive protected-route Playwright proof: `12` tests passed + - `website/server` suite: `10` files, `36` tests passed + - `Content/Browser` shell verification and production build passed + - `website/` and `Content/Browser/` production audits stayed at + `found 0 vulnerabilities` + - `website/server/` again retained only the already-documented upstream + `supertokens-node -> nodemailer` residual advisory +- the adjacent HyperTwist-owned refactor/tooling wrapper was also hardened: + - `scripts/run-hypertwist-gitnexus-status.sh` now reports when the bounded + source-only mirror exists but a completed `.gitnexus/meta.json` index does + not yet, so refresh-window checks no longer look corrupted + - that message was exercised directly by temporarily withholding the + disposable index metadata and rerunning the wrapper + - the graph loop then re-proved current freshness under: + - `scripts/run-hypertwist-gitnexus-analyze.sh` + - `16,387` nodes + - `38,686` edges + - `676` clusters + - `300` flows + - `scripts/run-hypertwist-gitnexus-status.sh` + - `Indexed commit: a41d7ef` + - `Current commit: a41d7ef` + - `Status: up-to-date` + - `scripts/run-hypertwist-sentrux-source-only.sh` also stayed green at + `Quality: 6228` with all `7` rules passing +- current truthful interpretation: + - the current website/public-manual lane is not just implemented, but + revalidated at product-shaped breakpoints after the latest copy/structure + deepening work + - the HyperTwist-owned refactor/tooling posture is healthy and now clearer + for operators during GitNexus mirror refresh windows + +## Latest launch-summary authority alignment follow-up (`2026-06-29`) + +- the next same-family continuation stayed in the owned browser rollout lane + and corrected a real code-versus-authority mismatch +- the shared launch-status resolver in + `website/src/shared/public-launch.ts` now prefers the auth server's richer + `launch` summary when `GET /api/auth/health` provides it, instead of always + recomputing checklist, blockers, and checkout targets only from lower-level + booleans +- that means the public `/launch-status` and protected `/app/launch-status` + surfaces now directly consume server-owned launch blocker labels and current + operator/studio checkout targets when present, while still degrading safely + into bounded local derived checklist truth if the richer summary is missing +- validation stayed green under: + - `npm --prefix website run type-check` + - `npm --prefix website test -- --run src/__tests__/public-launch.test.ts src/__tests__/public-marketing-pages.test.tsx src/__tests__/protected-app-pages.test.tsx` + - `3` files passed + - `29` tests passed + - `scripts/run-hypertwist-web-surface-validation.sh` + - focused website route/auth/release validation: `13` files, `79` tests + passed + - `website/server` suite: `10` files, `36` tests passed + - `Content/Browser` shell verification and production build passed + - `website/` and `Content/Browser/` production audits stayed at + `found 0 vulnerabilities` + - `website/server/` again retained only the already-documented upstream + `supertokens-node -> nodemailer` residual advisory +- current truthful interpretation: + - the browser launch-authority lane now matches the already-declared + server-owned contract more closely instead of merely being consistent with + it by coincidence + +## Latest shared public-manual helper consolidation follow-up (`2026-06-29`) + +- the next same-family website quality pass stayed inside the owned public + manual lane and removed more repeated route-local section rendering +- `website/src/pages/public-page-helpers.tsx` now also owns reusable sections + for: + - simulator manual + - higher-dimensional runtime guide + - input and device posture + - control-profile roster + - runtime control guide +- the current browser-manual consumers now route those sections through: + - `website/src/pages/public-pages-marketing.tsx` + - `website/src/pages/public-pages-commerce.tsx` +- this keeps the docs/about/resources/pricing/download/getting-started family + aligned as one operator/distribution manual instead of separate near-copy + route implementations +- validation stayed green under: + - `npm --prefix website run type-check` + - `scripts/run-hypertwist-web-surface-validation.sh` + - focused website route/auth/release validation: `13` files, `79` tests + passed + - `website/server` suite: `10` files, `36` tests passed + - `Content/Browser` shell verification and production build passed + - `website/` and `Content/Browser/` production audits stayed at + `found 0 vulnerabilities` + - `website/server/` again retained only the already-documented upstream + `supertokens-node -> nodemailer` residual advisory +- the owned refactor/tooling loop also stayed healthy on the same pass: + - `scripts/run-hypertwist-sentrux-source-only.sh` + - `Quality: 6227` + - all `7` rules pass + - `scripts/run-hypertwist-gitnexus-analyze.sh` + - bounded mirror result: + - `16,389` nodes + - `38,702` edges + - `674` clusters + - `300` flows + - `scripts/run-hypertwist-gitnexus-status.sh` + - `Indexed commit: f1f5cce` + - `Current commit: f1f5cce` + - `Status: up-to-date` + +## Latest protected launch-status responsive recovery plus tooling rerun (`2026-06-29`) + +- the next same-family browser pass fixed a real small-screen regression on the + protected `/app/launch-status` route instead of widening scope again +- the current mobile overflow came from stacked action rows whose button links + still sized to long label text rather than the available column width +- `website/src/styles/global.css` now tightens the owned small-screen + button-row posture so stacked actions take the full column width and allow + wrapped labels instead of widening the viewport by a couple of pixels +- that correction stayed inside the existing protected browser shell and did + not alter the browser-versus-desktop product boundary +- the owned browser validation lane then re-ran fully and stayed green under: + - `scripts/run-hypertwist-web-surface-validation.sh --with-responsive-e2e` + - focused website route/auth/release validation: `13` files, `79` tests + passed + - responsive public-route Playwright proof: `22` tests passed + - responsive protected-route Playwright proof: `12` tests passed + - `website/server` suite: `10` files, `36` tests passed + - `Content/Browser` shell verification and production build passed + - `website/` and `Content/Browser/` production audits stayed at + `found 0 vulnerabilities` + - `website/server/` again retained only the already-documented upstream + `supertokens-node -> nodemailer` residual advisory +- the owned structural and graph refresh also stayed healthy on the same pass: + - `scripts/run-hypertwist-sentrux-source-only.sh` + - `Quality: 6228` + - all `7` rules pass + - `scripts/run-hypertwist-gitnexus-analyze.sh` + - bounded mirror result: + - `16,394` nodes + - `38,737` edges + - `674` clusters + - `300` flows + - `scripts/run-hypertwist-gitnexus-status.sh` + - `Indexed commit: a863f79` + - `Current commit: a863f79` + - `Status: up-to-date` +- current truthful reading after this recovery pass: + - the public and protected website/manual surfaces are still professional at + real mobile/tablet breakpoints after the recent manual widening + - the HyperTwist-owned refactor loop remains healthy enough that the next + worthwhile work continues to be native/runtime truth and product-boundary + refinement, not missing browser or analyzer hygiene + +## Latest feature-atlas shared-section completion plus public legal-route responsive proof (`2026-06-29`) + +- the next same-family continuation stayed inside the owned website/manual lane + and closed a remaining public-route drift-risk gap instead of widening scope +- `website/src/pages/public-pages-features.tsx` now routes the repeated manual + sections through the same shared helper ownership already used by the + broader public family: + - `HigherDimensionalRuntimeGuideSection` + - `InputAndDevicePostureSection` + - `ControlProfileRosterSection` + - `RuntimeControlGuideSection` +- this keeps the public feature atlas aligned with the surrounding + docs/resources/pricing/download/getting-started surfaces instead of leaving + `/features` on a separate near-copy structure for the same manual truth +- the same continuation then widened responsive browser proof across the + remaining public legal/reference routes: + - `/changelog` + - `/open-source-notices` + - `/privacy` + - `/terms` + - `/shipping-payment` +- a later adjacent auth-entry parity continuation then also added `/login` to + that same public matrix so both real browser account-entry routes sit under + explicit mobile/tablet proof +- the owned public responsive route matrix therefore now covers: + - homepage + - features + - about + - resources + - docs + - pricing + - download + - getting-started + - launch-status + - support + - changelog + - open-source-notices + - privacy + - terms + - shipping-payment + - login + - register +- validation stayed green under: + - `scripts/run-hypertwist-web-surface-validation.sh --with-responsive-e2e` + - focused website route/auth/release validation: `13` files, `79` tests + passed + - responsive public-route Playwright proof: `34` tests passed + - responsive protected-route Playwright proof: `12` tests passed + - `website/server` suite: `10` files, `36` tests passed + - `Content/Browser` shell verification and production build passed + - `website/` and `Content/Browser/` production audits stayed at + `found 0 vulnerabilities` + - `website/server/` again retained only the already-documented upstream + `supertokens-node -> nodemailer` residual advisory +- current truthful reading after this continuation: + - the feature atlas now sits on the same shared public-manual ownership path + as the surrounding major public routes + - the lower-traffic public legal/reference routes now have real + mobile/tablet browser proof instead of relying only on unit tests and + source review + +## Latest hygiene-aware GitNexus status plus feature-atlas FAQ continuity (`2026-06-29`) + +- the next bounded continuation stayed inside two already-open owned lanes: + the HyperTwist refactor wrapper surface and the public/manual feature-atlas + surface +- `scripts/run-hypertwist-gitnexus-status.sh` now treats a missing disposable + `.gitnexus-source-only-root/` mirror as normal post-hygiene absence in + default mode and points the operator back to + `scripts/run-hypertwist-gitnexus-analyze.sh` to recreate it +- the same wrapper now also distinguishes an interrupted or rebuilding mirror + whose `.gitnexus/meta.json` is not yet present, so a half-built analysis + root no longer looks identical to a fully cleaned one +- callers that still want fail-fast behavior can restore it with: + - `HYPERTWIST_GITNEXUS_STATUS_REQUIRE_INDEX=1` +- the adjacent public/manual follow-up then widened the public feature atlas + with an explicit capability FAQ seam so the route itself now answers the + common product-boundary questions advanced readers usually ask there: + - why the browser surface is intentionally narrower than the desktop runtime + - why HyperTwist still keeps the web product surface even though the + simulator is desktop-first + - why XR/controller completion is not yet marketed as finished + - how current control, settings, and bounded higher-dimensional continuity + should be understood +- current truthful reading after this continuation: + - the HyperTwist-owned analyzer lane now behaves more professionally after + correct hygiene instead of manufacturing a false corruption signal + - the public feature atlas is now closer to a real operator-facing manual, + not just a capability list diff --git a/docs/v6_5_deep_manual_pack/HyperTwist/FEATURE_REGISTRY.md b/docs/v6_5_deep_manual_pack/HyperTwist/FEATURE_REGISTRY.md index 85171c9..bf16b7b 100644 --- a/docs/v6_5_deep_manual_pack/HyperTwist/FEATURE_REGISTRY.md +++ b/docs/v6_5_deep_manual_pack/HyperTwist/FEATURE_REGISTRY.md @@ -147,7 +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, exact classic-cube pointer, orbit, zoom, and action-shortcut truth, higher-dimensional dedicated-family runtime ownership truth, project-level `EnhancedInput` plus motion-controller groundwork facts, immersive-presence contract presence, and explicit unfinished XR/runtime plus preferences truth. The rendered detail line now also carries the fixed desktop-hosted `No-Go` decision on native OpenXR/controller widening instead of leaving that truth stranded in a non-rendered follow-up field. A later same-day structured-boundary hardening follow-up then promoted that same XR/controller boundary into stable inspect-surface fields as well, including decision id `desktop-hosted-openxr-controller-widening-no-go` plus explicit reopen requirements for dedicated runtime owners, user-facing settings or rebinding ownership, and Windows packaged controller validation, so native operator automation no longer depends only on rendered prose to verify the boundary. 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. The latest same-family truth-render follow-up on `2026-06-24` then rebuilt that same maintained validation root with `Result: Succeeded`, UnrealBuildTool `Total execution time: 172.52 seconds`, and exported `Saved\AutomationReports\Browser-XrNoGoRendered-Verify\index.json` with all `20` `HyperTwist.Browser.*` tests green again, explicitly covering both training-panel and coach-dashboard control-input detail-line visibility for the `No-Go` host decision. A later same-day post-build structured-boundary follow-up then rebuilt that same maintained validation root once more with `Result: Succeeded`, UnrealBuildTool `Total execution time: 2323.18 seconds`, and exported `Saved\AutomationReports\Browser-XrBoundaryStructured-PostBuild-Verify\index.json` with all `20` `HyperTwist.Browser.*` tests green again, now explicitly covering the stable decision-id and reopen-requirement fields on both control-input inspect surfaces alongside the sibling control/settings and control/profile seams. A later same-day `2026-06-25` parity follow-up then widened the same surface from general readiness truth into literal roster truth by rendering dedicated classic-cube pointer and action-shortcut lines, rebuilding the maintained validation root with `Result: Succeeded` at `5278.57 seconds` and exact-source rerun `70.76 seconds`, and exporting `Saved\AutomationReports\Browser-ControlRosterParity-Verify\index.json` with all `21` `HyperTwist.Browser.*` tests green, including both training-panel and coach-dashboard control-input surfaces plus the structured dashboard artifact seam. The latest same-family `2026-06-28` ownership-truth follow-up then tightened higher-dimensional readiness again by resolving the shipped `Magic120Cell` and `MagicCube5D` dedicated-family host, view-context, session, and interactive-scene surfaces explicitly by activation profile id instead of treating broad catalog validity as equivalent proof. That exact-source-state follow-up rebuilt maintained validation root `C:\HyperTwist_worktrees\phase10validate` with `Result: Succeeded`, UnrealBuildTool `Total execution time: 109.14 seconds`, then passed all three focused browser filters `TrainingPanel.ControlInputReadinessInspectSurface`, `CoachDashboard.ControlInputReadinessInspectSurface`, and `CoachDashboard.ControlSurfaceStructuredTextArtifacts`, so both the inspect surfaces and the rendered structured dashboard row now keep concrete family ownership ids such as `phase6c/magic120cell/runtime-host-surface` and `phase6c/magiccube5d/interactive-scene-surface` visible to operators. A later same-day bounded preferences-continuity follow-up then tightened the non-`XR` seam again without reopening the controller lane: the preferences line now resolves the first valid viewer camera-export artifact instead of trusting only the first listed id, keeps `artifact/camera-export-json` plus `immersive-training-session-recall-boundary` visible with recall-scope and preference-field counts, and preserves the honest boundary that broader polished rebinding and control-settings UI are still not shipped. That exact-source continuity follow-up then rebuilt maintained validation root `C:\HyperTwist_worktrees\phase10validate` with `Result: Succeeded`, UnrealBuildTool `Total execution time: 3372.27 seconds`, and exported `Browser-PreferencesContinuity-20260628-HyperTwist.Browser.TrainingPanel.ControlInputReadinessInspectSurface`, `Browser-PreferencesContinuity-20260628-HyperTwist.Browser.CoachDashboard.ControlInputReadinessInspectSurface`, and `Browser-PreferencesContinuity-20260628-HyperTwist.Browser.CoachDashboard.ControlSurfaceStructuredTextArtifacts`, each with `index.json` `State=Success`, while the accepted unattended `Failed to create the web browser window.` dialog remained a non-blocking Windows editor lane artifact. | | 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, persisted generated-mode selector recall when a structurally valid launch request is present, and explicit unfinished XR/controller rebinding truth. A later same-day structured-boundary hardening follow-up then carried the same `desktop-hosted-openxr-controller-widening-no-go` decision id plus the explicit reopen requirements for dedicated runtime owners, polished user-facing settings or rebinding ownership, and Windows packaged controller validation into this surface’s structured state as well, so control-settings diagnostics no longer have to prove the boundary only by substring matching their rendered detail line. 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. A later same-day selector-recall hardening follow-up then rebuilt that same maintained validation root again with `Result: Succeeded`, UnrealBuildTool `Total execution time: 4084.77 seconds`, and exported `Saved\AutomationReports\Browser-SelectorRecall-Verify\index.json` with all `20` `HyperTwist.Browser.*` tests passing, keeping the current control/settings proof aligned with the latest repository-backed selector-recall behavior. A later same-day post-build structured-boundary follow-up then rebuilt that same maintained validation root once more with `Result: Succeeded`, UnrealBuildTool `Total execution time: 2323.18 seconds`, and exported `Saved\AutomationReports\Browser-XrBoundaryStructured-PostBuild-Verify\index.json` with all `20` `HyperTwist.Browser.*` tests green again, now explicitly covering the stable decision-id and reopen-requirement fields on both control/settings inspect surfaces alongside the sibling control/input and control/profile seams. The latest same-family `2026-06-28` ownership-proof follow-up then tightened this settings seam again by resolving the active higher-dimensional session surface, active interactive-scene surface, dedicated-family session surface, dedicated-family interactive-scene surface, persistence-boundary id, and state-semantics id explicitly for both `Magic120Cell` and `MagicCube5D`, while also carrying concrete projection, symmetry, stereo, visibility, and focus tag counts plus persistence-readiness booleans in structured state instead of leaving that ownership implied by broad view-profile validity. That exact-source proof-hardening follow-up synced the tightened browser test source into the already-current maintained validation root, rebuilt it with `Result: Succeeded` and UnrealBuildTool `Total execution time: 168.35 seconds`, then passed focused browser proof for `HyperTwist.Browser.TrainingPanel.ControlSettingsOwnershipInspectSurface`, `HyperTwist.Browser.CoachDashboard.ControlSettingsOwnershipInspectSurface`, and `HyperTwist.Browser.CoachDashboard.ControlSurfaceStructuredTextArtifacts`, so both the inspect surfaces and the rendered structured dashboard row now keep exact family-owned ids such as `phase6c/magic120cell/dedicated-training-session-surface`, `phase6c/magic120cell/interactive-scene-surface`, `magic120cell-persistence-boundary`, `phase6c/magiccube5d/dedicated-training-session-surface`, and `phase6c/magiccube5d/family-owned-scene-state` visible to operators. A later same-day bounded preferences-continuity follow-up then tightened the same settings seam again without reopening native controller widening: the structured state now carries camera workflow, preview-state, export-artifact, immersive presence-surface, recall-scope, preference-field, and reset-surface counts together with explicit camera-continuity and immersive-session-recall readiness booleans; the rendered status text now distinguishes `missing`, `partial`, and `ready` ownership truth instead of collapsing those states; and the shipped `artifact/camera-export-json` plus `immersive-training-session-recall-boundary` ids now stay visible in both the training-panel and coach-dashboard settings detail lines. That exact-source continuity follow-up then rebuilt maintained validation root `C:\HyperTwist_worktrees\phase10validate` with `Result: Succeeded`, UnrealBuildTool `Total execution time: 3372.27 seconds`, and exported `Browser-PreferencesContinuity-20260628-HyperTwist.Browser.TrainingPanel.ControlSettingsOwnershipInspectSurface`, `Browser-PreferencesContinuity-20260628-HyperTwist.Browser.CoachDashboard.ControlSettingsOwnershipInspectSurface`, and `Browser-PreferencesContinuity-20260628-HyperTwist.Browser.CoachDashboard.ControlSurfaceStructuredTextArtifacts`, each with `index.json` `State=Success`, while the same accepted unattended `Failed to create the web browser window.` dialog remained non-blocking on the Windows editor lane. | -| 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 plus the exact classic move roster, 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, persisted generated-mode selector recall when a structurally valid launch request is present, and explicit unfinished controller rebinding truth. The rendered roster boundary now also states the fixed desktop-hosted `No-Go` decision on native OpenXR/controller widening instead of sounding like a merely pending generic settings packet. A later same-day structured-boundary hardening follow-up then carried the same `desktop-hosted-openxr-controller-widening-no-go` decision id plus its explicit reopen requirements into the roster surface’s structured state too, so native operator automation can prove the shipped roster boundary without depending only on rendered text. 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`. A later same-day selector-recall hardening follow-up then rebuilt that same maintained validation root again with `Result: Succeeded`, UnrealBuildTool `Total execution time: 4084.77 seconds`, and exported `Saved\AutomationReports\Browser-SelectorRecall-Verify\index.json` with all `20` `HyperTwist.Browser.*` tests passing again, now explicitly covering imported-request fallback plus active-deck precedence for repository-backed selector recall inside the training-panel and coach-dashboard roster surface. The latest same-family truth-render follow-up on `2026-06-24` then rebuilt that same maintained validation root with `Result: Succeeded`, UnrealBuildTool `Total execution time: 172.52 seconds`, and exported `Saved\AutomationReports\Browser-XrNoGoRendered-Verify\index.json` with all `20` `HyperTwist.Browser.*` tests green again, explicitly covering the roster detail-line visibility of the same fixed `No-Go` boundary. A later same-day post-build structured-boundary follow-up then rebuilt that same maintained validation root once more with `Result: Succeeded`, UnrealBuildTool `Total execution time: 2323.18 seconds`, and exported `Saved\AutomationReports\Browser-XrBoundaryStructured-PostBuild-Verify\index.json` with all `20` `HyperTwist.Browser.*` tests green again, now explicitly covering the stable decision-id and reopen-requirement fields on both control/profile inspect surfaces alongside the sibling control/input and control/settings seams. A later same-day `2026-06-25` parity follow-up then added the literal shipped classic move-roster line to that surface, mirrored it into dedicated coach-dashboard structured rows, rebuilt the maintained validation root with `Result: Succeeded` at `5278.57 seconds` and exact-source rerun `70.76 seconds`, and exported `Saved\AutomationReports\Browser-ControlRosterParity-Verify\index.json` with all `21` `HyperTwist.Browser.*` tests green, including both training-panel and coach-dashboard control/profile surfaces plus the structured dashboard artifact seam. | +| 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 plus the exact classic move roster, 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, persisted generated-mode selector recall when a structurally valid launch request is present, and explicit unfinished controller rebinding truth. The rendered roster boundary now also states the fixed desktop-hosted `No-Go` decision on native OpenXR/controller widening instead of sounding like a merely pending generic settings packet. A later same-day structured-boundary hardening follow-up then carried the same `desktop-hosted-openxr-controller-widening-no-go` decision id plus its explicit reopen requirements into the roster surface’s structured state too, so native operator automation can prove the shipped roster boundary without depending only on rendered text. 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`. A later same-day selector-recall hardening follow-up then rebuilt that same maintained validation root again with `Result: Succeeded`, UnrealBuildTool `Total execution time: 4084.77 seconds`, and exported `Saved\AutomationReports\Browser-SelectorRecall-Verify\index.json` with all `20` `HyperTwist.Browser.*` tests passing again, now explicitly covering imported-request fallback plus active-deck precedence for repository-backed selector recall inside the training-panel and coach-dashboard roster surface. The latest same-family truth-render follow-up on `2026-06-24` then rebuilt that same maintained validation root with `Result: Succeeded`, UnrealBuildTool `Total execution time: 172.52 seconds`, and exported `Saved\AutomationReports\Browser-XrNoGoRendered-Verify\index.json` with all `20` `HyperTwist.Browser.*` tests green again, explicitly covering the roster detail-line visibility of the same fixed `No-Go` boundary. A later same-day post-build structured-boundary follow-up then rebuilt that same maintained validation root once more with `Result: Succeeded`, UnrealBuildTool `Total execution time: 2323.18 seconds`, and exported `Saved\AutomationReports\Browser-XrBoundaryStructured-PostBuild-Verify\index.json` with all `20` `HyperTwist.Browser.*` tests green again, now explicitly covering the stable decision-id and reopen-requirement fields on both control/profile inspect surfaces alongside the sibling control/input and control/settings seams. A later same-day `2026-06-25` parity follow-up then added the literal shipped classic move-roster line to that surface, mirrored it into dedicated coach-dashboard structured rows, rebuilt the maintained validation root with `Result: Succeeded` at `5278.57 seconds` and exact-source rerun `70.76 seconds`, and exported `Saved\AutomationReports\Browser-ControlRosterParity-Verify\index.json` with all `21` `HyperTwist.Browser.*` tests green, including both training-panel and coach-dashboard control/profile surfaces plus the structured dashboard artifact seam. The later same-family `2026-06-28` continuity follow-up then widened that roster seam again by carrying the active higher-dimensional scene id alongside the active activation, view-context, and session ids, while also resolving the first valid viewer camera-export artifact and keeping `artifact/camera-export-json` plus `immersive-training-session-recall-boundary` visible with recall-scope and preference-field counts through both the native detail line and a dedicated coach-dashboard structured row. The authoritative short-root recovery lane on `C:\HTpp` then re-synced the exact touched Unreal files, rebuilt the exact-source state with `Result: Succeeded` and UnrealBuildTool `Total execution time: 2374.44 seconds`, and exported both `Browser-ControlProfileContinuityParity-20260628-HyperTwist.Browser.TrainingPanel.ControlProfileContinuityParity` and `Browser-ControlProfileContinuityParity-20260628-HyperTwist.Browser.CoachDashboard.ControlProfileContinuityArtifacts` with `Result={Success}`, while the repeated `Failed to create the web browser window.` dialog remained a non-blocking unattended editor artifact. A later exact-source short-root recovery proof on `2026-06-29` then rebuilt the same touched state again with `Result: Succeeded` and UnrealBuildTool `Total execution time: 78.51 seconds`, re-exported `Saved\AutomationReports\ControlProfileContinuity-Rerun` with `HyperTwist.Browser.CoachDashboard.ControlProfileContinuityArtifacts`, `HyperTwist.Browser.TrainingPanel.ControlProfileContinuityParity`, and `HyperTwist.Browser.ControlProfileContinuityStateFormatting` all `Result={Success}`, and also re-exported `Saved\AutomationReports\ContinuityStateFormatting-Rerun` with the wider shared continuity-formatting trio green, so the roster-parity and shared continuity-helper seams are both grounded in current exact-source Windows proof rather than only the earlier broader maintained-root evidence. A final maintained-root exact-source hardening follow-up later that same day then tightened the shared continuity formatter so absent readiness masks stale ids and counts instead of leaking carried-over values, rebuilt `C:\HyperTwist_worktrees\phase10validate` with `Result: Succeeded` and UnrealBuildTool `Total execution time: 3325.07 seconds`, and exported `Continuity-CountMasking-20260629-*` with `HyperTwist.Browser.ControlProfileContinuityStateFormatting`, `HyperTwist.Browser.TrainingPanel.ControlProfileContinuityParity`, and `HyperTwist.Browser.CoachDashboard.ControlProfileContinuityArtifacts` all `Result={Success}`, keeping the shipped roster-continuity truth grounded in current maintained-root degraded-state proof as well. | | Native XR project-plugin posture inspect truth | Implemented now | landed first-party `2026-06-25` browser/native operator continuation | All three native control/input, control/settings, and control/profile inspect surfaces now expose the current project `OpenXR` plugin enabled/disabled fact in both structured state and rendered operator lines, so project-level motion-controller groundwork no longer masquerades as an enabled `OpenXR` shipping posture. The same primary reverse-SSH `localhost:22022` lane rebuilt the exact-source state on maintained validation root `C:\HyperTwist_worktrees\phase10validate` with `Result: Succeeded`, UnrealBuildTool `Total execution time: 99.38 seconds`, then exported `Saved\AutomationReports\Browser-XrPluginProjectPosture-Verify\index.json` with all `20` `HyperTwist.Browser.*` tests green across the training-panel and coach-dashboard input/settings/profile seams. | | 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. | @@ -268,7 +268,7 @@ repo. | Feature | Status | Primary authority | Notes | |---|---|---|---| -| Public `hypertwist.app` marketing shell | Implemented now | first-party `website/` app + feature registry/roadmap authority | HyperTwist now has a dedicated first-party public web surface for homepage, feature atlas, about, resources, pricing, download, support, legal routes, a dedicated `/getting-started` onboarding surface, and a dedicated `/launch-status` authority surface. This lane is separate from the embedded Unreal browser runtime under `Content/Browser/` and does not claim browser-simulator parity. The same public lane now also serves as a bounded operator/distribution manual through the docs/resources/download/support surfaces, the public feature-atlas route, the dedicated getting-started route, the dedicated launch-status route, and related launch/status surfaces, explaining browser-versus-desktop posture, rollout steps, package proof, simulator-use guidance, and current input/device truth without claiming browser ownership of the native runtime or overclaiming unfinished VR/controller posture. The same package now also carries a first-party external runtime-readiness verifier so deploy-time env and live health posture can be checked outside the dashboard, plus separated local-versus-production env templates whose placeholder values are intentionally rejected until real launch config is in place, bootstrap CI now validates both the frontend and auth-server website commands directly, and the auth server can now auto-serve the built `website/dist` bundle with bounded SPA fallback for same-origin public deployment. Request-level server coverage now also proves that public/app shell delivery does not shadow `/api/*`, `/auth*`, `/health`, or missing asset paths, while the pricing/download/notices routes now surface first-party preview-versus-launch posture from the same bounded launch checklist instead of relying on hidden operator-only status. The shared marketing shell now also carries a compact public-site-status banner across public pages, the homepage keeps a fuller status section, and the shared public launch-status component now consumes live auth-health webhook/runtime truth in addition to release-manifest download readiness so public marketing copy does not claim launch posture from static checkout/download config alone. The auth server now also emits an authoritative `launch` summary on `/api/auth/health`, including required blocker labels, billing product/price-map gates, and current checkout targets, so the public banner and protected dashboard no longer duplicate launch-blocker evaluation client-side. A later same-family continuation then widened that release-manifest authority again to carry public runtime commerce config for operator/studio checkout URLs and live plan-price strings, so pricing, notices, and dashboard launch-readiness surfaces no longer depend only on frontend build-time checkout config. The live website lane now also owns route-aware title/description/canonical/Open-Graph/Twitter metadata for the real `hypertwist.app` marketing surface so deployed public pages no longer remain on a single generic SPA title/description, plus first-party `robots.txt` and `sitemap.xml` assets for the public route set while keeping `/app`, `/login`, and `/register` out of crawler posture. The real `check-runtime-readiness` CLI is now also exercised against the checked-in production example env files, and a spawned `website/server` bootstrap proof now verifies the live same-origin process path from production-shaped env into `/health`, `/api/auth/health`, built-shell serving, and the public anonymous release-manifest posture for the shared desktop release lane. The same verifier now also probes the deployed root-shell marker and can explicitly fail when the public origin is still serving the older placeholder rollout page instead of the first-party website/auth-server lane, while the repo now also carries first-party `website/deploy/` `nginx` plus `systemd` handoff templates, a concrete same-origin public-host cutover guide, a deployment-file renderer that emits resolved operator outputs from real checkout paths, and a manifest-driven bundle renderer that lets one authoritative input own the public origin while emitting validated env plus install artifacts together, with the shared-VPS-safe default upstream moved to `3011` after live host inspection confirmed `3001` is already occupied by FamiliarOS. The same deployment lane now also distinguishes `launch` from `preview` posture so honest missing checkout/download/webhook/release values are accepted only for non-public rehearsal while placeholder strings still fail, `runtime.mode: mixed` plus `public_origin_ready: true` counts as valid preview-host proof, and the staging helper can archive either committed `HEAD` or the live worktree through `--archive-source worktree`. An isolated VPS-local staging proof then confirmed that both the committed HyperTwist website lane and the later preview-tier worktree packet can serve green health, release-manifest, and first-party shell responses on that real shared host behind `3011`, and a later root-owned cutover then replaced the public placeholder site with the live first-party same-origin preview deployment on `https://hypertwist.app`. The package now also ships a bounded root-owned live-deploy helper that stages the committed checkout, uploads the rendered bundle, installs env, rebuilds the site, replaces the live `systemd` plus `nginx` files, and validates the public origin; that helper has already been re-proved idempotently against the live host. The repo now also ships that host-proof flow as a first-party staging helper so future sessions can rerun the temp checkout/build/boot verification path directly before or after root-owned cutover. The website lane now also owns a sanitized generated packaged-validation summary for the Windows higher-dimensional desktop proof, rendered from the checked-in authoritative package report into `website/src/shared/generated/windows-package-validation-summary.json`, and the owned web-surface validation gate now checks that generated proof for freshness before approving the current public/auth/download/browser lane. The remaining public conversion seams now also stop dead-ending on generic sign-in/support detours when the next lane is already known: the explorer CTA preserves `/register?next=/app`, operator fallback opens the protected downloads lane, studio fallback opens the protected browser-access rollout lane, and launch/download fallback callouts now point directly at protected release, notices, or dashboard follow-through. The narrative/help surfaces then widened again so the public About and Support pages also surface the same live launch-readiness callout and packaged desktop-proof section already used by the stronger public manual routes, keeping maturity language attached to current native release evidence instead of leaving those pages purely abstract. The same public manual continuation now also adds a direct reusable surface-choice guide across the homepage, About, Pricing, Download, and Support pages so operators no longer have to infer from the larger surface matrix alone when they should stay on the public web surface, move into the protected dashboard, or move into the packaged desktop runtime. A later same-family continuation then propagated that same guide through the remaining public feature/docs/resources/changelog/legal pages as well, so the whole public site now preserves one consistent browser-versus-protected-versus-desktop handoff story instead of leaving those lower-traffic surfaces on older implicit wording. A further same-day manual-clarity continuation then added a reusable direct comparison section across the homepage, About, Docs, and Download routes explaining why the website remains necessary, where it is intentionally narrower than the simulator, why the native Unreal runtime stays primary, and how the current keyboard or mouse versus unfinished XR/controller truth should be read. The latest same-family parity follow-up then widened that exact browser-versus-desktop reality section into Pricing and Resources as well, so commercial and reference-heavy public routes no longer rely only on the lighter surface-choice guide when explaining what stays native and where the current XR/controller boundary still begins. The next adjacent parity follow-up then extended the same direct comparison into the public Feature atlas and Support routes as well, so the remaining major public operator-facing surfaces no longer fall back to the lighter guide alone when capability review or recovery work needs the sharper website-versus-native split. A later same-family continuity follow-up then widened the shared release-decision guide into the remaining public legal/notices routes too, so open-source notices, privacy, terms, and shipping/payment now also tell the operator whether the next honest move is protected desktop access, pricing/provisioning, protected browser/account continuity, or notices/source follow-through instead of leaving those pages on the older lighter handoff only. The same browser shell now also has a first-party top-level runtime-recovery boundary, so unexpected React route failures degrade into a HyperTwist-owned retry/return surface that keeps the browser-versus-desktop product truth explicit instead of collapsing into a blank shell. A later same-family quickstart/manual continuation then added a reusable first serious-session guide across homepage, docs, and download so operators can see the real path from release-target choice through desktop-link pairing, first native verification, higher-dimensional verification, and the current XR/controller `No-Go` boundary in one place instead of reconstructing that flow from scattered adjacent sections. That same onboarding/manual packet is now also anchored at a dedicated public `/getting-started` route so the shortest complete browser-to-desktop first-session path is canonical, crawlable, and easier to hand off than the broader site sections alone. The next adjacent launch-authority continuation then did the same for rollout truth through a dedicated public `/launch-status` route, giving preview-versus-launch posture, rollout blockers, packaged proof, and release-reference follow-through one canonical public authority surface instead of leaving that lane distributed across pricing and compact status banners alone. The next same-family shared-auth manual continuation then widened the real browser-account method lineup beyond the auth entry forms and deeper docs surfaces into the homepage, pricing, download, and support routes too, so the public pages where operators actually decide to sign in, buy access, or recover access posture now expose the real provider lineup directly. The latest same-family manual continuation now also adds a shared public route atlas across homepage, docs, and resources so each major public page explains its exact job in the broader operator/distribution manual instead of leaving page purpose mostly implicit in navigation alone. | +| Public `hypertwist.app` marketing shell | Implemented now | first-party `website/` app + feature registry/roadmap authority | HyperTwist now has a dedicated first-party public web surface for homepage, feature atlas, about, resources, pricing, download, support, legal routes, a dedicated `/getting-started` onboarding surface, and a dedicated `/launch-status` authority surface. This lane is separate from the embedded Unreal browser runtime under `Content/Browser/` and does not claim browser-simulator parity. The same public lane now also serves as a bounded operator/distribution manual through the docs/resources/download/support surfaces, the public feature-atlas route, the dedicated getting-started route, the dedicated launch-status route, and related launch/status surfaces, explaining browser-versus-desktop posture, rollout steps, package proof, simulator-use guidance, and current input/device truth without claiming browser ownership of the native runtime or overclaiming unfinished VR/controller posture. The same package now also carries a first-party external runtime-readiness verifier so deploy-time env and live health posture can be checked outside the dashboard, plus separated local-versus-production env templates whose placeholder values are intentionally rejected until real launch config is in place, bootstrap CI now validates both the frontend and auth-server website commands directly, and the auth server can now auto-serve the built `website/dist` bundle with bounded SPA fallback for same-origin public deployment. Request-level server coverage now also proves that public/app shell delivery does not shadow `/api/*`, `/auth*`, `/health`, or missing asset paths, while the pricing/download/notices routes now surface first-party preview-versus-launch posture from the same bounded launch checklist instead of relying on hidden operator-only status. The shared marketing shell now also carries a compact public-site-status banner across public pages, the homepage keeps a fuller status section, and the shared public launch-status component now consumes live auth-health webhook/runtime truth in addition to release-manifest download readiness so public marketing copy does not claim launch posture from static checkout/download config alone. The auth server now also emits an authoritative `launch` summary on `/api/auth/health`, including required blocker labels, billing product/price-map gates, and current checkout targets, so the public banner and protected dashboard no longer duplicate launch-blocker evaluation client-side. A later same-family continuation then widened that release-manifest authority again to carry public runtime commerce config for operator/studio checkout URLs and live plan-price strings, so pricing, notices, and dashboard launch-readiness surfaces no longer depend only on frontend build-time checkout config. The live website lane now also owns route-aware title/description/canonical/Open-Graph/Twitter metadata for the real `hypertwist.app` marketing surface so deployed public pages no longer remain on a single generic SPA title/description, plus first-party `robots.txt` and `sitemap.xml` assets for the public route set while keeping `/app`, `/login`, and `/register` out of crawler posture. The real `check-runtime-readiness` CLI is now also exercised against the checked-in production example env files, and a spawned `website/server` bootstrap proof now verifies the live same-origin process path from production-shaped env into `/health`, `/api/auth/health`, built-shell serving, and the public anonymous release-manifest posture for the shared desktop release lane. The same verifier now also probes the deployed root-shell marker and can explicitly fail when the public origin is still serving the older placeholder rollout page instead of the first-party website/auth-server lane, while the repo now also carries first-party `website/deploy/` `nginx` plus `systemd` handoff templates, a concrete same-origin public-host cutover guide, a deployment-file renderer that emits resolved operator outputs from real checkout paths, and a manifest-driven bundle renderer that lets one authoritative input own the public origin while emitting validated env plus install artifacts together, with the shared-VPS-safe default upstream moved to `3011` after live host inspection confirmed `3001` is already occupied by FamiliarOS. The same deployment lane now also distinguishes `launch` from `preview` posture so honest missing checkout/download/webhook/release values are accepted only for non-public rehearsal while placeholder strings still fail, `runtime.mode: mixed` plus `public_origin_ready: true` counts as valid preview-host proof, and the staging helper can archive either committed `HEAD` or the live worktree through `--archive-source worktree`. An isolated VPS-local staging proof then confirmed that both the committed HyperTwist website lane and the later preview-tier worktree packet can serve green health, release-manifest, and first-party shell responses on that real shared host behind `3011`, and a later root-owned cutover then replaced the public placeholder site with the live first-party same-origin preview deployment on `https://hypertwist.app`. The package now also ships a bounded root-owned live-deploy helper that stages the committed checkout, uploads the rendered bundle, installs env, rebuilds the site, replaces the live `systemd` plus `nginx` files, and validates the public origin; that helper has already been re-proved idempotently against the live host. The repo now also ships that host-proof flow as a first-party staging helper so future sessions can rerun the temp checkout/build/boot verification path directly before or after root-owned cutover. The website lane now also owns a sanitized generated packaged-validation summary for the Windows higher-dimensional desktop proof, rendered from the checked-in authoritative package report into `website/src/shared/generated/windows-package-validation-summary.json`, and the owned web-surface validation gate now checks that generated proof for freshness before approving the current public/auth/download/browser lane. The remaining public conversion seams now also stop dead-ending on generic sign-in/support detours when the next lane is already known: the explorer CTA preserves `/register?next=/app`, operator fallback opens the protected downloads lane, studio fallback opens the protected browser-access rollout lane, and launch/download fallback callouts now point directly at protected release, notices, or dashboard follow-through. The narrative/help surfaces then widened again so the public About and Support pages also surface the same live launch-readiness callout and packaged desktop-proof section already used by the stronger public manual routes, keeping maturity language attached to current native release evidence instead of leaving those pages purely abstract. The same public manual continuation now also adds a direct reusable surface-choice guide across the homepage, About, Pricing, Download, and Support pages so operators no longer have to infer from the larger surface matrix alone when they should stay on the public web surface, move into the protected dashboard, or move into the packaged desktop runtime. A later same-family continuation then propagated that same guide through the remaining public feature/docs/resources/changelog/legal pages as well, so the whole public site now preserves one consistent browser-versus-protected-versus-desktop handoff story instead of leaving those lower-traffic surfaces on older implicit wording. A further same-day manual-clarity continuation then added a reusable direct comparison section across the homepage, About, Docs, and Download routes explaining why the website remains necessary, where it is intentionally narrower than the simulator, why the native Unreal runtime stays primary, and how the current keyboard or mouse versus unfinished XR/controller truth should be read. The latest same-family parity follow-up then widened that exact browser-versus-desktop reality section into Pricing and Resources as well, so commercial and reference-heavy public routes no longer rely only on the lighter surface-choice guide when explaining what stays native and where the current XR/controller boundary still begins. The next adjacent parity follow-up then extended the same direct comparison into the public Feature atlas and Support routes as well, so the remaining major public operator-facing surfaces no longer fall back to the lighter guide alone when capability review or recovery work needs the sharper website-versus-native split. A later same-family continuity follow-up then widened the shared release-decision guide into the remaining public legal/notices routes too, so open-source notices, privacy, terms, and shipping/payment now also tell the operator whether the next honest move is protected desktop access, pricing/provisioning, protected browser/account continuity, or notices/source follow-through instead of leaving those pages on the older lighter handoff only. The same browser shell now also has a first-party top-level runtime-recovery boundary, so unexpected React route failures degrade into a HyperTwist-owned retry/return surface that keeps the browser-versus-desktop product truth explicit instead of collapsing into a blank shell. A later same-family quickstart/manual continuation then added a reusable first serious-session guide across homepage, docs, and download so operators can see the real path from release-target choice through desktop-link pairing, first native verification, higher-dimensional verification, and the current XR/controller `No-Go` boundary in one place instead of reconstructing that flow from scattered adjacent sections. That same onboarding/manual packet is now also anchored at a dedicated public `/getting-started` route so the shortest complete browser-to-desktop first-session path is canonical, crawlable, and easier to hand off than the broader site sections alone. The next adjacent launch-authority continuation then did the same for rollout truth through a dedicated public `/launch-status` route, giving preview-versus-launch posture, rollout blockers, packaged proof, and release-reference follow-through one canonical public authority surface instead of leaving that lane distributed across pricing and compact status banners alone. The next same-family shared-auth manual continuation then widened the real browser-account method lineup beyond the auth entry forms and deeper docs surfaces into the homepage, pricing, download, and support routes too, so the public pages where operators actually decide to sign in, buy access, or recover access posture now expose the real provider lineup directly. The latest same-family manual continuation now also adds a shared public route atlas across homepage, docs, and resources so each major public page explains its exact job in the broader operator/distribution manual instead of leaving page purpose mostly implicit in navigation alone. The latest same-family atlas-parity follow-up then widened the public feature-atlas route again so it now also carries the shared runtime control guide directly, keeping the practical classic-control, higher-dimensional-control, native-diagnostics, and explicit XR/controller-boundary truth visible on `/features` instead of forcing advanced readers to leave the atlas for deeper manual routes. The latest same-family responsive-proof expansion then widened browser-level viewport evidence across those newer manual and authority routes too, so `/features`, `/docs`, `/getting-started`, and `/launch-status` now sit inside the owned public responsive validation lane instead of relying only on source-level or unit-level proof. The latest same-family commerce/download manual deepening follow-up then widened `/pricing` and `/download` again so the actual purchase and package routes now carry the installed-software simulator manual, the higher-dimensional family guide, and the current input/device plus runtime-control truth directly instead of leaving that practical product explanation to docs/resources/getting-started alone. A later same-family continuation then completed the shared-section path on the feature atlas itself by routing its higher-dimensional guide, input/device posture, control-profile roster, and runtime-control guide through the same shared helper ownership as the surrounding public routes, and widened responsive public-route proof across `/changelog`, `/open-source-notices`, `/privacy`, `/terms`, and `/shipping-payment`, while a later adjacent auth-entry parity follow-up also brought `/login` into that same owned mobile/tablet matrix, bringing the explicit public-route browser proof to `34` passed Playwright checks while the broader `13`-file/`79`-test website route/auth/release suite and `10`-file/`36`-test auth-server suite stayed green. | | Browser-based operator/account dashboard | Implemented now | first-party `website/` app + shared auth/dashboard packet | A protected browser dashboard is now live for operator access, account state, download posture, browser-access boundary explanation, notices review, and bounded billing/entitlement status. It reuses the shared SuperTokens auth posture proven in FamiliarOS and ScriptoriumAI while remaining HyperTwist-specific in product content and boundary claims, the current auth-health surface now truthfully distinguishes configured versus reachable or ready shared-core posture while exposing fallback-active reason instead of hardcoding readiness, and the same dashboard now also surfaces launch-readiness truth for download URLs, checkout links, source/notices URLs, billing-secret/map configuration, and local-versus-public runtime deployment posture. The same shared-auth lane now also carries end-to-end optional provider parity for GitHub, Google, and bounded ORCID sign-in: the auth server owns the ORCID custom-provider path, the same-origin bundle emits matching ORCID frontend/server env truth, auth-health reports ORCID readiness alongside the other providers, and the public docs route now exposes the current browser-account method lineup instead of leaving provider truth visible only on the form pages. The surrounding public decision surfaces now also mirror that same provider-lineup truth on homepage, pricing, download, and support, so shared-auth reality is not hidden until operators reach either the auth forms or the deeper manual. The same protected overview now also consumes the server-backed Windows packaged-validation summary that the release-manifest authority exposes, so operators can see current higher-dimensional desktop proof without drilling into the dedicated downloads screen. The adjacent protected `/app/browser-access` and `/app/notices` routes now also reuse the bounded escalation-map and release-follow-through guidance from the public support/manual lane, so sign-in does not degrade operator troubleshooting quality into a thinner shell than the public surface. The protected overview and protected download center now also mirror the same launch-readiness, operator-access, and studio-rollout help lanes as the public support/manual surface, but translate those actions into direct signed-in dashboard, downloads, browser-access, account, notices, pricing, and release-notes targets instead of sending the operator back through anonymous auth detours. A later same-family parity follow-up then added the same blunt browser-versus-desktop reality explanation to the protected dashboard, protected downloads, and browser-access routes as well, so sign-in no longer makes the product boundary or unfinished XR/controller truth less explicit than the public manual. The next adjacent parity follow-up then extended that same compact reality panel into the protected account and notices routes too, so entitlement review and distribution/compliance work no longer soften the browser-support versus native-simulator split after sign-in. The auth entry pages now also render the same browser-versus-desktop truth before sign-in is even complete, so login and register no longer rely only on next-step routing plus later dashboard surfaces to explain what stays native and where the current XR/controller boundary still begins. A later same-family protected-shell continuation then widened signed-in auth truth itself, so the dashboard and account routes now surface the auth method, current provider lineup, shared-auth readiness, runtime origins, cookie/public-origin posture, fallback state, and deployment diagnostics directly instead of collapsing that truth down to a thin stack label. The protected fallback path now also preserves signed-in viewer plan/access posture from local session truth when live manifest authority is temporarily unavailable, while still keeping download authority conservative until the auth server returns. The shared browser auth layer now also has a bounded release-authority reconciliation path that refreshes and persists the local browser session snapshot from fresher manifest viewer truth, while the dashboard and account surfaces expose a compact live-authority sync notice summarizing what changed so operators can see the session catch-up clearly. That same auth layer now also clears stale stored sessions when shared auth is configured and `/api/auth/me` returns `401`, while still preserving the intended offline/local-fallback posture when the account API is merely unreachable or shared auth is not configured. The next adjacent protected-shell launch-authority continuation then added a dedicated signed-in `/app/launch-status` route, so launch posture, rollout blockers, release references, packaged proof, and signed-in next actions no longer collapse back to a single overview panel once account context exists. The follow-through continuation after that then threaded the same signed-in launch-status route back through protected release-action cards, release-reference panels, and the browser-access, download, account, and notices surfaces, so rollout authority remains attached to the surrounding signed-in operator shell instead of becoming an isolated page. Focused frontend coverage now also protects deep-link login redirect preservation, safe `next`-path normalization across auth entry points, fallback/email auth-bootstrap normalization, login/register continuation behavior, public download-gating behavior, protected-route/shell behavior, real lazy-route tree behavior for key public and protected paths, top-level app-bootstrap and SuperTokens-wrapper posture, login/register unhappy-path and OAuth-button behavior, support-topic fallback routing when live checkout is not configured, desktop-link verify-url/dashboard readiness behavior, and explicit `noindex,nofollow` posture on protected/auth browser surfaces. The validation lane now also has a bounded signed test-session harness under `TEST_MODE=testing` that proves `/api/auth/me`, stale-session invalidation, release-authority reconciliation, and `/api/auth/desktop-link` behavior through the live spawned auth-server process without widening production auth posture. A later same-family responsive-browser hardening follow-up then added Playwright viewport proof for `/app`, `/app/launch-status`, `/app/downloads`, `/app/browser-access`, `/app/account`, and `/app/notices`, so the shipped signed-in operator shell now has the same bounded mobile/tablet no-horizontal-overflow proof posture as the current public-route family. | | Desktop download posture and browser-to-desktop pairing | Implemented now | first-party `website/` app + `website/server` desktop-link endpoints | Public download targets, dashboard-side release posture, and short-lived desktop-link token generation/verification are now first-party owned. The current server posture now enforces exact website-origin matching, bounded per-user issuance, one-time token consumption, and billing-backed plan/download entitlement resolution with focused `website/server` tests green on `2026-06-22`, and the verify handshake now returns the same resolved download-entitlement posture the dashboard sees instead of only identity plus plan/role. The same lane now also owns a shared `GET /api/releases/manifest` runtime authority for release version/channel/build/published/file-size/checksum/docs/source metadata, with anonymous callers intentionally denied raw download URLs while entitled session-backed callers receive the configured direct platform URL. That manifest now also carries first-party packaged-validation summary truth for the Windows higher-dimensional desktop lane, so the public `/download` page, the public `/resources` reference page, and the protected `/app/downloads` surface can project real package evidence for the dedicated-family `Magic120Cell` / `MagicCube5D` maps even while launch-tier release URLs remain unconfigured. That website-facing packaged proof is now sourced through a sanitized generated summary rendered from the checked-in authoritative `phase6c_dedicated_family_package_validation_report.json`, and the owned web-surface validation gate now checks that generated summary for freshness before approving the current public/auth/download/browser lane. The public `/download` page now keeps raw download URLs behind the protected dashboard instead of exposing them directly, preserves requested platform continuity through `/app/downloads?platform=...`, and surfaces that requested target again after auth handoff inside the protected release lane. The public download fallbacks now also open exact protected download and dashboard follow-through instead of stopping at a generic anonymous login hop. When live manifest authority is unavailable, the protected fallback path now still reflects the signed-in viewer posture from local session truth while continuing to withhold raw delivery authority. When live manifest authority resolves fresher entitled viewer truth than the local browser auth snapshot, the protected download-center lane now also follows that server-backed viewer posture for the actual download action instead of leaving the operator blocked behind stale local session state. Both the public and protected download surfaces now also carry first-party rollout steps, first-launch desktop setup guidance, browser-to-desktop pairing follow-through, and release/notices/source references so the desktop setup lane is more than a generic link bucket, while the support surface now carries an explicit escalation map separating account, package, runtime, and rollout/compliance problems. The protected dashboard overview and protected account surface now also mirror that same first-launch follow-through, and the protected browser-access/notices routes now mirror the same escalation separation, so post-sign-in operator guidance does not collapse back into a thinner release-only shell. The protected download center now also mirrors the same three help-topic lanes used by the public support/manual surface, but with direct signed-in actions for downloads, dashboard, account, browser access, notices, and release notes so entitled operators can stay inside the protected rollout lane once auth has already succeeded. The dashboard plus public launch-status callouts now consume the same manifest-backed Windows download truth instead of only static frontend config. Actual release URLs remain deployment configuration rather than hardcoded product truth. | | Paddle-ready pricing and billing webhook seam | Implemented now | first-party `website/` app + `website/server` billing endpoint | The public pricing surface now exists with plan structure, checkout-link configuration seams, and the same `/api/billing/paddle/webhook` endpoint family used by the broader product website lane. The current server now verifies `Paddle-Signature` against `PADDLE_WEBHOOK_SECRET` using the documented raw-body HMAC flow, persists a bounded first-party billing state file, and applies verified Paddle events into account/download entitlement state that the browser dashboard consumes, with focused `website/server` tests green on `2026-06-22`. The shared `GET /api/releases/manifest` authority now also carries public runtime commerce config for operator/studio checkout URLs and live plan-price strings, allowing the pricing page to switch from frontend build-time checkout assumptions to auth-server runtime truth when those values are configured. The fallback plan CTAs now also use exact protected release/browser-access targets when live checkout URLs are absent, instead of routing operators back into a vague public support detour. A spawned live-process proof now also verifies that a real signed webhook updates processed-event health and persisted billing state through the actual auth-server runtime, not only helper-level store tests, and transaction events no longer leak their id into stored `subscriptionId` state. Production checkout URLs, secret management, and broader operator/admin billing workflows remain deployment/application tasks, not shipped-code omissions. | diff --git a/docs/v6_5_deep_manual_pack/HyperTwist/PRD.md b/docs/v6_5_deep_manual_pack/HyperTwist/PRD.md index 5cae993..7256e5d 100644 --- a/docs/v6_5_deep_manual_pack/HyperTwist/PRD.md +++ b/docs/v6_5_deep_manual_pack/HyperTwist/PRD.md @@ -139,6 +139,11 @@ immersive settings now keep session-local recall ownership explicit, and the current product story stays honest that this is real local continuity rather than a finished global preferences or rebinding suite. +The same-family truth pass also carried that bounded continuity and active +scene ownership into the native control-profile roster seam, so the selectable +roster truth now stays aligned with the sibling control-settings and active +runtime surfaces instead of leaving those facts implied. + Canonical audit note: - `C:\HyperTwist\docs\ops\HYPERTWIST_UNREAL_INPUT_AND_XR_COMPLETENESS_AUDIT_2026-06-22.md` diff --git a/scripts/lib-hypertwist-sentrux.sh b/scripts/lib-hypertwist-sentrux.sh new file mode 100644 index 0000000..d214aa6 --- /dev/null +++ b/scripts/lib-hypertwist-sentrux.sh @@ -0,0 +1,88 @@ +#!/usr/bin/env bash + +hypertwist_sentrux_repo_root() { + cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd +} + +hypertwist_resolve_sentrux_command() { + local repo_root="${1:-$(hypertwist_sentrux_repo_root)}" + local repo_local_sentrux_binary="$repo_root/sentrux" + local repo_local_sentrux_windows_binary="$repo_root/sentrux.exe" + local repo_tools_sentrux_binary="$repo_root/tools/sentrux/bin/sentrux" + local repo_tools_sentrux_windows_binary="$repo_root/tools/sentrux/bin/sentrux.exe" + local bootstrap_script="$repo_root/scripts/bootstrap-hypertwist-sentrux.sh" + + if [[ -n "${HYPERTWIST_SENTRUX_BINARY:-}" && -x "${HYPERTWIST_SENTRUX_BINARY}" ]]; then + printf '%s\n' "${HYPERTWIST_SENTRUX_BINARY}" + return 0 + fi + + if [[ -x "$repo_local_sentrux_binary" ]]; then + printf '%s\n' "$repo_local_sentrux_binary" + return 0 + fi + + if [[ -x "$repo_local_sentrux_windows_binary" ]]; then + printf '%s\n' "$repo_local_sentrux_windows_binary" + return 0 + fi + + if [[ -x "$repo_tools_sentrux_binary" ]]; then + printf '%s\n' "$repo_tools_sentrux_binary" + return 0 + fi + + if [[ -x "$repo_tools_sentrux_windows_binary" ]]; then + printf '%s\n' "$repo_tools_sentrux_windows_binary" + return 0 + fi + + if [[ -x "$bootstrap_script" ]]; then + "$bootstrap_script" --if-missing >/dev/null 2>&1 || true + fi + + if [[ -x "$repo_tools_sentrux_binary" ]]; then + printf '%s\n' "$repo_tools_sentrux_binary" + return 0 + fi + + if [[ -x "$repo_tools_sentrux_windows_binary" ]]; then + printf '%s\n' "$repo_tools_sentrux_windows_binary" + return 0 + fi + + if command -v sentrux >/dev/null 2>&1; then + printf 'sentrux\n' + return 0 + fi + + return 1 +} + +hypertwist_populate_sentrux_source_only_root() { + local repo_root="$1" + local temp_root="$2" + + mkdir -p "$temp_root/.sentrux" + cp "$repo_root/.sentrux/rules.toml" "$temp_root/.sentrux/rules.toml" + + local copy_targets=( + "UnrealHyperTwist/Source" + "Content/Browser/src" + "website/src" + "website/server/src" + "scripts" + ) + + local target="" + for target in "${copy_targets[@]}"; do + local source_path="$repo_root/$target" + if [[ ! -e "$source_path" ]]; then + continue + fi + + local destination_path="$temp_root/$target" + mkdir -p "$(dirname "$destination_path")" + cp -R "$source_path" "$destination_path" + done +} diff --git a/scripts/run-hypertwist-gitnexus-status.sh b/scripts/run-hypertwist-gitnexus-status.sh index dc1774c..87a9f0e 100644 --- a/scripts/run-hypertwist-gitnexus-status.sh +++ b/scripts/run-hypertwist-gitnexus-status.sh @@ -5,10 +5,32 @@ repo_root="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)" source "$repo_root/scripts/lib-hypertwist-gitnexus.sh" local_gitnexus_cli="$repo_root/mirrors/GitNexus/gitnexus/dist/cli/index.js" analysis_root="$repo_root/.gitnexus-source-only-root" +analysis_meta_path="$analysis_root/.gitnexus/meta.json" +require_index="${HYPERTWIST_GITNEXUS_STATUS_REQUIRE_INDEX:-0}" if [[ ! -d "$analysis_root" ]]; then - echo "No HyperTwist GitNexus source-only analysis root exists yet. Run scripts/run-hypertwist-gitnexus-analyze.sh first." >&2 - exit 1 + message="HyperTwist GitNexus source-only analysis root is currently absent. This is normal after hygiene because .gitnexus-source-only-root is disposable. Run scripts/run-hypertwist-gitnexus-analyze.sh to recreate it before requesting status." + if [[ "$require_index" == "1" ]]; then + echo "$message" >&2 + exit 1 + fi + + echo "$message" + exit 0 +fi + +if [[ ! -f "$analysis_meta_path" ]]; then + first_message="HyperTwist GitNexus source-only analysis root exists, but no completed index metadata is available yet." + second_message="This can happen during an interrupted refresh or immediately after rebuilding the disposable bounded mirror. Rerun scripts/run-hypertwist-gitnexus-analyze.sh to recreate a finished index before requesting status again." + if [[ "$require_index" == "1" ]]; then + echo "$first_message" >&2 + echo "$second_message" >&2 + exit 1 + fi + + echo "$first_message" + echo "$second_message" + exit 0 fi cd "$analysis_root" diff --git a/scripts/run-hypertwist-sentrux-gate.sh b/scripts/run-hypertwist-sentrux-gate.sh new file mode 100644 index 0000000..55f0de6 --- /dev/null +++ b/scripts/run-hypertwist-sentrux-gate.sh @@ -0,0 +1,88 @@ +#!/usr/bin/env bash +set -euo pipefail + +repo_root="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)" +source "$repo_root/scripts/lib-hypertwist-sentrux.sh" +temp_root_parent="${TMPDIR:-/tmp}" +source_only_baseline_path="${HYPERTWIST_SENTRUX_SOURCE_ONLY_BASELINE_PATH:-$repo_root/.sentrux/source-only-baseline.json}" + +usage() { + cat <&2 + usage >&2 + exit 1 + ;; + esac +done + +sentrux_command="$(hypertwist_resolve_sentrux_command "$repo_root")" || { + echo "Unable to locate sentrux. Provide HYPERTWIST_SENTRUX_BINARY, place a repo-local sentrux binary under $repo_root/tools/sentrux/bin, add sentrux to PATH, or run scripts/bootstrap-hypertwist-sentrux.sh (set HYPERTWIST_ALLOW_SIBLING_SENTRUX_BOOTSTRAP=1 only if you intentionally want legacy sibling-repo seeding on this machine)." >&2 + exit 1 +} + +temp_root="$(mktemp -d "${temp_root_parent%/}/hypertwist-sentrux-gate.XXXXXX")" +cleanup() { + rm -rf "$temp_root" +} +trap cleanup EXIT + +hypertwist_populate_sentrux_source_only_root "$repo_root" "$temp_root" + +temp_baseline_path="$temp_root/.sentrux/baseline.json" + +if [[ "$save_mode" -eq 0 ]]; then + if [[ ! -f "$source_only_baseline_path" ]]; then + echo "No HyperTwist source-only sentrux baseline exists yet at $source_only_baseline_path." >&2 + echo "Run scripts/run-hypertwist-sentrux-gate.sh --save once to create the baseline before requesting a comparison gate." >&2 + exit 1 + fi + + cp "$source_only_baseline_path" "$temp_baseline_path" +fi + +( + cd "$repo_root" + if [[ "$save_mode" -eq 1 ]]; then + "$sentrux_command" gate --save "$temp_root" + else + "$sentrux_command" gate "$temp_root" + fi +) + +if [[ "$save_mode" -eq 1 ]]; then + if [[ ! -f "$temp_baseline_path" ]]; then + echo "sentrux gate --save completed but no baseline was produced at $temp_baseline_path." >&2 + exit 1 + fi + + mkdir -p "$(dirname "$source_only_baseline_path")" + cp "$temp_baseline_path" "$source_only_baseline_path" + echo "Persisted HyperTwist source-only sentrux baseline to $source_only_baseline_path." +fi diff --git a/scripts/run-hypertwist-sentrux-source-only.sh b/scripts/run-hypertwist-sentrux-source-only.sh index 48c20a4..d6eed8a 100644 --- a/scripts/run-hypertwist-sentrux-source-only.sh +++ b/scripts/run-hypertwist-sentrux-source-only.sh @@ -2,90 +2,22 @@ set -euo pipefail repo_root="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)" -temp_root="${TMPDIR:-/tmp}/hypertwist-sentrux-source-only" -repo_local_sentrux_binary="$repo_root/sentrux" -repo_local_sentrux_windows_binary="$repo_root/sentrux.exe" -repo_tools_sentrux_binary="$repo_root/tools/sentrux/bin/sentrux" -repo_tools_sentrux_windows_binary="$repo_root/tools/sentrux/bin/sentrux.exe" -bootstrap_script="$repo_root/scripts/bootstrap-hypertwist-sentrux.sh" - -resolve_sentrux_command() { - if [[ -n "${HYPERTWIST_SENTRUX_BINARY:-}" && -x "${HYPERTWIST_SENTRUX_BINARY}" ]]; then - printf '%s\n' "${HYPERTWIST_SENTRUX_BINARY}" - return 0 - fi - - if [[ -x "$repo_local_sentrux_binary" ]]; then - printf '%s\n' "$repo_local_sentrux_binary" - return 0 - fi - - if [[ -x "$repo_local_sentrux_windows_binary" ]]; then - printf '%s\n' "$repo_local_sentrux_windows_binary" - return 0 - fi - - if [[ -x "$repo_tools_sentrux_binary" ]]; then - printf '%s\n' "$repo_tools_sentrux_binary" - return 0 - fi - - if [[ -x "$repo_tools_sentrux_windows_binary" ]]; then - printf '%s\n' "$repo_tools_sentrux_windows_binary" - return 0 - fi - - if [[ -x "$bootstrap_script" ]]; then - "$bootstrap_script" --if-missing >/dev/null 2>&1 || true - fi - - if [[ -x "$repo_tools_sentrux_binary" ]]; then - printf '%s\n' "$repo_tools_sentrux_binary" - return 0 - fi - - if [[ -x "$repo_tools_sentrux_windows_binary" ]]; then - printf '%s\n' "$repo_tools_sentrux_windows_binary" - return 0 - fi - - if command -v sentrux >/dev/null 2>&1; then - printf 'sentrux\n' - return 0 - fi - - return 1 -} - -sentrux_command="$(resolve_sentrux_command)" || { +source "$repo_root/scripts/lib-hypertwist-sentrux.sh" +temp_root_parent="${TMPDIR:-/tmp}" +sentrux_command="$(hypertwist_resolve_sentrux_command "$repo_root")" || { echo "Unable to locate sentrux. Provide HYPERTWIST_SENTRUX_BINARY, place a repo-local sentrux binary under $repo_root/tools/sentrux/bin, add sentrux to PATH, or run scripts/bootstrap-hypertwist-sentrux.sh (set HYPERTWIST_ALLOW_SIBLING_SENTRUX_BOOTSTRAP=1 only if you intentionally want legacy sibling-repo seeding on this machine)." >&2 exit 1 } -rm -rf "$temp_root" -mkdir -p "$temp_root/.sentrux" -cp "$repo_root/.sentrux/rules.toml" "$temp_root/.sentrux/rules.toml" +temp_root="$(mktemp -d "${temp_root_parent%/}/hypertwist-sentrux-source-only.XXXXXX")" +cleanup() { + rm -rf "$temp_root" +} +trap cleanup EXIT -copy_targets=( - "UnrealHyperTwist/Source" - "Content/Browser/src" - "website/src" - "website/server/src" - "scripts" -) - -for target in "${copy_targets[@]}"; do - source_path="$repo_root/$target" - if [[ ! -e "$source_path" ]]; then - continue - fi - - destination_path="$temp_root/$target" - mkdir -p "$(dirname "$destination_path")" - cp -R "$source_path" "$destination_path" -done +hypertwist_populate_sentrux_source_only_root "$repo_root" "$temp_root" ( cd "$repo_root" - eval "$sentrux_command" check "$temp_root" + "$sentrux_command" check "$temp_root" ) diff --git a/scripts/run-hypertwist-web-surface-validation.sh b/scripts/run-hypertwist-web-surface-validation.sh index 88c9e5e..00e968d 100644 --- a/scripts/run-hypertwist-web-surface-validation.sh +++ b/scripts/run-hypertwist-web-surface-validation.sh @@ -153,6 +153,7 @@ run_step \ src/__tests__/package-validation.test.ts \ src/__tests__/platform-auth.bootstrap.test.tsx \ src/__tests__/download-center-page.test.tsx \ + src/__tests__/public-launch.test.ts \ src/__tests__/protected-app-pages.test.tsx \ src/__tests__/DashboardOverviewPage.test.tsx \ src/__tests__/app-route-tree.test.tsx \ diff --git a/website/README.md b/website/README.md index 655401b..13b9b60 100644 --- a/website/README.md +++ b/website/README.md @@ -175,6 +175,10 @@ Repo-owned structural-tool posture: - `scripts/run-hypertwist-sentrux-source-only.sh` still prefers `HYPERTWIST_SENTRUX_BINARY`, repo-local `./sentrux` or `./sentrux.exe`, then `tools/sentrux/bin/`, then `PATH` +- `scripts/run-hypertwist-sentrux-gate.sh` now gives the website lane the same + bounded source-only before/after regression loop through the HyperTwist-owned + mirror and a persisted repo baseline at + `.sentrux/source-only-baseline.json` - `scripts/bootstrap-hypertwist-sentrux.sh` now keeps sibling-repo seed lookup opt-in behind `HYPERTWIST_ALLOW_SIBLING_SENTRUX_BOOTSTRAP=1`, so ordinary HyperTwist analyzer recovery does not silently drift back into cross-repo diff --git a/website/src/__tests__/protected-app-pages.test.tsx b/website/src/__tests__/protected-app-pages.test.tsx index 0d4d419..1b5673e 100644 --- a/website/src/__tests__/protected-app-pages.test.tsx +++ b/website/src/__tests__/protected-app-pages.test.tsx @@ -227,6 +227,79 @@ describe('protected app pages', () => { expect(screen.getByRole('link', { name: 'Public notices' }).getAttribute('href')).toBe('/open-source-notices') }) + it('uses the authoritative auth-health launch summary on the protected launch route when the server provides it', async () => { + mockGetAuthHealth.mockResolvedValue({ + ok: true, + service: 'hypertwist-auth-server', + supertokens: { + configured: true, + reachable: true, + ready: true, + apiVersion: '5.0', + oauth: { + github: false, + google: false, + }, + }, + fallback: { + enabled: true, + active: false, + reason: null, + }, + billing: { + statePath: '/tmp/hypertwist-billing.json', + processedEventCount: 1, + pricePlanMapConfigured: true, + productPlanMapConfigured: true, + webhookSecretConfigured: true, + }, + runtime: { + mode: 'public', + public_origin_ready: true, + cookie_secure: true, + api_domain: 'https://hypertwist.app', + website_domain: 'https://hypertwist.app', + warnings: [], + errors: [], + }, + launch: { + posture: 'preview', + ready: false, + readiness: { + windowsDownloadConfigured: true, + operatorCheckoutConfigured: true, + studioCheckoutConfigured: true, + mplSourceConfigured: true, + openSourceRepoConfigured: true, + billingProductPlanMapConfigured: true, + billingPricePlanMapConfigured: true, + billingWebhookSecretConfigured: true, + publicAuthRuntimeReady: true, + }, + checklist: [ + { + id: 'windows-download', + label: 'Windows release authority', + configured: true, + requiredForPublicLaunch: true, + }, + ], + missingLabels: ['preview-tier launch gate'], + targets: { + operatorCheckoutTarget: 'https://buy.paddle.com/operator-authoritative', + studioCheckoutTarget: 'https://buy.paddle.com/studio-authoritative', + }, + }, + }) + + renderPage(, '/app/launch-status') + + expect(await screen.findByText('Windows release authority: configured')).toBeTruthy() + expect(screen.getByText('Operator checkout target: https://buy.paddle.com/operator-authoritative')).toBeTruthy() + expect(screen.getByText('Studio checkout target: https://buy.paddle.com/studio-authoritative')).toBeTruthy() + expect(screen.getByText(/Public launch is not fully configured yet: preview-tier launch gate\./i)).toBeTruthy() + }) + it('keeps the protected download center aligned with packaged proof, notices, and escalation guidance', async () => { renderPage(, '/app/downloads?platform=windows') diff --git a/website/src/__tests__/public-launch.test.ts b/website/src/__tests__/public-launch.test.ts index 8e16fc8..741989e 100644 --- a/website/src/__tests__/public-launch.test.ts +++ b/website/src/__tests__/public-launch.test.ts @@ -3,6 +3,7 @@ import { getMissingPublicLaunchChecklistItems, getPublicLaunchChecklist, isPublicLaunchReady, + resolvePublicLaunchStatusSummary, } from '../public-launch' describe('public launch readiness helpers', () => { @@ -65,4 +66,123 @@ describe('public launch readiness helpers', () => { publicAuthRuntimeReady: true, })).toBe(true) }) + + it('prefers the authoritative auth-health launch summary when the server already resolved rollout posture', () => { + const launchStatus = resolvePublicLaunchStatusSummary( + { + ok: true, + service: 'hypertwist-auth-server', + supertokens: { + configured: true, + reachable: true, + ready: true, + }, + fallback: { + enabled: true, + active: false, + reason: null, + }, + billing: { + statePath: '/tmp/hypertwist-billing.json', + processedEventCount: 3, + pricePlanMapConfigured: true, + productPlanMapConfigured: true, + webhookSecretConfigured: true, + }, + runtime: { + mode: 'public', + public_origin_ready: true, + cookie_secure: true, + api_domain: 'https://hypertwist.app', + website_domain: 'https://hypertwist.app', + warnings: [], + errors: [], + }, + launch: { + posture: 'preview', + ready: false, + readiness: { + windowsDownloadConfigured: true, + macosDownloadConfigured: false, + linuxDownloadConfigured: false, + operatorCheckoutConfigured: true, + studioCheckoutConfigured: true, + mplSourceConfigured: true, + openSourceRepoConfigured: true, + billingProductPlanMapConfigured: true, + billingPricePlanMapConfigured: true, + billingWebhookSecretConfigured: true, + publicAuthRuntimeReady: true, + }, + checklist: [ + { + id: 'windows-download', + label: 'Windows release authority', + configured: true, + requiredForPublicLaunch: true, + }, + ], + missingLabels: ['preview-tier launch gate'], + targets: { + operatorCheckoutTarget: 'https://buy.paddle.com/operator-authoritative', + studioCheckoutTarget: 'https://buy.paddle.com/studio-authoritative', + }, + }, + }, + { + generated_at: '2026-06-29T12:00:00.000Z', + support_email: 'hello@hypertwist.app', + public_docs_url: 'https://docs.hypertwist.app', + release_notes_url: 'https://notes.hypertwist.app', + platforms: [ + { + platform_key: 'windows', + platform: 'Windows', + subtitle: 'Primary shipping lane', + details: 'Current packaged validation is strongest on the Windows Unreal lane.', + configured: true, + channel: 'preview', + version: null, + build_id: null, + published_at: null, + file_name: null, + file_size_bytes: null, + checksum_sha256: null, + download_url: null, + download_available: false, + validation_summary: null, + }, + ], + commerce: { + operator_checkout_url: null, + studio_checkout_url: null, + plan_price_operator: 'Launch pricing via Paddle', + plan_price_studio: 'Contact for launch readiness', + }, + corresponding_source_url: null, + open_source_repo_url: null, + viewer: { + authenticated: false, + canDownload: false, + plan: null, + role: null, + accessStatus: null, + }, + }, + { + windowsDownloadConfigured: true, + }, + ) + + expect(launchStatus.ready).toBe(false) + expect(launchStatus.posture).toBe('preview') + expect(launchStatus.missingLabels).toEqual(['preview-tier launch gate']) + expect(launchStatus.targets).toEqual({ + operatorCheckoutTarget: 'https://buy.paddle.com/operator-authoritative', + studioCheckoutTarget: 'https://buy.paddle.com/studio-authoritative', + }) + expect(launchStatus.checklist.find((item) => item.id === 'windows-download')?.label).toBe('Windows release authority') + expect(launchStatus.readiness.operatorCheckoutConfigured).toBe(true) + expect(launchStatus.readiness.publicAuthRuntimeReady).toBe(true) + }) }) diff --git a/website/src/__tests__/public-marketing-pages.test.tsx b/website/src/__tests__/public-marketing-pages.test.tsx index f7bc59e..90de8c9 100644 --- a/website/src/__tests__/public-marketing-pages.test.tsx +++ b/website/src/__tests__/public-marketing-pages.test.tsx @@ -268,6 +268,9 @@ describe('public marketing pages', () => { expect(screen.getByText('Operator checkout URL: missing')).toBeTruthy() expect(screen.getByText('Current packaged desktop proof')).toBeTruthy() expect(screen.getByText('How the release lane works')).toBeTruthy() + expect(screen.getByText('What the installed runtime already owns')).toBeTruthy() + expect(screen.getByText('Higher-dimensional family guide')).toBeTruthy() + expect(screen.getByText('Current input and runtime control truth')).toBeTruthy() expect(screen.getByText('Why HyperTwist keeps both a website and a desktop runtime')).toBeTruthy() expect(screen.getByText('Why the browser is intentionally narrower')).toBeTruthy() expect(screen.getByRole('heading', { name: 'Browser account access methods' })).toBeTruthy() @@ -293,6 +296,10 @@ describe('public marketing pages', () => { expect(screen.getByRole('link', { name: 'https://docs.hypertwist.app' })).toBeTruthy() expect(screen.getByRole('link', { name: 'https://notes.hypertwist.app' })).toBeTruthy() expect(screen.getByText('Pair desktop access to the browser account')).toBeTruthy() + expect(screen.getByText('Higher-dimensional runtime ownership')).toBeTruthy() + expect(screen.getByText('Magic120Cell packaged runtime')).toBeTruthy() + expect(screen.getByText('Current input and runtime control truth')).toBeTruthy() + expect(screen.getByText('Native diagnostics check')).toBeTruthy() expect(await screen.findByText('Version: 1.0.0')).toBeTruthy() expect(screen.getByText('SHA-256: abc123')).toBeTruthy() expect(screen.getAllByText('Packaged validation passed').length).toBeGreaterThan(0) @@ -714,6 +721,11 @@ describe('public marketing pages', () => { expect(screen.getByText('Current shipped capability')).toBeTruthy() expect(screen.getByText('Current selectable control roster')).toBeTruthy() expect(screen.getAllByText('Selectable immersive and family-specific settings').length).toBeGreaterThan(0) + expect(screen.getByText('Runtime control guide')).toBeTruthy() + expect(screen.getByText('Native diagnostics check')).toBeTruthy() + expect(screen.getByText('Common capability questions')).toBeTruthy() + expect(screen.getByText('If the desktop app is primary, why keep the web version?')).toBeTruthy() + expect(screen.getByText('Is VR/controller support already fully finished?')).toBeTruthy() expect(screen.getByText('Current public rollout posture')).toBeTruthy() expect(screen.getByText('Public feature and launch posture')).toBeTruthy() const featuresDecisionGuideHeading = screen.getByRole('heading', { name: 'Choose the next release move' }) @@ -897,6 +909,9 @@ describe('public marketing pages', () => { expect(screen.getByText('$99 / month')).toBeTruthy() expect(screen.getByText('Current packaged desktop proof')).toBeTruthy() expect(screen.getAllByText('What happens after access is granted').length).toBeGreaterThan(0) + expect(screen.getByText('What the software actually does after access is granted')).toBeTruthy() + expect(screen.getByText('Higher-dimensional families behind the plans')).toBeTruthy() + expect(screen.getAllByText('Current input and runtime control truth').length).toBeGreaterThan(0) expect(screen.getByText('Choose the right HyperTwist surface')).toBeTruthy() const pricingDecisionGuideHeading = screen.getByRole('heading', { name: 'Choose the next release move' }) const pricingDecisionGuideSection = pricingDecisionGuideHeading.closest('section') @@ -916,6 +931,10 @@ describe('public marketing pages', () => { expect(screen.getByText('Owns recognition, replay, coaching, and packaged training behavior')).toBeTruthy() expect(screen.getByText('Commercial distribution doctrine')).toBeTruthy() expect(screen.getByText('Public pages are distribution surfaces')).toBeTruthy() + expect(screen.getByText('Higher-dimensional runtime ownership')).toBeTruthy() + expect(screen.getByText('MagicTile embedded-browser runtime')).toBeTruthy() + expect(screen.getByText('XR groundwork exists, but the full VR lane is not finished')).toBeTruthy() + expect(screen.getByText('Native diagnostics check')).toBeTruthy() expect(screen.getByText('Release references and source availability')).toBeTruthy() expect(screen.getByRole('link', { name: 'https://docs.hypertwist.app' })).toBeTruthy() expect(screen.getByRole('link', { name: 'https://notes.hypertwist.app' })).toBeTruthy() @@ -1330,7 +1349,7 @@ describe('public marketing pages', () => { expect(screen.getByRole('link', { name: 'Review public notices' }).getAttribute('href')).toBe('/open-source-notices') expect(screen.getByText('Common operator questions')).toBeTruthy() expect(screen.getByText('If the desktop app is primary, why keep the web version?')).toBeTruthy() - expect(screen.getByText(/intentionally narrower than the simulator for training and device\/runtime work/i)).toBeTruthy() + expect(screen.getByText(/it does not own package-validated training behavior, low-latency native input, higher-dimensional packaged execution, or device\/runtime integration authority/i)).toBeTruthy() expect(screen.getByText('Packaged validation passed')).toBeTruthy() expect(screen.getByText('Release references and source availability')).toBeTruthy() expect(screen.getByRole('link', { name: 'https://docs.hypertwist.app' })).toBeTruthy() @@ -1438,8 +1457,11 @@ describe('public marketing pages', () => { expect(screen.getByText('Browser account access methods')).toBeTruthy() expect(screen.getByText('First launch and desktop setup')).toBeTruthy() expect(screen.getByText('Simulator use today')).toBeTruthy() + expect(screen.getByText('Higher-dimensional family guide')).toBeTruthy() expect(screen.getByText('Current control and device truth')).toBeTruthy() expect(screen.getAllByText('Selectable control and settings roster').length).toBeGreaterThan(0) + expect(screen.getByText('Runtime control guide')).toBeTruthy() + expect(screen.getByText('Native diagnostics check')).toBeTruthy() expect(screen.getByText('Choose the right HyperTwist surface')).toBeTruthy() expect(screen.getByText('Current packaged desktop proof')).toBeTruthy() expect(screen.getByText('Need help on the way in?')).toBeTruthy() @@ -1682,6 +1704,142 @@ describe('public marketing pages', () => { expect(document.head.querySelector('meta[property=\"og:url\"]')?.getAttribute('content')).toBe('https://hypertwist.app/changelog') }) + it('uses the authoritative auth-health launch summary on the public launch-status route when the server provides it', async () => { + mockGetAuthHealth.mockResolvedValue({ + ok: true, + service: 'hypertwist-auth-server', + supertokens: { + configured: true, + reachable: true, + ready: true, + apiVersion: '5.4', + error: null, + oauth: { + github: false, + google: false, + }, + }, + fallback: { + enabled: true, + active: false, + reason: null, + }, + billing: { + statePath: '/var/lib/hypertwist/auth/hypertwist-billing-state.json', + processedEventCount: 2, + pricePlanMapConfigured: true, + productPlanMapConfigured: true, + webhookSecretConfigured: true, + }, + runtime: { + mode: 'public', + public_origin_ready: true, + cookie_secure: true, + api_domain: 'https://hypertwist.app', + website_domain: 'https://hypertwist.app', + warnings: [], + errors: [], + }, + launch: { + posture: 'preview', + ready: false, + readiness: { + windowsDownloadConfigured: true, + operatorCheckoutConfigured: true, + studioCheckoutConfigured: true, + mplSourceConfigured: true, + openSourceRepoConfigured: true, + billingProductPlanMapConfigured: true, + billingPricePlanMapConfigured: true, + billingWebhookSecretConfigured: true, + publicAuthRuntimeReady: true, + }, + checklist: [ + { + id: 'windows-download', + label: 'Windows release authority', + configured: true, + requiredForPublicLaunch: true, + }, + ], + missingLabels: ['preview-tier launch gate'], + targets: { + operatorCheckoutTarget: 'https://buy.paddle.com/operator-authoritative', + studioCheckoutTarget: 'https://buy.paddle.com/studio-authoritative', + }, + }, + }) + mockGetReleaseManifest.mockResolvedValue({ + ok: true, + manifest: { + generated_at: '2026-06-29T12:00:00.000Z', + support_email: 'hello@hypertwist.app', + public_docs_url: 'https://docs.hypertwist.app', + release_notes_url: 'https://notes.hypertwist.app', + corresponding_source_url: null, + open_source_repo_url: null, + commerce: { + operator_checkout_url: null, + studio_checkout_url: null, + plan_price_operator: '$29 / month', + plan_price_studio: '$99 / month', + }, + viewer: { + authenticated: false, + canDownload: false, + plan: null, + role: null, + accessStatus: null, + }, + platforms: [ + { + platform_key: 'windows', + platform: 'Windows', + subtitle: 'Primary shipping lane', + details: 'Current packaged validation is strongest on the Windows Unreal lane.', + configured: true, + channel: 'preview', + version: '1.0.0', + build_id: 'win64-1000', + published_at: '2026-06-29T00:00:00.000Z', + file_name: 'HyperTwist-Windows.zip', + file_size_bytes: 1048576, + checksum_sha256: 'abc123', + download_url: null, + download_available: false, + validation_summary: { + lane: 'Windows Unreal packaged validation', + result: 'passed', + generated_at: '2026-06-29T01:43:08.7625247Z', + configuration: 'Development', + skip_build: true, + smoke_map_count: 2, + smoke_maps: [ + { + map_url: '/Game/HyperTwistTraining/Maps/L_HyperTwist_Magic120CellTraining', + label: 'Magic120Cell dedicated-family training map', + result: 'passed', + }, + { + map_url: '/Game/HyperTwistTraining/Maps/L_HyperTwist_MagicCube5DTraining', + label: 'MagicCube5D dedicated-family training map', + result: 'passed', + }, + ], + }, + }, + ], + }, + }) + + renderWithProviders(, ['/launch-status']) + + expect(await screen.findByText(/external launch still needs preview-tier launch gate/i)).toBeTruthy() + expect(screen.getByText('Windows release authority: configured')).toBeTruthy() + expect(screen.getByText('Operator checkout target: https://buy.paddle.com/operator-authoritative')).toBeTruthy() + expect(screen.getByText('Studio checkout target: https://buy.paddle.com/studio-authoritative')).toBeTruthy() + }) + it('renders the expanded legal and digital-delivery guidance across public support surfaces', async () => { mockGetAuthHealth.mockResolvedValue({ ok: true, diff --git a/website/src/pages/public-page-helpers.tsx b/website/src/pages/public-page-helpers.tsx index 455f406..6d595cf 100644 --- a/website/src/pages/public-page-helpers.tsx +++ b/website/src/pages/public-page-helpers.tsx @@ -18,9 +18,14 @@ import { } from '../site-config' import { browserDesktopRealityCards, + controlProfileRosterCards, deliverySurfaceCards, + higherDimensionalRuntimeGuideCards, + inputAndDevicePostureCards, operatorDesktopQuickstartCards, publicManualRouteAtlasCards, + runtimeControlGuideCards, + simulatorManualCards, } from '../site-data' import { buildLoginPath, @@ -159,6 +164,28 @@ type StepOnlyCard = { bullets?: readonly string[] } +type PrincipleCard = { + title: string + description: string +} + +type BulletCard = { + title: string + description: string + bullets: readonly string[] +} + +type StepCard = { + title: string + description: string + steps: readonly string[] +} + +type FaqCard = { + question: string + answer: string +} + type SupportTopicCard = (typeof supportTopicDirectory)[number] type PublicManualRouteAtlasCard = (typeof publicManualRouteAtlasCards)[number] @@ -350,6 +377,159 @@ export function OperatorDesktopQuickstartSection({ ) } +export function PrincipleCardSection({ + title, + description, + cards, +}: { + title: string + description?: string + cards: readonly PrincipleCard[] +}) { + return ( +
+
+ {cards.map((card) => ( +
+

{card.title}

+

{card.description}

+
+ ))} +
+
+ ) +} + +export function SimulatorManualSection({ + title = 'Simulator manual', + description = 'These are the current product-safe usage tracks for the native runtime itself.', +}: { + title?: string + description?: string +}) { + return +} + +export function HigherDimensionalRuntimeGuideSection({ + title = 'Higher-dimensional family guide', + description = 'These are the currently represented higher-dimensional lanes and the truthful host/runtime posture for each.', +}: { + title?: string + description?: string +}) { + return ( + + ) +} + +export function InputAndDevicePostureSection({ + title = 'Input and device posture', + description = 'Public documentation should be explicit about the current control/runtime truth instead of blurring groundwork and finished VR claims together.', +}: { + title?: string + description?: string +}) { + return ( + + ) +} + +export function ControlProfileRosterSection({ + title = 'Selectable control and settings roster', + description = 'This manual section answers the concrete user question: what settings, profiles, selectors, and persistence surfaces are already real today?', +}: { + title?: string + description?: string +}) { + return ( + + ) +} + +export function RuntimeControlGuideSection({ + title = 'Runtime control guide', + description = 'This manual section explains how to approach the current desktop runtime without pretending the currently closed XR/controller branch has already been reopened.', +}: { + title?: string + description?: string +}) { + return ( + + ) +} + +export function BulletCardSection({ + title, + description, + cards, +}: { + title: string + description?: string + cards: readonly BulletCard[] +}) { + return ( +
+
+ {cards.map((card) => ( +
+

{card.title}

+

{card.description}

+
    + {card.bullets.map((bullet) => ( +
  • {bullet}
  • + ))} +
+
+ ))} +
+
+ ) +} + +export function StepCardSection({ + title, + description, + cards, +}: { + title: string + description?: string + cards: readonly StepCard[] +}) { + return ( +
+
+ {cards.map((card) => ( +
+

{card.title}

+

{card.description}

+
    + {card.steps.map((step) => ( +
  • {step}
  • + ))} +
+
+ ))} +
+
+ ) +} + export function StepOnlyCardSection({ title, description, @@ -377,6 +557,29 @@ export function StepOnlyCardSection({ ) } +export function FaqCardSection({ + title, + description, + cards, +}: { + title: string + description?: string + cards: readonly FaqCard[] +}) { + return ( +
+
+ {cards.map((card) => ( +
+

{card.question}

+

{card.answer}

+
+ ))} +
+
+ ) +} + export function SupportTopicDirectorySection({ title, description, diff --git a/website/src/pages/public-pages-commerce.tsx b/website/src/pages/public-pages-commerce.tsx index efde502..1fb40ec 100644 --- a/website/src/pages/public-pages-commerce.tsx +++ b/website/src/pages/public-pages-commerce.tsx @@ -15,19 +15,23 @@ import { desktopReleaseSignals, digitalDeliveryCards, distributionDoctrineCards, + inputAndDevicePostureCards, openSourceNotices, operatorManualTracks, privacyBoundaryCards, productSurfaceMatrixRows, releaseRolloutChecklist, + runtimeControlGuideCards, supportEscalationCards, termsBoundaryCards, } from '../site-data' import { + BulletCardSection, BrowserAuthMethodsSection, BrowserDesktopRealitySection, DeliverySurfaceResponsibilitiesGrid, explorerFallbackPlan, + HigherDimensionalRuntimeGuideSection, OperatorDesktopQuickstartSection, operatorFallbackPlan, PlanActionLink, @@ -36,6 +40,8 @@ import { ReleaseAuthorityBundleSection, releaseCommerceFallback, Section, + SimulatorManualSection, + StepCardSection, studioFallbackPlan, SurfaceChoiceGuideSection, usePublicReleaseManifestView, @@ -114,24 +120,27 @@ export function PricingPage() { description="Pricing decisions are safer when the current shared-auth sign-in lineup is visible before checkout, protected release access, or browser-account follow-through." /> -
-
- {operatorManualTracks.slice(0, 3).map((track) => ( -
-

{track.title}

-

{track.description}

-
    - {track.steps.map((step) => ( -
  • {step}
  • - ))} -
-
- ))} -
-
+ cards={operatorManualTracks.slice(0, 3)} + /> + + + + + + @@ -149,43 +158,17 @@ export function PricingPage() { -
-
- {distributionDoctrineCards.map((card) => ( -
-

{card.title}

-

{card.description}

-
    - {card.bullets.map((bullet) => ( -
  • {bullet}
  • - ))} -
-
- ))} -
-
+ cards={distributionDoctrineCards} + /> -
-
- {termsBoundaryCards.map((card) => ( -
-

{card.title}

-

{card.description}

-
    - {card.bullets.map((bullet) => ( -
  • {bullet}
  • - ))} -
-
- ))} -
-
+ cards={termsBoundaryCards} + />
@@ -305,6 +288,22 @@ export function DownloadPage() {
+ + + + + + @@ -318,24 +317,11 @@ export function DownloadPage() { description="Download posture is clearer when the current shared-auth sign-in lineup is visible before operators cross into the protected entitlement and package-delivery lane." /> -
-
- {desktopFirstLaunchCards.map((card) => ( -
-

{card.title}

-

{card.description}

-
    - {card.bullets.map((bullet) => ( -
  • {bullet}
  • - ))} -
-
- ))} -
-
+ cards={desktopFirstLaunchCards} + /> @@ -351,24 +337,11 @@ export function DownloadPage() { ]} /> -
-
- {digitalDeliveryCards.map((card) => ( -
-

{card.title}

-

{card.description}

-
    - {card.bullets.map((bullet) => ( -
  • {bullet}
  • - ))} -
-
- ))} -
-
+ cards={digitalDeliveryCards} + />
-
-
- {distributionDoctrineCards.map((card) => ( -
-

{card.title}

-

{card.description}

-
    - {card.bullets.map((bullet) => ( -
  • {bullet}
  • - ))} -
-
- ))} -
-
+ cards={distributionDoctrineCards} + />
diff --git a/website/src/pages/public-pages-features.tsx b/website/src/pages/public-pages-features.tsx index 09a20f3..385d3be 100644 --- a/website/src/pages/public-pages-features.tsx +++ b/website/src/pages/public-pages-features.tsx @@ -4,21 +4,25 @@ import { SiteMetadata } from '../components/seo/SiteMetadata' import { PublicLaunchStatus } from '../components/ui/PublicLaunchStatus' import { ProductSurfaceMatrix } from '../components/ui/ProductSurfaceMatrix' import { - controlProfileRosterCards, deploymentReadinessTracks, featureAtlasCurrentTracks, featureRegistryTierCards, - higherDimensionalRuntimeGuideCards, - inputAndDevicePostureCards, productSurfaceMatrixRows, releaseStoryCards, roadmapHonestyCards, + supportFaqs, } from '../site-data' import { + BulletCardSection, BrowserDesktopRealitySection, + ControlProfileRosterSection, + FaqCardSection, + HigherDimensionalRuntimeGuideSection, + InputAndDevicePostureSection, PublicPackagedDesktopProofSection, PublicReleaseDecisionGuideSection, ReleaseAuthorityBundleSection, + RuntimeControlGuideSection, Section, SurfaceChoiceGuideSection, usePublicReleaseManifestView, @@ -39,43 +43,17 @@ export function FeaturesPage() { title="Feature truth without the roadmap archaeology." lede="This page condenses the real HyperTwist product surface into one public map: what ships now, what stays desktop-first, what the browser shell owns, and which branches remain intentionally gated." > -
-
- {featureRegistryTierCards.map((card) => ( -
-

{card.title}

-

{card.description}

-
    - {card.bullets.map((bullet) => ( -
  • {bullet}
  • - ))} -
-
- ))} -
-
+ cards={featureRegistryTierCards} + /> -
-
- {featureAtlasCurrentTracks.map((track) => ( -
-

{track.title}

-

{track.description}

-
    - {track.bullets.map((bullet) => ( -
  • {bullet}
  • - ))} -
-
- ))} -
-
+ cards={featureAtlasCurrentTracks} + />
-
-
- {higherDimensionalRuntimeGuideCards.map((card) => ( -
-

{card.title}

-

{card.description}

-
    - {card.bullets.map((bullet) => ( -
  • {bullet}
  • - ))} -
-
- ))} -
-
+ /> -
-
- {inputAndDevicePostureCards.map((card) => ( -
-

{card.title}

-

{card.description}

-
    - {card.bullets.map((bullet) => ( -
  • {bullet}
  • - ))} -
-
- ))} -
-
+ /> -
-
- {controlProfileRosterCards.map((card) => ( -
-

{card.title}

-

{card.description}

-
    - {card.bullets.map((bullet) => ( -
  • {bullet}
  • - ))} -
-
- ))} -
-
+ /> + + + +
-
- {cards.map((card) => ( -
-

{card.title}

-

{card.description}

-
- ))} -
-
- ) -} - -function BulletCardSection({ - title, - description, - cards, -}: { - title: string - description?: string - cards: readonly BulletCard[] -}) { - return ( -
-
- {cards.map((card) => ( -
-

{card.title}

-

{card.description}

-
    - {card.bullets.map((bullet) => ( -
  • {bullet}
  • - ))} -
-
- ))} -
-
- ) -} - -function StepCardSection({ - title, - description, - cards, -}: { - title: string - description?: string - cards: readonly StepCard[] -}) { - return ( -
-
- {cards.map((card) => ( -
-

{card.title}

-

{card.description}

-
    - {card.steps.map((step) => ( -
  • {step}
  • - ))} -
-
- ))} -
-
- ) -} - -function FaqCardSection({ - title, - description, - cards, -}: { - title: string - description?: string - cards: readonly FaqCard[] -}) { - return ( -
-
- {cards.map((card) => ( -
-

{card.question}

-

{card.answer}

-
- ))} -
-
- ) -} - export function HomeLanding() { const { releaseManifest, windowsValidationPlatform } = usePublicReleaseManifestView('public-home') @@ -458,43 +338,15 @@ export function AboutPage() { description="The about page should also say what the next honest operator move is, not only why the product exists." /> -
-
- {inputAndDevicePostureCards.map((card) => ( -
-

{card.title}

-

{card.description}

-
    - {card.bullets.map((bullet) => ( -
  • {bullet}
  • - ))} -
-
- ))} -
-
+ /> -
-
- {controlProfileRosterCards.map((card) => ( -
-

{card.title}

-

{card.description}

-
    - {card.bullets.map((bullet) => ( -
  • {bullet}
  • - ))} -
-
- ))} -
-
+ />
-
-
- {simulatorManualCards.map((card) => ( -
-

{card.title}

-

{card.description}

-
    - {card.bullets.map((bullet) => ( -
  • {bullet}
  • - ))} -
-
- ))} -
-
+ /> -
-
- {higherDimensionalRuntimeGuideCards.map((card) => ( -
-

{card.title}

-

{card.description}

-
    - {card.bullets.map((bullet) => ( -
  • {bullet}
  • - ))} -
-
- ))} -
-
+ /> -
-
- {inputAndDevicePostureCards.map((card) => ( -
-

{card.title}

-

{card.description}

-
    - {card.bullets.map((bullet) => ( -
  • {bullet}
  • - ))} -
-
- ))} -
-
+ /> -
-
- {controlProfileRosterCards.map((card) => ( -
-

{card.title}

-

{card.description}

-
    - {card.bullets.map((bullet) => ( -
  • {bullet}
  • - ))} -
-
- ))} -
-
+ /> -
-
- {runtimeControlGuideCards.map((card) => ( -
-

{card.title}

-

{card.description}

-
    - {card.bullets.map((bullet) => ( -
  • {bullet}
  • - ))} -
-
- ))} -
-
+ />
-
-
- {simulatorManualCards.map((card) => ( -
-

{card.title}

-

{card.description}

-
    - {card.bullets.map((bullet) => ( -
  • {bullet}
  • - ))} -
-
- ))} -
-
- - - + + + + + + @@ -992,17 +768,9 @@ export function DocsPage() { description="The public manual should not only explain the surface split. It should also tell operators whether the next honest move is pricing, protected browser/account work, protected desktop access, or notices/source follow-through." /> - + - + - + - + - + , + readiness: PublicLaunchReadiness, +): PublicLaunchChecklistItem[] { + const derivedChecklist = getPublicLaunchChecklist(readiness) + if (!Array.isArray(launch.checklist) || launch.checklist.length === 0) { + return derivedChecklist + } + + const launchChecklistById = new Map( + launch.checklist.map((item) => [item.id, item]), + ) + + return derivedChecklist.map((item) => { + const launchItem = launchChecklistById.get(item.id) + if (!launchItem) { + return item + } + + return { + ...item, + label: + typeof launchItem.label === 'string' && launchItem.label.trim().length > 0 + ? launchItem.label + : item.label, + configured: normalizeConfiguredValue(launchItem.configured), + requiredForPublicLaunch: + typeof launchItem.requiredForPublicLaunch === 'boolean' + ? launchItem.requiredForPublicLaunch + : item.requiredForPublicLaunch, + } + }) +} + +function resolveHealthLaunchMissingLabels( + launch: NonNullable, + checklist: readonly PublicLaunchChecklistItem[], + ready: boolean, +): string[] { + const launchMissingLabels = Array.isArray(launch.missingLabels) + ? launch.missingLabels + .map((label) => String(label || '').trim()) + .filter(Boolean) + : [] + + if (launchMissingLabels.length > 0 || ready) { + return launchMissingLabels + } + + return checklist + .filter((item) => item.requiredForPublicLaunch && !item.configured) + .map((item) => item.label) +} + export function resolvePublicLaunchStatusSummary({ manifest, health, @@ -313,7 +367,7 @@ export function resolvePublicLaunchStatusSummary({ health?: AuthHealthLike | null fallback?: PublicLaunchReadinessInput | null }): PublicLaunchStatusSummary { - return buildPublicLaunchStatusSummary( + const derivedSummary = buildPublicLaunchStatusSummary( resolveHealthPublicLaunchReadiness({ manifest, health, @@ -321,4 +375,27 @@ export function resolvePublicLaunchStatusSummary({ }), resolvePublicLaunchTargets(manifest, health), ) + + if (!health?.launch) { + return derivedSummary + } + + const readiness = normalizePublicLaunchReadiness({ + ...derivedSummary.readiness, + ...health.launch.readiness, + }) + const checklist = resolveHealthLaunchChecklist(health.launch, readiness) + const ready = + typeof health.launch.ready === 'boolean' + ? health.launch.ready && health.launch.posture === 'launch-ready' + : derivedSummary.ready + + return { + posture: ready ? 'launch-ready' : 'preview', + ready, + readiness, + checklist, + missingLabels: resolveHealthLaunchMissingLabels(health.launch, checklist, ready), + targets: resolvePublicLaunchTargets(manifest, health), + } } diff --git a/website/src/site-data.ts b/website/src/site-data.ts index 9bb98b0..c35dae6 100644 --- a/website/src/site-data.ts +++ b/website/src/site-data.ts @@ -548,6 +548,16 @@ export const runtimeControlGuideCards = [ 'Treat symmetry, stereo, visibility, and focus posture as current packaged runtime ownership rather than as a fully generalized preferences suite.', ], }, + { + title: 'Native diagnostics check', + description: 'Use the native training panel or coach dashboard to confirm the runtime you are actually operating before longer sessions, support escalation, or rollout review.', + bullets: [ + 'Read the active higher-dimensional selection line to confirm the current activation, view-context, session, and displayed scene ids instead of inferring them from the launched map alone.', + 'Read the profile continuity line to confirm the shipped camera-export artifact `artifact/camera-export-json`, immersive recall boundary `immersive-training-session-recall-boundary`, and the current recall-scope and preference-field counts when bounded continuity is available.', + 'Use the same native surfaces to verify that the desktop-hosted No-Go XR/controller boundary is still the live truth before assuming headset-runtime or controller-rebinding support.', + 'If behavior and rollout posture disagree, capture the native diagnostics first and then move into the protected browser support or release lanes with the exact runtime state in hand.', + ], + }, { title: 'Current control boundary', description: 'This keeps the manual useful by being explicit about what is supported now and what remains outside the current desktop-hosted No-Go XR/controller branch.', @@ -578,7 +588,7 @@ export const controlProfileRosterCards = [ 'The current scenic immersive roster includes 3 immersive-intensity presets and 3 reduced-distraction presets.', 'Magic120Cell currently exposes 4 selector options alongside its symmetry, focus, and visibility owners.', 'MagicCube5D currently exposes 4 selector options alongside its projection-distance, stereo, focus, and visibility owners.', - 'Both higher-dimensional families now also surface their dedicated session, interactive-scene, persistence-boundary, and state-semantics ownership directly in the native diagnostics lane.', + 'Both higher-dimensional families now also surface their dedicated session, interactive-scene, persistence-boundary, and state-semantics ownership directly in the native diagnostics lane, and the live roster surface keeps the currently displayed scene id visible too.', ], }, { @@ -586,7 +596,7 @@ export const controlProfileRosterCards = [ description: 'Current continuity is real, but it is still narrower than a finished global preferences and controller-rebinding suite.', bullets: [ 'The native operator and training surfaces can recall the latest persisted generated-mode selector posture when a structurally valid launch request exists.', - 'Those same native surfaces now also keep the shipped camera-export artifact and immersive session-recall boundary explicit, so bounded local continuity is no longer implied only through summary prose.', + 'Those same native surfaces now also keep the shipped camera-export artifact and immersive session-recall boundary explicit together with recall-scope and preference-field counts, so bounded local continuity is no longer implied only through summary prose.', 'Those same native surfaces now also prove which family-specific persistence boundary and state-semantics contract currently owns the higher-dimensional settings lane.', 'Viewer camera settings and immersive-presence settings are already first-party owned in the desktop runtime.', 'Finished headset-specific controller rebinding and broad VR onboarding remain outside the current desktop-hosted No-Go lane unless a later reopen proves the need.', @@ -1026,6 +1036,11 @@ export const publicManualRouteAtlasCards = [ ] as const export const changelogEntries = [ + { + date: 'June 28, 2026', + title: 'Native control roster now exposes active scene and bounded continuity truth', + details: 'The desktop training-panel and coach-dashboard roster surfaces now keep the active higher-dimensional scene id visible alongside the active activation, view-context, and session ids, while also rendering the shipped camera-export artifact and immersive session-recall boundary with bounded continuity counts instead of leaving those facts implied behind sibling settings surfaces.', + }, { date: 'June 28, 2026', title: 'Public pages now explain what each route is actually for', @@ -1278,11 +1293,11 @@ export const supportFaqs = [ }, { question: 'If the desktop app is primary, why keep the web version?', - answer: 'Because the browser shell owns the parts that should stay outside the simulator: public positioning, account access, billing, release posture, download gating, notices, and browser-to-desktop pairing. It is intentionally narrower than the simulator for training and device/runtime work, and that narrower boundary makes the native runtime easier to trust and easier to operate.', + answer: 'Because the browser shell owns the parts that should stay outside the simulator: public positioning, account access, billing, release posture, download gating, notices, support-safe rollout guidance, and browser-to-desktop pairing. It is intentionally inferior for the core simulator job: it does not own package-validated training behavior, low-latency native input, higher-dimensional packaged execution, or device/runtime integration authority. That narrower boundary is a strength, not a weakness, because it keeps the native runtime easier to trust, easier to operate, and easier to ship honestly.', }, { question: 'Is VR/controller support already fully finished?', - answer: 'Not yet. HyperTwist already has real EnhancedInput posture, motion-controller groundwork, and a desktop-hosted scenic immersive lane, but the current host decision remains desktop-hosted No-Go on native OpenXR/controller widening, so it does not claim a fully finished OpenXR/controller/runtime or polished rebinding lane today.', + answer: 'Not yet. HyperTwist already has real classic keyboard and mouse or touch ownership, viewer camera and immersive settings ownership, higher-dimensional selector and view ownership, EnhancedInput posture, and motion-controller groundwork. But the current host decision remains desktop-hosted No-Go on native OpenXR/controller widening, so it does not yet claim a fully finished headset/runtime lane, packaged controller proof, or polished controller rebinding and preferences suite.', }, { question: 'Can I already customize controls and higher-dimensional view posture?', diff --git a/website/src/styles/global.css b/website/src/styles/global.css index 69ecaac..05a9e98 100644 --- a/website/src/styles/global.css +++ b/website/src/styles/global.css @@ -839,4 +839,14 @@ code { width: 100%; flex-direction: column; } + + .button-row > * { + width: 100%; + } + + .button-row .button { + width: 100%; + max-width: 100%; + white-space: normal; + } } diff --git a/website/tests/e2e/responsive-public-pages.spec.ts b/website/tests/e2e/responsive-public-pages.spec.ts index 2aa8d84..4f56be5 100644 --- a/website/tests/e2e/responsive-public-pages.spec.ts +++ b/website/tests/e2e/responsive-public-pages.spec.ts @@ -14,6 +14,10 @@ const responsivePublicRoutes: readonly PublicRouteExpectation[] = [ heading: 'HyperTwist turns cube practice into a real operator-grade training stack.', cta: 'Download desktop app', }, + { + path: '/features', + heading: 'Feature truth without the roadmap archaeology.', + }, { path: '/about', heading: 'A training stack serious enough for higher-dimensional cubing.', @@ -22,6 +26,10 @@ const responsivePublicRoutes: readonly PublicRouteExpectation[] = [ path: '/resources', heading: 'Resources that explain the product without leaking operator-only internals.', }, + { + path: '/docs', + heading: 'HyperTwist documentation stays capability-accurate.', + }, { path: '/pricing', heading: 'Pricing that matches the actual delivery model.', @@ -30,10 +38,43 @@ const responsivePublicRoutes: readonly PublicRouteExpectation[] = [ path: '/download', heading: 'Download the desktop build and pair it with your browser account.', }, + { + path: '/getting-started', + heading: 'Start in the browser. Train in the desktop runtime.', + }, + { + path: '/launch-status', + heading: 'See exactly what still separates preview from public launch.', + }, { path: '/support', heading: 'Support for rollout, downloads, pricing, and browser-to-desktop access.', }, + { + path: '/login', + heading: 'Log in to HyperTwist', + cta: 'Log in', + }, + { + path: '/changelog', + heading: 'Recent public-facing HyperTwist changes.', + }, + { + path: '/open-source-notices', + heading: 'Open-source notices for public distribution surfaces.', + }, + { + path: '/privacy', + heading: 'Privacy posture', + }, + { + path: '/terms', + heading: 'Terms of access', + }, + { + path: '/shipping-payment', + heading: 'Digital delivery only', + }, { path: '/register', heading: 'Create a HyperTwist account',