Harden public manual surfaces and owned refactor tooling

This commit is contained in:
axiomlogicnexus 2026-06-29 13:20:34 +00:00
parent 30bec87f9d
commit 3ccfe617ab
32 changed files with 3622 additions and 734 deletions

View file

@ -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
}

View file

@ -1,7 +1,42 @@
import { defineConfig } from 'vite'; import { defineConfig } from 'vite';
import { resolve } from 'path'; 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({ export default defineConfig({
plugins: [
annotateGltfViewerMikktspaceFallback()
],
build: { build: {
outDir: 'dist', outDir: 'dist',
emptyOutDir: true, emptyOutDir: true,

View file

@ -19383,6 +19383,14 @@ void UHyperTwistCoachDashboardWidget::EnsureDefaultDashboardBuilt()
4 4
) )
); );
ControlProfileRosterStructuredTextBlocks.Add(
HyperTwistCoachDashboardWidgetInternal::AddTextRow(
WidgetTree,
RootLayout,
TEXT("CoachControlProfileRosterPreferencesContinuity"),
4
)
);
ControlProfileRosterStructuredTextBlocks.Add( ControlProfileRosterStructuredTextBlocks.Add(
HyperTwistCoachDashboardWidgetInternal::AddTextRow( HyperTwistCoachDashboardWidgetInternal::AddTextRow(
WidgetTree, WidgetTree,
@ -30546,6 +30554,7 @@ void UHyperTwistCoachDashboardWidget::UpdateDashboardPresentation()
ControlProfileRosterSurface.MagicCube5DProfileLine, ControlProfileRosterSurface.MagicCube5DProfileLine,
ControlProfileRosterSurface.ActiveHigherDimensionalProfileLine, ControlProfileRosterSurface.ActiveHigherDimensionalProfileLine,
ControlProfileRosterSurface.SelectorRecallLine, ControlProfileRosterSurface.SelectorRecallLine,
ControlProfileRosterSurface.PreferencesContinuityLine,
ControlProfileRosterSurface.PreferencesGapLine, ControlProfileRosterSurface.PreferencesGapLine,
} }
); );

View file

@ -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)
);
}
}

View file

@ -1,10 +1,12 @@
#include "HyperTwistTraining/HyperTwistTrainingPanelWidget.h" #include "HyperTwistTraining/HyperTwistTrainingPanelWidget.h"
#include "HyperTwistAlgorithm/HyperTwistAlgorithmKeyboard.h" #include "HyperTwistAlgorithm/HyperTwistAlgorithmKeyboard.h"
#include "HyperTwistAlgorithm/HyperTwistAlgorithmSerializer.h"
#include "HyperTwistBrowser/HyperTwistBrowserWidget.h" #include "HyperTwistBrowser/HyperTwistBrowserWidget.h"
#include "HyperTwistSimulation/HyperTwistClassicCubeOrbitPawn.h" #include "HyperTwistSimulation/HyperTwistClassicCubeOrbitPawn.h"
#include "HyperTwistSimulation/HyperTwistClassicCubePlayerController.h" #include "HyperTwistSimulation/HyperTwistClassicCubePlayerController.h"
#include "HyperTwistSimulation/HyperTwistVirtual3333ProjectionPlayerController.h" #include "HyperTwistSimulation/HyperTwistVirtual3333ProjectionPlayerController.h"
#include "HyperTwistTraining/HyperTwistTrainingControlSurfaceFormatting.h"
#include "HyperTwistTraining/HyperTwistTrainingImmersiveEnvironmentLibrary.h" #include "HyperTwistTraining/HyperTwistTrainingImmersiveEnvironmentLibrary.h"
#include "HyperTwistTraining/HyperTwistTrainingMagic120CellLibrary.h" #include "HyperTwistTraining/HyperTwistTrainingMagic120CellLibrary.h"
#include "HyperTwistTraining/HyperTwistTrainingMagicCube5DLibrary.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) FString DescribeBool(const bool bValue)
{ {
return bValue ? TEXT("yes") : TEXT("no"); return HyperTwistTrainingControlSurfaceFormatting::DescribeBool(bValue);
} }
FString DescribeReadyState(const bool bValue) FString DescribeReadyState(const bool bValue)
{ {
return bValue ? TEXT("ready") : TEXT("not ready"); return HyperTwistTrainingControlSurfaceFormatting::DescribeReadyState(bValue);
} }
FString DescribeAggregateReadyState( FString DescribeAggregateReadyState(
@ -77,17 +93,9 @@ namespace HyperTwistTrainingPanelWidgetInternal
const bool bSecondaryReady const bool bSecondaryReady
) )
{ {
if (bPrimaryReady && bSecondaryReady) return HyperTwistTrainingControlSurfaceFormatting::DescribeAggregateReadyState(
{ bPrimaryReady,
return TEXT("ready"); bSecondaryReady);
}
if (bPrimaryReady || bSecondaryReady)
{
return TEXT("partial");
}
return TEXT("missing");
} }
FString DescribeOwnedContinuityState( FString DescribeOwnedContinuityState(
@ -95,17 +103,14 @@ namespace HyperTwistTrainingPanelWidgetInternal
const bool bContinuityReady const bool bContinuityReady
) )
{ {
if (!bOwnershipReady) return HyperTwistTrainingControlSurfaceFormatting::DescribeOwnedContinuityState(
{ bOwnershipReady,
return TEXT("missing"); bContinuityReady);
}
return bContinuityReady ? TEXT("ready") : TEXT("partial");
} }
FString DescribeIdOrFallback(const FString& Value) FString DescribeIdOrFallback(const FString& Value)
{ {
return !Value.IsEmpty() ? Value : FString(TEXT("n/a")); return HyperTwistTrainingControlSurfaceFormatting::DescribeIdOrFallback(Value);
} }
FString DescribeKeyForRoster(const FKey& Key) FString DescribeKeyForRoster(const FKey& Key)
@ -120,17 +125,16 @@ namespace HyperTwistTrainingPanelWidgetInternal
return TEXT("n/a"); return TEXT("n/a");
} }
FString Text = Move.Family; FHyperTwistAlgorithmNode Node;
if (Move.Amount < 0) Node.NodeType = EHyperTwistAlgorithmNodeType::BlockMove;
{ Node.BlockMove = Move;
Text += TEXT("'");
}
else if (FMath::Abs(Move.Amount) > 1)
{
Text += FString::FromInt(FMath::Abs(Move.Amount));
}
return Text; FHyperTwistAlgorithmSequence Sequence;
Sequence.Nodes.Add(Node);
const FString CanonicalText =
UHyperTwistAlgorithmSerializer::SerializeAlgorithm(Sequence);
return !CanonicalText.IsEmpty() ? CanonicalText : TEXT("n/a");
} }
FString BuildClassicKeyboardMoveRosterLine( FString BuildClassicKeyboardMoveRosterLine(
@ -286,6 +290,43 @@ namespace HyperTwistTrainingPanelWidgetInternal
return false; 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( bool AxisConfigEntriesContainToken(
const TArray<FString>& AxisConfigEntries, const TArray<FString>& AxisConfigEntries,
const TCHAR* Token const TCHAR* Token
@ -1253,29 +1294,17 @@ UHyperTwistTrainingPanelWidget::GetDisplayedControlInputReadinessInspectSurface(
TEXT("immersive-training-presence-control-contract"), TEXT("immersive-training-presence-control-contract"),
PresenceControlContract PresenceControlContract
); );
const FHyperTwistTrainingViewerReferenceBundle ViewerBundle = const HyperTwistTrainingPanelWidgetInternal::FViewerCameraSettingsFacts
UHyperTwistTrainingViewerLibrary::BuildBundledBrowserViewerReferenceBundle(); CameraSettingsFacts =
FHyperTwistTrainingViewerEditorToolReference CameraSettingsTool; HyperTwistTrainingPanelWidgetInternal::BuildViewerCameraSettingsFacts();
FHyperTwistTrainingViewerQaArtifactReference CameraExportArtifact;
FString CameraExportArtifactId;
const bool bCameraSettingsContinuityReady = const bool bCameraSettingsContinuityReady =
ViewerBundle.IsStructurallyValid() CameraSettingsFacts.bExportArtifactReady;
&& HyperTwistTrainingPanelWidgetInternal::TryFindViewerEditorToolById( const FString CameraExportArtifactId = CameraSettingsFacts.ExportArtifactId;
ViewerBundle, const HyperTwistTrainingPanelWidgetInternal::FImmersiveSessionRecallFacts
TEXT("tool/camera-settings"), ImmersiveSessionRecallFacts =
CameraSettingsTool HyperTwistTrainingPanelWidgetInternal::BuildImmersiveSessionRecallFacts();
) && HyperTwistTrainingPanelWidgetInternal::TryFindFirstViewerQaArtifactByIds(
ViewerBundle,
CameraSettingsTool.ExportArtifactIds,
CameraExportArtifactId,
CameraExportArtifact
);
FHyperTwistTrainingImmersiveSessionRecallBoundary ImmersiveSessionRecallBoundary;
const bool bImmersiveSessionRecallReady = const bool bImmersiveSessionRecallReady =
UHyperTwistTrainingRuntimeLibrary::TryGetBundledImmersiveSessionRecallBoundary( ImmersiveSessionRecallFacts.bReady;
TEXT("immersive-training-session-recall-boundary"),
ImmersiveSessionRecallBoundary
) && ImmersiveSessionRecallBoundary.IsStructurallyValid();
const bool bBoundedPreferencesContinuityReady = const bool bBoundedPreferencesContinuityReady =
bCameraSettingsContinuityReady && bImmersiveSessionRecallReady; bCameraSettingsContinuityReady && bImmersiveSessionRecallReady;
@ -1347,24 +1376,15 @@ UHyperTwistTrainingPanelWidget::GetDisplayedControlInputReadinessInspectSurface(
*HyperTwistTrainingPanelWidgetInternal::DescribeBool( *HyperTwistTrainingPanelWidgetInternal::DescribeBool(
Surface.bImmersivePresenceContractReady) Surface.bImmersivePresenceContractReady)
); );
Surface.PreferencesStatusLine = FString::Printf( Surface.PreferencesStatusLine =
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."), HyperTwistTrainingControlSurfaceFormatting::BuildControlInputPreferencesStatusLine(
*HyperTwistTrainingPanelWidgetInternal::DescribeAggregateReadyState(
bCameraSettingsContinuityReady, bCameraSettingsContinuityReady,
bImmersiveSessionRecallReady), CameraExportArtifactId,
*HyperTwistTrainingPanelWidgetInternal::DescribeIdOrFallback( bImmersiveSessionRecallReady,
bCameraSettingsContinuityReady ? CameraExportArtifactId : FString()), ImmersiveSessionRecallFacts.Boundary.BoundaryId,
*HyperTwistTrainingPanelWidgetInternal::DescribeIdOrFallback( ImmersiveSessionRecallFacts.Boundary.RecallScopeIds.Num(),
bImmersiveSessionRecallReady ImmersiveSessionRecallFacts.Boundary.PreferenceFieldTags.Num()
? ImmersiveSessionRecallBoundary.BoundaryId );
: FString()),
bImmersiveSessionRecallReady
? ImmersiveSessionRecallBoundary.RecallScopeIds.Num()
: 0,
bImmersiveSessionRecallReady
? ImmersiveSessionRecallBoundary.PreferenceFieldTags.Num()
: 0
);
Surface.NextPacketLine = Surface.NextPacketLine =
HyperTwistTrainingPanelWidgetInternal::BuildControlInputXrBoundaryLine(); HyperTwistTrainingPanelWidgetInternal::BuildControlInputXrBoundaryLine();
Surface.StatusLine = FString::Printf( Surface.StatusLine = FString::Printf(
@ -1404,36 +1424,23 @@ UHyperTwistTrainingPanelWidget::GetDisplayedControlSettingsOwnershipInspectSurfa
FHyperTwistTrainingControlSettingsOwnershipInspectSurface Surface; FHyperTwistTrainingControlSettingsOwnershipInspectSurface Surface;
Surface.Headline = TEXT("Control settings ownership"); Surface.Headline = TEXT("Control settings ownership");
const FHyperTwistTrainingViewerReferenceBundle ViewerBundle = const HyperTwistTrainingPanelWidgetInternal::FViewerCameraSettingsFacts
UHyperTwistTrainingViewerLibrary::BuildBundledBrowserViewerReferenceBundle(); CameraSettingsFacts =
FHyperTwistTrainingViewerEditorToolReference CameraSettingsTool; HyperTwistTrainingPanelWidgetInternal::BuildViewerCameraSettingsFacts();
Surface.bCameraSettingsReady = Surface.bCameraSettingsReady = CameraSettingsFacts.bToolReady;
ViewerBundle.IsStructurallyValid()
&& HyperTwistTrainingPanelWidgetInternal::TryFindViewerEditorToolById(
ViewerBundle,
TEXT("tool/camera-settings"),
CameraSettingsTool
);
if (Surface.bCameraSettingsReady) if (Surface.bCameraSettingsReady)
{ {
Surface.CameraSettingsToolId = CameraSettingsTool.ToolId; Surface.CameraSettingsToolId = CameraSettingsFacts.Tool.ToolId;
Surface.CameraSettingsWorkflowTagCount = CameraSettingsTool.WorkflowTags.Num(); Surface.CameraSettingsWorkflowTagCount =
CameraSettingsFacts.Tool.WorkflowTags.Num();
Surface.CameraSettingsPreviewStateTagCount = Surface.CameraSettingsPreviewStateTagCount =
CameraSettingsTool.PreviewStateTags.Num(); CameraSettingsFacts.Tool.PreviewStateTags.Num();
Surface.CameraSettingsExportArtifactCount = Surface.CameraSettingsExportArtifactCount =
CameraSettingsTool.ExportArtifactIds.Num(); CameraSettingsFacts.Tool.ExportArtifactIds.Num();
} }
FHyperTwistTrainingViewerQaArtifactReference CameraExportArtifact;
FString CameraExportArtifactId;
Surface.bCameraSettingsContinuityReady = Surface.bCameraSettingsContinuityReady =
Surface.bCameraSettingsReady CameraSettingsFacts.bExportArtifactReady;
&& HyperTwistTrainingPanelWidgetInternal::TryFindFirstViewerQaArtifactByIds( Surface.CameraSettingsExportArtifactId = CameraSettingsFacts.ExportArtifactId;
ViewerBundle,
CameraSettingsTool.ExportArtifactIds,
CameraExportArtifactId,
CameraExportArtifact
);
Surface.CameraSettingsExportArtifactId = CameraExportArtifactId;
FHyperTwistTrainingImmersivePresenceControlContract ImmersivePresenceContract; FHyperTwistTrainingImmersivePresenceControlContract ImmersivePresenceContract;
Surface.bImmersivePresenceSettingsReady = Surface.bImmersivePresenceSettingsReady =
@ -1447,22 +1454,20 @@ UHyperTwistTrainingPanelWidget::GetDisplayedControlSettingsOwnershipInspectSurfa
Surface.ImmersivePresenceSurfaceTagCount = Surface.ImmersivePresenceSurfaceTagCount =
ImmersivePresenceContract.PresenceSurfaceTags.Num(); ImmersivePresenceContract.PresenceSurfaceTags.Num();
} }
FHyperTwistTrainingImmersiveSessionRecallBoundary ImmersiveSessionRecallBoundary; const HyperTwistTrainingPanelWidgetInternal::FImmersiveSessionRecallFacts
Surface.bImmersiveSessionRecallReady = ImmersiveSessionRecallFacts =
UHyperTwistTrainingRuntimeLibrary::TryGetBundledImmersiveSessionRecallBoundary( HyperTwistTrainingPanelWidgetInternal::BuildImmersiveSessionRecallFacts();
TEXT("immersive-training-session-recall-boundary"), Surface.bImmersiveSessionRecallReady = ImmersiveSessionRecallFacts.bReady;
ImmersiveSessionRecallBoundary
) && ImmersiveSessionRecallBoundary.IsStructurallyValid();
if (Surface.bImmersiveSessionRecallReady) if (Surface.bImmersiveSessionRecallReady)
{ {
Surface.ImmersiveSessionRecallBoundaryId = Surface.ImmersiveSessionRecallBoundaryId =
ImmersiveSessionRecallBoundary.BoundaryId; ImmersiveSessionRecallFacts.Boundary.BoundaryId;
Surface.ImmersiveSessionRecallScopeCount = Surface.ImmersiveSessionRecallScopeCount =
ImmersiveSessionRecallBoundary.RecallScopeIds.Num(); ImmersiveSessionRecallFacts.Boundary.RecallScopeIds.Num();
Surface.ImmersiveSessionRecallPreferenceFieldTagCount = Surface.ImmersiveSessionRecallPreferenceFieldTagCount =
ImmersiveSessionRecallBoundary.PreferenceFieldTags.Num(); ImmersiveSessionRecallFacts.Boundary.PreferenceFieldTags.Num();
Surface.ImmersiveSessionRecallResetSurfaceTagCount = Surface.ImmersiveSessionRecallResetSurfaceTagCount =
ImmersiveSessionRecallBoundary.ResetSurfaceTags.Num(); ImmersiveSessionRecallFacts.Boundary.ResetSurfaceTags.Num();
} }
FHyperTwistTrainingHigherDimensionalRuntimeViewContextSurface Magic120CellViewContextSurface; FHyperTwistTrainingHigherDimensionalRuntimeViewContextSurface Magic120CellViewContextSurface;
@ -1622,8 +1627,6 @@ UHyperTwistTrainingPanelWidget::GetDisplayedControlSettingsOwnershipInspectSurfa
Surface.bRequiresWindowsPackagedControllerValidationForReopen = Surface.bRequiresWindowsPackagedControllerValidationForReopen =
XrBoundaryFacts.bRequiresWindowsPackagedControllerValidationForReopen; XrBoundaryFacts.bRequiresWindowsPackagedControllerValidationForReopen;
const FString CameraSettingsToolId =
!Surface.CameraSettingsToolId.IsEmpty() ? Surface.CameraSettingsToolId : TEXT("n/a");
const FString ActiveViewContextId = const FString ActiveViewContextId =
!Surface.ActiveHigherDimensionalViewContextId.IsEmpty() !Surface.ActiveHigherDimensionalViewContextId.IsEmpty()
? Surface.ActiveHigherDimensionalViewContextId ? Surface.ActiveHigherDimensionalViewContextId
@ -1682,51 +1685,32 @@ UHyperTwistTrainingPanelWidget::GetDisplayedControlSettingsOwnershipInspectSurfa
const bool bMagicCube5DOwnedSettingsReady = const bool bMagicCube5DOwnedSettingsReady =
Surface.bMagicCube5DViewSettingsReady Surface.bMagicCube5DViewSettingsReady
&& Surface.bMagicCube5DPersistenceSettingsReady; && 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 = 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."); 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( Surface.CameraSettingsLine =
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."), HyperTwistTrainingControlSurfaceFormatting::BuildControlSettingsCameraSettingsLine(
*HyperTwistTrainingPanelWidgetInternal::DescribeOwnedContinuityState(
Surface.bCameraSettingsReady, Surface.bCameraSettingsReady,
Surface.bCameraSettingsContinuityReady), Surface.bCameraSettingsContinuityReady,
*CameraSettingsToolId, Surface.CameraSettingsToolId,
*DisplayCameraExportArtifactId, Surface.CameraSettingsExportArtifactId,
Surface.CameraSettingsWorkflowTagCount, Surface.CameraSettingsWorkflowTagCount,
Surface.CameraSettingsPreviewStateTagCount, Surface.CameraSettingsPreviewStateTagCount,
Surface.CameraSettingsExportArtifactCount Surface.CameraSettingsExportArtifactCount
); );
Surface.ImmersiveSettingsLine = FString::Printf( Surface.ImmersiveSettingsLine =
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."), HyperTwistTrainingControlSurfaceFormatting::BuildControlSettingsImmersiveSettingsLine(
*HyperTwistTrainingPanelWidgetInternal::DescribeOwnedContinuityState(
Surface.bImmersivePresenceSettingsReady, Surface.bImmersivePresenceSettingsReady,
Surface.bImmersiveSessionRecallReady), Surface.bImmersiveSessionRecallReady,
*ImmersivePresenceContractId, Surface.ImmersivePresenceContractId,
*ImmersiveSessionRecallBoundaryId, Surface.ImmersiveSessionRecallBoundaryId,
ImmersivePresenceContract.ImmersionIntensityIds.Num(), ImmersivePresenceContract.ImmersionIntensityIds.Num(),
ImmersivePresenceContract.ReducedDistractionPresetIds.Num(), ImmersivePresenceContract.ReducedDistractionPresetIds.Num(),
Surface.ImmersivePresenceSurfaceTagCount, Surface.ImmersivePresenceSurfaceTagCount,
Surface.ImmersiveSessionRecallScopeCount, Surface.ImmersiveSessionRecallScopeCount,
Surface.ImmersiveSessionRecallPreferenceFieldTagCount, Surface.ImmersiveSessionRecallPreferenceFieldTagCount,
Surface.ImmersiveSessionRecallResetSurfaceTagCount Surface.ImmersiveSessionRecallResetSurfaceTagCount
); );
Surface.Magic120CellSettingsLine = FString::Printf( 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."), 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( *HyperTwistTrainingPanelWidgetInternal::DescribeReadyState(
@ -1774,19 +1758,17 @@ UHyperTwistTrainingPanelWidget::GetDisplayedControlSettingsOwnershipInspectSurfa
HyperTwistTrainingPanelWidgetInternal::BuildControlSettingsXrBoundaryLine( HyperTwistTrainingPanelWidgetInternal::BuildControlSettingsXrBoundaryLine(
Surface.bOpenXrProjectPluginEnabled Surface.bOpenXrProjectPluginEnabled
); );
Surface.StatusLine = FString::Printf( Surface.StatusLine =
TEXT("camera %s | immersive %s | 120-cell owned settings %s | 5D owned settings %s | selectors %s | selector recall %s | XR rebinding not yet shipped"), HyperTwistTrainingControlSurfaceFormatting::BuildControlSettingsStatusLine(
*HyperTwistTrainingPanelWidgetInternal::DescribeOwnedContinuityState(
Surface.bCameraSettingsReady, Surface.bCameraSettingsReady,
Surface.bCameraSettingsContinuityReady), Surface.bCameraSettingsContinuityReady,
*HyperTwistTrainingPanelWidgetInternal::DescribeOwnedContinuityState(
Surface.bImmersivePresenceSettingsReady, Surface.bImmersivePresenceSettingsReady,
Surface.bImmersiveSessionRecallReady), Surface.bImmersiveSessionRecallReady,
bMagic120CellOwnedSettingsReady ? TEXT("ready") : TEXT("partial"), bMagic120CellOwnedSettingsReady,
bMagicCube5DOwnedSettingsReady ? TEXT("ready") : TEXT("partial"), bMagicCube5DOwnedSettingsReady,
Surface.bHigherDimensionalSelectorSettingsReady ? TEXT("ready") : TEXT("partial"), Surface.bHigherDimensionalSelectorSettingsReady,
Surface.bRepositoryBackedSelectorRecallReady ? TEXT("ready") : TEXT("unavailable") Surface.bRepositoryBackedSelectorRecallReady
); );
Surface.DetailLine = FString::Printf( Surface.DetailLine = FString::Printf(
TEXT("%s | %s | %s | %s | %s | %s | %s"), TEXT("%s | %s | %s | %s | %s | %s | %s"),
*Surface.CameraSettingsLine, *Surface.CameraSettingsLine,
@ -1827,6 +1809,25 @@ UHyperTwistTrainingPanelWidget::GetDisplayedControlProfileRosterInspectSurface()
Surface.ReducedDistractionPresetCount = Surface.ReducedDistractionPresetCount =
PresenceContract.ReducedDistractionPresetIds.Num(); 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 = const FHyperTwistTrainingMagic120CellReferenceBundle Magic120CellBundle =
UHyperTwistTrainingRuntimeLibrary::GetBundledMagic120CellReferenceBundle(); UHyperTwistTrainingRuntimeLibrary::GetBundledMagic120CellReferenceBundle();
@ -1900,6 +1901,10 @@ UHyperTwistTrainingPanelWidget::GetDisplayedControlProfileRosterInspectSurface()
HasDisplayedHigherDimensionalRuntimeSessionSurface() HasDisplayedHigherDimensionalRuntimeSessionSurface()
? GetDisplayedHigherDimensionalRuntimeSessionSurface() ? GetDisplayedHigherDimensionalRuntimeSessionSurface()
: FHyperTwistTrainingHigherDimensionalRuntimeSessionSurface(); : FHyperTwistTrainingHigherDimensionalRuntimeSessionSurface();
const FHyperTwistTrainingHigherDimensionalInteractiveSceneSurface ActiveSceneSurface =
HasDisplayedHigherDimensionalInteractiveSceneSurface()
? GetDisplayedHigherDimensionalInteractiveSceneSurface()
: FHyperTwistTrainingHigherDimensionalInteractiveSceneSurface();
Surface.bActiveHigherDimensionalProfileVisible = ActiveActivationProfile.IsStructurallyValid(); Surface.bActiveHigherDimensionalProfileVisible = ActiveActivationProfile.IsStructurallyValid();
Surface.ActiveHigherDimensionalActivationProfileId = Surface.ActiveHigherDimensionalActivationProfileId =
Surface.bActiveHigherDimensionalProfileVisible Surface.bActiveHigherDimensionalProfileVisible
@ -1911,6 +1916,10 @@ UHyperTwistTrainingPanelWidget::GetDisplayedControlProfileRosterInspectSurface()
Surface.ActiveHigherDimensionalSessionSurfaceId = ActiveSessionSurface.IsStructurallyValid() Surface.ActiveHigherDimensionalSessionSurfaceId = ActiveSessionSurface.IsStructurallyValid()
? ActiveSessionSurface.SessionSurfaceId ? ActiveSessionSurface.SessionSurfaceId
: TEXT("none"); : TEXT("none");
Surface.ActiveHigherDimensionalInteractiveSceneSurfaceId =
ActiveSceneSurface.IsStructurallyValid()
? ActiveSceneSurface.SceneSurfaceId
: TEXT("none");
Surface.ActiveHigherDimensionalSelectorCount = ActiveViewContextSurface.IsStructurallyValid() Surface.ActiveHigherDimensionalSelectorCount = ActiveViewContextSurface.IsStructurallyValid()
? ActiveViewContextSurface.Selectors.Num() ? ActiveViewContextSurface.Selectors.Num()
: 0; : 0;
@ -1975,9 +1984,12 @@ UHyperTwistTrainingPanelWidget::GetDisplayedControlProfileRosterInspectSurface()
!Surface.ActiveHigherDimensionalSessionSurfaceId.IsEmpty() !Surface.ActiveHigherDimensionalSessionSurfaceId.IsEmpty()
? Surface.ActiveHigherDimensionalSessionSurfaceId ? Surface.ActiveHigherDimensionalSessionSurfaceId
: TEXT("none"); : TEXT("none");
const FString ActiveSceneSurfaceId =
!Surface.ActiveHigherDimensionalInteractiveSceneSurfaceId.IsEmpty()
? Surface.ActiveHigherDimensionalInteractiveSceneSurfaceId
: TEXT("none");
Surface.SummaryLine = 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( Surface.ClassicKeyboardProfileLine = FString::Printf(
TEXT("Classic keyboard profile: %s | bindings %d | ctrl suppressed %s | alt suppressed %s | meta suppressed %s | repeat suppressed %s."), TEXT("Classic keyboard profile: %s | bindings %d | ctrl suppressed %s | alt suppressed %s | meta suppressed %s | repeat suppressed %s."),
*ClassicKeyboardProfileName, *ClassicKeyboardProfileName,
@ -2022,10 +2034,11 @@ UHyperTwistTrainingPanelWidget::GetDisplayedControlProfileRosterInspectSurface()
Surface.ActiveHigherDimensionalProfileLine = Surface.ActiveHigherDimensionalProfileLine =
Surface.bActiveHigherDimensionalProfileVisible Surface.bActiveHigherDimensionalProfileVisible
? FString::Printf( ? 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, *ActiveActivationProfileId,
*ActiveViewContextId, *ActiveViewContextId,
*ActiveSessionSurfaceId, *ActiveSessionSurfaceId,
*ActiveSceneSurfaceId,
Surface.ActiveHigherDimensionalSelectorCount Surface.ActiveHigherDimensionalSelectorCount
) )
: TEXT("Active higher-dimensional selection: none currently displayed in this widget."); : TEXT("Active higher-dimensional selection: none currently displayed in this widget.");
@ -2033,21 +2046,32 @@ UHyperTwistTrainingPanelWidget::GetDisplayedControlProfileRosterInspectSurface()
HyperTwistTrainingPanelWidgetInternal::BuildSelectorRecallLine( HyperTwistTrainingPanelWidgetInternal::BuildSelectorRecallLine(
SelectorRecallFacts SelectorRecallFacts
); );
Surface.PreferencesContinuityLine =
HyperTwistTrainingControlSurfaceFormatting::BuildControlProfilePreferencesContinuityLine(
Surface.bCameraSettingsContinuityReady,
Surface.CameraSettingsExportArtifactId,
Surface.bImmersiveSessionRecallReady,
Surface.ImmersiveSessionRecallBoundaryId,
Surface.ImmersiveSessionRecallScopeCount,
Surface.ImmersiveSessionRecallPreferenceFieldTagCount
);
Surface.PreferencesGapLine = Surface.PreferencesGapLine =
HyperTwistTrainingPanelWidgetInternal::BuildControlProfileRosterXrBoundaryLine( HyperTwistTrainingPanelWidgetInternal::BuildControlProfileRosterXrBoundaryLine(
Surface.bOpenXrProjectPluginEnabled Surface.bOpenXrProjectPluginEnabled
); );
Surface.StatusLine = FString::Printf( Surface.StatusLine =
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"), HyperTwistTrainingControlSurfaceFormatting::BuildControlProfileStatusLine(
Surface.bClassicKeyboardProfileReady ? TEXT("ready") : TEXT("missing"), Surface.bClassicKeyboardProfileReady,
Surface.bImmersivePresenceProfileReady ? TEXT("ready") : TEXT("missing"), Surface.bImmersivePresenceProfileReady,
Surface.bMagic120CellProfileReady ? TEXT("ready") : TEXT("missing"), Surface.bMagic120CellProfileReady,
Surface.bMagicCube5DProfileReady ? TEXT("ready") : TEXT("missing"), Surface.bMagicCube5DProfileReady,
Surface.bActiveHigherDimensionalProfileVisible ? TEXT("visible") : TEXT("not loaded"), Surface.bActiveHigherDimensionalProfileVisible,
Surface.bRepositoryBackedSelectorRecallReady ? TEXT("ready") : TEXT("unavailable") Surface.bRepositoryBackedSelectorRecallReady,
); Surface.bCameraSettingsContinuityReady,
Surface.bImmersiveSessionRecallReady
);
Surface.DetailLine = FString::Printf( 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.ClassicKeyboardProfileLine,
*Surface.ClassicKeyboardMoveRosterLine, *Surface.ClassicKeyboardMoveRosterLine,
*Surface.ImmersivePresenceProfileLine, *Surface.ImmersivePresenceProfileLine,
@ -2055,6 +2079,7 @@ UHyperTwistTrainingPanelWidget::GetDisplayedControlProfileRosterInspectSurface()
*Surface.MagicCube5DProfileLine, *Surface.MagicCube5DProfileLine,
*Surface.ActiveHigherDimensionalProfileLine, *Surface.ActiveHigherDimensionalProfileLine,
*Surface.SelectorRecallLine, *Surface.SelectorRecallLine,
*Surface.PreferencesContinuityLine,
*Surface.PreferencesGapLine *Surface.PreferencesGapLine
); );

View file

@ -10353,6 +10353,9 @@ struct FHyperTwistTrainingControlProfileRosterInspectSurface
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist") UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
FString SelectorRecallLine; FString SelectorRecallLine;
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
FString PreferencesContinuityLine;
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist") UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
FString PreferencesGapLine; FString PreferencesGapLine;
@ -10365,6 +10368,12 @@ struct FHyperTwistTrainingControlProfileRosterInspectSurface
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist") UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
FString ImmersivePresenceContractId; FString ImmersivePresenceContractId;
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
FString CameraSettingsExportArtifactId;
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
FString ImmersiveSessionRecallBoundaryId;
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist") UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
FString Magic120CellRuntimeProfileContractId; FString Magic120CellRuntimeProfileContractId;
@ -10386,6 +10395,9 @@ struct FHyperTwistTrainingControlProfileRosterInspectSurface
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist") UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
FString ActiveHigherDimensionalSessionSurfaceId; FString ActiveHigherDimensionalSessionSurfaceId;
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
FString ActiveHigherDimensionalInteractiveSceneSurfaceId;
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist") UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
int32 ClassicKeyboardBindingCount = 0; int32 ClassicKeyboardBindingCount = 0;
@ -10407,12 +10419,24 @@ struct FHyperTwistTrainingControlProfileRosterInspectSurface
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist") UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
int32 RecalledHigherDimensionalSelectorCount = 0; int32 RecalledHigherDimensionalSelectorCount = 0;
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
int32 ImmersiveSessionRecallScopeCount = 0;
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
int32 ImmersiveSessionRecallPreferenceFieldTagCount = 0;
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist") UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
bool bClassicKeyboardProfileReady = false; bool bClassicKeyboardProfileReady = false;
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist") UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
bool bImmersivePresenceProfileReady = false; bool bImmersivePresenceProfileReady = false;
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
bool bCameraSettingsContinuityReady = false;
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
bool bImmersiveSessionRecallReady = false;
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist") UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
bool bMagic120CellProfileReady = false; bool bMagic120CellProfileReady = false;
@ -10454,8 +10478,11 @@ struct FHyperTwistTrainingControlProfileRosterInspectSurface
|| !MagicCube5DProfileLine.IsEmpty() || !MagicCube5DProfileLine.IsEmpty()
|| !ActiveHigherDimensionalProfileLine.IsEmpty() || !ActiveHigherDimensionalProfileLine.IsEmpty()
|| !SelectorRecallLine.IsEmpty() || !SelectorRecallLine.IsEmpty()
|| !PreferencesContinuityLine.IsEmpty()
|| bClassicKeyboardProfileReady || bClassicKeyboardProfileReady
|| bImmersivePresenceProfileReady || bImmersivePresenceProfileReady
|| bCameraSettingsContinuityReady
|| bImmersiveSessionRecallReady
|| bMagic120CellProfileReady || bMagic120CellProfileReady
|| bMagicCube5DProfileReady || bMagicCube5DProfileReady
|| bActiveHigherDimensionalProfileVisible || bActiveHigherDimensionalProfileVisible

View file

@ -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<UTextBlock>(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<UHyperTwistTrainingPanelWidget>();
TestNotNull(TEXT("The training panel widget must be constructible."), TrainingPanel);
if (TrainingPanel == nullptr)
{
return false;
}
const FHyperTwistTrainingControlProfileRosterInspectSurface Surface =
TrainingPanel->GetDisplayedControlProfileRosterInspectSurface();
TestTrue(
TEXT("The control/profile roster surface must 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<UHyperTwistCoachDashboardWidget>();
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

View file

@ -178,7 +178,7 @@ closeout must now explicitly state one of the following:
Required shape example: 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 or
@ -203,6 +203,14 @@ The governing interpretation is now explicit:
- future instances must not infer adoption from `continue` alone when the - future instances must not infer adoption from `continue` alone when the
closeout does not authorize that adoption closeout does not authorize that adoption
Compact-string note:
- `HO:<codes>` is the canonical hard-omit prefix in new closeouts and prepared
decision packets
- older historical closeouts may still use `X:<codes>` for hard omit; read that older form as
legacy shorthand for `HO:<codes>`
- `O:<codes>` remains the omit-from-current-lane / reroute-later bucket
Expanded closeout-shape repertoire: Expanded closeout-shape repertoire:
- recommendation-adoption status: plain `continue` may adopt the displayed - recommendation-adoption status: plain `continue` may adopt the displayed

View file

@ -491,3 +491,41 @@ This packet does not claim any of the following:
Those are deployment/runtime configuration tasks, not missing ownership of the Those are deployment/runtime configuration tasks, not missing ownership of the
public website lane itself. 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

View file

@ -835,3 +835,370 @@ Latest shared-release-bundle follow-up on `2026-06-25`:
- `16,253` nodes, `38,116` edges, `665` clusters, `300` flows - `16,253` nodes, `38,116` edges, `665` clusters, `300` flows
- `scripts/run-hypertwist-gitnexus-status.sh` - `scripts/run-hypertwist-gitnexus-status.sh`
- bounded mirror `Status: up-to-date` - 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

View file

@ -22,6 +22,7 @@ VectorShell.
- `.sentrux/rules.toml` - `.sentrux/rules.toml`
- `scripts/bootstrap-hypertwist-sentrux.sh` - `scripts/bootstrap-hypertwist-sentrux.sh`
- `scripts/run-hypertwist-sentrux-source-only.sh` - `scripts/run-hypertwist-sentrux-source-only.sh`
- `scripts/run-hypertwist-sentrux-gate.sh`
- `scripts/run-hypertwist-gitnexus-analyze.sh` - `scripts/run-hypertwist-gitnexus-analyze.sh`
- `scripts/run-hypertwist-gitnexus-status.sh` - `scripts/run-hypertwist-gitnexus-status.sh`
@ -53,6 +54,24 @@ Run:
scripts/run-hypertwist-sentrux-source-only.sh 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: Resolution order for the analyzer binary is now HyperTwist-owned first:
- `HYPERTWIST_SENTRUX_BINARY` if explicitly provided - `HYPERTWIST_SENTRUX_BINARY` if explicitly provided
@ -114,12 +133,21 @@ Behavior:
available or is not runnable available or is not runnable
- always uses `--skip-agents-md` so HyperTwist authority files are not - always uses `--skip-agents-md` so HyperTwist authority files are not
rewritten just to refresh analysis state 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 ## Working-reference note
The retained HyperTwist `mirrors/GitNexus` working reference already contains The retained HyperTwist `mirrors/GitNexus` working reference already contains
the newer stack-overflow and cycle-hardening work recorded in its the newer stack-overflow and cycle-hardening work visible in its retained
`CHANGELOG.md`, including: source tree and tests, including:
- iterative stdio newline handling to prevent stack overflow on empty-line - iterative stdio newline handling to prevent stack overflow on empty-line
bursts 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` 1. run `scripts/run-hypertwist-gitnexus-analyze.sh`
2. review impact/freshness through `scripts/run-hypertwist-gitnexus-status.sh` 2. review impact/freshness through `scripts/run-hypertwist-gitnexus-status.sh`
3. run `scripts/run-hypertwist-sentrux-source-only.sh` for a structural 3. run `scripts/run-hypertwist-sentrux-gate.sh --save` when you need to stamp
baseline a fresh bounded baseline for the current refactor lane
4. make the bounded packet 4. run `scripts/run-hypertwist-sentrux-source-only.sh` for the immediate
5. rerun `scripts/run-hypertwist-sentrux-source-only.sh` structural snapshot
6. rerun product tests for the affected lane 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 ## Current findings snapshot
@ -1014,3 +1046,371 @@ This note does not:
- make `GitNexus` a product runtime dependency - make `GitNexus` a product runtime dependency
- claim `sentrux` replaces product validation - claim `sentrux` replaces product validation
- widen HyperTwist into a generic code-intelligence product - 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 HyperTwists 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

View file

@ -259,9 +259,47 @@ truthfully claim:
- `TrainingPanel.ControlSettingsOwnershipInspectSurface` - `TrainingPanel.ControlSettingsOwnershipInspectSurface`
- `CoachDashboard.ControlProfileRosterInspectSurface` - `CoachDashboard.ControlProfileRosterInspectSurface`
- `TrainingPanel.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 - the unattended run still emitted the already-accepted
`Failed to create the web browser window.` message, but that noise did not `Failed to create the web browser window.` message, but that noise did not
block report export or any of the focused browser automation proof 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 ### Explicit project OpenXR plugin posture now exists

View file

@ -32,6 +32,7 @@ claims over the same capability.
HyperTwist now has its own bounded refactor/analyzer entry points: HyperTwist now has its own bounded refactor/analyzer entry points:
- `scripts/run-hypertwist-sentrux-source-only.sh` - `scripts/run-hypertwist-sentrux-source-only.sh`
- `scripts/run-hypertwist-sentrux-gate.sh`
- `scripts/run-hypertwist-gitnexus-analyze.sh` - `scripts/run-hypertwist-gitnexus-analyze.sh`
- `scripts/run-hypertwist-gitnexus-status.sh` - `scripts/run-hypertwist-gitnexus-status.sh`
- `scripts/run-hypertwist-web-surface-validation.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 - `HYPERTWIST_GITNEXUS_DEBUG_LOCAL=1` keeps local GitNexus stderr visible so
retained-runtime problems can be diagnosed instead of being silently retained-runtime problems can be diagnosed instead of being silently
suppressed during the normal fallback path 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 - `scripts/run-hypertwist-sentrux-source-only.sh` now prefers a HyperTwist
owned entry path first: `HYPERTWIST_SENTRUX_BINARY`, repo-local `./sentrux` owned entry path first: `HYPERTWIST_SENTRUX_BINARY`, repo-local `./sentrux`
or `./sentrux.exe`, then repo-local `tools/sentrux/bin/`, then a bootstrap or `./sentrux.exe`, then repo-local `tools/sentrux/bin/`, then a bootstrap
attempt, then `PATH` 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 current `2026-06-24` wrapper hardening tightens that posture further:
- the source-only wrapper now auto-attempts - the source-only wrapper now auto-attempts
`scripts/bootstrap-hypertwist-sentrux.sh --if-missing` before it gives up `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 1. run `scripts/run-hypertwist-gitnexus-analyze.sh` before a larger rename or
subsystem split subsystem split
2. use `scripts/run-hypertwist-gitnexus-status.sh` to confirm index freshness 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 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 focused product tests
Additional dependency-health loop for the current browser and website family: 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` - `npm --prefix website run test:e2e:responsive:list`
- that responsive packet covers the real current HyperTwist public routes for: - that responsive packet covers the real current HyperTwist public routes for:
- homepage - homepage
- feature atlas
- about - about
- resources - resources
- docs
- pricing - pricing
- download - download
- getting-started
- launch-status
- support - support
- register - register
- each route now has a browser-level proof for: - 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 responsive browser proofs when `--with-responsive-e2e` is explicitly
requested 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`) ## Latest native/public control-roster parity follow-up (`2026-06-25`)
- the same-family native/operator continuity lane then aligned the shipped - the same-family native/operator continuity lane then aligned the shipped
@ -1393,3 +1449,627 @@ Current audit note:
- `CoachDashboard.ControlProfileRosterInspectSurface` - `CoachDashboard.ControlProfileRosterInspectSurface`
- `TrainingPanel.ControlProfileRosterInspectSurface` - `TrainingPanel.ControlProfileRosterInspectSurface`
- `CoachDashboard.ControlSurfaceStructuredTextArtifacts` - `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

File diff suppressed because one or more lines are too long

View file

@ -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 current product story stays honest that this is real local continuity rather
than a finished global preferences or rebinding suite. 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: Canonical audit note:
- `C:\HyperTwist\docs\ops\HYPERTWIST_UNREAL_INPUT_AND_XR_COMPLETENESS_AUDIT_2026-06-22.md` - `C:\HyperTwist\docs\ops\HYPERTWIST_UNREAL_INPUT_AND_XR_COMPLETENESS_AUDIT_2026-06-22.md`

View file

@ -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
}

View file

@ -5,10 +5,32 @@ repo_root="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
source "$repo_root/scripts/lib-hypertwist-gitnexus.sh" source "$repo_root/scripts/lib-hypertwist-gitnexus.sh"
local_gitnexus_cli="$repo_root/mirrors/GitNexus/gitnexus/dist/cli/index.js" local_gitnexus_cli="$repo_root/mirrors/GitNexus/gitnexus/dist/cli/index.js"
analysis_root="$repo_root/.gitnexus-source-only-root" 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 if [[ ! -d "$analysis_root" ]]; then
echo "No HyperTwist GitNexus source-only analysis root exists yet. Run scripts/run-hypertwist-gitnexus-analyze.sh first." >&2 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."
exit 1 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 fi
cd "$analysis_root" cd "$analysis_root"

View file

@ -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 <<EOF
Usage:
scripts/run-hypertwist-sentrux-gate.sh [--save]
Runs sentrux gate against the HyperTwist-owned source-only mirror.
Behavior:
--save refreshes the persisted source-only baseline at:
$source_only_baseline_path
Without --save, the wrapper restores that persisted baseline into the disposable
mirror before running the comparison gate.
EOF
}
save_mode=0
while [[ $# -gt 0 ]]; do
case "$1" in
--save)
save_mode=1
shift
;;
-h|--help)
usage
exit 0
;;
*)
echo "Unknown argument: $1" >&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

View file

@ -2,90 +2,22 @@
set -euo pipefail set -euo pipefail
repo_root="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)" repo_root="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
temp_root="${TMPDIR:-/tmp}/hypertwist-sentrux-source-only" source "$repo_root/scripts/lib-hypertwist-sentrux.sh"
repo_local_sentrux_binary="$repo_root/sentrux" temp_root_parent="${TMPDIR:-/tmp}"
repo_local_sentrux_windows_binary="$repo_root/sentrux.exe" sentrux_command="$(hypertwist_resolve_sentrux_command "$repo_root")" || {
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)" || {
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 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 exit 1
} }
rm -rf "$temp_root" temp_root="$(mktemp -d "${temp_root_parent%/}/hypertwist-sentrux-source-only.XXXXXX")"
mkdir -p "$temp_root/.sentrux" cleanup() {
cp "$repo_root/.sentrux/rules.toml" "$temp_root/.sentrux/rules.toml" rm -rf "$temp_root"
}
trap cleanup EXIT
copy_targets=( hypertwist_populate_sentrux_source_only_root "$repo_root" "$temp_root"
"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
( (
cd "$repo_root" cd "$repo_root"
eval "$sentrux_command" check "$temp_root" "$sentrux_command" check "$temp_root"
) )

View file

@ -153,6 +153,7 @@ run_step \
src/__tests__/package-validation.test.ts \ src/__tests__/package-validation.test.ts \
src/__tests__/platform-auth.bootstrap.test.tsx \ src/__tests__/platform-auth.bootstrap.test.tsx \
src/__tests__/download-center-page.test.tsx \ src/__tests__/download-center-page.test.tsx \
src/__tests__/public-launch.test.ts \
src/__tests__/protected-app-pages.test.tsx \ src/__tests__/protected-app-pages.test.tsx \
src/__tests__/DashboardOverviewPage.test.tsx \ src/__tests__/DashboardOverviewPage.test.tsx \
src/__tests__/app-route-tree.test.tsx \ src/__tests__/app-route-tree.test.tsx \

View file

@ -175,6 +175,10 @@ Repo-owned structural-tool posture:
- `scripts/run-hypertwist-sentrux-source-only.sh` still prefers - `scripts/run-hypertwist-sentrux-source-only.sh` still prefers
`HYPERTWIST_SENTRUX_BINARY`, repo-local `./sentrux` or `./sentrux.exe`, then `HYPERTWIST_SENTRUX_BINARY`, repo-local `./sentrux` or `./sentrux.exe`, then
`tools/sentrux/bin/`, then `PATH` `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 - `scripts/bootstrap-hypertwist-sentrux.sh` now keeps sibling-repo seed lookup
opt-in behind `HYPERTWIST_ALLOW_SIBLING_SENTRUX_BOOTSTRAP=1`, so ordinary opt-in behind `HYPERTWIST_ALLOW_SIBLING_SENTRUX_BOOTSTRAP=1`, so ordinary
HyperTwist analyzer recovery does not silently drift back into cross-repo HyperTwist analyzer recovery does not silently drift back into cross-repo

View file

@ -227,6 +227,79 @@ describe('protected app pages', () => {
expect(screen.getByRole('link', { name: 'Public notices' }).getAttribute('href')).toBe('/open-source-notices') 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(<ProtectedLaunchStatusPage />, '/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 () => { it('keeps the protected download center aligned with packaged proof, notices, and escalation guidance', async () => {
renderPage(<DownloadCenterPage />, '/app/downloads?platform=windows') renderPage(<DownloadCenterPage />, '/app/downloads?platform=windows')

View file

@ -3,6 +3,7 @@ import {
getMissingPublicLaunchChecklistItems, getMissingPublicLaunchChecklistItems,
getPublicLaunchChecklist, getPublicLaunchChecklist,
isPublicLaunchReady, isPublicLaunchReady,
resolvePublicLaunchStatusSummary,
} from '../public-launch' } from '../public-launch'
describe('public launch readiness helpers', () => { describe('public launch readiness helpers', () => {
@ -65,4 +66,123 @@ describe('public launch readiness helpers', () => {
publicAuthRuntimeReady: true, publicAuthRuntimeReady: true,
})).toBe(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)
})
}) })

View file

@ -268,6 +268,9 @@ describe('public marketing pages', () => {
expect(screen.getByText('Operator checkout URL: missing')).toBeTruthy() expect(screen.getByText('Operator checkout URL: missing')).toBeTruthy()
expect(screen.getByText('Current packaged desktop proof')).toBeTruthy() expect(screen.getByText('Current packaged desktop proof')).toBeTruthy()
expect(screen.getByText('How the release lane works')).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 HyperTwist keeps both a website and a desktop runtime')).toBeTruthy()
expect(screen.getByText('Why the browser is intentionally narrower')).toBeTruthy() expect(screen.getByText('Why the browser is intentionally narrower')).toBeTruthy()
expect(screen.getByRole('heading', { name: 'Browser account access methods' })).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://docs.hypertwist.app' })).toBeTruthy()
expect(screen.getByRole('link', { name: 'https://notes.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('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(await screen.findByText('Version: 1.0.0')).toBeTruthy()
expect(screen.getByText('SHA-256: abc123')).toBeTruthy() expect(screen.getByText('SHA-256: abc123')).toBeTruthy()
expect(screen.getAllByText('Packaged validation passed').length).toBeGreaterThan(0) 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 shipped capability')).toBeTruthy()
expect(screen.getByText('Current selectable control roster')).toBeTruthy() expect(screen.getByText('Current selectable control roster')).toBeTruthy()
expect(screen.getAllByText('Selectable immersive and family-specific settings').length).toBeGreaterThan(0) 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('Current public rollout posture')).toBeTruthy()
expect(screen.getByText('Public feature and launch posture')).toBeTruthy() expect(screen.getByText('Public feature and launch posture')).toBeTruthy()
const featuresDecisionGuideHeading = screen.getByRole('heading', { name: 'Choose the next release move' }) 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('$99 / month')).toBeTruthy()
expect(screen.getByText('Current packaged desktop proof')).toBeTruthy() expect(screen.getByText('Current packaged desktop proof')).toBeTruthy()
expect(screen.getAllByText('What happens after access is granted').length).toBeGreaterThan(0) 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() expect(screen.getByText('Choose the right HyperTwist surface')).toBeTruthy()
const pricingDecisionGuideHeading = screen.getByRole('heading', { name: 'Choose the next release move' }) const pricingDecisionGuideHeading = screen.getByRole('heading', { name: 'Choose the next release move' })
const pricingDecisionGuideSection = pricingDecisionGuideHeading.closest('section') 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('Owns recognition, replay, coaching, and packaged training behavior')).toBeTruthy()
expect(screen.getByText('Commercial distribution doctrine')).toBeTruthy() expect(screen.getByText('Commercial distribution doctrine')).toBeTruthy()
expect(screen.getByText('Public pages are distribution surfaces')).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.getByText('Release references and source availability')).toBeTruthy()
expect(screen.getByRole('link', { name: 'https://docs.hypertwist.app' })).toBeTruthy() expect(screen.getByRole('link', { name: 'https://docs.hypertwist.app' })).toBeTruthy()
expect(screen.getByRole('link', { name: 'https://notes.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.getByRole('link', { name: 'Review public notices' }).getAttribute('href')).toBe('/open-source-notices')
expect(screen.getByText('Common operator questions')).toBeTruthy() 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('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('Packaged validation passed')).toBeTruthy()
expect(screen.getByText('Release references and source availability')).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://docs.hypertwist.app' })).toBeTruthy()
@ -1438,8 +1457,11 @@ describe('public marketing pages', () => {
expect(screen.getByText('Browser account access methods')).toBeTruthy() expect(screen.getByText('Browser account access methods')).toBeTruthy()
expect(screen.getByText('First launch and desktop setup')).toBeTruthy() expect(screen.getByText('First launch and desktop setup')).toBeTruthy()
expect(screen.getByText('Simulator use today')).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.getByText('Current control and device truth')).toBeTruthy()
expect(screen.getAllByText('Selectable control and settings roster').length).toBeGreaterThan(0) 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('Choose the right HyperTwist surface')).toBeTruthy()
expect(screen.getByText('Current packaged desktop proof')).toBeTruthy() expect(screen.getByText('Current packaged desktop proof')).toBeTruthy()
expect(screen.getByText('Need help on the way in?')).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') 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(<LaunchStatusPage />, ['/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 () => { it('renders the expanded legal and digital-delivery guidance across public support surfaces', async () => {
mockGetAuthHealth.mockResolvedValue({ mockGetAuthHealth.mockResolvedValue({
ok: true, ok: true,

View file

@ -18,9 +18,14 @@ import {
} from '../site-config' } from '../site-config'
import { import {
browserDesktopRealityCards, browserDesktopRealityCards,
controlProfileRosterCards,
deliverySurfaceCards, deliverySurfaceCards,
higherDimensionalRuntimeGuideCards,
inputAndDevicePostureCards,
operatorDesktopQuickstartCards, operatorDesktopQuickstartCards,
publicManualRouteAtlasCards, publicManualRouteAtlasCards,
runtimeControlGuideCards,
simulatorManualCards,
} from '../site-data' } from '../site-data'
import { import {
buildLoginPath, buildLoginPath,
@ -159,6 +164,28 @@ type StepOnlyCard = {
bullets?: readonly string[] 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 SupportTopicCard = (typeof supportTopicDirectory)[number]
type PublicManualRouteAtlasCard = (typeof publicManualRouteAtlasCards)[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 (
<Section title={title} description={description}>
<div className="card-grid">
{cards.map((card) => (
<article key={card.title} className="card">
<h3>{card.title}</h3>
<p>{card.description}</p>
</article>
))}
</div>
</Section>
)
}
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 <BulletCardSection title={title} description={description} cards={simulatorManualCards} />
}
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 (
<BulletCardSection
title={title}
description={description}
cards={higherDimensionalRuntimeGuideCards}
/>
)
}
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 (
<BulletCardSection
title={title}
description={description}
cards={inputAndDevicePostureCards}
/>
)
}
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 (
<BulletCardSection
title={title}
description={description}
cards={controlProfileRosterCards}
/>
)
}
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 (
<BulletCardSection
title={title}
description={description}
cards={runtimeControlGuideCards}
/>
)
}
export function BulletCardSection({
title,
description,
cards,
}: {
title: string
description?: string
cards: readonly BulletCard[]
}) {
return (
<Section title={title} description={description}>
<div className="card-grid">
{cards.map((card) => (
<article key={card.title} className="card">
<h3>{card.title}</h3>
<p>{card.description}</p>
<ul className="list top-gap">
{card.bullets.map((bullet) => (
<li key={bullet}>{bullet}</li>
))}
</ul>
</article>
))}
</div>
</Section>
)
}
export function StepCardSection({
title,
description,
cards,
}: {
title: string
description?: string
cards: readonly StepCard[]
}) {
return (
<Section title={title} description={description}>
<div className="card-grid">
{cards.map((card) => (
<article key={card.title} className="card">
<h3>{card.title}</h3>
<p>{card.description}</p>
<ul className="list top-gap">
{card.steps.map((step) => (
<li key={step}>{step}</li>
))}
</ul>
</article>
))}
</div>
</Section>
)
}
export function StepOnlyCardSection({ export function StepOnlyCardSection({
title, title,
description, description,
@ -377,6 +557,29 @@ export function StepOnlyCardSection({
) )
} }
export function FaqCardSection({
title,
description,
cards,
}: {
title: string
description?: string
cards: readonly FaqCard[]
}) {
return (
<Section title={title} description={description}>
<div className="card-grid">
{cards.map((card) => (
<article key={card.question} className="card">
<h3>{card.question}</h3>
<p>{card.answer}</p>
</article>
))}
</div>
</Section>
)
}
export function SupportTopicDirectorySection({ export function SupportTopicDirectorySection({
title, title,
description, description,

View file

@ -15,19 +15,23 @@ import {
desktopReleaseSignals, desktopReleaseSignals,
digitalDeliveryCards, digitalDeliveryCards,
distributionDoctrineCards, distributionDoctrineCards,
inputAndDevicePostureCards,
openSourceNotices, openSourceNotices,
operatorManualTracks, operatorManualTracks,
privacyBoundaryCards, privacyBoundaryCards,
productSurfaceMatrixRows, productSurfaceMatrixRows,
releaseRolloutChecklist, releaseRolloutChecklist,
runtimeControlGuideCards,
supportEscalationCards, supportEscalationCards,
termsBoundaryCards, termsBoundaryCards,
} from '../site-data' } from '../site-data'
import { import {
BulletCardSection,
BrowserAuthMethodsSection, BrowserAuthMethodsSection,
BrowserDesktopRealitySection, BrowserDesktopRealitySection,
DeliverySurfaceResponsibilitiesGrid, DeliverySurfaceResponsibilitiesGrid,
explorerFallbackPlan, explorerFallbackPlan,
HigherDimensionalRuntimeGuideSection,
OperatorDesktopQuickstartSection, OperatorDesktopQuickstartSection,
operatorFallbackPlan, operatorFallbackPlan,
PlanActionLink, PlanActionLink,
@ -36,6 +40,8 @@ import {
ReleaseAuthorityBundleSection, ReleaseAuthorityBundleSection,
releaseCommerceFallback, releaseCommerceFallback,
Section, Section,
SimulatorManualSection,
StepCardSection,
studioFallbackPlan, studioFallbackPlan,
SurfaceChoiceGuideSection, SurfaceChoiceGuideSection,
usePublicReleaseManifestView, 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." 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."
/> />
<Section <StepCardSection
title="What happens after access is granted" title="What happens after access is granted"
description="Pricing only stays professional when it explains the real path from browser entitlement into the packaged simulator instead of stopping at the checkout button." description="Pricing only stays professional when it explains the real path from browser entitlement into the packaged simulator instead of stopping at the checkout button."
> cards={operatorManualTracks.slice(0, 3)}
<div className="card-grid"> />
{operatorManualTracks.slice(0, 3).map((track) => (
<article key={track.title} className="card"> <SimulatorManualSection
<h3>{track.title}</h3> title="What the software actually does after access is granted"
<p>{track.description}</p> description="Plans only make sense if the public pricing lane also says what the entitled desktop software is for once it is installed."
<ul className="list top-gap"> />
{track.steps.map((step) => (
<li key={step}>{step}</li> <HigherDimensionalRuntimeGuideSection
))} title="Higher-dimensional families behind the plans"
</ul> description="This keeps commercial copy tied to the real runtime families the desktop product already owns instead of leaving serious capability buried elsewhere in the manual."
</article> />
))}
</div> <BulletCardSection
</Section> title="Current input and runtime control truth"
description="The pricing page should also be explicit about the present control quality bar so buyers can see what is real today and what still remains gated."
cards={[...inputAndDevicePostureCards, ...runtimeControlGuideCards]}
/>
<SurfaceChoiceGuideSection description="This keeps pricing honest about what should happen next: stay public for plan comparison, move protected for account-aware access, and move native for the actual simulator." /> <SurfaceChoiceGuideSection description="This keeps pricing honest about what should happen next: stay public for plan comparison, move protected for account-aware access, and move native for the actual simulator." />
@ -149,43 +158,17 @@ export function PricingPage() {
<DeliverySurfaceResponsibilitiesGrid limit={3} /> <DeliverySurfaceResponsibilitiesGrid limit={3} />
</Section> </Section>
<Section <BulletCardSection
title="Commercial distribution doctrine" title="Commercial distribution doctrine"
description="Commercial pages should stay as explicit about release and legal posture as the rest of the public site." description="Commercial pages should stay as explicit about release and legal posture as the rest of the public site."
> cards={distributionDoctrineCards}
<div className="card-grid"> />
{distributionDoctrineCards.map((card) => (
<article key={card.title} className="card">
<h3>{card.title}</h3>
<p>{card.description}</p>
<ul className="list top-gap">
{card.bullets.map((bullet) => (
<li key={bullet}>{bullet}</li>
))}
</ul>
</article>
))}
</div>
</Section>
<Section <BulletCardSection
title="Terms of access in practice" title="Terms of access in practice"
description="Pricing is easier to trust when the access model, simulator boundary, and operator obligations stay visible before checkout." description="Pricing is easier to trust when the access model, simulator boundary, and operator obligations stay visible before checkout."
> cards={termsBoundaryCards}
<div className="card-grid"> />
{termsBoundaryCards.map((card) => (
<article key={card.title} className="card">
<h3>{card.title}</h3>
<p>{card.description}</p>
<ul className="list top-gap">
{card.bullets.map((bullet) => (
<li key={bullet}>{bullet}</li>
))}
</ul>
</article>
))}
</div>
</Section>
<Section title="Important launch note"> <Section title="Important launch note">
<article className="callout"> <article className="callout">
@ -305,6 +288,22 @@ export function DownloadPage() {
</div> </div>
</Section> </Section>
<SimulatorManualSection
title="What the installed runtime already owns"
description="Download posture is stronger when the page also explains the real software lane operators receive after the package handoff."
/>
<HigherDimensionalRuntimeGuideSection
title="Higher-dimensional family guide"
description="This keeps the download lane concrete about which serious family runtimes are already real and what host posture each one currently uses."
/>
<BulletCardSection
title="Current input and runtime control truth"
description="The download lane should also teach the real control boundary before the first session starts, including what is strong now and what still remains gated."
cards={[...inputAndDevicePostureCards, ...runtimeControlGuideCards]}
/>
<BrowserDesktopRealitySection /> <BrowserDesktopRealitySection />
<SurfaceChoiceGuideSection description="Download posture is clearer when the current best surface is explicit: public for target and release context, protected for entitlement, and desktop for the real training runtime." /> <SurfaceChoiceGuideSection description="Download posture is clearer when the current best surface is explicit: public for target and release context, protected for entitlement, and desktop for the real training runtime." />
@ -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." 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."
/> />
<Section <BulletCardSection
title="First launch and desktop setup" title="First launch and desktop setup"
description="This keeps the download page useful after the archive is in hand: what to verify, how to pair the app, and which current runtime lanes matter first." description="This keeps the download page useful after the archive is in hand: what to verify, how to pair the app, and which current runtime lanes matter first."
> cards={desktopFirstLaunchCards}
<div className="card-grid"> />
{desktopFirstLaunchCards.map((card) => (
<article key={card.title} className="card">
<h3>{card.title}</h3>
<p>{card.description}</p>
<ul className="list top-gap">
{card.bullets.map((bullet) => (
<li key={bullet}>{bullet}</li>
))}
</ul>
</article>
))}
</div>
</Section>
<OperatorDesktopQuickstartSection title="First desktop session after install" /> <OperatorDesktopQuickstartSection title="First desktop session after install" />
@ -351,24 +337,11 @@ export function DownloadPage() {
]} ]}
/> />
<Section <BulletCardSection
title="Digital delivery workflow" title="Digital delivery workflow"
description="The download page should explain the real delivery sequence from platform selection to protected entitlement and first desktop launch." description="The download page should explain the real delivery sequence from platform selection to protected entitlement and first desktop launch."
> cards={digitalDeliveryCards}
<div className="card-grid"> />
{digitalDeliveryCards.map((card) => (
<article key={card.title} className="card">
<h3>{card.title}</h3>
<p>{card.description}</p>
<ul className="list top-gap">
{card.bullets.map((bullet) => (
<li key={bullet}>{bullet}</li>
))}
</ul>
</article>
))}
</div>
</Section>
<Section <Section
title="Browser and desktop responsibilities" title="Browser and desktop responsibilities"
@ -377,24 +350,11 @@ export function DownloadPage() {
<DeliverySurfaceResponsibilitiesGrid /> <DeliverySurfaceResponsibilitiesGrid />
</Section> </Section>
<Section <BulletCardSection
title="Distribution doctrine" title="Distribution doctrine"
description="Download posture should stay tied to package proof, notices, and the desktop-first simulator boundary." description="Download posture should stay tied to package proof, notices, and the desktop-first simulator boundary."
> cards={distributionDoctrineCards}
<div className="card-grid"> />
{distributionDoctrineCards.map((card) => (
<article key={card.title} className="card">
<h3>{card.title}</h3>
<p>{card.description}</p>
<ul className="list top-gap">
{card.bullets.map((bullet) => (
<li key={bullet}>{bullet}</li>
))}
</ul>
</article>
))}
</div>
</Section>
<Section title="Release integrity and documentation"> <Section title="Release integrity and documentation">
<div className="card-grid"> <div className="card-grid">

View file

@ -4,21 +4,25 @@ import { SiteMetadata } from '../components/seo/SiteMetadata'
import { PublicLaunchStatus } from '../components/ui/PublicLaunchStatus' import { PublicLaunchStatus } from '../components/ui/PublicLaunchStatus'
import { ProductSurfaceMatrix } from '../components/ui/ProductSurfaceMatrix' import { ProductSurfaceMatrix } from '../components/ui/ProductSurfaceMatrix'
import { import {
controlProfileRosterCards,
deploymentReadinessTracks, deploymentReadinessTracks,
featureAtlasCurrentTracks, featureAtlasCurrentTracks,
featureRegistryTierCards, featureRegistryTierCards,
higherDimensionalRuntimeGuideCards,
inputAndDevicePostureCards,
productSurfaceMatrixRows, productSurfaceMatrixRows,
releaseStoryCards, releaseStoryCards,
roadmapHonestyCards, roadmapHonestyCards,
supportFaqs,
} from '../site-data' } from '../site-data'
import { import {
BulletCardSection,
BrowserDesktopRealitySection, BrowserDesktopRealitySection,
ControlProfileRosterSection,
FaqCardSection,
HigherDimensionalRuntimeGuideSection,
InputAndDevicePostureSection,
PublicPackagedDesktopProofSection, PublicPackagedDesktopProofSection,
PublicReleaseDecisionGuideSection, PublicReleaseDecisionGuideSection,
ReleaseAuthorityBundleSection, ReleaseAuthorityBundleSection,
RuntimeControlGuideSection,
Section, Section,
SurfaceChoiceGuideSection, SurfaceChoiceGuideSection,
usePublicReleaseManifestView, usePublicReleaseManifestView,
@ -39,43 +43,17 @@ export function FeaturesPage() {
title="Feature truth without the roadmap archaeology." 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." 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."
> >
<Section <BulletCardSection
title="How to read the product truth" title="How to read the product truth"
description="The public website now mirrors the same discipline used in the internal feature registry so advanced readers do not have to guess which surfaces are live, retained, or still gated." description="The public website now mirrors the same discipline used in the internal feature registry so advanced readers do not have to guess which surfaces are live, retained, or still gated."
> cards={featureRegistryTierCards}
<div className="card-grid"> />
{featureRegistryTierCards.map((card) => (
<article key={card.title} className="card">
<h3>{card.title}</h3>
<p>{card.description}</p>
<ul className="list top-gap">
{card.bullets.map((bullet) => (
<li key={bullet}>{bullet}</li>
))}
</ul>
</article>
))}
</div>
</Section>
<Section <BulletCardSection
title="Current shipped capability" title="Current shipped capability"
description="These are the major product tracks that are already first-party owned and safe to describe as current HyperTwist capability." description="These are the major product tracks that are already first-party owned and safe to describe as current HyperTwist capability."
> cards={featureAtlasCurrentTracks}
<div className="card-grid"> />
{featureAtlasCurrentTracks.map((track) => (
<article key={track.title} className="card">
<h3>{track.title}</h3>
<p>{track.description}</p>
<ul className="list top-gap">
{track.bullets.map((bullet) => (
<li key={bullet}>{bullet}</li>
))}
</ul>
</article>
))}
</div>
</Section>
<Section <Section
title="Current surface authority map" title="Current surface authority map"
@ -93,62 +71,31 @@ export function FeaturesPage() {
<BrowserDesktopRealitySection /> <BrowserDesktopRealitySection />
<Section <HigherDimensionalRuntimeGuideSection
title="Higher-dimensional families and runtime posture" title="Higher-dimensional families and runtime posture"
description="These are the current public-safe explanations of the serious hypercubing lanes and the runtime host each one actually uses." description="These are the current public-safe explanations of the serious hypercubing lanes and the runtime host each one actually uses."
> />
<div className="card-grid">
{higherDimensionalRuntimeGuideCards.map((card) => (
<article key={card.title} className="card">
<h3>{card.title}</h3>
<p>{card.description}</p>
<ul className="list top-gap">
{card.bullets.map((bullet) => (
<li key={bullet}>{bullet}</li>
))}
</ul>
</article>
))}
</div>
</Section>
<Section <InputAndDevicePostureSection
title="Current control and XR posture" title="Current control and XR posture"
description="The public product surface stays stronger when it is explicit about what input quality exists now and what still belongs to a later native completion packet." description="The public product surface stays stronger when it is explicit about what input quality exists now and what still belongs to a later native completion packet."
> />
<div className="card-grid">
{inputAndDevicePostureCards.map((card) => (
<article key={card.title} className="card">
<h3>{card.title}</h3>
<p>{card.description}</p>
<ul className="list top-gap">
{card.bullets.map((bullet) => (
<li key={bullet}>{bullet}</li>
))}
</ul>
</article>
))}
</div>
</Section>
<Section <ControlProfileRosterSection
title="Current selectable control roster" title="Current selectable control roster"
description="This keeps the feature atlas concrete about the shipped keyboard profile, scenic presets, dedicated-family selectors, and the current persistence boundary." description="This keeps the feature atlas concrete about the shipped keyboard profile, scenic presets, dedicated-family selectors, and the current persistence boundary."
> />
<div className="card-grid">
{controlProfileRosterCards.map((card) => ( <RuntimeControlGuideSection
<article key={card.title} className="card"> title="Runtime control guide"
<h3>{card.title}</h3> description="The feature atlas is more useful when it also teaches the current practical desktop control posture instead of stopping at capability labels and roster summaries."
<p>{card.description}</p> />
<ul className="list top-gap">
{card.bullets.map((bullet) => ( <FaqCardSection
<li key={bullet}>{bullet}</li> title="Common capability questions"
))} description="These are the short, public-safe answers to the product-boundary questions advanced readers usually ask after reading the capability atlas."
</ul> cards={supportFaqs.slice(1, 6)}
</article> />
))}
</div>
</Section>
<Section <Section
title="Release and distribution maturity" title="Release and distribution maturity"

View file

@ -16,9 +16,6 @@ import {
digitalDeliveryCards, digitalDeliveryCards,
featureAtlasCurrentTracks, featureAtlasCurrentTracks,
heroMetrics, heroMetrics,
higherDimensionalRuntimeGuideCards,
controlProfileRosterCards,
inputAndDevicePostureCards,
operatorManualTracks, operatorManualTracks,
operatorPlaybooks, operatorPlaybooks,
publicDocumentationPrinciples, publicDocumentationPrinciples,
@ -27,23 +24,30 @@ import {
releaseStoryCards, releaseStoryCards,
resourceCollections, resourceCollections,
roadmapHonestyCards, roadmapHonestyCards,
runtimeControlGuideCards,
shippingNowCards, shippingNowCards,
privacyBoundaryCards, privacyBoundaryCards,
supportEscalationCards, supportEscalationCards,
simulatorManualCards,
supportFaqs, supportFaqs,
} from '../site-data' } from '../site-data'
import { import {
BrowserAuthMethodsSection, BrowserAuthMethodsSection,
BrowserDesktopRealitySection, BrowserDesktopRealitySection,
ControlProfileRosterSection,
DeliverySurfaceResponsibilitiesGrid, DeliverySurfaceResponsibilitiesGrid,
BulletCardSection,
FaqCardSection,
HigherDimensionalRuntimeGuideSection,
InputAndDevicePostureSection,
OperatorDesktopQuickstartSection, OperatorDesktopQuickstartSection,
PrincipleCardSection,
PublicManualRouteAtlasSection, PublicManualRouteAtlasSection,
PublicPackagedDesktopProofSection, PublicPackagedDesktopProofSection,
PublicReleaseDecisionGuideSection, PublicReleaseDecisionGuideSection,
ReleaseAuthorityBundleSection, ReleaseAuthorityBundleSection,
RuntimeControlGuideSection,
Section, Section,
SimulatorManualSection,
StepCardSection,
StepOnlyCardSection, StepOnlyCardSection,
SupportTopicDirectorySection, SupportTopicDirectorySection,
SurfaceChoiceGuideSection, SurfaceChoiceGuideSection,
@ -52,130 +56,6 @@ import {
usePublicReleaseManifestView, usePublicReleaseManifestView,
} from './public-page-helpers' } from './public-page-helpers'
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
}
function PrincipleCardSection({
title,
description,
cards,
}: {
title: string
description?: string
cards: readonly PrincipleCard[]
}) {
return (
<Section title={title} description={description}>
<div className="card-grid">
{cards.map((card) => (
<article key={card.title} className="card">
<h3>{card.title}</h3>
<p>{card.description}</p>
</article>
))}
</div>
</Section>
)
}
function BulletCardSection({
title,
description,
cards,
}: {
title: string
description?: string
cards: readonly BulletCard[]
}) {
return (
<Section title={title} description={description}>
<div className="card-grid">
{cards.map((card) => (
<article key={card.title} className="card">
<h3>{card.title}</h3>
<p>{card.description}</p>
<ul className="list top-gap">
{card.bullets.map((bullet) => (
<li key={bullet}>{bullet}</li>
))}
</ul>
</article>
))}
</div>
</Section>
)
}
function StepCardSection({
title,
description,
cards,
}: {
title: string
description?: string
cards: readonly StepCard[]
}) {
return (
<Section title={title} description={description}>
<div className="card-grid">
{cards.map((card) => (
<article key={card.title} className="card">
<h3>{card.title}</h3>
<p>{card.description}</p>
<ul className="list top-gap">
{card.steps.map((step) => (
<li key={step}>{step}</li>
))}
</ul>
</article>
))}
</div>
</Section>
)
}
function FaqCardSection({
title,
description,
cards,
}: {
title: string
description?: string
cards: readonly FaqCard[]
}) {
return (
<Section title={title} description={description}>
<div className="card-grid">
{cards.map((card) => (
<article key={card.question} className="card">
<h3>{card.question}</h3>
<p>{card.answer}</p>
</article>
))}
</div>
</Section>
)
}
export function HomeLanding() { export function HomeLanding() {
const { releaseManifest, windowsValidationPlatform } = usePublicReleaseManifestView('public-home') 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." description="The about page should also say what the next honest operator move is, not only why the product exists."
/> />
<Section <InputAndDevicePostureSection
title="Current desktop control and XR truth" title="Current desktop control and XR truth"
description="The product can be ambitious without overclaiming. This page now makes the current input, controller, and XR posture explicit." description="The product can be ambitious without overclaiming. This page now makes the current input, controller, and XR posture explicit."
> />
<div className="card-grid">
{inputAndDevicePostureCards.map((card) => (
<article key={card.title} className="card">
<h3>{card.title}</h3>
<p>{card.description}</p>
<ul className="list top-gap">
{card.bullets.map((bullet) => (
<li key={bullet}>{bullet}</li>
))}
</ul>
</article>
))}
</div>
</Section>
<Section <ControlProfileRosterSection
title="Selectable control and settings roster" title="Selectable control and settings roster"
description="This keeps the public manual concrete about what users can already choose or persist today without inflating that into finished controller rebinding or headset-runtime completion." description="This keeps the public manual concrete about what users can already choose or persist today without inflating that into finished controller rebinding or headset-runtime completion."
> />
<div className="card-grid">
{controlProfileRosterCards.map((card) => (
<article key={card.title} className="card">
<h3>{card.title}</h3>
<p>{card.description}</p>
<ul className="list top-gap">
{card.bullets.map((bullet) => (
<li key={bullet}>{bullet}</li>
))}
</ul>
</article>
))}
</div>
</Section>
<Section <Section
title="Release and deployment maturity" title="Release and deployment maturity"
@ -661,100 +513,30 @@ export function ResourcesPage() {
</div> </div>
</Section> </Section>
<Section <SimulatorManualSection
title="Simulator use today" title="Simulator use today"
description="This summary is deliberately practical: what you actually do in the desktop runtime once browser identity and release posture are already resolved." description="This summary is deliberately practical: what you actually do in the desktop runtime once browser identity and release posture are already resolved."
> />
<div className="card-grid">
{simulatorManualCards.map((card) => (
<article key={card.title} className="card">
<h3>{card.title}</h3>
<p>{card.description}</p>
<ul className="list top-gap">
{card.bullets.map((bullet) => (
<li key={bullet}>{bullet}</li>
))}
</ul>
</article>
))}
</div>
</Section>
<Section <HigherDimensionalRuntimeGuideSection
title="Higher-dimensional runtime guide" title="Higher-dimensional runtime guide"
description="These public-safe cards explain which higher-dimensional family lanes are already real and what runtime posture each one actually uses." description="These public-safe cards explain which higher-dimensional family lanes are already real and what runtime posture each one actually uses."
> />
<div className="card-grid">
{higherDimensionalRuntimeGuideCards.map((card) => (
<article key={card.title} className="card">
<h3>{card.title}</h3>
<p>{card.description}</p>
<ul className="list top-gap">
{card.bullets.map((bullet) => (
<li key={bullet}>{bullet}</li>
))}
</ul>
</article>
))}
</div>
</Section>
<Section <InputAndDevicePostureSection
title="Current control and device posture" title="Current control and device posture"
description="This keeps public resources honest about what input/runtime ownership is already strong and what remains outside the current desktop-hosted No-Go XR/controller branch." description="This keeps public resources honest about what input/runtime ownership is already strong and what remains outside the current desktop-hosted No-Go XR/controller branch."
> />
<div className="card-grid">
{inputAndDevicePostureCards.map((card) => (
<article key={card.title} className="card">
<h3>{card.title}</h3>
<p>{card.description}</p>
<ul className="list top-gap">
{card.bullets.map((bullet) => (
<li key={bullet}>{bullet}</li>
))}
</ul>
</article>
))}
</div>
</Section>
<Section <ControlProfileRosterSection
title="Selectable control and settings roster" title="Selectable control and settings roster"
description="This keeps the public resources lane concrete about the shipped keyboard profile, scenic presets, family selectors, and current persistence boundary." description="This keeps the public resources lane concrete about the shipped keyboard profile, scenic presets, family selectors, and current persistence boundary."
> />
<div className="card-grid">
{controlProfileRosterCards.map((card) => (
<article key={card.title} className="card">
<h3>{card.title}</h3>
<p>{card.description}</p>
<ul className="list top-gap">
{card.bullets.map((bullet) => (
<li key={bullet}>{bullet}</li>
))}
</ul>
</article>
))}
</div>
</Section>
<Section <RuntimeControlGuideSection
title="Runtime control guide" title="Runtime control guide"
description="This public-safe guide focuses on how operators and trainees actually drive the current desktop runtime today." description="This public-safe guide focuses on how operators and trainees actually drive the current desktop runtime today."
> />
<div className="card-grid">
{runtimeControlGuideCards.map((card) => (
<article key={card.title} className="card">
<h3>{card.title}</h3>
<p>{card.description}</p>
<ul className="list top-gap">
{card.bullets.map((bullet) => (
<li key={bullet}>{bullet}</li>
))}
</ul>
</article>
))}
</div>
</Section>
<Section <Section
title="Deployment readiness snapshot" title="Deployment readiness snapshot"
@ -833,35 +615,29 @@ function GettingStartedPageContent({
<BrowserDesktopRealitySection /> <BrowserDesktopRealitySection />
<Section <SimulatorManualSection
title="Simulator use today" title="Simulator use today"
description="This keeps onboarding anchored to the lanes that actually execute in the current native runtime." description="This keeps onboarding anchored to the lanes that actually execute in the current native runtime."
>
<div className="card-grid">
{simulatorManualCards.map((card) => (
<article key={card.title} className="card">
<h3>{card.title}</h3>
<p>{card.description}</p>
<ul className="list top-gap">
{card.bullets.map((bullet) => (
<li key={bullet}>{bullet}</li>
))}
</ul>
</article>
))}
</div>
</Section>
<BulletCardSection
title="Current control and device truth"
description="This is the practical runtime boundary that first-session onboarding should teach directly instead of leaving as a later surprise."
cards={inputAndDevicePostureCards}
/> />
<BulletCardSection <HigherDimensionalRuntimeGuideSection
title="Higher-dimensional family guide"
description="The onboarding route is stronger when it also teaches which higher-dimensional lanes already exist and what host/runtime posture each one actually uses."
/>
<InputAndDevicePostureSection
title="Current control and device truth"
description="This is the practical runtime boundary that first-session onboarding should teach directly instead of leaving as a later surprise."
/>
<ControlProfileRosterSection
title="Selectable control and settings roster" title="Selectable control and settings roster"
description="The current desktop runtime already has real profile and settings ownership, but it stays narrower than a finished XR/controller/preferences suite." description="The current desktop runtime already has real profile and settings ownership, but it stays narrower than a finished XR/controller/preferences suite."
cards={controlProfileRosterCards} />
<RuntimeControlGuideSection
title="Runtime control guide"
description="This onboarding route should also show the practical desktop control posture so operators do not have to leave the canonical first-session page just to find the real input and diagnostics guidance."
/> />
<SurfaceChoiceGuideSection description="Onboarding is smoother when the right next surface is explicit too: public for orientation, protected for entitled access, and desktop for simulator execution." /> <SurfaceChoiceGuideSection description="Onboarding is smoother when the right next surface is explicit too: public for orientation, protected for entitled access, and desktop for simulator execution." />
@ -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." 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."
/> />
<BulletCardSection <SimulatorManualSection />
title="Simulator manual"
description="These are the current product-safe usage tracks for the native runtime itself."
cards={simulatorManualCards}
/>
<BulletCardSection <HigherDimensionalRuntimeGuideSection />
title="Higher-dimensional family guide"
description="These are the currently represented higher-dimensional lanes and the truthful host/runtime posture for each."
cards={higherDimensionalRuntimeGuideCards}
/>
<StepOnlyCardSection <StepOnlyCardSection
title="Deployment readiness manual" title="Deployment readiness manual"
@ -1010,23 +778,11 @@ export function DocsPage() {
cards={deploymentReadinessTracks} cards={deploymentReadinessTracks}
/> />
<BulletCardSection <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."
cards={inputAndDevicePostureCards}
/>
<BulletCardSection <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?"
cards={controlProfileRosterCards}
/>
<BulletCardSection <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."
cards={runtimeControlGuideCards}
/>
<PublicPackagedDesktopProofSection <PublicPackagedDesktopProofSection
platform={windowsValidationPlatform} platform={windowsValidationPlatform}

View file

@ -304,6 +304,60 @@ export function buildPublicLaunchStatusSummary(
} }
} }
function resolveHealthLaunchChecklist(
launch: NonNullable<AuthHealthLike['launch']>,
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<AuthHealthLike['launch']>,
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({ export function resolvePublicLaunchStatusSummary({
manifest, manifest,
health, health,
@ -313,7 +367,7 @@ export function resolvePublicLaunchStatusSummary({
health?: AuthHealthLike | null health?: AuthHealthLike | null
fallback?: PublicLaunchReadinessInput | null fallback?: PublicLaunchReadinessInput | null
}): PublicLaunchStatusSummary { }): PublicLaunchStatusSummary {
return buildPublicLaunchStatusSummary( const derivedSummary = buildPublicLaunchStatusSummary(
resolveHealthPublicLaunchReadiness({ resolveHealthPublicLaunchReadiness({
manifest, manifest,
health, health,
@ -321,4 +375,27 @@ export function resolvePublicLaunchStatusSummary({
}), }),
resolvePublicLaunchTargets(manifest, health), 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),
}
} }

View file

@ -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.', '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', 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.', 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.', '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.', '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.', '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.', description: 'Current continuity is real, but it is still narrower than a finished global preferences and controller-rebinding suite.',
bullets: [ bullets: [
'The native operator and training surfaces can recall the latest persisted generated-mode selector posture when a structurally valid launch request exists.', '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.', '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.', '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.', '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 ] as const
export const changelogEntries = [ 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', date: 'June 28, 2026',
title: 'Public pages now explain what each route is actually for', 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?', 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?', 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?', question: 'Can I already customize controls and higher-dimensional view posture?',

View file

@ -839,4 +839,14 @@ code {
width: 100%; width: 100%;
flex-direction: column; flex-direction: column;
} }
.button-row > * {
width: 100%;
}
.button-row .button {
width: 100%;
max-width: 100%;
white-space: normal;
}
} }

View file

@ -14,6 +14,10 @@ const responsivePublicRoutes: readonly PublicRouteExpectation[] = [
heading: 'HyperTwist turns cube practice into a real operator-grade training stack.', heading: 'HyperTwist turns cube practice into a real operator-grade training stack.',
cta: 'Download desktop app', cta: 'Download desktop app',
}, },
{
path: '/features',
heading: 'Feature truth without the roadmap archaeology.',
},
{ {
path: '/about', path: '/about',
heading: 'A training stack serious enough for higher-dimensional cubing.', heading: 'A training stack serious enough for higher-dimensional cubing.',
@ -22,6 +26,10 @@ const responsivePublicRoutes: readonly PublicRouteExpectation[] = [
path: '/resources', path: '/resources',
heading: 'Resources that explain the product without leaking operator-only internals.', heading: 'Resources that explain the product without leaking operator-only internals.',
}, },
{
path: '/docs',
heading: 'HyperTwist documentation stays capability-accurate.',
},
{ {
path: '/pricing', path: '/pricing',
heading: 'Pricing that matches the actual delivery model.', heading: 'Pricing that matches the actual delivery model.',
@ -30,10 +38,43 @@ const responsivePublicRoutes: readonly PublicRouteExpectation[] = [
path: '/download', path: '/download',
heading: 'Download the desktop build and pair it with your browser account.', 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', path: '/support',
heading: 'Support for rollout, downloads, pricing, and browser-to-desktop access.', 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', path: '/register',
heading: 'Create a HyperTwist account', heading: 'Create a HyperTwist account',