Add shared product surface authority matrix

This commit is contained in:
axiomlogicnexus 2026-06-24 02:19:26 +00:00
parent 922c7f2319
commit ee7b525393
15 changed files with 381 additions and 63 deletions

View file

@ -246,6 +246,45 @@ Latest authority-sync follow-up later on `2026-06-23`:
- XR groundwork exists, but finished XR/preferences ownership is still a
later native packet
Latest same-family public-manual follow-up on `2026-06-24`:
- the public and protected manual no longer make readers reconstruct product
topology from separate card grids alone
- a new shared product-surface authority matrix now keeps five distinct
surfaces visible across the homepage, feature atlas, public docs, and the
protected dashboard:
- public website
- protected browser dashboard
- embedded simulator browser shell
- native Unreal desktop runtime
- optional full-browser simulator branch
- that matrix now makes two easy-to-confuse truths materially clearer:
- the public website and the embedded browser shell are not the same thing
- the embedded browser shell and the frozen optional full-browser simulator
branch are not the same thing
- the protected dashboard therefore now carries the same topology/ownership map
as the public manual instead of relying on operator memory after sign-in
- focused validation for that matrix and protected-dashboard continuation then
stayed green under:
- `npm --prefix website test -- --run src/__tests__/public-marketing-pages.test.tsx src/__tests__/protected-app-pages.test.tsx src/__tests__/DashboardOverviewPage.test.tsx src/__tests__/app-route-tree.test.tsx`
- `4` test files passed
- `30` tests passed
- the broader current website/runtime/server umbrella then also stayed green
again under:
- `scripts/run-hypertwist-web-surface-validation.sh`
- focused website route/auth/release validation: `12` test files passed,
`61` tests passed
- `npm --prefix website run build`
- `npm --prefix website/server run type-check`
- `npm --prefix website/server test -- --run`
- `10` website/server test files passed, `36` tests passed
- `npm --prefix Content/Browser run verify:shell`
- `npm --prefix Content/Browser run build`
- website and `Content/Browser` production audits stayed at
`found 0 vulnerabilities`
- website/server still retained only the already-documented upstream
`supertokens-node -> nodemailer` residual
Latest protected-surface resilience follow-up later on `2026-06-23`:
- the shared release-manifest fallback was tightened so protected browser

View file

