Tighten control ownership truth and public manual guidance
This commit is contained in:
parent
163eb927cd
commit
42fcd54ecc
16 changed files with 805 additions and 208 deletions
|
|
@ -40,6 +40,28 @@ namespace HyperTwistTrainingPanelWidgetInternal
|
|||
bool bRequiresWindowsPackagedControllerValidationForReopen = true;
|
||||
};
|
||||
|
||||
struct FDedicatedHigherDimensionalRuntimeOwnershipFacts
|
||||
{
|
||||
FString FamilyLabel;
|
||||
FString ActivationProfileId;
|
||||
FString HostSurfaceId;
|
||||
FString ViewContextSurfaceId;
|
||||
FString SessionSurfaceId;
|
||||
FString SceneSurfaceId;
|
||||
bool bHostReady = false;
|
||||
bool bViewContextReady = false;
|
||||
bool bSessionReady = false;
|
||||
bool bSceneReady = false;
|
||||
|
||||
bool IsReady() const
|
||||
{
|
||||
return bHostReady
|
||||
&& bViewContextReady
|
||||
&& bSessionReady
|
||||
&& bSceneReady;
|
||||
}
|
||||
};
|
||||
|
||||
FString DescribeBool(const bool bValue)
|
||||
{
|
||||
return bValue ? TEXT("yes") : TEXT("no");
|
||||
|
|
@ -50,6 +72,11 @@ namespace HyperTwistTrainingPanelWidgetInternal
|
|||
return bValue ? TEXT("ready") : TEXT("not ready");
|
||||
}
|
||||
|
||||
FString DescribeIdOrFallback(const FString& Value)
|
||||
{
|
||||
return !Value.IsEmpty() ? Value : FString(TEXT("n/a"));
|
||||
}
|
||||
|
||||
FString DescribeKeyForRoster(const FKey& Key)
|
||||
{
|
||||
return Key.IsValid() ? Key.GetDisplayName().ToString() : TEXT("n/a");
|
||||
|
|
@ -329,6 +356,83 @@ namespace HyperTwistTrainingPanelWidgetInternal
|
|||
);
|
||||
}
|
||||
|
||||
FDedicatedHigherDimensionalRuntimeOwnershipFacts
|
||||
BuildDedicatedHigherDimensionalRuntimeOwnershipFacts(
|
||||
const FString& FamilyLabel,
|
||||
const FString& ActivationProfileId
|
||||
)
|
||||
{
|
||||
FDedicatedHigherDimensionalRuntimeOwnershipFacts Facts;
|
||||
Facts.FamilyLabel = FamilyLabel;
|
||||
Facts.ActivationProfileId = ActivationProfileId;
|
||||
|
||||
FHyperTwistTrainingHigherDimensionalRuntimeHostSurface HostSurface;
|
||||
Facts.bHostReady =
|
||||
UHyperTwistTrainingRuntimeLibrary::TryGetBundledHigherDimensionalRuntimeHostSurfaceByActivationProfileId(
|
||||
ActivationProfileId,
|
||||
HostSurface
|
||||
) && HostSurface.IsStructurallyValid();
|
||||
if (Facts.bHostReady)
|
||||
{
|
||||
Facts.HostSurfaceId = HostSurface.HostSurfaceId;
|
||||
}
|
||||
|
||||
FHyperTwistTrainingHigherDimensionalRuntimeViewContextSurface ViewContextSurface;
|
||||
Facts.bViewContextReady =
|
||||
UHyperTwistTrainingRuntimeLibrary::TryGetBundledHigherDimensionalRuntimeViewContextSurfaceByActivationProfileId(
|
||||
ActivationProfileId,
|
||||
ViewContextSurface
|
||||
) && ViewContextSurface.IsStructurallyValid();
|
||||
if (Facts.bViewContextReady)
|
||||
{
|
||||
Facts.ViewContextSurfaceId = ViewContextSurface.ViewContextSurfaceId;
|
||||
}
|
||||
|
||||
FHyperTwistTrainingHigherDimensionalRuntimeSessionSurface SessionSurface;
|
||||
Facts.bSessionReady =
|
||||
UHyperTwistTrainingRuntimeLibrary::TryGetBundledHigherDimensionalRuntimeSessionSurfaceByActivationProfileId(
|
||||
ActivationProfileId,
|
||||
SessionSurface
|
||||
) && SessionSurface.IsStructurallyValid();
|
||||
if (Facts.bSessionReady)
|
||||
{
|
||||
Facts.SessionSurfaceId = SessionSurface.SessionSurfaceId;
|
||||
}
|
||||
|
||||
FHyperTwistTrainingHigherDimensionalInteractiveSceneSurface SceneSurface;
|
||||
Facts.bSceneReady =
|
||||
UHyperTwistTrainingRuntimeLibrary::TryGetBundledHigherDimensionalInteractiveSceneSurfaceByActivationProfileId(
|
||||
ActivationProfileId,
|
||||
SceneSurface
|
||||
) && SceneSurface.IsStructurallyValid();
|
||||
if (Facts.bSceneReady)
|
||||
{
|
||||
Facts.SceneSurfaceId = SceneSurface.SceneSurfaceId;
|
||||
}
|
||||
|
||||
return Facts;
|
||||
}
|
||||
|
||||
FString BuildDedicatedHigherDimensionalRuntimeOwnershipLine(
|
||||
const FDedicatedHigherDimensionalRuntimeOwnershipFacts& Facts
|
||||
)
|
||||
{
|
||||
return FString::Printf(
|
||||
TEXT("%s %s | activation %s | host %s (%s) | view %s (%s) | session %s (%s) | scene %s (%s)"),
|
||||
*Facts.FamilyLabel,
|
||||
*DescribeReadyState(Facts.IsReady()),
|
||||
*DescribeIdOrFallback(Facts.ActivationProfileId),
|
||||
*DescribeBool(Facts.bHostReady),
|
||||
*DescribeIdOrFallback(Facts.HostSurfaceId),
|
||||
*DescribeBool(Facts.bViewContextReady),
|
||||
*DescribeIdOrFallback(Facts.ViewContextSurfaceId),
|
||||
*DescribeBool(Facts.bSessionReady),
|
||||
*DescribeIdOrFallback(Facts.SessionSurfaceId),
|
||||
*DescribeBool(Facts.bSceneReady),
|
||||
*DescribeIdOrFallback(Facts.SceneSurfaceId)
|
||||
);
|
||||
}
|
||||
|
||||
const FXrControllerBoundaryFacts& GetXrControllerBoundaryFacts()
|
||||
{
|
||||
static const FXrControllerBoundaryFacts CachedFacts = []()
|
||||
|
|
@ -1043,19 +1147,23 @@ UHyperTwistTrainingPanelWidget::GetDisplayedControlInputReadinessInspectSurface(
|
|||
Surface.bHigherDimensionalKeyboardInputReady =
|
||||
HigherDimensionalDefaults != nullptr && HigherDimensionalDefaults->bUseGameAndUiInputMode;
|
||||
|
||||
const FHyperTwistTrainingHigherDimensionalRuntimeHostCatalog HostCatalog =
|
||||
UHyperTwistTrainingRuntimeLibrary::GetBundledHigherDimensionalRuntimeHostCatalog();
|
||||
const FHyperTwistTrainingHigherDimensionalRuntimeViewContextCatalog ViewContextCatalog =
|
||||
UHyperTwistTrainingRuntimeLibrary::GetBundledHigherDimensionalRuntimeViewContextCatalog();
|
||||
const FHyperTwistTrainingHigherDimensionalRuntimeSessionCatalog SessionCatalog =
|
||||
UHyperTwistTrainingRuntimeLibrary::GetBundledHigherDimensionalRuntimeSessionCatalog();
|
||||
const FHyperTwistTrainingHigherDimensionalInteractiveSceneCatalog SceneCatalog =
|
||||
UHyperTwistTrainingRuntimeLibrary::GetBundledHigherDimensionalInteractiveSceneCatalog();
|
||||
const HyperTwistTrainingPanelWidgetInternal::FDedicatedHigherDimensionalRuntimeOwnershipFacts
|
||||
Magic120CellRuntimeOwnershipFacts =
|
||||
HyperTwistTrainingPanelWidgetInternal::
|
||||
BuildDedicatedHigherDimensionalRuntimeOwnershipFacts(
|
||||
TEXT("Magic120Cell"),
|
||||
TEXT("magic120cell-cleanroom-runtime-activation")
|
||||
);
|
||||
const HyperTwistTrainingPanelWidgetInternal::FDedicatedHigherDimensionalRuntimeOwnershipFacts
|
||||
MagicCube5DRuntimeOwnershipFacts =
|
||||
HyperTwistTrainingPanelWidgetInternal::
|
||||
BuildDedicatedHigherDimensionalRuntimeOwnershipFacts(
|
||||
TEXT("MagicCube5D"),
|
||||
TEXT("magiccube5d-cleanroom-runtime-activation")
|
||||
);
|
||||
Surface.bHigherDimensionalDedicatedFamilyReady =
|
||||
HostCatalog.IsStructurallyValid()
|
||||
&& ViewContextCatalog.IsStructurallyValid()
|
||||
&& SessionCatalog.IsStructurallyValid()
|
||||
&& SceneCatalog.IsStructurallyValid();
|
||||
Magic120CellRuntimeOwnershipFacts.IsReady()
|
||||
&& MagicCube5DRuntimeOwnershipFacts.IsReady();
|
||||
|
||||
const HyperTwistTrainingPanelWidgetInternal::FProjectInputGroundworkFacts& InputGroundworkFacts =
|
||||
HyperTwistTrainingPanelWidgetInternal::GetProjectInputGroundworkFacts();
|
||||
|
|
@ -1116,12 +1224,15 @@ UHyperTwistTrainingPanelWidget::GetDisplayedControlInputReadinessInspectSurface(
|
|||
*Surface.KeyboardProfileName
|
||||
);
|
||||
Surface.HigherDimensionalStatusLine = FString::Printf(
|
||||
TEXT("Higher-dimensional: keyboard-driven slice/layer control %s | dedicated-family runtime catalogs %s | scene surfaces %d."),
|
||||
TEXT("Higher-dimensional: keyboard-driven slice/layer control %s | %s | %s."),
|
||||
*HyperTwistTrainingPanelWidgetInternal::DescribeBool(
|
||||
Surface.bHigherDimensionalKeyboardInputReady),
|
||||
*HyperTwistTrainingPanelWidgetInternal::DescribeBool(
|
||||
Surface.bHigherDimensionalDedicatedFamilyReady),
|
||||
SceneCatalog.SceneSurfaces.Num()
|
||||
*HyperTwistTrainingPanelWidgetInternal::
|
||||
BuildDedicatedHigherDimensionalRuntimeOwnershipLine(
|
||||
Magic120CellRuntimeOwnershipFacts),
|
||||
*HyperTwistTrainingPanelWidgetInternal::
|
||||
BuildDedicatedHigherDimensionalRuntimeOwnershipLine(
|
||||
MagicCube5DRuntimeOwnershipFacts)
|
||||
);
|
||||
const FString MotionControllerFamilyLabels =
|
||||
InputGroundworkFacts.MotionControllerFamilies.Num() > 0
|
||||
|
|
|
|||
|
|
@ -1124,10 +1124,23 @@ bool FHyperTwistTrainingPanelControlInputReadinessInspectSurfaceTest::RunTest(
|
|||
&& Surface.ClassicCubeActionShortcutLine.Contains(TEXT("C cycle voice"))
|
||||
);
|
||||
TestTrue(
|
||||
TEXT("The control/input readiness surface must report the higher-dimensional keyboard lane and dedicated-family runtime catalogs."),
|
||||
TEXT("The control/input readiness surface must report the higher-dimensional keyboard lane and explicit dedicated-family runtime ownership for both shipped families."),
|
||||
Surface.bHigherDimensionalKeyboardInputReady
|
||||
&& Surface.bHigherDimensionalDedicatedFamilyReady
|
||||
);
|
||||
TestTrue(
|
||||
TEXT("The control/input readiness surface must name the concrete Magic120Cell and MagicCube5D runtime ownership surfaces instead of only reporting broad catalog validity."),
|
||||
Surface.HigherDimensionalStatusLine.Contains(TEXT("magic120cell-cleanroom-runtime-activation"))
|
||||
&& Surface.HigherDimensionalStatusLine.Contains(TEXT("phase6c/magic120cell/runtime-host-surface"))
|
||||
&& Surface.HigherDimensionalStatusLine.Contains(TEXT("phase6c/magic120cell/dedicated-training-view-context-surface"))
|
||||
&& Surface.HigherDimensionalStatusLine.Contains(TEXT("phase6c/magic120cell/dedicated-training-session-surface"))
|
||||
&& Surface.HigherDimensionalStatusLine.Contains(TEXT("phase6c/magic120cell/interactive-scene-surface"))
|
||||
&& Surface.HigherDimensionalStatusLine.Contains(TEXT("magiccube5d-cleanroom-runtime-activation"))
|
||||
&& Surface.HigherDimensionalStatusLine.Contains(TEXT("phase6c/magiccube5d/runtime-host-surface"))
|
||||
&& Surface.HigherDimensionalStatusLine.Contains(TEXT("phase6c/magiccube5d/dedicated-training-view-context-surface"))
|
||||
&& Surface.HigherDimensionalStatusLine.Contains(TEXT("phase6c/magiccube5d/dedicated-training-session-surface"))
|
||||
&& Surface.HigherDimensionalStatusLine.Contains(TEXT("phase6c/magiccube5d/interactive-scene-surface"))
|
||||
);
|
||||
TestTrue(
|
||||
TEXT("The control/input readiness surface must report the current project-level input groundwork."),
|
||||
Surface.bEnhancedInputProjectGroundworkPresent
|
||||
|
|
@ -1204,6 +1217,11 @@ bool FHyperTwistCoachDashboardControlInputReadinessInspectSurfaceTest::RunTest(
|
|||
TEXT("The coach dashboard control/input readiness surface must retain the keyboard profile fact in its detail line."),
|
||||
Surface.DetailLine.Contains(TEXT("classic-wca-keyboard/v1"))
|
||||
);
|
||||
TestTrue(
|
||||
TEXT("The coach dashboard control/input readiness surface must retain the concrete higher-dimensional family ownership ids in its detail line."),
|
||||
Surface.DetailLine.Contains(TEXT("phase6c/magic120cell/runtime-host-surface"))
|
||||
&& Surface.DetailLine.Contains(TEXT("phase6c/magiccube5d/interactive-scene-surface"))
|
||||
);
|
||||
TestTrue(
|
||||
TEXT("The coach dashboard control/input readiness surface must retain the exact classic cube pointer and action rosters in its detail line."),
|
||||
Surface.DetailLine.Contains(TEXT("LMB clockwise"))
|
||||
|
|
@ -1726,6 +1744,11 @@ bool FHyperTwistCoachDashboardControlSurfaceStructuredTextArtifactsTest::RunTest
|
|||
CoachDashboard,
|
||||
TEXT("CoachControlInputReadinessXr")
|
||||
);
|
||||
UTextBlock* ControlInputHigherDimensionalTextBlock =
|
||||
HyperTwistBrowserBridgeObjectTestInternal::FindDashboardTextBlock(
|
||||
CoachDashboard,
|
||||
TEXT("CoachControlInputReadinessHigherDimensional")
|
||||
);
|
||||
TestNotNull(
|
||||
TEXT("The coach dashboard must build the control/input summary text row."),
|
||||
ControlInputSummaryTextBlock
|
||||
|
|
@ -1746,6 +1769,10 @@ bool FHyperTwistCoachDashboardControlSurfaceStructuredTextArtifactsTest::RunTest
|
|||
TEXT("The coach dashboard must build the structured XR control/input row."),
|
||||
ControlInputXrTextBlock
|
||||
);
|
||||
TestNotNull(
|
||||
TEXT("The coach dashboard must build the structured higher-dimensional control/input row."),
|
||||
ControlInputHigherDimensionalTextBlock
|
||||
);
|
||||
if (ControlInputSummaryTextBlock != nullptr)
|
||||
{
|
||||
TestEqual(
|
||||
|
|
@ -1786,6 +1813,21 @@ bool FHyperTwistCoachDashboardControlSurfaceStructuredTextArtifactsTest::RunTest
|
|||
ControlInputSurface.XrStatusLine
|
||||
);
|
||||
}
|
||||
if (ControlInputHigherDimensionalTextBlock != nullptr)
|
||||
{
|
||||
TestEqual(
|
||||
TEXT("The structured higher-dimensional control/input row must mirror the inspect surface."),
|
||||
ControlInputHigherDimensionalTextBlock->GetText().ToString(),
|
||||
ControlInputSurface.HigherDimensionalStatusLine
|
||||
);
|
||||
TestTrue(
|
||||
TEXT("The structured higher-dimensional control/input row must expose the concrete dedicated-family runtime ownership ids."),
|
||||
ControlInputHigherDimensionalTextBlock->GetText().ToString().Contains(
|
||||
TEXT("phase6c/magic120cell/runtime-host-surface"))
|
||||
&& ControlInputHigherDimensionalTextBlock->GetText().ToString().Contains(
|
||||
TEXT("phase6c/magiccube5d/interactive-scene-surface"))
|
||||
);
|
||||
}
|
||||
|
||||
UTextBlock* ControlSettingsSummaryTextBlock =
|
||||
HyperTwistBrowserBridgeObjectTestInternal::FindDashboardTextBlock(
|
||||
|
|
|
|||
|
|
@ -67,6 +67,15 @@ Use them with this posture:
|
|||
- once bootstrapped, analyzer execution stays on the HyperTwist-local
|
||||
`tools/sentrux/bin/` landing zone instead of reaching back into
|
||||
`VectorShell` during ordinary runs
|
||||
- the current `2026-06-28` ownership follow-up narrows bootstrap posture
|
||||
further again:
|
||||
- `scripts/bootstrap-hypertwist-sentrux.sh` still honors an explicit
|
||||
`HYPERTWIST_SENTRUX_BINARY`
|
||||
- sibling-repo seed lookup is now opt-in behind
|
||||
`HYPERTWIST_ALLOW_SIBLING_SENTRUX_BOOTSTRAP=1` instead of being the default
|
||||
bootstrap path on a fresh machine
|
||||
- ordinary HyperTwist analyzer operation therefore stays repo-owned by
|
||||
default even during recovery/bootstrap flows
|
||||
|
||||
Suggested loop:
|
||||
|
||||
|
|
@ -993,6 +1002,11 @@ Current audit note:
|
|||
- the public docs route now also exposes the real shared browser-auth method
|
||||
lineup so provider truth is no longer stranded only on the auth entry
|
||||
pages
|
||||
- the next same-family public-manual continuation then widened that same
|
||||
real browser-account method lineup into the homepage, pricing, download,
|
||||
and support routes as well, so the high-traffic public decision pages no
|
||||
longer require operators to infer provider truth only from the later
|
||||
sign-in forms or deeper docs surfaces
|
||||
- cross-repo source truth for this packet stayed disciplined:
|
||||
- FamiliarOS current website auth posture remains intentionally narrower
|
||||
(`email/password` plus `GitHub`)
|
||||
|
|
@ -1005,6 +1019,9 @@ Current audit note:
|
|||
- `npm --prefix website/server test -- --run src/__tests__/runtime-config.test.ts src/__tests__/auth-health.test.ts`
|
||||
- `npm --prefix website run test -- --run scripts/render-same-origin-bundle-lib.test.mjs`
|
||||
- `npm --prefix website/server run type-check`
|
||||
- the same public-marketing suite now also explicitly protects the widened
|
||||
homepage, pricing, download, and support auth-lineup sections alongside
|
||||
the earlier docs/getting-started coverage
|
||||
- the same-family umbrella and structural gates also remained the target truth:
|
||||
- `scripts/run-hypertwist-web-surface-validation.sh`
|
||||
- `scripts/run-hypertwist-sentrux-source-only.sh`
|
||||
|
|
@ -1080,9 +1097,98 @@ Current audit note:
|
|||
- `Quality: 6217`
|
||||
- `scripts/run-hypertwist-gitnexus-analyze.sh`
|
||||
- `16,312` nodes, `38,387` edges, `672` clusters, `300` flows
|
||||
- `scripts/run-hypertwist-gitnexus-status.sh`
|
||||
- `Status: up-to-date`
|
||||
|
||||
## Latest public-manual route-atlas and tooling-ownership follow-up (`2026-06-28`)
|
||||
|
||||
- the next same-family public/manual continuation then made the broader public
|
||||
route set easier to use as a professional operator manual instead of leaving
|
||||
page purpose mostly implicit in navigation labels:
|
||||
- homepage, docs, and resources now share a first-party public route atlas
|
||||
that explains what each major public page owns today
|
||||
- the atlas keeps onboarding, launch authority, pricing, download, support,
|
||||
release notes, and the legal/distribution routes readable as distinct
|
||||
operator surfaces instead of one flatter marketing shell
|
||||
- the public release-notes feed now also records that new route-atlas/manual
|
||||
continuation directly
|
||||
- the same packet also tightened HyperTwist-owned tooling posture again:
|
||||
- `StepOnlyCardSection` and `SupportTopicDirectorySection` now live once in
|
||||
`website/src/pages/public-page-helpers.tsx` instead of being duplicated
|
||||
locally across the public marketing and launch-status modules
|
||||
- `scripts/bootstrap-hypertwist-sentrux.sh` now keeps sibling-repo seed
|
||||
lookup opt-in behind `HYPERTWIST_ALLOW_SIBLING_SENTRUX_BOOTSTRAP=1`, so the
|
||||
normal bootstrap path does not silently drift back into cross-repo
|
||||
analyzer ownership
|
||||
- focused website validation for that continuation stayed green under:
|
||||
- `npm --prefix website test -- --run src/__tests__/public-marketing-pages.test.tsx src/__tests__/app-route-tree.test.tsx`
|
||||
- `2` test files passed
|
||||
- `29` tests passed
|
||||
- `npm --prefix website run type-check`
|
||||
- `bash -n scripts/bootstrap-hypertwist-sentrux.sh scripts/run-hypertwist-sentrux-source-only.sh`
|
||||
- the same-family umbrella, structural, and analysis gates then stayed green
|
||||
again under:
|
||||
- `scripts/run-hypertwist-sentrux-source-only.sh`
|
||||
- `Quality: 6226`
|
||||
- `All rules pass`
|
||||
- `scripts/run-hypertwist-web-surface-validation.sh`
|
||||
- website focused route/auth/release suite: `12` files, `74` tests passed
|
||||
- website/server suite: `10` files, `36` tests passed
|
||||
- website and `Content/Browser` production audits: `found 0 vulnerabilities`
|
||||
- auth-server retained only the already-documented upstream
|
||||
`supertokens-node -> nodemailer` residual
|
||||
- `scripts/run-hypertwist-gitnexus-analyze.sh`
|
||||
- `16,332` nodes, `38,486` edges, `674` clusters, `300` flows
|
||||
- `scripts/run-hypertwist-gitnexus-status.sh`
|
||||
- `Status: up-to-date`
|
||||
|
||||
## Latest dedicated-family runtime-ownership truth follow-up (`2026-06-28`)
|
||||
|
||||
- the next same-family native/operator truth packet then tightened the shipped
|
||||
control-input readiness seam so higher-dimensional readiness is no longer
|
||||
inferred only from broad catalog validity:
|
||||
- `UHyperTwistTrainingPanelWidget::GetDisplayedControlInputReadinessInspectSurface()`
|
||||
now resolves the shipped `Magic120Cell` and `MagicCube5D` dedicated-family
|
||||
host, view-context, session, and interactive-scene surfaces explicitly by
|
||||
activation profile id
|
||||
- the higher-dimensional readiness line now renders concrete family/runtime
|
||||
ownership ids such as:
|
||||
- `magic120cell-cleanroom-runtime-activation`
|
||||
- `phase6c/magic120cell/runtime-host-surface`
|
||||
- `phase6c/magiccube5d/interactive-scene-surface`
|
||||
- the coach-dashboard structured higher-dimensional row now mirrors that
|
||||
exact explicit ownership line instead of leaving the family/runtime truth
|
||||
hidden behind broader readiness wording
|
||||
- the maintained Windows validation lane then proved that exact-source state on
|
||||
`C:\HyperTwist_worktrees\phase10validate`:
|
||||
- synced exact touched files through
|
||||
`scripts/run-hypertwist-remote-windows-file-sync.sh`
|
||||
- remote Unreal rebuild through
|
||||
`scripts/run-hypertwist-remote-unreal-build.sh`
|
||||
- `Result: Succeeded`
|
||||
- UnrealBuildTool `Total execution time: 109.14 seconds`
|
||||
- focused remote automation through
|
||||
`scripts/run-hypertwist-remote-unreal-automation-sequence.sh`
|
||||
- all `3` exact-source filters passed:
|
||||
- `HyperTwist.Browser.TrainingPanel.ControlInputReadinessInspectSurface`
|
||||
- `HyperTwist.Browser.CoachDashboard.ControlInputReadinessInspectSurface`
|
||||
- `HyperTwist.Browser.CoachDashboard.ControlSurfaceStructuredTextArtifacts`
|
||||
- the HyperTwist-owned structural loop stayed healthy after that packet:
|
||||
- `scripts/run-hypertwist-sentrux-source-only.sh`
|
||||
- `Quality: 6226`
|
||||
- all `7` rules pass
|
||||
- `scripts/run-hypertwist-gitnexus-analyze.sh`
|
||||
- retained runtime truthfully fell back to `npx -y gitnexus@latest` on this
|
||||
Linux host because `@ladybugdb/core` still hits `ERR_DLOPEN_FAILED` with an
|
||||
`invalid ELF header`
|
||||
- bounded mirror refreshed at:
|
||||
- `16,352` nodes
|
||||
- `38,540` edges
|
||||
- `679` clusters
|
||||
- `300` flows
|
||||
- `scripts/run-hypertwist-gitnexus-status.sh`
|
||||
- bounded mirror `Status: up-to-date`
|
||||
|
||||
## Latest native/public control-roster parity follow-up (`2026-06-25`)
|
||||
|
||||
- the same-family native/operator continuity lane then aligned the shipped
|
||||
|
|
|
|||
File diff suppressed because one or more lines are too long
|
|
@ -120,6 +120,12 @@ mouse/touch flows, higher-dimensional keyboard interaction, and project-level
|
|||
motion-control groundwork, but HyperTwist should not yet claim a fully finished
|
||||
shipping VR/controller/preferences lane without a dedicated completion packet.
|
||||
|
||||
The latest native/operator truth follow-up on `2026-06-28` also tightened the
|
||||
higher-dimensional side of that statement: native control-input readiness now
|
||||
proves shipped `Magic120Cell` and `MagicCube5D` host, view-context, session,
|
||||
and interactive-scene ownership explicitly by activation profile id instead of
|
||||
only implying readiness from broad runtime-catalog validity.
|
||||
|
||||
Canonical audit note:
|
||||
|
||||
- `C:\HyperTwist\docs\ops\HYPERTWIST_UNREAL_INPUT_AND_XR_COMPLETENESS_AUDIT_2026-06-22.md`
|
||||
|
|
|
|||
|
|
@ -15,14 +15,16 @@ usage() {
|
|||
Usage:
|
||||
scripts/bootstrap-hypertwist-sentrux.sh [--if-missing]
|
||||
|
||||
Materializes a repo-local sentrux binary under tools/sentrux/bin/ using the
|
||||
best available retained seed on this machine.
|
||||
Materializes a repo-local sentrux binary under tools/sentrux/bin/ while keeping
|
||||
ordinary HyperTwist runs repo-owned by default.
|
||||
|
||||
Resolution order:
|
||||
1. HYPERTWIST_SENTRUX_BINARY if explicitly provided
|
||||
2. existing VectorShell Linux build artifact
|
||||
3. local VectorShell source build via cargo
|
||||
4. local ScriptoriumAI Windows binary
|
||||
2. optional sibling-repo seeds, but only when
|
||||
HYPERTWIST_ALLOW_SIBLING_SENTRUX_BOOTSTRAP=1
|
||||
- existing VectorShell Linux build artifact
|
||||
- local VectorShell source build via cargo
|
||||
- local ScriptoriumAI Windows binary
|
||||
|
||||
The resulting analyzer then lives under HyperTwist-owned tools/sentrux/bin/
|
||||
so later runs do not need to execute directly from sibling repos.
|
||||
|
|
@ -66,22 +68,26 @@ if [[ -n "${HYPERTWIST_SENTRUX_BINARY:-}" && -x "${HYPERTWIST_SENTRUX_BINARY}" ]
|
|||
exit 0
|
||||
fi
|
||||
|
||||
if [[ -x "$vector_sentrux_binary" ]]; then
|
||||
copy_binary "$vector_sentrux_binary" "$dest_linux"
|
||||
exit 0
|
||||
fi
|
||||
allow_sibling_bootstrap="${HYPERTWIST_ALLOW_SIBLING_SENTRUX_BOOTSTRAP:-0}"
|
||||
|
||||
if command -v cargo >/dev/null 2>&1 && [[ -f "$vector_sentrux_manifest" ]]; then
|
||||
cargo build --quiet --release --manifest-path "$vector_sentrux_manifest" --bin sentrux
|
||||
if [[ "$allow_sibling_bootstrap" == "1" ]]; then
|
||||
if [[ -x "$vector_sentrux_binary" ]]; then
|
||||
copy_binary "$vector_sentrux_binary" "$dest_linux"
|
||||
exit 0
|
||||
fi
|
||||
fi
|
||||
|
||||
if [[ -f "$scriptorium_sentrux_windows" ]]; then
|
||||
copy_binary "$scriptorium_sentrux_windows" "$dest_windows"
|
||||
exit 0
|
||||
if command -v cargo >/dev/null 2>&1 && [[ -f "$vector_sentrux_manifest" ]]; then
|
||||
cargo build --quiet --release --manifest-path "$vector_sentrux_manifest" --bin sentrux
|
||||
if [[ -x "$vector_sentrux_binary" ]]; then
|
||||
copy_binary "$vector_sentrux_binary" "$dest_linux"
|
||||
exit 0
|
||||
fi
|
||||
fi
|
||||
|
||||
if [[ -f "$scriptorium_sentrux_windows" ]]; then
|
||||
copy_binary "$scriptorium_sentrux_windows" "$dest_windows"
|
||||
exit 0
|
||||
fi
|
||||
fi
|
||||
|
||||
cat >&2 <<EOF
|
||||
|
|
@ -89,11 +95,13 @@ Unable to materialize a repo-local sentrux binary.
|
|||
|
||||
Checked:
|
||||
- HYPERTWIST_SENTRUX_BINARY
|
||||
- sibling seeds are $(if [[ "$allow_sibling_bootstrap" == "1" ]]; then printf 'enabled'; else printf 'disabled by default'; fi)
|
||||
- $vector_sentrux_binary
|
||||
- $vector_sentrux_manifest
|
||||
- $scriptorium_sentrux_windows
|
||||
|
||||
Provide HYPERTWIST_SENTRUX_BINARY directly or place a compatible sentrux binary
|
||||
under tools/sentrux/bin/.
|
||||
under tools/sentrux/bin/. If you intentionally want to seed from sibling repos
|
||||
on this machine, rerun with HYPERTWIST_ALLOW_SIBLING_SENTRUX_BOOTSTRAP=1.
|
||||
EOF
|
||||
exit 1
|
||||
|
|
|
|||
|
|
@ -58,7 +58,7 @@ resolve_sentrux_command() {
|
|||
}
|
||||
|
||||
sentrux_command="$(resolve_sentrux_command)" || {
|
||||
echo "Unable to locate sentrux. Provide HYPERTWIST_SENTRUX_BINARY, run scripts/bootstrap-hypertwist-sentrux.sh, add sentrux to PATH, or place a repo-local sentrux binary under $repo_root/tools/sentrux/bin." >&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
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -6,6 +6,7 @@ First-party `hypertwist.app` surface for HyperTwist:
|
|||
- dedicated public `/getting-started` onboarding route for the first real browser-to-desktop operator journey
|
||||
- dedicated public `/launch-status` route for the canonical preview-versus-launch rollout checklist
|
||||
- public feature-atlas route for current capability and boundary truth
|
||||
- shared public-manual route atlas across homepage, docs, and resources so each major public page explains its exact job
|
||||
- browser-facing operator/account dashboard
|
||||
- protected launch-status, browser-access, account, and notices routes backed by live auth-health and release-manifest authority
|
||||
- shared SuperTokens auth posture reused from the FamiliarOS and ScriptoriumAI website lane
|
||||
|
|
@ -63,6 +64,13 @@ manual:
|
|||
- the docs and resources pages now also carry a practical simulator-use manual
|
||||
for recognition, replay, higher-dimensional runtime ownership, and operator
|
||||
diagnostics without overclaiming browser or VR parity
|
||||
- the public browser-account method lineup is now also visible on the
|
||||
homepage, pricing, download, support, docs, and getting-started routes so
|
||||
high-traffic decision pages no longer hide provider truth until the auth
|
||||
entry forms
|
||||
- the homepage, docs, and resources surfaces now also share a route atlas that
|
||||
explains what each major public page owns, so the site reads more like a
|
||||
professional operator manual than a flatter brochure shell
|
||||
- the about, feature-atlas, resources, and docs surfaces now also expose a
|
||||
concrete shipped control-profile and settings roster for the desktop lane,
|
||||
including the current `classic-wca-keyboard/v1` profile, scenic immersive
|
||||
|
|
@ -157,6 +165,16 @@ the one remaining accepted browser-build warning is the current upstream
|
|||
`@khronosgroup/gltf-viewer` `mikktspace_bg.wasm` Vite asset-resolution message,
|
||||
which does not currently break the owned shell verification or production build.
|
||||
|
||||
Repo-owned structural-tool posture:
|
||||
|
||||
- `scripts/run-hypertwist-sentrux-source-only.sh` still prefers
|
||||
`HYPERTWIST_SENTRUX_BINARY`, repo-local `./sentrux` or `./sentrux.exe`, then
|
||||
`tools/sentrux/bin/`, then `PATH`
|
||||
- `scripts/bootstrap-hypertwist-sentrux.sh` now keeps sibling-repo seed lookup
|
||||
opt-in behind `HYPERTWIST_ALLOW_SIBLING_SENTRUX_BOOTSTRAP=1`, so ordinary
|
||||
HyperTwist analyzer recovery does not silently drift back into cross-repo
|
||||
ownership
|
||||
|
||||
Latest auth-shell hardening follow-up on `2026-06-24`:
|
||||
|
||||
- the website now carries a first-party HyperTwist auth-shell backdrop module
|
||||
|
|
@ -250,6 +268,20 @@ Latest protected control-roster follow-up later on `2026-06-24`:
|
|||
- `41` test files passed
|
||||
- `168` tests passed
|
||||
|
||||
Latest browser-versus-desktop reality follow-up on `2026-06-28`:
|
||||
|
||||
- the shared browser-versus-desktop public-manual copy now says more directly
|
||||
why the browser lane is narrower instead of relying only on abstract
|
||||
boundary language:
|
||||
- low-latency simulator input remains native
|
||||
- packaged runtime ownership remains native
|
||||
- higher-dimensional scene execution remains native
|
||||
- any future serious controller or VR completion remains native
|
||||
- that wording now propagates automatically anywhere the shared
|
||||
`BrowserDesktopRealitySection` is rendered, including homepage, about,
|
||||
features, pricing, docs, resources, launch-status, and the mirrored
|
||||
protected operator surfaces
|
||||
|
||||
Latest first-session quickstart/manual follow-up on `2026-06-27`:
|
||||
|
||||
- the public and protected manual lane now explains the first real operator
|
||||
|
|
|
|||
|
|
@ -270,6 +270,12 @@ describe('public marketing pages', () => {
|
|||
expect(screen.getByText('How the release lane works')).toBeTruthy()
|
||||
expect(screen.getByText('Why HyperTwist keeps both a website and a desktop runtime')).toBeTruthy()
|
||||
expect(screen.getByText('Why the browser is intentionally narrower')).toBeTruthy()
|
||||
expect(screen.getByRole('heading', { name: 'Browser account access methods' })).toBeTruthy()
|
||||
expect(screen.getByText('Auth methods ready')).toBeTruthy()
|
||||
expect(screen.getByText('Email and password')).toBeTruthy()
|
||||
expect(screen.getByText('GitHub sign-in')).toBeTruthy()
|
||||
expect(screen.getByText('ORCID sign-in')).toBeTruthy()
|
||||
expect(screen.queryByText('Google sign-in')).toBeNull()
|
||||
expect(screen.getByText('Choose the right HyperTwist surface')).toBeTruthy()
|
||||
const downloadDecisionGuideHeading = screen.getByRole('heading', { name: 'Choose the next release move' })
|
||||
const downloadDecisionGuideSection = downloadDecisionGuideHeading.closest('section')
|
||||
|
|
@ -449,6 +455,12 @@ describe('public marketing pages', () => {
|
|||
expect(screen.getByText('Current input, XR, and settings truth')).toBeTruthy()
|
||||
expect(screen.getAllByText('Paddle webhook secret: missing').length).toBeGreaterThan(0)
|
||||
expect(screen.getAllByText(/public auth runtime posture/i).length).toBeGreaterThan(0)
|
||||
expect(screen.getByRole('heading', { name: 'Browser account access methods' })).toBeTruthy()
|
||||
expect(screen.getByText('Auth methods ready')).toBeTruthy()
|
||||
expect(screen.getByText('Email and password')).toBeTruthy()
|
||||
expect(screen.getByText('GitHub sign-in')).toBeTruthy()
|
||||
expect(screen.getByText('ORCID sign-in')).toBeTruthy()
|
||||
expect(screen.queryByText('Google sign-in')).toBeNull()
|
||||
expect(screen.getByText('Current packaged desktop proof')).toBeTruthy()
|
||||
expect(screen.getByText('Packaged validation passed')).toBeTruthy()
|
||||
const homeDecisionGuideHeading = screen.getByRole('heading', { name: 'Choose the next release move' })
|
||||
|
|
@ -461,6 +473,8 @@ describe('public marketing pages', () => {
|
|||
expect(screen.getByText('How a real first session flows')).toBeTruthy()
|
||||
expect(screen.getByText('What the first serious session should look like')).toBeTruthy()
|
||||
expect(screen.getByText('1. Resolve access and choose the right build')).toBeTruthy()
|
||||
expect(screen.getByText('Which public page should you open next?')).toBeTruthy()
|
||||
expect(screen.getByText('Launch status')).toBeTruthy()
|
||||
expect(screen.getByText('Choose the right HyperTwist surface')).toBeTruthy()
|
||||
expect(screen.getByText('Move into the protected dashboard')).toBeTruthy()
|
||||
expect(screen.getAllByText('Current surface authority map').length).toBeGreaterThan(0)
|
||||
|
|
@ -892,6 +906,12 @@ describe('public marketing pages', () => {
|
|||
expect(screen.getByText('Why HyperTwist keeps both a website and a desktop runtime')).toBeTruthy()
|
||||
expect(screen.getByText('Use the desktop runtime')).toBeTruthy()
|
||||
expect(screen.getByText('Current input, XR, and settings truth')).toBeTruthy()
|
||||
expect(screen.getByRole('heading', { name: 'Browser account access methods' })).toBeTruthy()
|
||||
expect(screen.getByText('Auth methods ready')).toBeTruthy()
|
||||
expect(screen.getByText('Email and password')).toBeTruthy()
|
||||
expect(screen.getByText('GitHub sign-in')).toBeTruthy()
|
||||
expect(screen.getByText('ORCID sign-in')).toBeTruthy()
|
||||
expect(screen.queryByText('Google sign-in')).toBeNull()
|
||||
expect(screen.getByText('Shows account, auth, billing, and release readiness posture')).toBeTruthy()
|
||||
expect(screen.getByText('Owns recognition, replay, coaching, and packaged training behavior')).toBeTruthy()
|
||||
expect(screen.getByText('Commercial distribution doctrine')).toBeTruthy()
|
||||
|
|
@ -983,6 +1003,12 @@ describe('public marketing pages', () => {
|
|||
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('Browser and desktop responsibilities')).toBeTruthy()
|
||||
expect(screen.getByRole('heading', { name: 'Current browser sign-in methods' })).toBeTruthy()
|
||||
expect(screen.getByText('Auth methods ready')).toBeTruthy()
|
||||
expect(screen.getByText('Email and password')).toBeTruthy()
|
||||
expect(screen.getByText('GitHub sign-in')).toBeTruthy()
|
||||
expect(screen.getByText('ORCID sign-in')).toBeTruthy()
|
||||
expect(screen.queryByText('Google sign-in')).toBeNull()
|
||||
expect(screen.getByText('Shows account, auth, billing, and release readiness posture')).toBeTruthy()
|
||||
expect(screen.getByText('Support lanes')).toBeTruthy()
|
||||
expect(screen.getByText('Support topic quick routes')).toBeTruthy()
|
||||
|
|
@ -1129,6 +1155,8 @@ describe('public marketing pages', () => {
|
|||
expect(screen.getByText('Deployment readiness snapshot')).toBeTruthy()
|
||||
expect(screen.getAllByText('XR groundwork exists, but the full VR lane is not finished').length).toBeGreaterThan(0)
|
||||
expect(screen.getByText('Higher-dimensional runtime ownership')).toBeTruthy()
|
||||
expect(screen.getByText('Public manual route atlas')).toBeTruthy()
|
||||
expect(screen.getByText('Shipping & payment')).toBeTruthy()
|
||||
expect(screen.getByText('Choose the next release move')).toBeTruthy()
|
||||
expect(screen.getByText('Need account state, pairing, or protected browser follow-through?')).toBeTruthy()
|
||||
expect(screen.getByText(/The web lane is not superfluous/i)).toBeTruthy()
|
||||
|
|
@ -1291,6 +1319,8 @@ describe('public marketing pages', () => {
|
|||
expect(screen.getByText(/R scramble, H hint, Enter submit, F mode, V hold-to-talk, C cycle voice/i)).toBeTruthy()
|
||||
expect(screen.getAllByText(/latest persisted generated-mode selector posture is available for recall/i).length).toBeGreaterThan(0)
|
||||
expect(screen.getByText('Feature-registry-backed wording only')).toBeTruthy()
|
||||
expect(screen.getByText('Documentation and route atlas')).toBeTruthy()
|
||||
expect(screen.getByText('Open-source notices')).toBeTruthy()
|
||||
expect(screen.getByText('Browser auth degraded or mixed')).toBeTruthy()
|
||||
expect(screen.getByText('Release authority temporarily unavailable')).toBeTruthy()
|
||||
expect(screen.getByText('Current packaged desktop proof')).toBeTruthy()
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@ import { useMemo } from 'react'
|
|||
import { useQuery } from '@tanstack/react-query'
|
||||
import { Link } from 'react-router-dom'
|
||||
import { getReleaseManifest } from '../auth/auth-api'
|
||||
import { BrowserAuthMethodsGuide } from '../components/ui/BrowserAuthMethodsGuide'
|
||||
import { ReleaseValidationSummary } from '../components/ui/ReleaseValidationSummary'
|
||||
import type { ReleaseManifestPlatformView, ReleaseManifestView } from '../release-manifest'
|
||||
import { resolveReleaseCommerceView, resolveReleaseManifestView } from '../release-manifest'
|
||||
|
|
@ -19,6 +20,7 @@ import {
|
|||
browserDesktopRealityCards,
|
||||
deliverySurfaceCards,
|
||||
operatorDesktopQuickstartCards,
|
||||
publicManualRouteAtlasCards,
|
||||
} from '../site-data'
|
||||
import {
|
||||
buildLoginPath,
|
||||
|
|
@ -151,6 +153,16 @@ export function Section({
|
|||
)
|
||||
}
|
||||
|
||||
type StepOnlyCard = {
|
||||
title: string
|
||||
steps?: readonly string[]
|
||||
bullets?: readonly string[]
|
||||
}
|
||||
|
||||
type SupportTopicCard = (typeof supportTopicDirectory)[number]
|
||||
|
||||
type PublicManualRouteAtlasCard = (typeof publicManualRouteAtlasCards)[number]
|
||||
|
||||
export function usePublicReleaseManifestView(queryScope: string) {
|
||||
const releaseManifestQuery = useQuery({
|
||||
queryKey: ['release-manifest', queryScope],
|
||||
|
|
@ -338,6 +350,137 @@ export function OperatorDesktopQuickstartSection({
|
|||
)
|
||||
}
|
||||
|
||||
export function StepOnlyCardSection({
|
||||
title,
|
||||
description,
|
||||
cards,
|
||||
}: {
|
||||
title: string
|
||||
description?: string
|
||||
cards: readonly StepOnlyCard[]
|
||||
}) {
|
||||
return (
|
||||
<Section title={title} description={description}>
|
||||
<div className="card-grid">
|
||||
{cards.map((card) => (
|
||||
<article key={card.title} className="card">
|
||||
<h3>{card.title}</h3>
|
||||
<ul className="list top-gap">
|
||||
{(card.steps ?? card.bullets ?? []).map((step) => (
|
||||
<li key={step}>{step}</li>
|
||||
))}
|
||||
</ul>
|
||||
</article>
|
||||
))}
|
||||
</div>
|
||||
</Section>
|
||||
)
|
||||
}
|
||||
|
||||
export function SupportTopicDirectorySection({
|
||||
title,
|
||||
description,
|
||||
topics,
|
||||
selectedTopicKey,
|
||||
}: {
|
||||
title: string
|
||||
description?: string
|
||||
topics: readonly SupportTopicCard[]
|
||||
selectedTopicKey?: string | null
|
||||
}) {
|
||||
return (
|
||||
<Section title={title} description={description}>
|
||||
<div className="card-grid">
|
||||
{topics.map((topic) => {
|
||||
const isSelected = selectedTopicKey === topic.topicKey
|
||||
|
||||
return (
|
||||
<article
|
||||
key={topic.topicKey}
|
||||
className={`card${isSelected ? ' card--selected' : ''}`}
|
||||
>
|
||||
{isSelected ? <p className="status-pill status-pill--info">Selected help lane</p> : null}
|
||||
<h3>{topic.title}</h3>
|
||||
<p>{topic.description}</p>
|
||||
<p className="eyebrow top-gap">Next steps</p>
|
||||
<ul className="list top-gap">
|
||||
{topic.steps.map((step) => (
|
||||
<li key={step}>{step}</li>
|
||||
))}
|
||||
</ul>
|
||||
<p className="eyebrow top-gap">Manual and route focus</p>
|
||||
<ul className="list top-gap">
|
||||
{topic.routeFocus.map((item) => (
|
||||
<li key={item}>{item}</li>
|
||||
))}
|
||||
</ul>
|
||||
<div className="button-row top-gap">
|
||||
{topic.actions.map((action) => (
|
||||
<Link key={`${topic.topicKey}-${action.label}`} className="button button--ghost" to={action.to}>
|
||||
{action.label}
|
||||
</Link>
|
||||
))}
|
||||
</div>
|
||||
</article>
|
||||
)
|
||||
})}
|
||||
</div>
|
||||
</Section>
|
||||
)
|
||||
}
|
||||
|
||||
export function PublicManualRouteAtlasSection({
|
||||
title = 'Public manual route atlas',
|
||||
description = 'Each public page has a different job inside HyperTwist. This atlas keeps the route set readable as a real manual rather than a flat marketing shell.',
|
||||
cards = publicManualRouteAtlasCards,
|
||||
limit,
|
||||
}: {
|
||||
title?: string
|
||||
description?: string
|
||||
cards?: readonly PublicManualRouteAtlasCard[]
|
||||
limit?: number
|
||||
}) {
|
||||
const visibleCards = typeof limit === 'number' ? cards.slice(0, limit) : cards
|
||||
|
||||
return (
|
||||
<Section title={title} description={description}>
|
||||
<div className="card-grid">
|
||||
{visibleCards.map((card) => (
|
||||
<article key={card.route} className="card">
|
||||
<p className="status-pill status-pill--info">{card.route}</p>
|
||||
<h3>{card.title}</h3>
|
||||
<p>{card.description}</p>
|
||||
<ul className="list top-gap">
|
||||
{card.bullets.map((bullet) => (
|
||||
<li key={bullet}>{bullet}</li>
|
||||
))}
|
||||
</ul>
|
||||
<div className="button-row top-gap">
|
||||
<Link className="button button--ghost" to={card.route}>
|
||||
Open {card.title}
|
||||
</Link>
|
||||
</div>
|
||||
</article>
|
||||
))}
|
||||
</div>
|
||||
</Section>
|
||||
)
|
||||
}
|
||||
|
||||
export function BrowserAuthMethodsSection({
|
||||
title = 'Browser account access methods',
|
||||
description = 'The public browser-account provider lineup should stay visible wherever operators are being asked to sign in, buy access, pair the desktop runtime, or recover access posture.',
|
||||
}: {
|
||||
title?: string
|
||||
description?: string
|
||||
}) {
|
||||
return (
|
||||
<Section title={title} description={description}>
|
||||
<BrowserAuthMethodsGuide />
|
||||
</Section>
|
||||
)
|
||||
}
|
||||
|
||||
export function PublicPackagedDesktopProofSection({
|
||||
platform,
|
||||
actions = [],
|
||||
|
|
|
|||
|
|
@ -24,6 +24,7 @@ import {
|
|||
termsBoundaryCards,
|
||||
} from '../site-data'
|
||||
import {
|
||||
BrowserAuthMethodsSection,
|
||||
BrowserDesktopRealitySection,
|
||||
DeliverySurfaceResponsibilitiesGrid,
|
||||
explorerFallbackPlan,
|
||||
|
|
@ -109,6 +110,10 @@ export function PricingPage() {
|
|||
description="Pricing is a distribution surface, so its launch truth should carry the same docs, release, source, and escalation bundle as the rest of the public release lane."
|
||||
/>
|
||||
|
||||
<BrowserAuthMethodsSection
|
||||
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
|
||||
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."
|
||||
|
|
@ -309,6 +314,10 @@ export function DownloadPage() {
|
|||
description="The download page should also say whether the next honest move is protected desktop access, pricing/provisioning, browser/account continuity, or notices/source follow-through."
|
||||
/>
|
||||
|
||||
<BrowserAuthMethodsSection
|
||||
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
|
||||
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."
|
||||
|
|
|
|||
88
website/src/pages/public-pages-launch.tsx
Normal file
88
website/src/pages/public-pages-launch.tsx
Normal file
|
|
@ -0,0 +1,88 @@
|
|||
import { MarketingShell } from '../components/layout/MarketingShell'
|
||||
import { SiteMetadata } from '../components/seo/SiteMetadata'
|
||||
import { PublicLaunchStatus } from '../components/ui/PublicLaunchStatus'
|
||||
import { deploymentReadinessTracks, releaseRolloutChecklist } from '../site-data'
|
||||
import {
|
||||
BrowserDesktopRealitySection,
|
||||
PublicPackagedDesktopProofSection,
|
||||
PublicReleaseDecisionGuideSection,
|
||||
ReleaseAuthorityBundleSection,
|
||||
Section,
|
||||
StepOnlyCardSection,
|
||||
SupportTopicDirectorySection,
|
||||
SurfaceChoiceGuideSection,
|
||||
supportTopicDirectory,
|
||||
usePublicReleaseManifestView,
|
||||
} from './public-page-helpers'
|
||||
|
||||
export function LaunchStatusPage() {
|
||||
const { releaseManifest, windowsValidationPlatform } = usePublicReleaseManifestView('public-launch-status')
|
||||
|
||||
return (
|
||||
<>
|
||||
<SiteMetadata
|
||||
title="HyperTwist launch status"
|
||||
description="Check the canonical HyperTwist public launch-readiness posture: checkout, download, notices, corresponding source, public auth runtime, and release authority."
|
||||
canonicalPath="/launch-status"
|
||||
/>
|
||||
<MarketingShell
|
||||
eyebrow="Launch authority"
|
||||
title="See exactly what still separates preview from public launch."
|
||||
lede="This is the canonical public authority surface for rollout truth: release targets, checkout posture, notices, corresponding source, and public auth-runtime readiness stay visible here in one place instead of being reconstructed from scattered callouts."
|
||||
>
|
||||
<Section
|
||||
title="Current public launch status"
|
||||
description="Use this page when rollout language, pricing, download, and legal/distribution follow-through need one authoritative browser-owned checklist."
|
||||
>
|
||||
<PublicLaunchStatus title="Current launch-readiness checklist" />
|
||||
</Section>
|
||||
|
||||
<StepOnlyCardSection
|
||||
title="What must be true before public launch"
|
||||
description="These are the bounded rollout checks that keep external launch language tied to real release authority instead of aspiration."
|
||||
cards={releaseRolloutChecklist}
|
||||
/>
|
||||
|
||||
<StepOnlyCardSection
|
||||
title="Launch hardening tracks"
|
||||
description="These are the practical work tracks for turning a truthful preview lane into a production-grade public release lane."
|
||||
cards={deploymentReadinessTracks}
|
||||
/>
|
||||
|
||||
<PublicPackagedDesktopProofSection
|
||||
platform={windowsValidationPlatform}
|
||||
actions={[
|
||||
{ to: '/download', label: 'Open download center' },
|
||||
{ to: '/getting-started', label: 'Open getting started' },
|
||||
]}
|
||||
/>
|
||||
|
||||
<SupportTopicDirectorySection
|
||||
title="Launch support and escalation lanes"
|
||||
description="Launch posture only helps when the next human lane is explicit too, so these support routes stay attached to the same authority surface."
|
||||
topics={supportTopicDirectory}
|
||||
selectedTopicKey="launch-readiness"
|
||||
/>
|
||||
|
||||
<PublicReleaseDecisionGuideSection
|
||||
releaseManifest={releaseManifest}
|
||||
title="Choose the next launch move"
|
||||
description="This page should not stop at checklist language. It should also say whether the next honest move is protected desktop access, pricing/provisioning, browser/account follow-through, or notices/source review."
|
||||
/>
|
||||
|
||||
<ReleaseAuthorityBundleSection
|
||||
releaseManifest={releaseManifest}
|
||||
title="Release, notice, and support bundle"
|
||||
description="Launch readiness is only trustworthy when docs, release notes, corresponding source, public notices, and operator contact remain visible as one release bundle."
|
||||
/>
|
||||
|
||||
<SurfaceChoiceGuideSection description="This keeps launch posture grounded in the real product topology too: public for launch truth, protected for account-aware release work, and native for the simulator itself." />
|
||||
|
||||
<BrowserDesktopRealitySection
|
||||
title="Why launch authority stays in the browser shell"
|
||||
description="Launch-readiness posture belongs to the distribution shell because checkout, notices, release references, and account access are browser-owned even while the actual training runtime remains native."
|
||||
/>
|
||||
</MarketingShell>
|
||||
</>
|
||||
)
|
||||
}
|
||||
|
|
@ -3,7 +3,6 @@ import { ArrowRight, BookOpenText, Boxes, Download, ExternalLink, Landmark, Moni
|
|||
import { Link, useSearchParams } from 'react-router-dom'
|
||||
import { MarketingShell } from '../components/layout/MarketingShell'
|
||||
import { SiteMetadata } from '../components/seo/SiteMetadata'
|
||||
import { BrowserAuthMethodsGuide } from '../components/ui/BrowserAuthMethodsGuide'
|
||||
import { PublicLaunchStatus } from '../components/ui/PublicLaunchStatus'
|
||||
import { ProductSurfaceMatrix } from '../components/ui/ProductSurfaceMatrix'
|
||||
import { brandConfig } from '../site-config'
|
||||
|
|
@ -36,13 +35,17 @@ import {
|
|||
supportFaqs,
|
||||
} from '../site-data'
|
||||
import {
|
||||
BrowserAuthMethodsSection,
|
||||
BrowserDesktopRealitySection,
|
||||
DeliverySurfaceResponsibilitiesGrid,
|
||||
OperatorDesktopQuickstartSection,
|
||||
PublicManualRouteAtlasSection,
|
||||
PublicPackagedDesktopProofSection,
|
||||
PublicReleaseDecisionGuideSection,
|
||||
ReleaseAuthorityBundleSection,
|
||||
Section,
|
||||
StepOnlyCardSection,
|
||||
SupportTopicDirectorySection,
|
||||
SurfaceChoiceGuideSection,
|
||||
supportTopicDirectory,
|
||||
supportTopicGuidance,
|
||||
|
|
@ -66,19 +69,11 @@ type StepCard = {
|
|||
steps: readonly string[]
|
||||
}
|
||||
|
||||
type StepOnlyCard = {
|
||||
title: string
|
||||
steps?: readonly string[]
|
||||
bullets?: readonly string[]
|
||||
}
|
||||
|
||||
type FaqCard = {
|
||||
question: string
|
||||
answer: string
|
||||
}
|
||||
|
||||
type SupportTopicCard = (typeof supportTopicDirectory)[number]
|
||||
|
||||
function PrincipleCardSection({
|
||||
title,
|
||||
description,
|
||||
|
|
@ -158,33 +153,6 @@ function StepCardSection({
|
|||
)
|
||||
}
|
||||
|
||||
function StepOnlyCardSection({
|
||||
title,
|
||||
description,
|
||||
cards,
|
||||
}: {
|
||||
title: string
|
||||
description?: string
|
||||
cards: readonly StepOnlyCard[]
|
||||
}) {
|
||||
return (
|
||||
<Section title={title} description={description}>
|
||||
<div className="card-grid">
|
||||
{cards.map((card) => (
|
||||
<article key={card.title} className="card">
|
||||
<h3>{card.title}</h3>
|
||||
<ul className="list top-gap">
|
||||
{(card.steps ?? card.bullets ?? []).map((step) => (
|
||||
<li key={step}>{step}</li>
|
||||
))}
|
||||
</ul>
|
||||
</article>
|
||||
))}
|
||||
</div>
|
||||
</Section>
|
||||
)
|
||||
}
|
||||
|
||||
function FaqCardSection({
|
||||
title,
|
||||
description,
|
||||
|
|
@ -208,58 +176,6 @@ function FaqCardSection({
|
|||
)
|
||||
}
|
||||
|
||||
function SupportTopicDirectorySection({
|
||||
title,
|
||||
description,
|
||||
topics,
|
||||
selectedTopicKey,
|
||||
}: {
|
||||
title: string
|
||||
description?: string
|
||||
topics: readonly SupportTopicCard[]
|
||||
selectedTopicKey?: string | null
|
||||
}) {
|
||||
return (
|
||||
<Section title={title} description={description}>
|
||||
<div className="card-grid">
|
||||
{topics.map((topic) => {
|
||||
const isSelected = selectedTopicKey === topic.topicKey
|
||||
|
||||
return (
|
||||
<article
|
||||
key={topic.topicKey}
|
||||
className={`card${isSelected ? ' card--selected' : ''}`}
|
||||
>
|
||||
{isSelected ? <p className="status-pill status-pill--info">Selected help lane</p> : null}
|
||||
<h3>{topic.title}</h3>
|
||||
<p>{topic.description}</p>
|
||||
<p className="eyebrow top-gap">Next steps</p>
|
||||
<ul className="list top-gap">
|
||||
{topic.steps.map((step) => (
|
||||
<li key={step}>{step}</li>
|
||||
))}
|
||||
</ul>
|
||||
<p className="eyebrow top-gap">Manual and route focus</p>
|
||||
<ul className="list top-gap">
|
||||
{topic.routeFocus.map((item) => (
|
||||
<li key={item}>{item}</li>
|
||||
))}
|
||||
</ul>
|
||||
<div className="button-row top-gap">
|
||||
{topic.actions.map((action) => (
|
||||
<Link key={`${topic.topicKey}-${action.label}`} className="button button--ghost" to={action.to}>
|
||||
{action.label}
|
||||
</Link>
|
||||
))}
|
||||
</div>
|
||||
</article>
|
||||
)
|
||||
})}
|
||||
</div>
|
||||
</Section>
|
||||
)
|
||||
}
|
||||
|
||||
export function HomeLanding() {
|
||||
const { releaseManifest, windowsValidationPlatform } = usePublicReleaseManifestView('public-home')
|
||||
|
||||
|
|
@ -402,6 +318,12 @@ export function HomeLanding() {
|
|||
</div>
|
||||
</Section>
|
||||
|
||||
<PublicManualRouteAtlasSection
|
||||
title="Which public page should you open next?"
|
||||
description="The public website is a real product surface, not one generic brochure page. This atlas keeps the strongest next manual routes visible from the homepage."
|
||||
limit={8}
|
||||
/>
|
||||
|
||||
<PublicPackagedDesktopProofSection
|
||||
platform={windowsValidationPlatform}
|
||||
actions={[
|
||||
|
|
@ -420,6 +342,10 @@ export function HomeLanding() {
|
|||
description="The homepage is part of the real release lane, so it keeps docs, release notes, source, notices, and operator support references bundled instead of scattering them behind later pages."
|
||||
/>
|
||||
|
||||
<BrowserAuthMethodsSection
|
||||
description="The homepage now also makes the current shared-auth sign-in lineup visible before operators commit to the protected dashboard, pricing, or desktop-release handoff."
|
||||
/>
|
||||
|
||||
<Section
|
||||
title="How a real first session flows"
|
||||
description="This is the public-facing operator path from curiosity into the actual simulator lane, without pretending the browser already replaced the desktop runtime."
|
||||
|
|
@ -698,6 +624,10 @@ export function ResourcesPage() {
|
|||
</div>
|
||||
</Section>
|
||||
|
||||
<PublicManualRouteAtlasSection
|
||||
description="The resource portal is stronger when it also explains what each public page is for, so teams can move from reference reading into the exact route that owns the next question."
|
||||
/>
|
||||
|
||||
<SurfaceChoiceGuideSection description="The resource portal is most useful when it also tells operators where to go next: stay public for references, move protected for release access, and move native for simulator execution." />
|
||||
|
||||
<BrowserDesktopRealitySection />
|
||||
|
|
@ -878,12 +808,9 @@ function GettingStartedPageContent({
|
|||
cards={operatorManualTracks}
|
||||
/>
|
||||
|
||||
<Section
|
||||
title="Browser account access methods"
|
||||
<BrowserAuthMethodsSection
|
||||
description="The onboarding path is easier to trust when the shared-auth provider lineup is visible before operators cross into the protected shell."
|
||||
>
|
||||
<BrowserAuthMethodsGuide />
|
||||
</Section>
|
||||
/>
|
||||
|
||||
<Section
|
||||
title="First launch and desktop setup"
|
||||
|
|
@ -990,78 +917,6 @@ export function GettingStartedPage() {
|
|||
)
|
||||
}
|
||||
|
||||
export function LaunchStatusPage() {
|
||||
const { releaseManifest, windowsValidationPlatform } = usePublicReleaseManifestView('public-launch-status')
|
||||
|
||||
return (
|
||||
<>
|
||||
<SiteMetadata
|
||||
title="HyperTwist launch status"
|
||||
description="Check the canonical HyperTwist public launch-readiness posture: checkout, download, notices, corresponding source, public auth runtime, and release authority."
|
||||
canonicalPath="/launch-status"
|
||||
/>
|
||||
<MarketingShell
|
||||
eyebrow="Launch authority"
|
||||
title="See exactly what still separates preview from public launch."
|
||||
lede="This is the canonical public authority surface for rollout truth: release targets, checkout posture, notices, corresponding source, and public auth-runtime readiness stay visible here in one place instead of being reconstructed from scattered callouts."
|
||||
>
|
||||
<Section
|
||||
title="Current public launch status"
|
||||
description="Use this page when rollout language, pricing, download, and legal/distribution follow-through need one authoritative browser-owned checklist."
|
||||
>
|
||||
<PublicLaunchStatus title="Current launch-readiness checklist" />
|
||||
</Section>
|
||||
|
||||
<StepOnlyCardSection
|
||||
title="What must be true before public launch"
|
||||
description="These are the bounded rollout checks that keep external launch language tied to real release authority instead of aspiration."
|
||||
cards={releaseRolloutChecklist}
|
||||
/>
|
||||
|
||||
<StepOnlyCardSection
|
||||
title="Launch hardening tracks"
|
||||
description="These are the practical work tracks for turning a truthful preview lane into a production-grade public release lane."
|
||||
cards={deploymentReadinessTracks}
|
||||
/>
|
||||
|
||||
<PublicPackagedDesktopProofSection
|
||||
platform={windowsValidationPlatform}
|
||||
actions={[
|
||||
{ to: '/download', label: 'Open download center' },
|
||||
{ to: '/getting-started', label: 'Open getting started' },
|
||||
]}
|
||||
/>
|
||||
|
||||
<SupportTopicDirectorySection
|
||||
title="Launch support and escalation lanes"
|
||||
description="Launch posture only helps when the next human lane is explicit too, so these support routes stay attached to the same authority surface."
|
||||
topics={supportTopicDirectory}
|
||||
selectedTopicKey="launch-readiness"
|
||||
/>
|
||||
|
||||
<PublicReleaseDecisionGuideSection
|
||||
releaseManifest={releaseManifest}
|
||||
title="Choose the next launch move"
|
||||
description="This page should not stop at checklist language. It should also say whether the next honest move is protected desktop access, pricing/provisioning, browser/account follow-through, or notices/source review."
|
||||
/>
|
||||
|
||||
<ReleaseAuthorityBundleSection
|
||||
releaseManifest={releaseManifest}
|
||||
title="Release, notice, and support bundle"
|
||||
description="Launch readiness is only trustworthy when docs, release notes, corresponding source, public notices, and operator contact remain visible as one release bundle."
|
||||
/>
|
||||
|
||||
<SurfaceChoiceGuideSection description="This keeps launch posture grounded in the real product topology too: public for launch truth, protected for account-aware release work, and native for the simulator itself." />
|
||||
|
||||
<BrowserDesktopRealitySection
|
||||
title="Why launch authority stays in the browser shell"
|
||||
description="Launch-readiness posture belongs to the distribution shell because checkout, notices, release references, and account access are browser-owned even while the actual training runtime remains native."
|
||||
/>
|
||||
</MarketingShell>
|
||||
</>
|
||||
)
|
||||
}
|
||||
|
||||
export function DocsPage() {
|
||||
const { releaseManifest, windowsValidationPlatform } = usePublicReleaseManifestView('public-docs')
|
||||
|
||||
|
|
@ -1079,6 +934,11 @@ export function DocsPage() {
|
|||
>
|
||||
<PrincipleCardSection title="Public documentation lanes" cards={publicDocumentationPrinciples} />
|
||||
|
||||
<PublicManualRouteAtlasSection
|
||||
title="Documentation and route atlas"
|
||||
description="The manual is easier to use when it also says which public route owns which question, so operators do not have to infer structure from navigation labels alone."
|
||||
/>
|
||||
|
||||
<BulletCardSection
|
||||
title="Current shipped capability"
|
||||
description="This section is the public manual's feature-registry-backed answer to the obvious question: what is actually live in HyperTwist today?"
|
||||
|
|
@ -1093,12 +953,9 @@ export function DocsPage() {
|
|||
|
||||
<OperatorDesktopQuickstartSection />
|
||||
|
||||
<Section
|
||||
title="Browser account access methods"
|
||||
<BrowserAuthMethodsSection
|
||||
description="The public manual now makes the current shared-auth lineup explicit too, so operators do not have to infer provider truth only from the sign-in form buttons."
|
||||
>
|
||||
<BrowserAuthMethodsGuide />
|
||||
</Section>
|
||||
/>
|
||||
|
||||
<StepCardSection
|
||||
title="Recovery and degraded-state manual"
|
||||
|
|
@ -1264,6 +1121,11 @@ export function SupportPage() {
|
|||
description="Support conversations move faster when docs, release notes, source, notices, and operator contact stay visible beside the launch and package evidence."
|
||||
/>
|
||||
|
||||
<BrowserAuthMethodsSection
|
||||
title="Current browser sign-in methods"
|
||||
description="Support and recovery lanes are easier to navigate when the actual shared-auth method lineup is visible next to the launch, package, and help surfaces."
|
||||
/>
|
||||
|
||||
<Section title="Contact">
|
||||
<article className="card">
|
||||
<p>
|
||||
|
|
|
|||
|
|
@ -1,3 +1,4 @@
|
|||
export * from './public-pages-marketing'
|
||||
export * from './public-pages-features'
|
||||
export * from './public-pages-commerce'
|
||||
export * from './public-pages-launch'
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@ const FeaturesPage = lazy(() => import('../pages/public-pages-features').then((m
|
|||
const AboutPage = lazy(() => import('../pages/public-pages-marketing').then((m) => ({ default: m.AboutPage })))
|
||||
const ResourcesPage = lazy(() => import('../pages/public-pages-marketing').then((m) => ({ default: m.ResourcesPage })))
|
||||
const GettingStartedPage = lazy(() => import('../pages/public-pages-marketing').then((m) => ({ default: m.GettingStartedPage })))
|
||||
const LaunchStatusPage = lazy(() => import('../pages/public-pages-marketing').then((m) => ({ default: m.LaunchStatusPage })))
|
||||
const LaunchStatusPage = lazy(() => import('../pages/public-pages-launch').then((m) => ({ default: m.LaunchStatusPage })))
|
||||
const DocsPage = lazy(() => import('../pages/public-pages-marketing').then((m) => ({ default: m.DocsPage })))
|
||||
const SupportPage = lazy(() => import('../pages/public-pages-marketing').then((m) => ({ default: m.SupportPage })))
|
||||
const ChangelogPage = lazy(() => import('../pages/public-pages-marketing').then((m) => ({ default: m.ChangelogPage })))
|
||||
|
|
|
|||
|
|
@ -100,6 +100,7 @@ export const browserDesktopRealityCards = [
|
|||
description: 'The browser lane is useful precisely because it does not pretend to replace the simulator.',
|
||||
bullets: [
|
||||
'It does not claim package-validated training behavior, higher-dimensional execution, or device/runtime integration authority.',
|
||||
'Low-latency simulator input, packaged runtime ownership, higher-dimensional scene execution, and any future serious controller/VR completion still remain desktop-owned.',
|
||||
'It keeps identity, billing, release, and legal-distribution work outside the native runtime where operators can review it more safely.',
|
||||
'It preserves a clean browser-to-desktop pairing boundary instead of collapsing access, rollout, and simulator execution into one brittle shell.',
|
||||
],
|
||||
|
|
@ -865,7 +866,165 @@ export const resourceCollections = [
|
|||
},
|
||||
] as const
|
||||
|
||||
export const publicManualRouteAtlasCards = [
|
||||
{
|
||||
title: 'Home',
|
||||
route: '/',
|
||||
description: 'Start here when you need the shortest truthful overview of the product, the browser-versus-desktop split, and the current release posture.',
|
||||
bullets: [
|
||||
'Summarizes what HyperTwist already ships today.',
|
||||
'Shows live public launch-readiness and packaged-proof context.',
|
||||
'Points operators toward getting started, pricing, download, and the protected dashboard without overclaiming browser parity.',
|
||||
],
|
||||
},
|
||||
{
|
||||
title: 'Feature atlas',
|
||||
route: '/features',
|
||||
description: 'Open this page when you need capability truth instead of pitch language.',
|
||||
bullets: [
|
||||
'Separates implemented now, retained, and frozen or gated branches.',
|
||||
'Maps public website, protected dashboard, embedded browser shell, native runtime, and optional browser-client scope.',
|
||||
'Surfaces higher-dimensional, control-roster, and release-maturity truth in one place.',
|
||||
],
|
||||
},
|
||||
{
|
||||
title: 'About',
|
||||
route: '/about',
|
||||
description: 'Use this route when you want the product rationale and the higher-dimensional seriousness explained in operator-grade language.',
|
||||
bullets: [
|
||||
'Frames why HyperTwist keeps both browser and desktop surfaces.',
|
||||
'Explains the real end-to-end session story instead of flattening the topology.',
|
||||
'Keeps current control, XR, and release-maturity truth attached to the narrative.',
|
||||
],
|
||||
},
|
||||
{
|
||||
title: 'Resources',
|
||||
route: '/resources',
|
||||
description: 'Use this route as the public reference portal once you are comparing rollout, simulator, and training surfaces more deliberately.',
|
||||
bullets: [
|
||||
'Aggregates public-safe operator playbooks, support lanes, simulator-use guidance, and higher-dimensional references.',
|
||||
'Links directly to the strongest route for each common public research task.',
|
||||
'Keeps release proof and reference-bundle follow-through attached to the portal.',
|
||||
],
|
||||
},
|
||||
{
|
||||
title: 'Getting started',
|
||||
route: '/getting-started',
|
||||
description: 'Open this route when you need the canonical first-session manual from browser access into the native runtime.',
|
||||
bullets: [
|
||||
'Explains access resolution, protected release handoff, desktop pairing, and first launch.',
|
||||
'Keeps simulator-use guidance and the current control or XR boundary on the same page.',
|
||||
'Acts as the shortest handoff-friendly onboarding surface on the public site.',
|
||||
],
|
||||
},
|
||||
{
|
||||
title: 'Launch status',
|
||||
route: '/launch-status',
|
||||
description: 'Use this route when rollout truth, blockers, or preview-versus-public posture need one canonical authority page.',
|
||||
bullets: [
|
||||
'Shows the current launch-readiness checklist and hardening tracks.',
|
||||
'Keeps packaged desktop proof and release references attached to rollout status.',
|
||||
'Connects launch blockers to the real next public or protected help lane.',
|
||||
],
|
||||
},
|
||||
{
|
||||
title: 'Docs',
|
||||
route: '/docs',
|
||||
description: 'Use this route as the public manual when you need the most complete product-safe explanation of current HyperTwist usage.',
|
||||
bullets: [
|
||||
'Collects the feature-backed manual, recovery guidance, simulator-use guide, and control roster.',
|
||||
'Explains browser-versus-desktop boundaries and degraded-state operation directly.',
|
||||
'Ends with the same release references, notices, and proof lanes needed for real rollout follow-through.',
|
||||
],
|
||||
},
|
||||
{
|
||||
title: 'Support',
|
||||
route: '/support',
|
||||
description: 'Open this route when an operator needs help choosing the correct recovery or escalation lane.',
|
||||
bullets: [
|
||||
'Separates launch, access, rollout, package, runtime, and compliance questions.',
|
||||
'Keeps current release posture and packaged proof visible beside the help lanes.',
|
||||
'Mirrors the same browser-versus-desktop split so support does not soften product truth.',
|
||||
],
|
||||
},
|
||||
{
|
||||
title: 'Pricing',
|
||||
route: '/pricing',
|
||||
description: 'Use this route when plan comparison or billing posture matters but the product topology still needs to stay honest.',
|
||||
bullets: [
|
||||
'Keeps plan language aligned with the desktop-first delivery model.',
|
||||
'Shows launch posture, package proof, and current auth-method lineup before checkout.',
|
||||
'Explains the path from browser entitlement into the protected release lane and native runtime.',
|
||||
],
|
||||
},
|
||||
{
|
||||
title: 'Download',
|
||||
route: '/download',
|
||||
description: 'Open this route when you need platform targets, release posture, and the desktop handoff explained without exposing raw entitlement URLs.',
|
||||
bullets: [
|
||||
'Shows supported targets, package proof, and release-manifest posture.',
|
||||
'Explains protected delivery, desktop-link pairing, and first native launch follow-through.',
|
||||
'Keeps notices, distribution doctrine, and release references attached to install decisions.',
|
||||
],
|
||||
},
|
||||
{
|
||||
title: 'Release notes',
|
||||
route: '/changelog',
|
||||
description: 'Use this route when you need the current shipping chronology in operator-facing language.',
|
||||
bullets: [
|
||||
'Separates browser-shell work, native runtime work, and distribution hardening.',
|
||||
'Keeps rollout checklist and packaged proof attached to the release feed.',
|
||||
'Makes recent manual, control-boundary, and launch-authority changes easier to audit.',
|
||||
],
|
||||
},
|
||||
{
|
||||
title: 'Open-source notices',
|
||||
route: '/open-source-notices',
|
||||
description: 'Open this route when legal-distribution and corresponding-source follow-through matter for downloadable builds.',
|
||||
bullets: [
|
||||
'Lists key public notices and the current corresponding-source posture.',
|
||||
'Keeps the legal lane tied to current release proof instead of abstract compliance prose.',
|
||||
'Connects notices work back to download, release notes, and launch-readiness context.',
|
||||
],
|
||||
},
|
||||
{
|
||||
title: 'Privacy',
|
||||
route: '/privacy',
|
||||
description: 'Use this route when browser-account data handling and the desktop-runtime boundary need to be read together.',
|
||||
bullets: [
|
||||
'Explains what belongs to browser identity, what belongs to the simulator, and what stays in support/compliance lanes.',
|
||||
'Keeps privacy wording grounded in the live product topology.',
|
||||
'Connects privacy concerns back to package proof, release references, and escalation guidance.',
|
||||
],
|
||||
},
|
||||
{
|
||||
title: 'Terms',
|
||||
route: '/terms',
|
||||
description: 'Open this route when you need the access model, protected-download boundary, and desktop delivery posture expressed as product terms.',
|
||||
bullets: [
|
||||
'Keeps access, simulator, and redistribution obligations separated clearly.',
|
||||
'Explains why the current browser shell does not equal simulator parity.',
|
||||
'Connects terms language back to package proof and notices follow-through.',
|
||||
],
|
||||
},
|
||||
{
|
||||
title: 'Shipping & payment',
|
||||
route: '/shipping-payment',
|
||||
description: 'Use this route when you need the digital-delivery model and payment posture explained operationally rather than cosmetically.',
|
||||
bullets: [
|
||||
'Clarifies that HyperTwist is digitally delivered through browser account and desktop-release surfaces.',
|
||||
'Explains the handoff from checkout posture into protected entitlement and native runtime delivery.',
|
||||
'Keeps payment language attached to package proof, notices, and desktop-first truth.',
|
||||
],
|
||||
},
|
||||
] as const
|
||||
|
||||
export const changelogEntries = [
|
||||
{
|
||||
date: 'June 28, 2026',
|
||||
title: 'Public pages now explain what each route is actually for',
|
||||
details: 'The homepage, docs, and resources routes now share a first-party public route atlas explaining what each major public page owns: product truth, onboarding, launch readiness, pricing, download, support, release notes, and the legal/distribution surfaces are now easier to navigate as one professional operator manual instead of a flatter marketing shell.',
|
||||
},
|
||||
{
|
||||
date: 'June 27, 2026',
|
||||
title: 'Protected launch status now has its own signed-in authority route',
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue