core/workbench-ui/src/app/routes.ts
Shay 29ca5524d0
feat(workbench-ui): add Apple UMA report card route (#912)
* feat(workbench-ui): add Apple UMA report card route

* feat(workbench-ui): register Apple UMA route

* feat(workbench-ui): expose Apple UMA route path

* feat(workbench-ui): wire Apple UMA report card into route registry

* test(workbench-ui): fix UI and keyboard tests for Apple UMA route integration
2026-06-24 15:33:42 -07:00

337 lines
9.9 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import type { ReactElement } from "react";
/**
* Single source of truth for workbench navigation routes (Wave M B3.5-a).
*
* Every route list in the app derives from {@link WORKBENCH_ROUTES}:
* - App `<Route>` declarations (via {@link ROUTE_ELEMENTS})
* - LeftNav (grouped by section)
* - the command palette Navigate section
* - ⌘-digit navigation shortcuts
* - the landing-route preference dropdown
* - route-conformance fixtures
*
* Adding a route in one place only was the prior failure mode: Demos and
* Calibration shipped to LeftNav but never reached the command palette, and
* Replay/Calibration were absent from the landing dropdown. With one list,
* that drift is structurally impossible.
*
* Wayfinding `section`s group the flat route set by the organism's loop
* (Converse → Cognition → Determinism → Evidence → Discipline → Substrate →
* Settings). This is a display skin only — one workbench, one address space,
* one Evidence Chain Rail; never a split into separate apps.
*/
export const ROUTE_SECTIONS = [
"Converse",
"Cognition",
"Determinism",
"Evidence",
"Discipline",
"Substrate",
"Settings",
] as const;
export type RouteSection = (typeof ROUTE_SECTIONS)[number];
export interface WorkbenchRoute {
/** Stable id; React key and digit-shortcut anchor. */
id: string;
/** Navigation target with no params, e.g. "/trace". */
path: string;
/** App `<Route path>` pattern; may carry optional params, e.g. "trace/:turnId?". */
routePattern: string;
/** LeftNav / palette label. */
label: string;
/** One line: what this route is for. */
description: string;
/** Wayfinding group. */
section: RouteSection;
/** Rendered in LeftNav. */
leftNavVisible: boolean;
/** Listed as a Navigate command in the palette. */
commandPaletteVisible: boolean;
/** Eligible as the landing route. */
landingRouteAllowed: boolean;
/**
* Single-digit ⌘ shortcut, or `null` when the route is palette-only.
* There are more routes than digits (19, 0) — the honest model pins the
* first ten and leaves the rest searchable. KeyboardHelp says so; the
* palette shows no chord for palette-only routes.
*/
keyboardDigit: string | null;
/** Must pass ADR-0162 §6 route conformance (loading/error/empty). */
routeConformanceRequired: boolean;
}
// Array order is the LeftNav display order (already grouped by section).
export const WORKBENCH_ROUTES: readonly WorkbenchRoute[] = [
{
id: "chat",
path: "/chat",
routePattern: "chat",
label: "Chat",
description: "Ask CORE a question and create turn evidence.",
section: "Converse",
leftNavVisible: true,
commandPaletteVisible: true,
landingRouteAllowed: true,
keyboardDigit: "1",
routeConformanceRequired: true,
},
{
id: "trace",
path: "/trace",
routePattern: "trace/:turnId?",
label: "Trace",
description: "Inspect the cognitive turn pipeline for a turn.",
section: "Cognition",
leftNavVisible: true,
commandPaletteVisible: true,
landingRouteAllowed: true,
keyboardDigit: "2",
routeConformanceRequired: true,
},
{
id: "contemplation",
path: "/contemplation",
routePattern: "contemplation/:runId?",
label: "Contemplation",
description: "Inspect persisted contemplation process traces.",
section: "Cognition",
leftNavVisible: true,
commandPaletteVisible: true,
landingRouteAllowed: true,
keyboardDigit: null,
routeConformanceRequired: true,
},
{
id: "tour",
path: "/tour",
routePattern: "tour",
label: "Tour",
description: "Guided determinism tour over the real demos.",
section: "Determinism",
leftNavVisible: true,
commandPaletteVisible: true,
landingRouteAllowed: true,
keyboardDigit: null,
routeConformanceRequired: true,
},
{
id: "replay",
path: "/replay",
routePattern: "replay/:turnId?",
label: "Replay",
description: "Re-run a turn and compare trace hashes.",
section: "Determinism",
leftNavVisible: true,
commandPaletteVisible: true,
landingRouteAllowed: true,
keyboardDigit: "3",
routeConformanceRequired: true,
},
{
id: "demos",
path: "/demos",
routePattern: "demos/:demoId?",
label: "Demos",
description: "Run a registered determinism demo end to end.",
section: "Determinism",
leftNavVisible: true,
commandPaletteVisible: true,
landingRouteAllowed: true,
keyboardDigit: null,
routeConformanceRequired: true,
},
{
id: "proposals",
path: "/proposals",
routePattern: "proposals/:proposalId?",
label: "Proposals",
description: "Review the teaching proposal queue and HITL ratification.",
section: "Evidence",
leftNavVisible: true,
commandPaletteVisible: true,
landingRouteAllowed: true,
keyboardDigit: "4",
routeConformanceRequired: true,
},
{
id: "runs",
path: "/runs",
routePattern: "runs/:sessionId?",
label: "Runs",
description: "Browse recorded session runs.",
section: "Evidence",
leftNavVisible: true,
commandPaletteVisible: true,
landingRouteAllowed: true,
keyboardDigit: "6",
routeConformanceRequired: true,
},
{
id: "lived-life",
path: "/lived-life",
routePattern: "lived-life",
label: "Lived Life",
description: "Watch the always-on heartbeat hold one continuous life.",
section: "Evidence",
leftNavVisible: true,
commandPaletteVisible: true,
landingRouteAllowed: true,
keyboardDigit: null,
routeConformanceRequired: true,
},
{
id: "vault",
path: "/vault",
routePattern: "vault",
label: "Vault",
description: "Inspect persisted session memory.",
section: "Evidence",
leftNavVisible: true,
commandPaletteVisible: true,
landingRouteAllowed: true,
keyboardDigit: "8",
routeConformanceRequired: true,
},
{
id: "audit",
path: "/audit",
routePattern: "audit",
label: "Audit",
description: "Read the deterministic audit event log.",
section: "Evidence",
leftNavVisible: true,
commandPaletteVisible: true,
landingRouteAllowed: true,
keyboardDigit: "9",
routeConformanceRequired: true,
},
{
id: "evals",
path: "/evals",
routePattern: "evals/:laneId?",
label: "Evals",
description: "Run eval lanes and read the wrong=0 ledger.",
section: "Discipline",
leftNavVisible: true,
commandPaletteVisible: true,
landingRouteAllowed: true,
keyboardDigit: "5",
routeConformanceRequired: true,
},
{
id: "calibration",
path: "/calibration",
routePattern: "calibration",
label: "Calibration",
description: "See the gold-tether arena earn the right to guess.",
section: "Discipline",
leftNavVisible: true,
commandPaletteVisible: true,
landingRouteAllowed: true,
keyboardDigit: null,
routeConformanceRequired: true,
},
{
id: "packs",
path: "/packs",
routePattern: "packs/:packId?",
label: "Packs",
description: "Browse language/identity packs (CORE-Logos studio).",
section: "Substrate",
leftNavVisible: true,
commandPaletteVisible: true,
landingRouteAllowed: true,
keyboardDigit: "7",
routeConformanceRequired: true,
},
{
id: "logos",
path: "/logos",
routePattern: "logos/:logosPackId?",
label: "CORE-Logos",
description: "Inspect CORE-Logos pack identity and safety.",
section: "Substrate",
leftNavVisible: true,
commandPaletteVisible: true,
landingRouteAllowed: true,
keyboardDigit: null,
routeConformanceRequired: true,
},
{
id: "apple-uma",
path: "/apple-uma",
routePattern: "apple-uma",
label: "Apple UMA",
description: "Inspect the Apple Silicon mechanical-sympathy benchmark report.",
section: "Substrate",
leftNavVisible: true,
commandPaletteVisible: true,
landingRouteAllowed: true,
keyboardDigit: null,
routeConformanceRequired: true,
},
{
id: "settings",
path: "/settings",
routePattern: "settings",
label: "Settings",
description: "Local workbench preferences (read-only to the engine).",
section: "Settings",
leftNavVisible: true,
commandPaletteVisible: true,
landingRouteAllowed: true,
keyboardDigit: "0",
routeConformanceRequired: true,
},
];
/** Routes shown in LeftNav, in display order. */
export const LEFT_NAV_ROUTES = WORKBENCH_ROUTES.filter((r) => r.leftNavVisible);
/** Routes listed in the command palette Navigate section, in display order. */
export const PALETTE_ROUTES = WORKBENCH_ROUTES.filter(
(r) => r.commandPaletteVisible,
);
/** Route ids eligible as the workbench landing route. */
export const LANDING_ROUTE_IDS = WORKBENCH_ROUTES.filter(
(r) => r.landingRouteAllowed,
).map((r) => r.id);
/** ⌘-digit → navigation path, for the ten pinned routes. */
export const ROUTE_DIGIT_MAP: Record<string, string> = Object.fromEntries(
WORKBENCH_ROUTES.filter((r) => r.keyboardDigit !== null).map((r) => [
r.keyboardDigit as string,
r.path,
]),
);
/** LeftNav routes grouped by section, in section then route order. */
export function leftNavSections(): {
section: RouteSection;
routes: WorkbenchRoute[];
}[] {
const groups = new Map<RouteSection, WorkbenchRoute[]>(
ROUTE_SECTIONS.map((s) => [s, []]),
);
for (const route of LEFT_NAV_ROUTES) {
groups.get(route.section)!.push(route);
}
return ROUTE_SECTIONS.map((section) => ({
section,
routes: groups.get(section)!,
})).filter((group) => group.routes.length > 0);
}
/**
* The element registry consumed by `App`. Keyed by route id so that adding a
* route to {@link WORKBENCH_ROUTES} without giving it an element is caught by
* `routes.test.tsx` rather than rendering `undefined`. Populated in `App.tsx`
* (it owns the route-component imports); declared here so the contract — every
* route id has an element — lives next to the route list.
*/
export type RouteElementMap = Record<string, ReactElement>;