@ -58,8 +58,8 @@ Resolution order for the analyzer binary is now HyperTwist-owned first:
- `HYPERTWIST_SENTRUX_BINARY` if explicitly provided
- repo-local `./sentrux` or `./sentrux.exe` if present
- repo-local `tools/sentrux/bin/sentrux` or `tools/sentrux/bin/sentrux.exe`
- auto-bootstrap through `scripts/bootstrap-hypertwist-sentrux.sh --if-missing`
- `sentrux` on `PATH`
- the retained local fallback under `/home/dev/src/VectorShell/sentrux`
If the repo-local tools path is empty, materialize it with:
@ -67,6 +67,10 @@ If the repo-local tools path is empty, materialize it with:
scripts/bootstrap-hypertwist-sentrux.sh
```
That bootstrap may still use retained sibling-repo seeds when necessary, but
the ordinary HyperTwist wrapper no longer needs to execute directly from those
repos once the local landing zone exists.
Current rules enforce:
- no cycles
@ -599,6 +603,53 @@ Latest refactor-tooling follow-up later on `2026-06-23`:
- `Quality: 6108`
- all `7` checked rules passing
Latest wrapper-ownership follow-up on `2026-06-24`:
- `scripts/bootstrap-hypertwist-sentrux.sh` now also accepts
`HYPERTWIST_SENTRUX_BINARY` as an explicit local seed
- `scripts/run-hypertwist-sentrux-source-only.sh` now attempts repo-local
bootstrap before it falls back to `PATH`
- sibling-repo `VectorShell` and `ScriptoriumAI` `sentrux` artifacts are now
treated as bootstrap seeds rather than the normal direct runtime path for the
HyperTwist analyzer wrapper
- this keeps the toolchain more honestly HyperTwist-local after the first
materialization without changing the bounded analysis scope
Latest same-day validation follow-up later on `2026-06-24`:
- the wrapper and public-manual continuation were then revalidated together on
the current host instead of being left as a docs-only claim
- focused website coverage for the shared product-surface matrix and protected
dashboard continuation stayed green under:
- `npm --prefix website test -- --run src/__tests__/public-marketing-pages.test.tsx src/__tests__/protected-app-pages.test.tsx src/__tests__/DashboardOverviewPage.test.tsx src/__tests__/app-route-tree.test.tsx`
- `4` test files passed
- `30` tests passed
- the broader current web-surface umbrella then stayed green under:
- `scripts/run-hypertwist-web-surface-validation.sh`
- focused website route/auth/release validation: `12` test files passed,
`61` tests passed
- website/server tests: `10` test files passed, `36` tests passed
- website plus `Content/Browser` production audits: `found 0 vulnerabilities`
- website/server retained only the already-documented upstream
`supertokens-node -> nodemailer` residual
- `scripts/run-hypertwist-sentrux-source-only.sh` then improved again to:
- `Quality: 6135`
- all `7` checked rules passing
- `scripts/run-hypertwist-gitnexus-analyze.sh` then re-indexed the bounded
source-only mirror successfully at:
- `16,159` nodes
- `37,724` edges
- `666` clusters
- `300` flows
- fallback completion time `84.7s`
- the wrapper again rejected the broken retained local GitNexus CLI cleanly
first, then completed through `npx -y gitnexus@latest` instead of yielding a
false local success
- `scripts/run-hypertwist-gitnexus-status.sh` then again reported:
- `Indexed commit: ccbc988`
- `Current commit: ccbc988`
- `Status: up-to-date`
## Out of scope
This note does not:

View file

@ -51,7 +51,16 @@ Use them with this posture:
`CHANGELOG.md`
- `scripts/run-hypertwist-sentrux-source-only.sh` now prefers a HyperTwist
owned entry path first: `HYPERTWIST_SENTRUX_BINARY`, repo-local `./sentrux`
or `./sentrux.exe`, then `PATH`, then the retained fallback
or `./sentrux.exe`, then repo-local `tools/sentrux/bin/`, then a bootstrap
attempt, then `PATH`
- the current `2026-06-24` wrapper hardening tightens that posture further:
- the source-only wrapper now auto-attempts
`scripts/bootstrap-hypertwist-sentrux.sh --if-missing` before it gives up
- sibling-repo binaries are now bootstrap seeds rather than the normal direct
runtime path
- once bootstrapped, analyzer execution stays on the HyperTwist-local
`tools/sentrux/bin/` landing zone instead of reaching back into
`VectorShell` during ordinary runs
Suggested loop:
@ -123,6 +132,49 @@ Current bounded refactor-tool truth after the `2026-06-24` follow-up:
improved to `Quality: 6131`
- no new structural debt was introduced by the route-registry and sitemap
authority hardening packet
- the same-day wrapper hardening also improved repo-local ownership discipline:
- `scripts/bootstrap-hypertwist-sentrux.sh` now accepts
`HYPERTWIST_SENTRUX_BINARY` as an explicit seed
- `scripts/run-hypertwist-sentrux-source-only.sh` now prefers the
bootstrapped HyperTwist-local analyzer binary instead of directly executing
a sibling-repo fallback during ordinary runs
Latest same-day follow-up later on `2026-06-24`:
- the shared product-surface authority matrix landed across the homepage,
feature atlas, public docs, and protected dashboard without widening product
claims
- focused website coverage for that matrix plus the protected dashboard
continuation stayed green under:
- `npm --prefix website test -- --run src/__tests__/public-marketing-pages.test.tsx src/__tests__/protected-app-pages.test.tsx src/__tests__/DashboardOverviewPage.test.tsx src/__tests__/app-route-tree.test.tsx`
- `4` test files passed
- `30` tests passed
- the full current web-surface umbrella stayed green again under:
- `scripts/run-hypertwist-web-surface-validation.sh`
- focused website route/auth/release validation: `12` test files passed,
`61` tests passed
- `npm --prefix website run build`
- `npm --prefix website/server run type-check`
- `npm --prefix website/server test -- --run`
- `10` website/server test files passed, `36` tests passed
- `npm --prefix Content/Browser run verify:shell`
- `npm --prefix Content/Browser run build`
- website and `Content/Browser` production audits stayed at
`found 0 vulnerabilities`
- the documented upstream auth-server residual
`supertokens-node -> nodemailer` remained accepted in default mode
- `scripts/run-hypertwist-sentrux-source-only.sh` then improved again to:
- `Quality: 6135`
- all `7` rules passing
- `scripts/run-hypertwist-gitnexus-analyze.sh` then re-indexed the bounded
source-only mirror successfully at:
- `16,159` nodes
- `37,724` edges
- `666` clusters
- `300` flows
- fallback completion time `84.7s`
- `scripts/run-hypertwist-gitnexus-status.sh` then again reported the bounded
mirror `Status: up-to-date`
## Canonical development authorities

View file

@ -16,12 +16,16 @@ Usage:
scripts/bootstrap-hypertwist-sentrux.sh [--if-missing]
Materializes a repo-local sentrux binary under tools/sentrux/bin/ using the
best available retained source on this machine.
best available retained seed on this machine.
Resolution order:
1. existing VectorShell Linux build artifact
2. local VectorShell source build via cargo
3. local ScriptoriumAI Windows binary
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
The resulting analyzer then lives under HyperTwist-owned tools/sentrux/bin/
so later runs do not need to execute directly from sibling repos.
EOF
}
@ -50,6 +54,18 @@ elif [[ $# -gt 0 ]]; then
exit 1
fi
if [[ -n "${HYPERTWIST_SENTRUX_BINARY:-}" && -x "${HYPERTWIST_SENTRUX_BINARY}" ]]; then
case "${HYPERTWIST_SENTRUX_BINARY}" in
*.exe)
copy_binary "${HYPERTWIST_SENTRUX_BINARY}" "$dest_windows"
;;
*)
copy_binary "${HYPERTWIST_SENTRUX_BINARY}" "$dest_linux"
;;
esac
exit 0
fi
if [[ -x "$vector_sentrux_binary" ]]; then
copy_binary "$vector_sentrux_binary" "$dest_linux"
exit 0
@ -72,6 +88,7 @@ cat >&2 <<EOF
Unable to materialize a repo-local sentrux binary.
Checked:
- HYPERTWIST_SENTRUX_BINARY
- $vector_sentrux_binary
- $vector_sentrux_manifest
- $scriptorium_sentrux_windows

View file

@ -7,8 +7,7 @@ repo_local_sentrux_binary="$repo_root/sentrux"
repo_local_sentrux_windows_binary="$repo_root/sentrux.exe"
repo_tools_sentrux_binary="$repo_root/tools/sentrux/bin/sentrux"
repo_tools_sentrux_windows_binary="$repo_root/tools/sentrux/bin/sentrux.exe"
local_sentrux_binary="/home/dev/src/VectorShell/sentrux/target/release/sentrux"
local_sentrux_manifest="/home/dev/src/VectorShell/sentrux/Cargo.toml"
bootstrap_script="$repo_root/scripts/bootstrap-hypertwist-sentrux.sh"
resolve_sentrux_command() {
if [[ -n "${HYPERTWIST_SENTRUX_BINARY:-}" && -x "${HYPERTWIST_SENTRUX_BINARY}" ]]; then
@ -36,26 +35,30 @@ resolve_sentrux_command() {
return 0
fi
if [[ -x "$bootstrap_script" ]]; then
"$bootstrap_script" --if-missing >/dev/null 2>&1 || true
fi
if [[ -x "$repo_tools_sentrux_binary" ]]; then
printf '%s\n' "$repo_tools_sentrux_binary"
return 0
fi
if [[ -x "$repo_tools_sentrux_windows_binary" ]]; then
printf '%s\n' "$repo_tools_sentrux_windows_binary"
return 0
fi
if command -v sentrux >/dev/null 2>&1; then
printf 'sentrux\n'
return 0
fi
if [[ -x "$local_sentrux_binary" ]]; then
printf '%s\n' "$local_sentrux_binary"
return 0
fi
if command -v cargo >/dev/null 2>&1 && [[ -f "$local_sentrux_manifest" ]]; then
printf 'cargo run --quiet --manifest-path %q --bin sentrux --\n' "$local_sentrux_manifest"
return 0
fi
return 1
}
sentrux_command="$(resolve_sentrux_command)" || {
echo "Unable to locate sentrux. Provide HYPERTWIST_SENTRUX_BINARY, run scripts/bootstrap-hypertwist-sentrux.sh, add sentrux to PATH, place a repo-local sentrux binary at $repo_root, or keep /home/dev/src/VectorShell/sentrux available." >&2
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
exit 1
}

View file

@ -12,4 +12,8 @@ scripts/bootstrap-hypertwist-sentrux.sh
```
That helper materializes a local binary under `tools/sentrux/bin/` from the
best retained source available on this machine.
best retained seed available on this machine.
The normal HyperTwist wrapper then prefers that repo-local binary before it
falls back to anything else, so analyzer execution stays HyperTwist-local after
bootstrap.

View file

@ -188,6 +188,8 @@ describe('DashboardOverviewPage', () => {
expect(screen.getByText('Packaged validation passed')).toBeTruthy()
expect(screen.getByText(/Magic120Cell dedicated-family training map: passed/i)).toBeTruthy()
expect(screen.getByText('Desktop rollout follow-through')).toBeTruthy()
expect(screen.getByText('Current product-surface map')).toBeTruthy()
expect(screen.getByText('Embedded simulator browser shell')).toBeTruthy()
expect(screen.getByText('Pair desktop access to the browser account')).toBeTruthy()
const generateDesktopLinkButtons = screen.getAllByRole('button', { name: /generate desktop-link token/i })

View file

@ -256,6 +256,7 @@ describe('AppRouteTree', () => {
renderRoute('/app')
expect(await screen.findByText('HyperTwist dashboard')).toBeTruthy()
expect(await screen.findByText('Account state')).toBeTruthy()
expect(screen.getByText('Current product-surface map')).toBeTruthy()
})
it('renders the protected downloads route through the real route tree when authenticated', async () => {

View file

@ -352,7 +352,7 @@ describe('public marketing pages', () => {
expect(screen.getAllByText('Paddle webhook secret: missing').length).toBeGreaterThan(0)
expect(screen.getByText('Public auth runtime posture: production-ready')).toBeTruthy()
expect(screen.getByText('How a real first session flows')).toBeTruthy()
expect(screen.getByText('Why both browser and desktop stay')).toBeTruthy()
expect(screen.getAllByText('Current surface authority map').length).toBeGreaterThan(0)
expect(screen.getAllByText('Native Unreal desktop runtime').length).toBeGreaterThan(0)
})
@ -469,6 +469,8 @@ describe('public marketing pages', () => {
expect(screen.getByText('Feature truth without the roadmap archaeology.')).toBeTruthy()
expect(screen.getByText('How to read the product truth')).toBeTruthy()
expect(screen.getByText('Implemented now')).toBeTruthy()
expect(screen.getAllByText('Current surface authority map').length).toBeGreaterThan(0)
expect(screen.getAllByText('Embedded simulator browser shell').length).toBeGreaterThan(0)
expect(screen.getByText('Current shipped capability')).toBeTruthy()
expect(screen.getByText('Current public rollout posture')).toBeTruthy()
expect(screen.getByText('Public feature and launch posture')).toBeTruthy()
@ -852,7 +854,9 @@ describe('public marketing pages', () => {
renderWithProviders(<DocsPage />, ['/docs'])
expect(screen.getByText('Operator manual')).toBeTruthy()
expect(screen.getAllByText('Current surface authority map').length).toBeGreaterThan(0)
expect(screen.getAllByText('1. Start in the browser shell').length).toBeGreaterThan(0)
expect(screen.getAllByText('Optional full-browser simulator branch').length).toBeGreaterThan(0)
expect(screen.getByText('Simulator manual')).toBeTruthy()
expect(screen.getByText('Higher-dimensional family guide')).toBeTruthy()
expect(screen.getByText('Deployment readiness manual')).toBeTruthy()

View file

@ -0,0 +1,40 @@
import type { ProductSurfaceMatrixRow } from '../../site-data'
export function ProductSurfaceMatrix({
rows,
}: {
rows: readonly ProductSurfaceMatrixRow[]
}) {
return (
<div className="surface-matrix">
{rows.map((row) => (
<article key={row.title} className="card surface-matrix__card">
<p className="status-pill status-pill--info">{row.posture}</p>
<div>
<h3>{row.title}</h3>
<p>{row.description}</p>
</div>
<section className="surface-matrix__section">
<h4>Owns today</h4>
<ul className="list">
{row.owns.map((item) => (
<li key={item}>{item}</li>
))}
</ul>
</section>
<section className="surface-matrix__section">
<h4>Does not claim</h4>
<ul className="list">
{row.doesNotClaim.map((item) => (
<li key={item}>{item}</li>
))}
</ul>
</section>
<p className="surface-matrix__next">
<strong>Use it next:</strong> {row.nextStep}
</p>
</article>
))}
</div>
)
}

View file

@ -4,12 +4,13 @@ import { Link, useSearchParams } from 'react-router-dom'
import { buildAuthApiBaseUrls, createDesktopLinkToken, getAuthHealth, getReleaseManifest } from '../auth/auth-api'
import { usePlatformAuth, type PlatformUser } from '../auth/platform-auth'
import { SiteMetadata } from '../components/seo/SiteMetadata'
import { ProductSurfaceMatrix } from '../components/ui/ProductSurfaceMatrix'
import { ReleaseValidationSummary } from '../components/ui/ReleaseValidationSummary'
import { resolvePublicLaunchStatusSummary } from '../public-launch'
import { downloadTargets, launchReadiness, mplSourceUrl, openSourceRepoUrl, publicDocsUrl, releaseNotesUrl } from '../site-config'
import { buildReleaseMetadataItems, resolveReleaseManifestView, type ReleaseManifestView } from '../release-manifest'
import { buildSupportPath, getDownloadPlatformLabel, normalizeDownloadPlatform } from '../site-routes'
import { desktopDownloadSteps, desktopFirstLaunchCards, roadmapHonestyCards, supportEscalationCards } from '../site-data'
import { desktopDownloadSteps, desktopFirstLaunchCards, productSurfaceMatrixRows, roadmapHonestyCards, supportEscalationCards } from '../site-data'
function Panel({
title,
@ -460,6 +461,16 @@ export function DashboardOverviewPage() {
kicker="Post-download operator manual"
/>
<Panel title="Current product-surface map" kicker="Operator orientation">
<p>
The protected dashboard is only one surface in the product. This shared map keeps account,
embedded-browser, desktop-runtime, and frozen-branch truth visible without forcing operators to reconstruct topology from separate pages.
</p>
<div className="top-gap">
<ProductSurfaceMatrix rows={productSurfaceMatrixRows} />
</div>
</Panel>
<Panel title="Product boundary" kicker="Roadmap honesty">
<ul className="list">
{roadmapHonestyCards.map((item) => (

View file

@ -2,13 +2,14 @@ import { Link } from 'react-router-dom'
import { MarketingShell } from '../components/layout/MarketingShell'
import { SiteMetadata } from '../components/seo/SiteMetadata'
import { PublicLaunchStatus } from '../components/ui/PublicLaunchStatus'
import { ProductSurfaceMatrix } from '../components/ui/ProductSurfaceMatrix'
import {
deliverySurfaceCards,
deploymentReadinessTracks,
featureAtlasCurrentTracks,
featureRegistryTierCards,
higherDimensionalRuntimeGuideCards,
inputAndDevicePostureCards,
productSurfaceMatrixRows,
releaseStoryCards,
roadmapHonestyCards,
} from '../site-data'
@ -66,22 +67,10 @@ export function FeaturesPage() {
</Section>
<Section
title="Browser, dashboard, and simulator split"
description="HyperTwist keeps multiple surfaces on purpose. This is the clean public explanation of what each one does best."
title="Current surface authority map"
description="This is the clean public answer to the architecture question: public website, protected dashboard, embedded browser shell, native runtime, and the frozen browser-client branch each have different ownership."
>
<div className="card-grid">
{deliverySurfaceCards.map((surface) => (
<article key={surface.title} className="card">
<h3>{surface.title}</h3>
<p>{surface.description}</p>
<ul className="list top-gap">
{surface.bullets.map((bullet) => (
<li key={bullet}>{bullet}</li>
))}
</ul>
</article>
))}
</div>
<ProductSurfaceMatrix rows={productSurfaceMatrixRows} />
</Section>
<Section

View file

@ -6,6 +6,7 @@ import { getReleaseManifest } from '../auth/auth-api'
import { MarketingShell } from '../components/layout/MarketingShell'
import { SiteMetadata } from '../components/seo/SiteMetadata'
import { PublicLaunchStatus } from '../components/ui/PublicLaunchStatus'
import { ProductSurfaceMatrix } from '../components/ui/ProductSurfaceMatrix'
import { ReleaseValidationSummary } from '../components/ui/ReleaseValidationSummary'
import { brandConfig } from '../site-config'
import { resolveReleaseManifestView } from '../release-manifest'
@ -21,6 +22,7 @@ import {
operatorManualTracks,
operatorPlaybooks,
publicDocumentationPrinciples,
productSurfaceMatrixRows,
releaseStoryCards,
resourceCollections,
roadmapHonestyCards,
@ -187,22 +189,10 @@ export function HomeLanding() {
</Section>
<Section
title="Why both browser and desktop stay"
description="The public site owns operator and distribution work the simulator should not dilute, while the simulator stays native for the runtime-heavy training job."
title="Current surface authority map"
description="HyperTwist really has five distinct surfaces today. This shared map keeps the public site, embedded browser shell, protected dashboard, desktop runtime, and frozen browser-client branch from being blurred together."
>
<div className="card-grid">
{deliverySurfaceCards.map((surface) => (
<article key={surface.title} className="card">
<h3>{surface.title}</h3>
<p>{surface.description}</p>
<ul className="list top-gap">
{surface.bullets.map((bullet) => (
<li key={bullet}>{bullet}</li>
))}
</ul>
</article>
))}
</div>
<ProductSurfaceMatrix rows={productSurfaceMatrixRows} />
</Section>
</MarketingShell>
</>
@ -596,17 +586,10 @@ export function DocsPage() {
</Section>
<Section
title="Browser versus simulator boundary"
description="The docs stay professional by being explicit about what each surface does better."
title="Current surface authority map"
description="This is the quickest way to understand which live surface owns what today, including the difference between the public website and the embedded browser shell that ships inside the desktop runtime."
>
<div className="card-grid">
{deliverySurfaceCards.map((surface) => (
<article key={surface.title} className="card">
<h3>{surface.title}</h3>
<p>{surface.description}</p>
</article>
))}
</div>
<ProductSurfaceMatrix rows={productSurfaceMatrixRows} />
</Section>
<Section

View file

@ -65,6 +65,98 @@ export const deliverySurfaceCards = [
},
] as const
export type ProductSurfaceMatrixRow = {
title: string
posture: string
description: string
owns: readonly string[]
doesNotClaim: readonly string[]
nextStep: string
}
export const productSurfaceMatrixRows = [
{
title: 'Public website',
posture: 'Public release shell',
description: 'This is the anonymous-safe product surface for positioning, launch posture, release references, and operator-safe onboarding.',
owns: [
'Public docs, pricing, release notes, legal notices, and support-safe rollout guidance.',
'The first step into account creation, sign-in, and platform-aware download routing.',
'Public launch-readiness truth without exposing entitled package delivery on an anonymous route.',
],
doesNotClaim: [
'The native Unreal simulator runtime.',
'Packaged higher-dimensional execution or device/runtime integration.',
'The optional full-browser simulator branch as a live product lane.',
],
nextStep: 'Start here when discovery, documentation, release posture, or public rollout context matters.',
},
{
title: 'Protected browser dashboard',
posture: 'Signed-in operator shell',
description: 'This is the account-aware browser lane for entitlement, auth health, billing posture, protected notices, and desktop pairing.',
owns: [
'Live session, billing, entitlement, and release-manifest viewer posture.',
'Desktop-link token issuance and protected follow-through after sign-in.',
'Operator-facing release, notice, and download-center context that should not sit on public pages.',
],
doesNotClaim: [
'The simulator execution loop itself.',
'Higher-dimensional packaged runtime behavior.',
'General desktop-runtime telemetry ownership beyond the bounded pairing and release surfaces.',
],
nextStep: 'Use this surface once identity, plan, entitlement, or protected release access matters.',
},
{
title: 'Embedded simulator browser shell',
posture: 'In-simulator browser adjunct',
description: 'This is the browser runtime that ships inside the desktop product for bounded simulator-side interaction, not the public website.',
owns: [
'The current MagicTile host posture, browser-assisted recognition shell segments, and typed runtime-ready or runtime-status envelopes.',
'Bounded operator diagnostics that stay attached to the native training and dashboard surfaces.',
'A first-party browser bridge inside the desktop runtime instead of a separate public-web simulator claim.',
],
doesNotClaim: [
'Public auth, pricing, checkout, or legal-distribution ownership.',
'Standalone full-browser simulator parity.',
'A reopened native renderer-port branch for MagicTile.',
],
nextStep: 'Treat this as an in-product runtime adjunct when simulator-side browser interaction or diagnostics are the real need.',
},
{
title: 'Native Unreal desktop runtime',
posture: 'Simulator authority',
description: 'This remains the real product center for training quality, packaged proof, replay, recognition, and higher-dimensional runtime ownership.',
owns: [
'Recognition, correction, replay, coaching, analytics, and packaged training behavior.',
'Dedicated-family Magic120Cell and MagicCube5D runtime-state, projection, and persistence ownership.',
'The device, package, and runtime lane that public and protected browser surfaces deliberately do not absorb.',
],
doesNotClaim: [
'Anonymous public distribution and marketing duties.',
'Protected billing or plan management.',
'A finished VR or controller-rebinding lane beyond the current bounded keyboard, mouse, and settings ownership.',
],
nextStep: 'Use this surface for actual simulator execution, desktop training, package proof, and serious higher-dimensional work.',
},
{
title: 'Optional full-browser simulator branch',
posture: 'Frozen spec-only branch',
description: 'This is a deliberately separate future branch whose existence stays visible so the current shipped topology is not misread.',
owns: [
'A documented future possibility only after a separate backend and runtime contract is deliberately reopened.',
'Spec-only planning material that keeps the browser-client lane disciplined instead of vague.',
'A clear no-go boundary against accidental marketing overclaim.',
],
doesNotClaim: [
'Current shipping simulator truth.',
'Entitlement to displace the desktop-first runtime posture.',
'Any current production browser parity for higher-dimensional execution.',
],
nextStep: 'Keep it visible as a gated branch, but do not route current users toward it as if it already ships.',
},
] satisfies readonly ProductSurfaceMatrixRow[]
export const featureRegistryTierCards = [
{
title: 'Implemented now',

View file

@ -137,6 +137,7 @@ img {
.button-row,
.feature-band,
.metric-grid,
.surface-matrix,
.card-grid,
.split-grid,
.panel-grid,
@ -339,12 +340,14 @@ img {
.card-grid,
.split-grid,
.surface-matrix,
.panel-grid {
flex-wrap: wrap;
}
.card-grid > *,
.split-grid > *,
.surface-matrix > *,
.panel-grid > * {
flex: 1 1 280px;
}
@ -447,6 +450,33 @@ img {
border-color: var(--ht-border-strong);
}
.surface-matrix__card {
display: grid;
gap: 0.9rem;
}
.surface-matrix__section {
display: grid;
gap: 0.45rem;
}
.surface-matrix__section h4 {
margin: 0;
color: var(--ht-cyan);
font-size: 0.82rem;
letter-spacing: 0.1em;
text-transform: uppercase;
}
.surface-matrix__next {
margin: 0;
color: var(--ht-muted);
}
.surface-matrix__next strong {
color: var(--ht-text);
}
.inline-link {
display: inline-flex;
align-items: center;