Harden auth authority and operator quickstart
This commit is contained in:
parent
ce389a97a7
commit
1a7bbfae92
12 changed files with 427 additions and 102 deletions
|
|
@ -115,6 +115,10 @@ That auth/server health surface now also reports:
|
|||
- whether the shared SuperTokens core is merely configured or actually reachable
|
||||
- the reported core API version when reachable
|
||||
- whether fallback posture is currently active and why
|
||||
- the signed-in auth method plus currently available provider lineup for the
|
||||
deployment
|
||||
- the current runtime origins and cookie/public-origin posture that still gate
|
||||
whether the protected browser lane should be read as fully production-ready
|
||||
|
||||
The protected dashboard now also has a first-party launch-readiness panel for:
|
||||
|
||||
|
|
@ -124,6 +128,17 @@ The protected dashboard now also has a first-party launch-readiness panel for:
|
|||
- backend webhook-secret and billing-map configuration posture
|
||||
- public auth runtime posture, cookie-hardening posture, and local-vs-public runtime diagnostics
|
||||
|
||||
The adjacent protected account route now also mirrors that same signed-in
|
||||
auth/session-authority truth instead of reducing the account lane to a thinner
|
||||
identity-and-billing shell than the main protected dashboard.
|
||||
|
||||
The homepage, docs, and download surfaces now also share a tighter reusable
|
||||
first-session operator quickstart, and the protected dashboard mirrors that
|
||||
same end-to-end path after sign-in, so release-target choice, desktop-link
|
||||
pairing, first native classic-cube verification, higher-dimensional
|
||||
verification, and the current XR/controller `No-Go` boundary are visible in
|
||||
one deliberate manual lane instead of being scattered across unrelated cards.
|
||||
|
||||
The public pricing, download, and notices routes now also mirror that same
|
||||
bounded launch-truth posture through first-party preview-versus-launch callouts
|
||||
so external-facing copy no longer depends on operators opening the protected
|
||||
|
|
|
|||
|
|
@ -1011,6 +1011,60 @@ Current audit note:
|
|||
- `scripts/run-hypertwist-gitnexus-analyze.sh`
|
||||
- `scripts/run-hypertwist-gitnexus-status.sh`
|
||||
|
||||
## Latest protected auth/session authority follow-up (`2026-06-27`)
|
||||
|
||||
- the next same-family protected-shell continuation then brought the signed-in
|
||||
account and dashboard lanes up to the same auth honesty now visible on the
|
||||
public docs and auth-entry surfaces:
|
||||
- the dashboard and account routes now share a fuller protected auth/session
|
||||
authority surface instead of collapsing signed-in identity down to one thin
|
||||
`Auth stack` line
|
||||
- signed-in operators can now see the current auth method, provider lineup,
|
||||
shared-auth readiness, runtime origins, cookie posture, fallback status,
|
||||
and deployment diagnostics directly inside the protected shell
|
||||
- this keeps protected account review, release access, and browser-to-desktop
|
||||
pairing closer to the real shared-auth/runtime authority instead of making
|
||||
the public docs more explicit than the signed-in shell itself
|
||||
- focused protected-surface validation for that continuation stayed green
|
||||
under:
|
||||
- `npm --prefix website test -- --run src/__tests__/DashboardOverviewPage.test.tsx src/__tests__/protected-app-pages.test.tsx src/__tests__/app-route-tree.test.tsx`
|
||||
- `3` test files passed
|
||||
- `22` tests passed
|
||||
- `npm --prefix website run type-check`
|
||||
|
||||
## Latest first-session public/protected manual follow-up (`2026-06-27`)
|
||||
|
||||
- the next same-family public/manual continuation then tightened the practical
|
||||
“how do I actually use HyperTwist end to end?” story instead of leaving that
|
||||
journey distributed across too many adjacent cards:
|
||||
- homepage, docs, and download now share a reusable first-session
|
||||
quickstart covering release-target choice, protected dashboard pairing,
|
||||
first classic-cube verification, higher-dimensional verification, and the
|
||||
explicit XR/controller `No-Go` boundary
|
||||
- the protected dashboard now mirrors that same quickstart after sign-in so
|
||||
account state, desktop-link pairing, first launch, and native-runtime
|
||||
boundary truth remain visible together inside the operator shell
|
||||
- this keeps the public manual professional without inventing browser
|
||||
simulator parity or widening the native XR branch
|
||||
- focused validation for that continuation stayed green under:
|
||||
- `npm --prefix website test -- --run src/__tests__/DashboardOverviewPage.test.tsx src/__tests__/public-marketing-pages.test.tsx`
|
||||
- `2` test files passed
|
||||
- `16` tests passed
|
||||
- `npm --prefix website run type-check`
|
||||
- the same-family umbrella and tooling gates then stayed green again under:
|
||||
- `scripts/run-hypertwist-web-surface-validation.sh`
|
||||
- website focused route/auth/release suite: `12` files, `68` 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-sentrux-source-only.sh`
|
||||
- `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 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
|
|
@ -71,6 +71,11 @@ manual:
|
|||
that same native control/settings roster after sign-in, so entitled users do
|
||||
not lose the current simulator-control truth when they move from the public
|
||||
manual into the operator shell
|
||||
- the homepage, docs, and download surfaces now also share a tighter first
|
||||
serious-session quickstart, and the protected dashboard mirrors that same
|
||||
end-to-end operator path after sign-in so access, pairing, first launch, and
|
||||
the current XR/controller boundary do not have to be reconstructed from
|
||||
scattered cards
|
||||
- the protected app shell now also carries richer operator-facing browser
|
||||
boundary, account, entitlement, and notices guidance instead of treating
|
||||
those routes as thin placeholders beside the main dashboard
|
||||
|
|
@ -230,6 +235,37 @@ Latest protected control-roster follow-up later on `2026-06-24`:
|
|||
- `41` test files passed
|
||||
- `168` tests passed
|
||||
|
||||
Latest first-session quickstart/manual follow-up on `2026-06-27`:
|
||||
|
||||
- the public and protected manual lane now explains the first real operator
|
||||
journey more directly instead of forcing users to stitch it together from
|
||||
several adjacent page sections:
|
||||
- homepage, docs, and download now share a reusable first-session
|
||||
quickstart covering release-target choice, protected pairing, first native
|
||||
classic-cube verification, higher-dimensional verification, and the
|
||||
explicit XR/controller `No-Go` boundary
|
||||
- the protected dashboard now mirrors that same first-session path after
|
||||
sign-in so browser account work, desktop-link pairing, first launch, and
|
||||
runtime-boundary truth remain visible together
|
||||
- focused validation for that continuation stayed green under:
|
||||
- `npm --prefix website test -- --run src/__tests__/DashboardOverviewPage.test.tsx src/__tests__/public-marketing-pages.test.tsx`
|
||||
- `2` test files passed
|
||||
- `16` tests passed
|
||||
- `npm --prefix website run type-check`
|
||||
- the same-family umbrella, structural, and analysis gates then stayed green
|
||||
again under:
|
||||
- `scripts/run-hypertwist-web-surface-validation.sh`
|
||||
- website focused route/auth/release suite: `12` files, `68` tests passed
|
||||
- website/server suite: `10` files, `36` tests passed
|
||||
- website and `Content/Browser` production audits: `found 0 vulnerabilities`
|
||||
- `scripts/run-hypertwist-sentrux-source-only.sh`
|
||||
- `Quality: 6217`
|
||||
- `All rules pass`
|
||||
- `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`
|
||||
|
||||
Current dependency-health truth from the `2026-06-23` hardening pass:
|
||||
|
||||
- `website/` production audit is clean
|
||||
|
|
|
|||
|
|
@ -184,6 +184,10 @@ describe('DashboardOverviewPage', () => {
|
|||
|
||||
expect(screen.getByText(/This session is currently using local fallback posture/i)).toBeTruthy()
|
||||
expect(screen.getByText(/Shared auth core is not fully ready right now/i)).toBeTruthy()
|
||||
expect(screen.getByText('Auth and session authority')).toBeTruthy()
|
||||
expect(screen.getByText('Signed-in method: Email and password')).toBeTruthy()
|
||||
expect(screen.getByText('Available provider routes: Email/password on, GitHub off, Google off, ORCID off')).toBeTruthy()
|
||||
expect(screen.getByText('API domain: http://localhost:3001')).toBeTruthy()
|
||||
expect(screen.getByText('What stays intentionally bounded')).toBeTruthy()
|
||||
expect(screen.getByText('Recommended recovery order')).toBeTruthy()
|
||||
expect(screen.getByText(/Public launch is not fully configured yet:/i)).toBeTruthy()
|
||||
|
|
@ -199,11 +203,14 @@ describe('DashboardOverviewPage', () => {
|
|||
expect(screen.getByText('Protected browser-versus-desktop reality')).toBeTruthy()
|
||||
expect(screen.getByText('Current input, XR, and settings truth')).toBeTruthy()
|
||||
expect(screen.getByRole('link', { name: 'Open account' }).getAttribute('href')).toBe('/app/account')
|
||||
expect(screen.getByRole('link', { name: 'Open browser access' }).getAttribute('href')).toBe('/app/browser-access')
|
||||
expect(screen.getAllByRole('link', { name: 'Open browser access' }).every((link) => link.getAttribute('href') === '/app/browser-access')).toBe(true)
|
||||
expect(screen.getAllByRole('link', { name: 'Open notices' }).length).toBeGreaterThan(0)
|
||||
expect(screen.getByText('Current packaged desktop proof')).toBeTruthy()
|
||||
expect(screen.getByText('Packaged validation passed')).toBeTruthy()
|
||||
expect(screen.getByText(/Magic120Cell dedicated-family training map: passed/i)).toBeTruthy()
|
||||
expect(screen.getByText('First simulator session')).toBeTruthy()
|
||||
expect(screen.getByText('1. Resolve access and choose the right build')).toBeTruthy()
|
||||
expect(screen.getByText('4. Open the higher-dimensional lanes and read the control boundary honestly')).toBeTruthy()
|
||||
expect(screen.getByText('Native control and settings roster')).toBeTruthy()
|
||||
expect(screen.getAllByText(/classic-wca-keyboard\/v1/i).length).toBeGreaterThan(0)
|
||||
expect(screen.getByText('XR groundwork exists, but the full VR lane is not finished')).toBeTruthy()
|
||||
|
|
|
|||
|
|
@ -237,6 +237,10 @@ describe('protected app pages', () => {
|
|||
renderPage(<AccountPage />, '/app/account')
|
||||
|
||||
expect(await screen.findByText('Session profile')).toBeTruthy()
|
||||
expect(screen.getByText('Auth and session authority')).toBeTruthy()
|
||||
expect(await screen.findByText(byExactTextContent('Signed-in method: Email and password', 'LI'))).toBeTruthy()
|
||||
expect(await screen.findByText(byExactTextContent('Available provider routes: Email/password on, GitHub off, Google off, ORCID off', 'LI'))).toBeTruthy()
|
||||
expect(await screen.findByText(byExactTextContent('API domain: https://hypertwist.app', 'LI'))).toBeTruthy()
|
||||
expect(await screen.findByRole('link', { name: 'Download Windows package' })).toBeTruthy()
|
||||
expect(screen.getByText('Current packaged desktop proof')).toBeTruthy()
|
||||
expect(screen.getByText('Packaged validation passed')).toBeTruthy()
|
||||
|
|
|
|||
|
|
@ -275,6 +275,8 @@ describe('public marketing pages', () => {
|
|||
expect(within(downloadDecisionGuideSection as HTMLElement).getByText('Need the protected desktop-download lane?')).toBeTruthy()
|
||||
expect(within(downloadDecisionGuideSection as HTMLElement).getByText('Need notices, corresponding source, or release follow-through?')).toBeTruthy()
|
||||
expect(screen.getByText('First launch and desktop setup')).toBeTruthy()
|
||||
expect(screen.getByText('First desktop session after install')).toBeTruthy()
|
||||
expect(screen.getByText('2. Pair the installed runtime without password reuse')).toBeTruthy()
|
||||
expect(screen.getByText('Digital delivery workflow')).toBeTruthy()
|
||||
expect(screen.getByText('Protected entitlement handoff')).toBeTruthy()
|
||||
expect(screen.getByText('Distribution doctrine')).toBeTruthy()
|
||||
|
|
@ -455,6 +457,8 @@ describe('public marketing pages', () => {
|
|||
expect(screen.getByText('Release references and source availability')).toBeTruthy()
|
||||
expect(screen.getByRole('link', { name: 'https://docs.hypertwist.app' })).toBeTruthy()
|
||||
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('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)
|
||||
|
|
@ -1261,6 +1265,7 @@ describe('public marketing pages', () => {
|
|||
expect(screen.getByText('Current shipped capability')).toBeTruthy()
|
||||
expect(screen.getByText('Native training and coaching core')).toBeTruthy()
|
||||
expect(screen.getByText('Operator manual')).toBeTruthy()
|
||||
expect(screen.getByText('First real desktop session')).toBeTruthy()
|
||||
expect(screen.getByText('Recovery and degraded-state manual')).toBeTruthy()
|
||||
expect(screen.getByText('Support topic quick routes')).toBeTruthy()
|
||||
expect(screen.getAllByText('Current surface authority map').length).toBeGreaterThan(0)
|
||||
|
|
@ -1278,6 +1283,7 @@ describe('public marketing pages', () => {
|
|||
expect(screen.getAllByText('Selectable control and settings roster').length).toBeGreaterThan(0)
|
||||
expect(screen.getAllByText('Keyboard and mouse ship today').length).toBeGreaterThan(0)
|
||||
expect(screen.getAllByText(/classic-wca-keyboard\/v1/i).length).toBeGreaterThan(0)
|
||||
expect(screen.getByText('4. Open the higher-dimensional lanes and read the control boundary honestly')).toBeTruthy()
|
||||
expect(screen.getByText(/I\/K = R\/R', J\/F = U\/U', H\/G = F\/F'/i)).toBeTruthy()
|
||||
expect(screen.getByText(/OpenXR plugin disabled/i)).toBeTruthy()
|
||||
expect(screen.getByText(/R scramble, H hint, Enter submit, F mode, V hold-to-talk, C cycle voice/i)).toBeTruthy()
|
||||
|
|
|
|||
|
|
@ -23,6 +23,7 @@ import {
|
|||
desktopDownloadSteps,
|
||||
desktopFirstLaunchCards,
|
||||
inputAndDevicePostureCards,
|
||||
operatorDesktopQuickstartCards,
|
||||
productSurfaceMatrixRows,
|
||||
roadmapHonestyCards,
|
||||
supportEscalationCards,
|
||||
|
|
@ -152,6 +153,144 @@ function isUnauthorizedAuthApiError(error: unknown) {
|
|||
&& Number((error as { status?: number }).status) === 401
|
||||
}
|
||||
|
||||
function formatAuthMethodLabel(method: PlatformUser['authMethod'] | undefined) {
|
||||
switch (method) {
|
||||
case 'email':
|
||||
return 'Email and password'
|
||||
case 'github':
|
||||
return 'GitHub'
|
||||
case 'google':
|
||||
return 'Google'
|
||||
case 'orcid':
|
||||
return 'ORCID'
|
||||
case 'supertokens':
|
||||
return 'Shared SuperTokens session'
|
||||
default:
|
||||
return 'Unknown'
|
||||
}
|
||||
}
|
||||
|
||||
function ProtectedAuthSessionAuthorityPanel({
|
||||
title,
|
||||
kicker,
|
||||
user,
|
||||
superTokensConfigured,
|
||||
healthQuery,
|
||||
}: {
|
||||
title: string
|
||||
kicker: string
|
||||
user: PlatformUser | null | undefined
|
||||
superTokensConfigured: boolean
|
||||
healthQuery: ReturnType<typeof useProtectedAuthHealthQuery>
|
||||
}) {
|
||||
return (
|
||||
<Panel title={title} kicker={kicker}>
|
||||
<ul className="list">
|
||||
<li>Signed-in method: {formatAuthMethodLabel(user?.authMethod)}</li>
|
||||
<li>Auth stack: {superTokensConfigured ? 'SuperTokens-backed' : 'Local fallback mode'}</li>
|
||||
{healthQuery.data ? (
|
||||
<>
|
||||
<li>Shared auth configured: {healthQuery.data.supertokens.configured ? 'yes' : 'no'}</li>
|
||||
<li>Shared auth core reachable: {healthQuery.data.supertokens.reachable ? 'yes' : 'no'}</li>
|
||||
<li>Shared auth ready: {healthQuery.data.supertokens.ready ? 'yes' : 'no'}</li>
|
||||
<li>Core API version: {healthQuery.data.supertokens.apiVersion || 'unavailable'}</li>
|
||||
<li>
|
||||
Available provider routes: Email/password on, GitHub {healthQuery.data.supertokens.oauth?.github ? 'on' : 'off'}, Google {healthQuery.data.supertokens.oauth?.google ? 'on' : 'off'}, ORCID {healthQuery.data.supertokens.oauth?.orcid ? 'on' : 'off'}
|
||||
</li>
|
||||
<li>
|
||||
Fallback posture: {healthQuery.data.fallback.active
|
||||
? `active${healthQuery.data.fallback.reason ? ` (${healthQuery.data.fallback.reason})` : ''}`
|
||||
: 'inactive'}
|
||||
</li>
|
||||
<li>Runtime mode: {healthQuery.data.runtime.mode}</li>
|
||||
<li>API domain: {healthQuery.data.runtime.api_domain}</li>
|
||||
<li>Website domain: {healthQuery.data.runtime.website_domain}</li>
|
||||
<li>Cookie secure: {healthQuery.data.runtime.cookie_secure ? 'yes' : 'no'}</li>
|
||||
<li>Public auth origin ready: {healthQuery.data.runtime.public_origin_ready ? 'yes' : 'no'}</li>
|
||||
</>
|
||||
) : null}
|
||||
</ul>
|
||||
{healthQuery.isLoading ? <p>Checking auth server health...</p> : null}
|
||||
{healthQuery.isError ? (
|
||||
<OperationalStatusCallout
|
||||
badge="Auth probe degraded"
|
||||
title="Auth health probe failed."
|
||||
summary="The local fallback can still keep the protected browser shell usable."
|
||||
sections={[
|
||||
{
|
||||
title: 'What still works',
|
||||
items: [
|
||||
'Local session, packaged proof, and browser-to-desktop rollout guidance remain visible.',
|
||||
'Protected dashboard orientation and support escalation surfaces remain available.',
|
||||
],
|
||||
},
|
||||
{
|
||||
title: 'What stays intentionally bounded',
|
||||
items: [
|
||||
'Do not treat browser auth as shared production authority until the live auth probe recovers.',
|
||||
],
|
||||
},
|
||||
{
|
||||
title: 'Recommended recovery order',
|
||||
items: [
|
||||
'Restore shared auth reachability before trusting live entitlement or desktop-link issuance.',
|
||||
'Use operator support if the protected dashboard stays in degraded auth posture.',
|
||||
],
|
||||
},
|
||||
]}
|
||||
/>
|
||||
) : null}
|
||||
{healthQuery.data?.fallback.active ? (
|
||||
<OperationalStatusCallout
|
||||
badge="Dashboard fallback posture"
|
||||
title="Shared auth core is not fully ready right now."
|
||||
summary={`Dashboard fallback posture remains available${healthQuery.data.fallback.reason ? ` (${healthQuery.data.fallback.reason})` : ''}.`}
|
||||
sections={[
|
||||
{
|
||||
title: 'What still works',
|
||||
items: [
|
||||
'Bounded session continuity, packaged proof, and operator guidance remain usable inside the protected dashboard.',
|
||||
'Account, release, and desktop-pairing surfaces can still be reviewed without claiming live shared-auth authority.',
|
||||
],
|
||||
},
|
||||
{
|
||||
title: 'What stays intentionally bounded',
|
||||
items: [
|
||||
'Live entitlement proof, shared-production session authority, and rollout trust should wait for the auth core to recover.',
|
||||
],
|
||||
},
|
||||
{
|
||||
title: 'Recommended recovery order',
|
||||
items: [
|
||||
'Clear auth-core readiness problems first, then re-check release authority and desktop-link issuance.',
|
||||
],
|
||||
},
|
||||
]}
|
||||
/>
|
||||
) : null}
|
||||
{healthQuery.data && (healthQuery.data.runtime.errors.length > 0 || healthQuery.data.runtime.warnings.length > 0) ? (
|
||||
<div className="callout">
|
||||
<p>Runtime deployment diagnostics</p>
|
||||
{healthQuery.data.runtime.errors.length > 0 ? (
|
||||
<ul className="list">
|
||||
{healthQuery.data.runtime.errors.map((item) => (
|
||||
<li key={item}>Error: {item}</li>
|
||||
))}
|
||||
</ul>
|
||||
) : null}
|
||||
{healthQuery.data.runtime.warnings.length > 0 ? (
|
||||
<ul className="list">
|
||||
{healthQuery.data.runtime.warnings.map((item) => (
|
||||
<li key={item}>Warning: {item}</li>
|
||||
))}
|
||||
</ul>
|
||||
) : null}
|
||||
</div>
|
||||
) : null}
|
||||
</Panel>
|
||||
)
|
||||
}
|
||||
|
||||
function ReleaseAuthorityLinks({
|
||||
releaseManifest,
|
||||
includePublicNoticesLink = false,
|
||||
|
|
@ -661,6 +800,46 @@ function DesktopFirstLaunchChecklist({ title, kicker }: { title: string; kicker:
|
|||
)
|
||||
}
|
||||
|
||||
function OperatorDesktopQuickstartPanel({
|
||||
title,
|
||||
kicker,
|
||||
description,
|
||||
}: {
|
||||
title: string
|
||||
kicker: string
|
||||
description: string
|
||||
}) {
|
||||
return (
|
||||
<Panel title={title} kicker={kicker}>
|
||||
<p>{description}</p>
|
||||
<div className="card-grid top-gap">
|
||||
{operatorDesktopQuickstartCards.map((card) => (
|
||||
<article key={card.title} className="card card--compact">
|
||||
<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>
|
||||
<div className="button-row top-gap">
|
||||
<Link className="button button--ghost" to="/app/downloads">
|
||||
Open downloads
|
||||
</Link>
|
||||
<Link className="button button--ghost" to="/app/browser-access">
|
||||
Open browser access
|
||||
</Link>
|
||||
<Link className="button button--ghost" to="/docs">
|
||||
Open public manual
|
||||
</Link>
|
||||
</div>
|
||||
</Panel>
|
||||
)
|
||||
}
|
||||
|
||||
function SupportEscalationChecklist({
|
||||
title,
|
||||
kicker,
|
||||
|
|
@ -897,9 +1076,9 @@ export function DashboardOverviewPage() {
|
|||
<p className="form-error">
|
||||
This session is currently using local fallback posture, not fully shared production auth.
|
||||
</p>
|
||||
) : null}
|
||||
{releaseManifestQuery.data?.manifest && releaseAuthoritySyncItems.length > 0 ? (
|
||||
<div className="callout top-gap">
|
||||
) : null}
|
||||
{releaseManifestQuery.data?.manifest && releaseAuthoritySyncItems.length > 0 ? (
|
||||
<div className="callout top-gap">
|
||||
<p className="status-pill status-pill--info">Live authority sync</p>
|
||||
<p>
|
||||
The protected browser session was refreshed from live release authority so the local dashboard view catches up to current account-access truth.
|
||||
|
|
@ -913,100 +1092,13 @@ export function DashboardOverviewPage() {
|
|||
) : null}
|
||||
</Panel>
|
||||
|
||||
<Panel title="Auth and server health" kicker="Browser shell">
|
||||
{healthQuery.isLoading ? <p>Checking auth server health...</p> : null}
|
||||
{healthQuery.isError ? (
|
||||
<OperationalStatusCallout
|
||||
badge="Auth probe degraded"
|
||||
title="Auth health probe failed."
|
||||
summary="The local fallback can still keep the dashboard usable."
|
||||
sections={[
|
||||
{
|
||||
title: 'What still works',
|
||||
items: [
|
||||
'Local session, packaged proof, and browser-to-desktop rollout guidance remain visible.',
|
||||
'Protected dashboard orientation and support escalation surfaces remain available.',
|
||||
],
|
||||
},
|
||||
{
|
||||
title: 'What stays intentionally bounded',
|
||||
items: [
|
||||
'Do not treat browser auth as shared production authority until the live auth probe recovers.',
|
||||
],
|
||||
},
|
||||
{
|
||||
title: 'Recommended recovery order',
|
||||
items: [
|
||||
'Restore shared auth reachability before trusting live entitlement or desktop-link issuance.',
|
||||
'Use operator support if the protected dashboard stays in degraded auth posture.',
|
||||
],
|
||||
},
|
||||
]}
|
||||
/>
|
||||
) : null}
|
||||
{healthQuery.data ? (
|
||||
<ul className="list">
|
||||
<li>Service: {healthQuery.data.service}</li>
|
||||
<li>SuperTokens configured: {healthQuery.data.supertokens.configured ? 'yes' : 'no'}</li>
|
||||
<li>SuperTokens core reachable: {healthQuery.data.supertokens.reachable ? 'yes' : 'no'}</li>
|
||||
<li>SuperTokens ready: {healthQuery.data.supertokens.ready ? 'yes' : 'no'}</li>
|
||||
<li>Fallback enabled: {healthQuery.data.fallback.enabled ? 'yes' : 'no'}</li>
|
||||
<li>Fallback active: {healthQuery.data.fallback.active ? 'yes' : 'no'}</li>
|
||||
<li>Core API version: {healthQuery.data.supertokens.apiVersion || 'unavailable'}</li>
|
||||
<li>OAuth routes: GitHub {healthQuery.data.supertokens.oauth?.github ? 'on' : 'off'}, Google {healthQuery.data.supertokens.oauth?.google ? 'on' : 'off'}, ORCID {healthQuery.data.supertokens.oauth?.orcid ? 'on' : 'off'}</li>
|
||||
<li>Runtime mode: {healthQuery.data.runtime.mode}</li>
|
||||
<li>Cookie secure: {healthQuery.data.runtime.cookie_secure ? 'yes' : 'no'}</li>
|
||||
<li>Public auth origin ready: {healthQuery.data.runtime.public_origin_ready ? 'yes' : 'no'}</li>
|
||||
</ul>
|
||||
) : null}
|
||||
{healthQuery.data?.fallback.active ? (
|
||||
<OperationalStatusCallout
|
||||
badge="Dashboard fallback posture"
|
||||
title="Shared auth core is not fully ready right now."
|
||||
summary={`Dashboard fallback posture remains available${healthQuery.data.fallback.reason ? ` (${healthQuery.data.fallback.reason})` : ''}.`}
|
||||
sections={[
|
||||
{
|
||||
title: 'What still works',
|
||||
items: [
|
||||
'Bounded session continuity, packaged proof, and operator guidance remain usable inside the protected dashboard.',
|
||||
'Account, release, and desktop-pairing surfaces can still be reviewed without claiming live shared-auth authority.',
|
||||
],
|
||||
},
|
||||
{
|
||||
title: 'What stays intentionally bounded',
|
||||
items: [
|
||||
'Live entitlement proof, shared-production session authority, and rollout trust should wait for the auth core to recover.',
|
||||
],
|
||||
},
|
||||
{
|
||||
title: 'Recommended recovery order',
|
||||
items: [
|
||||
'Clear auth-core readiness problems first, then re-check release authority and desktop-link issuance.',
|
||||
],
|
||||
},
|
||||
]}
|
||||
/>
|
||||
) : null}
|
||||
{healthQuery.data && (healthQuery.data.runtime.errors.length > 0 || healthQuery.data.runtime.warnings.length > 0) ? (
|
||||
<div className="callout">
|
||||
<p>Runtime deployment diagnostics</p>
|
||||
{healthQuery.data.runtime.errors.length > 0 ? (
|
||||
<ul className="list">
|
||||
{healthQuery.data.runtime.errors.map((item) => (
|
||||
<li key={item}>Error: {item}</li>
|
||||
))}
|
||||
</ul>
|
||||
) : null}
|
||||
{healthQuery.data.runtime.warnings.length > 0 ? (
|
||||
<ul className="list">
|
||||
{healthQuery.data.runtime.warnings.map((item) => (
|
||||
<li key={item}>Warning: {item}</li>
|
||||
))}
|
||||
</ul>
|
||||
) : null}
|
||||
</div>
|
||||
) : null}
|
||||
</Panel>
|
||||
<ProtectedAuthSessionAuthorityPanel
|
||||
title="Auth and session authority"
|
||||
kicker="Browser shell"
|
||||
user={user}
|
||||
superTokensConfigured={superTokensConfigured}
|
||||
healthQuery={healthQuery}
|
||||
/>
|
||||
|
||||
<Panel title="Desktop-link pairing" kicker="Browser to desktop handoff">
|
||||
<p>Generate a short-lived token so the local desktop runtime can verify your browser session without exposing account credentials.</p>
|
||||
|
|
@ -1030,6 +1122,12 @@ export function DashboardOverviewPage() {
|
|||
) : null}
|
||||
</Panel>
|
||||
|
||||
<OperatorDesktopQuickstartPanel
|
||||
title="First simulator session"
|
||||
kicker="End-to-end operator manual"
|
||||
description="The protected dashboard now also condenses the real operator journey into one place so account state, desktop-link pairing, first launch, native training verification, and the current XR/controller boundary can be reviewed together instead of reconstructed from scattered cards."
|
||||
/>
|
||||
|
||||
<Panel title="Billing and entitlement state" kicker="Release access">
|
||||
<ul className="list">
|
||||
<li>Source: {user?.billing?.source || 'session'}</li>
|
||||
|
|
@ -1478,6 +1576,7 @@ export function AccountPage() {
|
|||
releaseManifest,
|
||||
releaseManifestQuery,
|
||||
} = useProtectedReleaseSurface('account')
|
||||
const healthQuery = useProtectedAuthHealthQuery('account')
|
||||
const configuredPlatforms = useMemo(
|
||||
() => releaseManifest.platforms.filter((platform) => platform.configured),
|
||||
[releaseManifest.platforms],
|
||||
|
|
@ -1501,7 +1600,6 @@ export function AccountPage() {
|
|||
<li>Desktop downloads: {user?.canDownload ? 'enabled' : 'not yet entitled'}</li>
|
||||
<li>Billing status: {user?.billing?.accessStatus || 'session-default'}</li>
|
||||
<li>Billing source: {user?.billing?.source || 'session'}</li>
|
||||
<li>Auth stack: {superTokensConfigured ? 'SuperTokens-backed' : 'Local fallback mode'}</li>
|
||||
</ul>
|
||||
{releaseManifestQuery.data?.manifest && releaseAuthoritySyncItems.length > 0 ? (
|
||||
<div className="callout top-gap">
|
||||
|
|
@ -1517,6 +1615,13 @@ export function AccountPage() {
|
|||
</div>
|
||||
) : null}
|
||||
</Panel>
|
||||
<ProtectedAuthSessionAuthorityPanel
|
||||
title="Auth and session authority"
|
||||
kicker="Protected browser identity"
|
||||
user={user}
|
||||
superTokensConfigured={superTokensConfigured}
|
||||
healthQuery={healthQuery}
|
||||
/>
|
||||
<Panel title="Entitlement and release access" kicker="Protected release lane">
|
||||
{releaseManifestQuery.isLoading ? <p>Refreshing release-access posture from the live manifest...</p> : null}
|
||||
{releaseManifestQuery.isError ? (
|
||||
|
|
|
|||
|
|
@ -15,7 +15,11 @@ import {
|
|||
publicDocsUrl,
|
||||
releaseNotesUrl,
|
||||
} from '../site-config'
|
||||
import { browserDesktopRealityCards, deliverySurfaceCards } from '../site-data'
|
||||
import {
|
||||
browserDesktopRealityCards,
|
||||
deliverySurfaceCards,
|
||||
operatorDesktopQuickstartCards,
|
||||
} from '../site-data'
|
||||
import {
|
||||
buildLoginPath,
|
||||
buildProtectedDownloadPath,
|
||||
|
|
@ -296,6 +300,43 @@ export function SurfaceChoiceGuideSection({
|
|||
)
|
||||
}
|
||||
|
||||
export function OperatorDesktopQuickstartSection({
|
||||
title = 'First real desktop session',
|
||||
description = 'This is the shortest honest path from browser discovery into the native simulator: resolve access, pair the installed runtime safely, verify the first training lane, and keep the current XR/controller boundary visible.',
|
||||
}: {
|
||||
title?: string
|
||||
description?: string
|
||||
}) {
|
||||
return (
|
||||
<Section title={title} description={description}>
|
||||
<div className="card-grid">
|
||||
{operatorDesktopQuickstartCards.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>
|
||||
<div className="button-row top-gap">
|
||||
<Link className="button button--ghost" to="/download">
|
||||
Open download center
|
||||
</Link>
|
||||
<Link className="button button--ghost" to="/app">
|
||||
Open operator dashboard
|
||||
</Link>
|
||||
<Link className="button button--ghost" to="/docs">
|
||||
Open public manual
|
||||
</Link>
|
||||
</div>
|
||||
</Section>
|
||||
)
|
||||
}
|
||||
|
||||
export function PublicPackagedDesktopProofSection({
|
||||
platform,
|
||||
actions = [],
|
||||
|
|
|
|||
|
|
@ -27,6 +27,7 @@ import {
|
|||
BrowserDesktopRealitySection,
|
||||
DeliverySurfaceResponsibilitiesGrid,
|
||||
explorerFallbackPlan,
|
||||
OperatorDesktopQuickstartSection,
|
||||
operatorFallbackPlan,
|
||||
PlanActionLink,
|
||||
PublicPackagedDesktopProofSection,
|
||||
|
|
@ -327,6 +328,8 @@ export function DownloadPage() {
|
|||
</div>
|
||||
</Section>
|
||||
|
||||
<OperatorDesktopQuickstartSection title="First desktop session after install" />
|
||||
|
||||
<Section title="Release posture">
|
||||
<PublicLaunchStatus title="Desktop release access stays launch-honest" />
|
||||
</Section>
|
||||
|
|
|
|||
|
|
@ -37,6 +37,7 @@ import {
|
|||
import {
|
||||
BrowserDesktopRealitySection,
|
||||
DeliverySurfaceResponsibilitiesGrid,
|
||||
OperatorDesktopQuickstartSection,
|
||||
PublicPackagedDesktopProofSection,
|
||||
PublicReleaseDecisionGuideSection,
|
||||
ReleaseAuthorityBundleSection,
|
||||
|
|
@ -433,6 +434,8 @@ export function HomeLanding() {
|
|||
</div>
|
||||
</Section>
|
||||
|
||||
<OperatorDesktopQuickstartSection title="What the first serious session should look like" />
|
||||
|
||||
<SurfaceChoiceGuideSection description="This is the shortest practical answer to the browser-versus-desktop question: stay public for release-safe context, move protected for account-aware release work, and move native for the actual simulator." />
|
||||
|
||||
<Section
|
||||
|
|
@ -872,6 +875,8 @@ export function DocsPage() {
|
|||
cards={operatorManualTracks}
|
||||
/>
|
||||
|
||||
<OperatorDesktopQuickstartSection />
|
||||
|
||||
<Section
|
||||
title="Browser account access methods"
|
||||
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."
|
||||
|
|
|
|||
|
|
@ -349,6 +349,45 @@ export const operatorManualTracks = [
|
|||
},
|
||||
] as const
|
||||
|
||||
export const operatorDesktopQuickstartCards = [
|
||||
{
|
||||
title: '1. Resolve access and choose the right build',
|
||||
description: 'The browser shell should settle identity, entitlement, release posture, and target platform before the simulator ever launches.',
|
||||
bullets: [
|
||||
'Use the public download surface to choose the target platform and review package proof before install.',
|
||||
'Preserve that target through sign-in and confirm protected download entitlement in the dashboard.',
|
||||
'Treat launch posture, release notes, and notices as part of the install decision rather than as later paperwork.',
|
||||
],
|
||||
},
|
||||
{
|
||||
title: '2. Pair the installed runtime without password reuse',
|
||||
description: 'HyperTwist keeps browser identity narrow and hands it to the desktop app through a bounded desktop-link token.',
|
||||
bullets: [
|
||||
'Generate a desktop-link token from the protected dashboard after sign-in succeeds.',
|
||||
'Use the token during first launch so the installed runtime inherits the correct account and release posture.',
|
||||
'Return to the browser shell later when account, plan, or release state changes.',
|
||||
],
|
||||
},
|
||||
{
|
||||
title: '3. Verify the first native training lane',
|
||||
description: 'The first serious simulator check should confirm classic-cube execution, replay, coaching, and the shipped control roster.',
|
||||
bullets: [
|
||||
'Open the classic-cube lane and confirm timing, replay, guidance, and desktop HUD behavior.',
|
||||
'Use the shipped classic profile `classic-wca-keyboard/v1` together with click, touch, orbit, zoom, hint, and hold-to-talk behavior.',
|
||||
'Treat the public and protected browser shell as coordination surfaces around this runtime, not as substitutes for it.',
|
||||
],
|
||||
},
|
||||
{
|
||||
title: '4. Open the higher-dimensional lanes and read the control boundary honestly',
|
||||
description: 'The native desktop runtime already owns real 120-cell and 5D execution, but it still keeps XR/controller widening behind an explicit boundary.',
|
||||
bullets: [
|
||||
'Launch the dedicated `Magic120Cell` and `MagicCube5D` training maps from the packaged runtime.',
|
||||
'Use the current projection, focus, visibility, selector, and persisted selector-recall ownership as the current first-party posture.',
|
||||
'Do not mistake project-level controller groundwork for a finished OpenXR or headset or rebinding product lane; that branch remains explicit No-Go today.',
|
||||
],
|
||||
},
|
||||
] as const
|
||||
|
||||
export const degradedStateRecoveryTracks = [
|
||||
{
|
||||
title: 'Browser auth degraded or mixed',
|
||||
|
|
@ -824,6 +863,16 @@ export const resourceCollections = [
|
|||
] as const
|
||||
|
||||
export const changelogEntries = [
|
||||
{
|
||||
date: 'June 27, 2026',
|
||||
title: 'Public and protected manuals now show the first real desktop-session path more directly',
|
||||
details: 'Homepage, docs, download, and the protected dashboard now share a tighter operator quickstart explaining the real end-to-end journey: choose the release target, pair the installed runtime through the desktop-link token, verify the first classic-cube session, open the higher-dimensional families, and read the current XR/controller No-Go boundary honestly.',
|
||||
},
|
||||
{
|
||||
date: 'June 27, 2026',
|
||||
title: 'Protected dashboard and account routes now surface signed-in auth authority more explicitly',
|
||||
details: 'The protected dashboard and account lanes now carry a fuller auth/session-authority surface instead of reducing signed-in browser identity to a thin auth-stack label. Operators can now see the signed-in method, current provider lineup, shared auth readiness, runtime origins, fallback posture, and deployment diagnostics directly inside the protected shell.',
|
||||
},
|
||||
{
|
||||
date: 'June 27, 2026',
|
||||
title: 'Shared browser auth now exposes real provider parity and public-manual account guidance',
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue