Merge pull request #738 from AssetOverflow/codex/lg-2-logos-route-shell

feat(workbench): CORE-Logos Studio LG-2 — /logos route shell + Overview/Identity/Safety
This commit is contained in:
Shay 2026-06-14 12:36:01 -07:00 committed by GitHub
commit b7ec02b869
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
23 changed files with 1381 additions and 21 deletions

View file

@ -59,7 +59,7 @@ successful proof.
## 4. Current Route Map
The route registry in `workbench-ui/src/app/routes.ts` is the source of truth.
Current route count: 14.
Current route count: 15.
| Section | Route | Path | Shortcut | Purpose |
|---|---|---|---|---|
@ -76,6 +76,7 @@ Current route count: 14.
| Discipline | Evals | `/evals` | `⌘5` | Run/read allowlisted eval lanes and wrong=0 ledgers. |
| Discipline | Calibration | `/calibration` | Palette | Inspect practice-class reliability and license verdicts. |
| Substrate | Packs | `/packs` | `⌘7` | Browse language/runtime pack metadata. |
| Substrate | CORE-Logos | `/logos` | Palette | Inspect CORE-Logos pack identity and safety. |
| Settings | Settings | `/settings` | `⌘0` | Manage local UI preferences; engine config remains CLI-only. |
Pinned route shortcuts cover Chat through Settings. All routes are searchable in

View file

@ -55,6 +55,7 @@ snapshot = {
"GroundingSource": literal_values(ROOT / "core" / "epistemic_state.py", "GroundingSource"),
"NormativeClearance": enum_values(ROOT / "core" / "epistemic_state.py", "NormativeClearance"),
"ReviewState": literal_values(ROOT / "teaching" / "proposals.py", "ReviewState"),
"SafetyVerdict": enum_values(ROOT / "workbench" / "schemas.py", "SafetyVerdict"),
}
print(json.dumps(snapshot, indent=2, sort_keys=True))

View file

@ -35,5 +35,11 @@
"accepted",
"rejected",
"withdrawn"
],
"SafetyVerdict": [
"clear",
"warning",
"failed",
"unknown"
]
}

View file

@ -17,6 +17,9 @@ import type {
RunDetail,
PackSummary,
PackDetail,
LogosPackSummary,
LogosPackOverview,
LogosSafetyReport,
VaultSummary,
VaultEntry,
CalibrationClass,
@ -298,6 +301,21 @@ export async function fetchPack(packId: string): Promise<PackDetail> {
return apiFetch<PackDetail>(`/packs/${encodeURIComponent(packId)}`);
}
export async function fetchLogosPacks(): Promise<LogosPackSummary[]> {
const envelope = await apiFetch<ItemsEnvelope<LogosPackSummary>>("/logos/packs");
return envelope.items;
}
export async function fetchLogosPackOverview(packId: string): Promise<LogosPackOverview> {
return apiFetch<LogosPackOverview>(`/logos/packs/${encodeURIComponent(packId)}`);
}
export async function fetchLogosPackSafety(packId: string): Promise<LogosSafetyReport> {
return apiFetch<LogosSafetyReport>(
`/logos/packs/${encodeURIComponent(packId)}/safety`,
);
}
export async function fetchVaultSummary(): Promise<VaultSummary> {
return apiFetch<VaultSummary>("/vault/summary");
}

View file

@ -20,6 +20,9 @@ import {
fetchRun,
fetchPacks,
fetchPack,
fetchLogosPacks,
fetchLogosPackOverview,
fetchLogosPackSafety,
fetchVaultSummary,
fetchVaultEntries,
fetchCalibrationClasses,
@ -53,6 +56,9 @@ import type {
RunDetail,
PackSummary,
PackDetail,
LogosPackSummary,
LogosPackOverview,
LogosSafetyReport,
VaultSummary,
VaultEntry,
CalibrationClass,
@ -399,6 +405,35 @@ export function usePack(packId?: string | null) {
});
}
export function useLogosPacks() {
return useQuery<LogosPackSummary[], WorkbenchApiError>({
queryKey: ["api", "logos", "packs"],
queryFn: fetchLogosPacks,
staleTime: 30_000,
refetchOnWindowFocus: false,
});
}
export function useLogosPackOverview(packId?: string | null) {
return useQuery<LogosPackOverview, WorkbenchApiError>({
queryKey: ["api", "logos", "pack", packId ?? null],
queryFn: () => fetchLogosPackOverview(packId as string),
enabled: typeof packId === "string" && packId.length > 0,
staleTime: 30_000,
refetchOnWindowFocus: false,
});
}
export function useLogosPackSafety(packId?: string | null) {
return useQuery<LogosSafetyReport, WorkbenchApiError>({
queryKey: ["api", "logos", "pack", packId ?? null, "safety"],
queryFn: () => fetchLogosPackSafety(packId as string),
enabled: typeof packId === "string" && packId.length > 0,
staleTime: 30_000,
refetchOnWindowFocus: false,
});
}
export function useVaultSummary() {
return useQuery<VaultSummary, WorkbenchApiError>({
queryKey: ["api", "vault", "summary"],

View file

@ -54,6 +54,9 @@ const CalibrationRoute = lazy(() =>
const PacksRoute = lazy(() =>
import("./packs/PacksRoute").then((module) => ({ default: module.PacksRoute })),
);
const LogosRoute = lazy(() =>
import("./logos/LogosRoute").then((module) => ({ default: module.LogosRoute })),
);
const SettingsRoute = lazy(() =>
import("./settings/SettingsRoute").then((module) => ({
default: module.SettingsRoute,
@ -89,6 +92,7 @@ export const ROUTE_ELEMENTS: RouteElementMap = {
evals: lazyRoute(<EvalsRoute />),
calibration: lazyRoute(<CalibrationRoute />),
packs: lazyRoute(<PacksRoute />),
logos: lazyRoute(<LogosRoute />),
settings: lazyRoute(<SettingsRoute />),
};

View file

@ -159,6 +159,30 @@ export function deriveStages(subject: EvidenceSubject): RailStage[] | null {
stage("action", "dim", "not applicable to pack metadata"),
];
}
case "logos_pack": {
const d = subject.data;
return [
stage("intent", "dim", "not applicable to read-only Logos pack inspection"),
stage("subject", "lit", "selected CORE-Logos pack"),
stage(
"provenance",
d ? evidenceAny(d.manifest_digest, d.manifest_path) : "hollow",
"manifest_digest / manifest_path",
),
stage(
"admissibility",
d ? evidenceAny(d.safety_status, d.checksum_status) : "hollow",
"safety_status / checksum_status",
),
stage(
"replay",
d && d.holonomy_case_count && d.holonomy_case_count > 0 ? "lit" : "hollow",
"holonomy_case_count (0 means missing_evidence)",
),
stage("authority", "dim", "read-only Logos Studio has no mutation authority"),
stage("action", "dim", "proposal mode none"),
];
}
case "vault_entry": {
const d = subject.data;
return [

View file

@ -8,9 +8,11 @@ import {
EpistemicStateBadge,
GroundingSourceBadge,
NormativeClearanceBadge,
SafetyVerdictBadge,
type EpistemicState,
type GroundingSource,
type NormativeClearance,
type SafetyVerdict,
} from "../design/components/badges";
import type { LeewayEvidence } from "../types/api";
@ -238,6 +240,75 @@ function PackInspector({ subject }: { subject: Extract<EvidenceSubject, { kind:
);
}
function LogosPackInspector({
subject,
}: {
subject: Extract<EvidenceSubject, { kind: "logos_pack" }>;
}) {
const { data } = subject;
return (
<div className="grid gap-3">
<h3 className="text-xs font-semibold text-[var(--color-text-secondary)]">
CORE-Logos Pack
</h3>
<p className="m-0 font-mono text-xs text-[var(--color-text-primary)]">
{subject.packId}
</p>
{data ? (
<MetadataTable
rows={[
...(data.safety_status
? [
{
key: "safety",
value: (
<SafetyVerdictBadge value={data.safety_status as SafetyVerdict} />
),
},
]
: []),
...(data.checksum_status
? [
{
key: "checksum",
value: (
<SafetyVerdictBadge value={data.checksum_status as SafetyVerdict} />
),
},
]
: []),
...(data.manifest_digest
? [
{
key: "manifest",
value: data.manifest_digest,
mono: true,
copyable: true,
},
]
: []),
...(data.role ? [{ key: "role", value: data.role }] : []),
...(data.language ? [{ key: "language", value: data.language }] : []),
...(typeof data.holonomy_case_count === "number"
? [
{
key: "holonomy",
value:
data.holonomy_case_count === 0
? "0 / missing_evidence"
: String(data.holonomy_case_count),
},
]
: []),
]}
/>
) : (
<DetailNotLoaded />
)}
</div>
);
}
function VaultEntryInspector({ subject }: { subject: Extract<EvidenceSubject, { kind: "vault_entry" }> }) {
const { data } = subject;
return (
@ -372,6 +443,8 @@ function InspectorProjection({ subject }: { subject: EvidenceSubject }) {
return <RunInspector subject={subject} />;
case "pack":
return <PackInspector subject={subject} />;
case "logos_pack":
return <LogosPackInspector subject={subject} />;
case "vault_entry":
return <VaultEntryInspector subject={subject} />;
case "audit_event":

View file

@ -85,11 +85,11 @@ describe("Shell", () => {
expect(document.querySelector('[data-density="compact"]')).toBeInTheDocument();
});
it("LeftNav has exactly 14 items in section-grouped order", () => {
it("LeftNav has exactly 15 items in section-grouped order", () => {
renderShell();
const nav = document.querySelector('[data-region="leftnav"]')!;
const links = nav.querySelectorAll("a");
expect(links).toHaveLength(14);
expect(links).toHaveLength(15);
const labels = Array.from(links).map((l) => l.textContent);
// Grouped by section (Converse → Cognition → Determinism → Evidence →
// Discipline → Substrate → Settings), derived from the route registry.
@ -107,6 +107,7 @@ describe("Shell", () => {
"Evals",
"Calibration",
"Packs",
"CORE-Logos",
"Settings",
]);
});

View file

@ -26,6 +26,8 @@ function routerParamsFor(url: string): Record<string, string | undefined> {
return segment === undefined ? {} : { sessionId: segment };
case "packs":
return segment === undefined ? {} : { packId: segment };
case "logos":
return segment === undefined ? {} : { logosPackId: segment };
case "evals":
return segment === undefined ? {} : { laneId: segment };
case "replay":
@ -68,6 +70,11 @@ const KINDS: Array<{ name: string; subject: AddressableSubject; path: string }>
subject: { kind: "pack", packId: "en/core pack" },
path: "/packs/en%2Fcore%20pack",
},
{
name: "logos_pack",
subject: { kind: "logos_pack", packId: "he_logos_micro_v1" },
path: "/logos/he_logos_micro_v1",
},
];
const INSPECT_ONLY_KINDS: Array<{ name: string; subject: AddressableSubject; path: string }> = [
@ -192,6 +199,7 @@ describe("urlToSubject malformed input", () => {
["empty proposal id", { proposalId: "" }],
["empty session id", { sessionId: "" }],
["empty pack id", { packId: "" }],
["empty logos pack id", { logosPackId: "" }],
["empty lane id", { laneId: "" }],
["empty artifact id", { artifactId: "" }],
["no params at all", {}],

View file

@ -10,6 +10,7 @@ import type { EvidenceSubject } from "./evidenceContext";
// artifact -> /replay/<artifactId>
// run -> /runs/<sessionId>
// pack -> /packs/<packId>
// logos_pack -> /logos/<packId> (?inspect uses logos:<packId>)
// vault_entry -> /vault?inspect=vault:<entryIndex>
// audit_event -> /audit?inspect=audit:<eventId>
// calibration_class -> /calibration?inspect=calibration:<className>
@ -45,6 +46,8 @@ export function sameIdentity(a: EvidenceSubject, b: EvidenceSubject): boolean {
return b.kind === "run" && b.sessionId === a.sessionId;
case "pack":
return b.kind === "pack" && b.packId === a.packId;
case "logos_pack":
return b.kind === "logos_pack" && b.packId === a.packId;
case "vault_entry":
return b.kind === "vault_entry" && b.entryIndex === a.entryIndex;
case "audit_event":
@ -86,6 +89,8 @@ function subjectAddress(subject: AddressableSubject): SubjectAddress {
return { path: `/runs/${encodeURIComponent(subject.sessionId)}`, params: emptyParams() };
case "pack":
return { path: `/packs/${encodeURIComponent(subject.packId)}`, params: emptyParams() };
case "logos_pack":
return { path: `/logos/${encodeURIComponent(subject.packId)}`, params: emptyParams() };
case "vault_entry":
{
const params = emptyParams();
@ -121,6 +126,8 @@ export function subjectToInspectValue(subject: AddressableSubject): string {
return `run:${subject.sessionId}`;
case "pack":
return `pack:${subject.packId}`;
case "logos_pack":
return `logos:${subject.packId}`;
case "vault_entry":
return `vault:${subject.entryIndex}`;
case "audit_event":
@ -172,6 +179,8 @@ export function inspectValueToSubject(
return { kind: "run", sessionId: id };
case "pack":
return { kind: "pack", packId: id };
case "logos":
return { kind: "logos_pack", packId: id };
case "vault": {
const entryIndex = parseTurnId(id);
return entryIndex === null ? null : { kind: "vault_entry", entryIndex };
@ -211,6 +220,11 @@ function routeParamsToSubject(
? null
: { kind: "pack", packId: params.packId };
}
if (params.logosPackId !== undefined) {
return params.logosPackId === ""
? null
: { kind: "logos_pack", packId: params.logosPackId };
}
if (params.laneId !== undefined) {
return params.laneId === ""
? null

View file

@ -14,6 +14,8 @@ import type {
ArtifactDetail,
EvalRunResult,
CalibrationClass,
LogosPackOverview,
SafetyVerdict,
} from "../types/api";
export type ProposalSubjectDomain = "cognition" | "math";
@ -33,6 +35,27 @@ export interface PackSubjectData {
determinism_class?: string | null;
}
export interface LogosPackSubjectData
extends Partial<
Pick<
LogosPackOverview,
| "pack_id"
| "language"
| "role"
| "script"
| "version"
| "determinism_class"
| "gate_engaged"
| "oov_policy"
| "safety_status"
| "manifest_digest"
| "manifest_path"
| "holonomy_case_count"
>
> {
checksum_status?: SafetyVerdict | null;
}
export interface VaultEntrySubjectData {
entry_index?: number;
epistemic_state?: string;
@ -60,6 +83,7 @@ export type EvidenceSubject =
| { kind: "eval_result"; lane: string; data?: EvalRunResult }
| { kind: "run"; sessionId: string; data?: RunSubjectData }
| { kind: "pack"; packId: string; data?: PackSubjectData }
| { kind: "logos_pack"; packId: string; data?: LogosPackSubjectData }
| { kind: "vault_entry"; entryIndex: number; data?: VaultEntrySubjectData }
| { kind: "audit_event"; eventId: string; data?: AuditEventSubjectData }
| { kind: "calibration_class"; className: string; data?: CalibrationClass }

View file

@ -0,0 +1,252 @@
import { QueryClientProvider } from "@tanstack/react-query";
import { render, screen, waitFor } from "@testing-library/react";
import userEvent from "@testing-library/user-event";
import { MemoryRouter, Route, Routes, useLocation } from "react-router-dom";
import { afterEach, describe, expect, it, vi } from "vitest";
import { createTestQueryClient } from "../../test/createTestQueryClient";
import type {
LogosPackOverview,
LogosPackSummary,
LogosSafetyReport,
SafetyVerdict,
} from "../../types/api";
import { EvidenceProvider } from "../evidenceContext";
import { RightInspector } from "../RightInspector";
import { LogosRoute } from "./LogosRoute";
const summaries: LogosPackSummary[] = [
{
pack_id: "he_logos_micro_v1",
language: "he",
role: "depth_root",
script: "Hebrew",
version: "1.0.0",
determinism_class: "D0",
gate_engaged: true,
oov_policy: "fail_closed",
lexicon_count: 3,
gloss_count: 2,
morphology_count: 3,
frame_count: 0,
composition_count: 0,
alignment_edge_count: 4,
holonomy_case_count: 0,
safety_status: "unknown",
manifest_digest: "sha256:aaaaaaaaaaaaaaaa",
manifest_path: "language_packs/data/he_logos_micro_v1/manifest.json",
},
{
pack_id: "grc_logos_cognition_v1",
language: "grc",
role: "depth_relation",
script: "Greek",
version: "1.0.0",
determinism_class: "D0",
gate_engaged: true,
oov_policy: "fail_closed",
lexicon_count: 5,
gloss_count: 5,
morphology_count: 5,
frame_count: 0,
composition_count: 0,
alignment_edge_count: 8,
holonomy_case_count: 0,
safety_status: "warning",
manifest_digest: "sha256:bbbbbbbbbbbbbbbb",
manifest_path: "language_packs/data/grc_logos_cognition_v1/manifest.json",
},
];
function overviewFor(packId: string): LogosPackOverview {
const summary = summaries.find((item) => item.pack_id === packId) ?? summaries[0];
return {
...summary,
schema_version: "logos_pack_overview_v1",
normalization_policy: "NFC",
source_manifest: "logos-source-manifest.json",
known_gaps: packId.includes("grc") ? ["undeclared English collapse anchors"] : [],
};
}
function safetyFor(
packId: string,
verdict: SafetyVerdict = packId.includes("grc") ? "warning" : "unknown",
): LogosSafetyReport {
return {
schema_version: "logos_safety_report_v1",
pack_id: packId,
checksum_status: verdict === "warning" ? "warning" : "unknown",
checksum_errors: verdict === "warning" ? ["alignment checksum pending review"] : [],
domain_contract: { valid: verdict !== "failed", domain_id: "hebrew_greek_textual_reasoning" },
domain_contract_status: verdict === "failed" ? "failed" : "unknown",
oov_policy_ok: true,
gate_policy_ok: true,
path_safety_ok: true,
dangling_morphology_links: verdict === "warning"
? [{ entry_id: "logos.entry.1", morphology_id: "missing-morph" }]
: [],
invalid_alignment_targets: verdict === "warning"
? [
{
edge_id: "edge-warning-1",
source_id: "grc-logos",
target_id: "en-collapse-logos",
relation: "logos-collapse",
target_pack_id: "en_core_cognition_v1",
},
]
: [],
missing_holonomy_refs: "unknown",
epistemic_status_counts: { speculative: 5, contested: verdict === "warning" ? 1 : 0 },
speculative_entries: ["logos.entry.1", "logos.entry.2"],
contested_entries: verdict === "warning" ? ["logos.entry.3"] : [],
falsified_entries: [],
known_gaps: verdict === "warning" ? ["no holonomy refs"] : [],
verdict,
};
}
function okEnvelope(data: unknown) {
return { ok: true, generated_at: "2026-06-14T00:00:00Z", data };
}
function stubLogosFetch() {
const paths: string[] = [];
const fetchMock = vi.fn((input: unknown) => {
const path = new URL(String(input)).pathname;
paths.push(path);
if (path === "/logos/packs") {
return Promise.resolve({
json: async () => okEnvelope({ items: summaries }),
});
}
const safetyMatch = path.match(/^\/logos\/packs\/([^/]+)\/safety$/);
if (safetyMatch) {
const packId = decodeURIComponent(safetyMatch[1]);
return Promise.resolve({
json: async () => okEnvelope(safetyFor(packId)),
});
}
const overviewMatch = path.match(/^\/logos\/packs\/([^/]+)$/);
if (overviewMatch) {
const packId = decodeURIComponent(overviewMatch[1]);
return Promise.resolve({
json: async () => okEnvelope(overviewFor(packId)),
});
}
return Promise.resolve({
json: async () => ({
ok: false,
generated_at: "2026-06-14T00:00:00Z",
error: { code: "not_found", message: `unexpected path ${path}` },
}),
});
});
vi.stubGlobal("fetch", fetchMock);
return { paths, fetchMock };
}
function LocationProbe() {
const location = useLocation();
return <span data-testid="location">{`${location.pathname}${location.search}`}</span>;
}
function renderRoute(initialEntry = "/logos") {
return render(
<QueryClientProvider client={createTestQueryClient()}>
<MemoryRouter initialEntries={[initialEntry]}>
<EvidenceProvider>
<Routes>
<Route
path="/logos/:logosPackId?"
element={
<div className="grid grid-cols-[1fr_20rem]">
<div>
<LogosRoute />
<LocationProbe />
</div>
<RightInspector />
</div>
}
/>
</Routes>
</EvidenceProvider>
</MemoryRouter>
</QueryClientProvider>,
);
}
afterEach(() => {
vi.restoreAllMocks();
vi.unstubAllGlobals();
localStorage.clear();
});
describe("LogosRoute", () => {
it("renders the grouped Pack Universe and persistent read-only status", async () => {
stubLogosFetch();
renderRoute();
expect(await screen.findByText("Pack Universe")).toBeInTheDocument();
expect(screen.getAllByText("Depth root").length).toBeGreaterThan(0);
expect(screen.getByText("Logos cognition")).toBeInTheDocument();
expect(screen.getByText("he_logos_micro_v1")).toBeInTheDocument();
expect(screen.getByText("grc_logos_cognition_v1")).toBeInTheDocument();
expect(screen.getByText("proposal mode: none — read-only")).toBeInTheDocument();
expect(screen.getByText("no pack selected")).toBeInTheDocument();
expect(screen.queryByText(/Draft proposal/i)).not.toBeInTheDocument();
});
it("selects a pack, renders Overview, projects logos_pack evidence, and avoids deferred endpoints", async () => {
const { paths } = stubLogosFetch();
const user = userEvent.setup();
renderRoute();
await user.click(await screen.findByText("he_logos_micro_v1"));
await waitFor(() =>
expect(screen.getByTestId("location")).toHaveTextContent("/logos/he_logos_micro_v1"),
);
expect(await screen.findByText("depth-root compression")).toBeInTheDocument();
expect(screen.getByText("operational articulation")).toBeInTheDocument();
expect(screen.getByText("depth-relation precision")).toBeInTheDocument();
expect(screen.getByText("holonomy_cases · missing_evidence")).toBeInTheDocument();
expect(screen.queryByRole("tab", { name: /holonomy/i })).not.toBeInTheDocument();
expect(screen.queryByText(/proof card/i)).not.toBeInTheDocument();
expect(screen.getByText("CORE-Logos Pack")).toBeInTheDocument();
expect(screen.getByText("0 / missing_evidence")).toBeInTheDocument();
expect(paths).not.toContain("/logos/packs/he_logos_micro_v1/contents");
expect(paths).not.toContain("/logos/packs/he_logos_micro_v1/alignment");
});
it("renders Identity passport fields and the raw live overview projection", async () => {
stubLogosFetch();
const user = userEvent.setup();
renderRoute("/logos/he_logos_micro_v1");
await user.click(await screen.findByRole("tab", { name: "Identity" }));
expect(await screen.findByText("manifest_digest")).toBeInTheDocument();
expect(screen.getByText("source_manifest")).toBeInTheDocument();
expect(screen.getByText("Raw overview projection")).toBeInTheDocument();
expect(screen.getByText(/\/manifest_digest/)).toBeInTheDocument();
expect(screen.getByText(/\/schema_version/)).toBeInTheDocument();
});
it("renders Safety warnings and unknown holonomy without mapping either to clear", async () => {
stubLogosFetch();
const user = userEvent.setup();
renderRoute("/logos/grc_logos_cognition_v1");
await user.click(await screen.findByRole("tab", { name: "Safety" }));
expect(await screen.findByText("Invalid alignment targets")).toBeInTheDocument();
expect(screen.getByText("en-collapse-logos")).toBeInTheDocument();
expect(screen.getByText("Dangling morphology links")).toBeInTheDocument();
expect(screen.getByText("missing-morph")).toBeInTheDocument();
expect(screen.getByText("missing_holonomy_refs")).toBeInTheDocument();
expect(screen.getAllByText("Warning").length).toBeGreaterThan(0);
expect(screen.getAllByText("Unknown").length).toBeGreaterThan(0);
expect(screen.queryByText("Clear")).not.toBeInTheDocument();
});
});

View file

@ -0,0 +1,733 @@
import { useEffect, useMemo, useState } from "react";
import type { ReactNode } from "react";
import { useNavigate, useParams } from "react-router-dom";
import { WorkbenchApiError } from "../../api/client";
import {
useLogosPackOverview,
useLogosPacks,
useLogosPackSafety,
} from "../../api/queries";
import { MetadataTable } from "../../design/components/MetadataTable/MetadataTable";
import { Panel } from "../../design/components/Panel/Panel";
import { SplitPane } from "../../design/components/SplitPane/SplitPane";
import { StableJsonViewer } from "../../design/components/StableJsonViewer";
import { TabBar, type Tab } from "../../design/components/TabBar/TabBar";
import { EmptyState } from "../../design/components/states/EmptyState";
import { ErrorState } from "../../design/components/states/ErrorState";
import { LoadingState } from "../../design/components/states/LoadingState";
import {
SafetyVerdict as BadgeSafetyVerdict,
SafetyVerdictBadge,
} from "../../design/components/badges";
import type {
LogosAlignmentTargetIssue,
LogosMorphologyLinkIssue,
LogosPackOverview,
LogosPackSummary,
LogosSafetyReport,
SafetyVerdict,
} from "../../types/api";
import { pushRecentItem } from "../commandRegistry";
import { subjectToUrl } from "../evidenceAddress";
import { useEvidenceSubject } from "../evidenceContext";
const LOGOS_TABS: readonly Tab[] = [
{ id: "overview", label: "Overview" },
{ id: "identity", label: "Identity" },
{ id: "safety", label: "Safety" },
];
const ROLE_ORDER = ["depth_root", "depth_relation", "logos-cognition", "other"] as const;
const ROLE_LABELS: Record<string, string> = {
depth_root: "Depth root",
depth_relation: "Depth relation",
"logos-cognition": "Logos cognition",
other: "Other Logos packs",
};
const TRI_LANGUAGE = [
{
id: "en",
label: "English",
role: "operational articulation",
},
{
id: "he",
label: "Hebrew",
role: "depth-root compression",
},
{
id: "grc",
label: "Koine Greek",
role: "depth-relation precision",
},
] as const;
function errorMessage(error: unknown) {
return error instanceof WorkbenchApiError
? error.message
: "CORE-Logos request failed.";
}
function safetyVerdict(value: SafetyVerdict): BadgeSafetyVerdict {
return value as BadgeSafetyVerdict;
}
function roleKey(pack: LogosPackSummary): (typeof ROLE_ORDER)[number] {
if (pack.role === "logos-cognition" || pack.pack_id.includes("cognition")) {
return "logos-cognition";
}
if (pack.role === "depth_root" || pack.role === "depth_relation") {
return pack.role;
}
return "other";
}
function roleLabel(role: string | null): string {
if (!role) return "not declared";
return ROLE_LABELS[role] ?? role.replaceAll("_", " ");
}
function languageLabel(language: string | null): string {
if (language === "he") return "Hebrew";
if (language === "grc") return "Koine Greek";
if (language === "en") return "English";
return language ?? "not declared";
}
function CountBadge({ label, value }: { label: string; value: number }) {
return (
<span className="inline-flex h-6 items-center rounded-md border border-[var(--color-border-subtle)] bg-[var(--color-surface-inset)] px-2 text-xs text-[var(--color-text-secondary)]">
<span className="font-mono text-[var(--color-text-primary)]">{value}</span>
<span className="ml-1">{label}</span>
</span>
);
}
function StatusPill({
tone,
children,
}: {
tone: "neutral" | "warning" | "danger";
children: ReactNode;
}) {
const className =
tone === "warning"
? "border-[var(--color-state-warning-border)] bg-[var(--color-state-warning-bg)] text-[var(--color-state-warning-text)]"
: tone === "danger"
? "border-[var(--color-state-danger-border)] bg-[var(--color-state-danger-bg)] text-[var(--color-state-danger-text)]"
: "border-[var(--color-border-subtle)] bg-[var(--color-surface-inset)] text-[var(--color-text-secondary)]";
return (
<span className={`inline-flex h-6 items-center rounded-md border px-2 text-xs ${className}`}>
{children}
</span>
);
}
function PackRow({
pack,
selected,
onSelect,
}: {
pack: LogosPackSummary;
selected: boolean;
onSelect: () => void;
}) {
return (
<div
role="button"
tabIndex={0}
aria-current={selected ? "true" : undefined}
onClick={onSelect}
onKeyDown={(event) => {
if (event.key !== "Enter" && event.key !== " ") return;
event.preventDefault();
onSelect();
}}
className={`grid w-full grid-cols-[minmax(0,1fr)_auto] items-start gap-3 border-b border-[var(--color-border-subtle)] px-3 py-2 text-left transition-colors hover:bg-[var(--color-surface-inset)] focus-visible:outline focus-visible:outline-2 focus-visible:outline-inset focus-visible:outline-[var(--color-focus-ring)] ${
selected
? "border-l-2 border-l-[var(--color-selected-border)] bg-[var(--color-selected-bg)] pl-[10px]"
: "border-l-2 border-l-transparent pl-[10px]"
}`}
>
<span className="min-w-0">
<span className="block truncate font-mono text-sm text-[var(--color-text-primary)]">
{pack.pack_id}
</span>
<span className="mt-1 flex flex-wrap items-center gap-2 text-xs text-[var(--color-text-secondary)]">
<span>{roleLabel(pack.role)}</span>
<span aria-hidden className="text-[var(--color-text-muted)]">
·
</span>
<span>{languageLabel(pack.language)}</span>
{pack.script ? <span>{pack.script}</span> : null}
</span>
<span className="mt-2 flex flex-wrap gap-1.5">
<CountBadge label="lex" value={pack.lexicon_count} />
<CountBadge label="gloss" value={pack.gloss_count} />
<CountBadge label="morph" value={pack.morphology_count} />
<CountBadge label="align" value={pack.alignment_edge_count} />
<CountBadge label="holonomy" value={pack.holonomy_case_count} />
</span>
</span>
<span
className="justify-self-end"
onClick={(event) => event.stopPropagation()}
>
<SafetyVerdictBadge value={safetyVerdict(pack.safety_status)} />
</span>
</div>
);
}
function PackUniverse({
packs,
selectedPackId,
onSelect,
}: {
packs: readonly LogosPackSummary[];
selectedPackId: string | null;
onSelect: (pack: LogosPackSummary) => void;
}) {
const groups = useMemo(() => {
const byRole = new Map<(typeof ROLE_ORDER)[number], LogosPackSummary[]>(
ROLE_ORDER.map((role) => [role, []]),
);
for (const pack of packs) byRole.get(roleKey(pack))!.push(pack);
return ROLE_ORDER.map((role) => ({
role,
packs: byRole.get(role)!.toSorted((a, b) => a.pack_id.localeCompare(b.pack_id)),
})).filter((group) => group.packs.length > 0);
}, [packs]);
return (
<Panel title="Pack Universe">
<div className="grid min-h-0 gap-4">
{groups.map((group) => (
<section key={group.role} aria-labelledby={`logos-group-${group.role}`}>
<div className="mb-2 flex items-center justify-between gap-2">
<h3
id={`logos-group-${group.role}`}
className="m-0 text-xs font-semibold uppercase text-[var(--color-text-secondary)]"
>
{ROLE_LABELS[group.role]}
</h3>
<CountBadge label="packs" value={group.packs.length} />
</div>
<div className="overflow-hidden rounded-md border border-[var(--color-border-subtle)]">
{group.packs.map((pack) => (
<PackRow
key={pack.pack_id}
pack={pack}
selected={pack.pack_id === selectedPackId}
onSelect={() => onSelect(pack)}
/>
))}
</div>
</section>
))}
</div>
</Panel>
);
}
function OverviewTab({ overview }: { overview: LogosPackOverview }) {
const counts = [
["lexicon", overview.lexicon_count],
["glosses", overview.gloss_count],
["morphology", overview.morphology_count],
["frames", overview.frame_count],
["compositions", overview.composition_count],
["alignment_edges", overview.alignment_edge_count],
] as const;
return (
<div className="grid gap-4">
<section className="grid gap-3 sm:grid-cols-3">
{TRI_LANGUAGE.map((item) => {
const active =
overview.language === item.id ||
(item.id === "he" && overview.role === "depth_root") ||
(item.id === "grc" && overview.role === "depth_relation");
return (
<div
key={item.id}
className={`rounded-md border p-3 ${
active
? "border-[var(--color-focus-ring)] bg-[var(--color-surface-inset)]"
: "border-[var(--color-border-subtle)]"
}`}
>
<h3 className="m-0 text-sm font-semibold text-[var(--color-text-primary)]">
{item.label}
</h3>
<p className="m-0 mt-1 text-xs text-[var(--color-text-secondary)]">
{item.role}
</p>
</div>
);
})}
</section>
<MetadataTable
rows={[
{ key: "role", value: roleLabel(overview.role) },
{ key: "language", value: languageLabel(overview.language) },
{ key: "script", value: overview.script ?? "not declared" },
{ key: "version", value: overview.version ?? "not declared", mono: true },
{
key: "determinism",
value: overview.determinism_class ?? "not declared",
},
{
key: "gate",
value: overview.gate_engaged ? "engaged" : "not engaged",
},
{ key: "OOV", value: overview.oov_policy ?? "not declared" },
{
key: "safety",
value: <SafetyVerdictBadge value={safetyVerdict(overview.safety_status)} />,
},
]}
/>
<section className="grid gap-2 sm:grid-cols-3 lg:grid-cols-4">
{counts.map(([label, value]) => (
<div
key={label}
className="rounded-md border border-[var(--color-border-subtle)] p-3"
>
<div className="font-mono text-lg text-[var(--color-text-primary)]">
{value}
</div>
<div className="text-xs text-[var(--color-text-secondary)]">{label}</div>
</div>
))}
<div className="rounded-md border border-[var(--color-state-warning-border)] bg-[var(--color-state-warning-bg)] p-3">
<div className="font-mono text-lg text-[var(--color-state-warning-text)]">
{overview.holonomy_case_count}
</div>
<div className="text-xs text-[var(--color-state-warning-text)]">
holonomy_cases · missing_evidence
</div>
</div>
</section>
</div>
);
}
function IdentityTab({ overview }: { overview: LogosPackOverview }) {
return (
<div className="grid gap-4">
<MetadataTable
rows={[
{ key: "pack_id", value: overview.pack_id, mono: true, copyable: true },
{ key: "manifest_path", value: overview.manifest_path, mono: true, copyable: true },
{
key: "manifest_digest",
value: overview.manifest_digest,
mono: true,
copyable: true,
},
{
key: "source_manifest",
value: overview.source_manifest ?? "not declared",
mono: overview.source_manifest !== null,
},
{
key: "normalization",
value: overview.normalization_policy ?? "not declared",
},
{ key: "known_gaps", value: overview.known_gaps.length.toString(), mono: true },
]}
/>
<section>
<h3 className="m-0 mb-2 text-xs font-semibold text-[var(--color-text-secondary)]">
Raw overview projection
</h3>
<StableJsonViewer source={JSON.stringify(overview, null, 2)} />
</section>
</div>
);
}
function IssueList({
title,
empty,
items,
}: {
title: string;
empty: string;
items: readonly ReactNode[];
}) {
return (
<section className="rounded-md border border-[var(--color-border-subtle)] p-3">
<h3 className="m-0 mb-2 text-xs font-semibold text-[var(--color-text-secondary)]">
{title}
</h3>
{items.length > 0 ? (
<div className="grid gap-2">{items}</div>
) : (
<p className="m-0 text-sm text-[var(--color-text-secondary)]">{empty}</p>
)}
</section>
);
}
function MorphologyIssue({ issue }: { issue: LogosMorphologyLinkIssue }) {
return (
<div className="rounded border border-[var(--color-state-warning-border)] bg-[var(--color-state-warning-bg)] p-2 text-xs text-[var(--color-state-warning-text)]">
<span className="font-mono">{issue.entry_id}</span>
<span> references missing morphology </span>
<span className="font-mono">{issue.morphology_id}</span>
</div>
);
}
function AlignmentIssue({ issue }: { issue: LogosAlignmentTargetIssue }) {
return (
<div className="rounded border border-[var(--color-state-warning-border)] bg-[var(--color-state-warning-bg)] p-2 text-xs text-[var(--color-state-warning-text)]">
<span className="font-mono">{issue.edge_id}</span>
<span> invalid target </span>
<span className="font-mono">{issue.target_id}</span>
<span> via {issue.relation}</span>
{issue.target_pack_id ? (
<span>
{" "}
in <span className="font-mono">{issue.target_pack_id}</span>
</span>
) : null}
</div>
);
}
function SafetyTab({ report }: { report: LogosSafetyReport }) {
const epistemicRows = Object.entries(report.epistemic_status_counts).sort(([a], [b]) =>
a.localeCompare(b),
);
return (
<div className="grid gap-4">
<MetadataTable
rows={[
{
key: "verdict",
value: <SafetyVerdictBadge value={safetyVerdict(report.verdict)} />,
},
{
key: "checksum",
value: <SafetyVerdictBadge value={safetyVerdict(report.checksum_status)} />,
},
{
key: "domain_contract",
value: (
<SafetyVerdictBadge value={safetyVerdict(report.domain_contract_status)} />
),
},
{
key: "missing_holonomy_refs",
value: (
<SafetyVerdictBadge value={safetyVerdict(report.missing_holonomy_refs)} />
),
},
{
key: "OOV policy",
value: report.oov_policy_ok ? (
<StatusPill tone="neutral">ok</StatusPill>
) : (
<StatusPill tone="danger">failed</StatusPill>
),
},
{
key: "gate policy",
value: report.gate_policy_ok ? (
<StatusPill tone="neutral">ok</StatusPill>
) : (
<StatusPill tone="danger">failed</StatusPill>
),
},
{
key: "path safety",
value: report.path_safety_ok ? (
<StatusPill tone="neutral">ok</StatusPill>
) : (
<StatusPill tone="danger">failed</StatusPill>
),
},
]}
/>
<section className="grid gap-3 md:grid-cols-2">
<IssueList
title="Checksum errors"
empty="none recorded"
items={report.checksum_errors.map((item) => (
<div
key={item}
className="rounded border border-[var(--color-state-danger-border)] bg-[var(--color-state-danger-bg)] p-2 text-xs text-[var(--color-state-danger-text)]"
>
{item}
</div>
))}
/>
<IssueList
title="Known gaps"
empty="none recorded"
items={report.known_gaps.map((item) => (
<div
key={item}
className="rounded border border-[var(--color-state-warning-border)] bg-[var(--color-state-warning-bg)] p-2 text-xs text-[var(--color-state-warning-text)]"
>
{item}
</div>
))}
/>
<IssueList
title="Dangling morphology links"
empty="none recorded"
items={report.dangling_morphology_links.map((issue) => (
<MorphologyIssue key={`${issue.entry_id}:${issue.morphology_id}`} issue={issue} />
))}
/>
<IssueList
title="Invalid alignment targets"
empty="none recorded"
items={report.invalid_alignment_targets.map((issue) => (
<AlignmentIssue key={issue.edge_id} issue={issue} />
))}
/>
</section>
<section className="grid gap-3 md:grid-cols-2">
<div className="rounded-md border border-[var(--color-border-subtle)] p-3">
<h3 className="m-0 mb-2 text-xs font-semibold text-[var(--color-text-secondary)]">
Epistemic counts
</h3>
{epistemicRows.length === 0 ? (
<p className="m-0 text-sm text-[var(--color-text-secondary)]">none recorded</p>
) : (
<MetadataTable
rows={epistemicRows.map(([key, value]) => ({
key,
value: String(value),
mono: true,
}))}
/>
)}
</div>
<div className="rounded-md border border-[var(--color-border-subtle)] p-3">
<h3 className="m-0 mb-2 text-xs font-semibold text-[var(--color-text-secondary)]">
Epistemic entry sets
</h3>
<MetadataTable
rows={[
{
key: "speculative",
value: String(report.speculative_entries.length),
mono: true,
},
{
key: "contested",
value: String(report.contested_entries.length),
mono: true,
},
{
key: "falsified",
value: String(report.falsified_entries.length),
mono: true,
},
]}
/>
</div>
</section>
</div>
);
}
function StatusStrip({
selectedPackId,
overview,
safety,
}: {
selectedPackId: string | null;
overview?: LogosPackOverview;
safety?: LogosSafetyReport;
}) {
const selected = overview?.pack_id ?? selectedPackId ?? "no pack selected";
const checksum = safety?.checksum_status ?? "unknown";
const gateOov = overview
? `gate ${overview.gate_engaged ? "engaged" : "not engaged"} / OOV ${
overview.oov_policy ?? "unknown"
}`
: "gate/OOV unknown";
return (
<footer className="mt-3 flex flex-wrap items-center gap-2 border-t border-[var(--color-border-subtle)] pt-2 text-xs text-[var(--color-text-secondary)]">
<span className="font-mono text-[var(--color-text-primary)]">{selected}</span>
<span aria-hidden>·</span>
<span>checksum {checksum}</span>
<span aria-hidden>·</span>
<span>{gateOov}</span>
<span aria-hidden>·</span>
<span>proposal mode: none read-only</span>
</footer>
);
}
function Workspace({
selectedPackId,
overview,
overviewLoading,
overviewError,
safety,
safetyLoading,
safetyError,
}: {
selectedPackId: string | null;
overview?: LogosPackOverview;
overviewLoading: boolean;
overviewError: unknown;
safety?: LogosSafetyReport;
safetyLoading: boolean;
safetyError: unknown;
}) {
const [activeTab, setActiveTab] = useState("overview");
if (selectedPackId === null) {
return (
<EmptyState
statement="Select a CORE-Logos pack to inspect overview, identity, and safety evidence."
nextAction={{ kind: "cli", command: "core pack validate <path>" }}
/>
);
}
if (overviewLoading) {
return <LoadingState label="Loading CORE-Logos pack..." />;
}
if (overviewError) {
return (
<ErrorState
whatFailed={errorMessage(overviewError)}
mutationStatus="No Logos mutation occurred."
reproducer={`curl /logos/packs/${selectedPackId}`}
retrySafety="Retry: safe"
/>
);
}
if (!overview) return null;
return (
<Panel
title={overview.pack_id}
toolbar={<SafetyVerdictBadge value={safetyVerdict(overview.safety_status)} />}
>
<TabBar tabs={LOGOS_TABS} activeTab={activeTab} onTabChange={setActiveTab}>
{activeTab === "overview" ? <OverviewTab overview={overview} /> : null}
{activeTab === "identity" ? <IdentityTab overview={overview} /> : null}
{activeTab === "safety" ? (
safetyLoading ? (
<LoadingState label="Loading CORE-Logos safety..." />
) : safetyError ? (
<ErrorState
whatFailed={errorMessage(safetyError)}
mutationStatus="No Logos mutation occurred."
reproducer={`curl /logos/packs/${selectedPackId}/safety`}
retrySafety="Retry: safe"
/>
) : safety ? (
<SafetyTab report={safety} />
) : null
) : null}
</TabBar>
</Panel>
);
}
export function LogosRoute() {
const { logosPackId } = useParams();
const selectedPackId = logosPackId && logosPackId.length > 0 ? logosPackId : null;
const navigate = useNavigate();
const { setSubject } = useEvidenceSubject();
const packsQuery = useLogosPacks();
const overviewQuery = useLogosPackOverview(selectedPackId);
const safetyQuery = useLogosPackSafety(selectedPackId);
useEffect(() => {
if (selectedPackId === null) return;
setSubject({
kind: "logos_pack",
packId: selectedPackId,
data: overviewQuery.data
? {
...overviewQuery.data,
checksum_status: safetyQuery.data?.checksum_status ?? null,
}
: undefined,
});
}, [selectedPackId, setSubject, overviewQuery.data, safetyQuery.data]);
function selectPack(pack: LogosPackSummary) {
const subject = { kind: "logos_pack" as const, packId: pack.pack_id };
const path = subjectToUrl(subject);
navigate(path, { replace: true });
pushRecentItem({ label: pack.pack_id, path });
}
if (packsQuery.isLoading) {
return <LoadingState label="Loading CORE-Logos packs..." />;
}
if (packsQuery.isError) {
return (
<ErrorState
whatFailed={errorMessage(packsQuery.error)}
mutationStatus="No Logos mutation occurred."
reproducer="curl /logos/packs"
retrySafety="Retry: safe"
/>
);
}
const packs = packsQuery.data ?? [];
if (packs.length === 0) {
return (
<EmptyState
statement="No CORE-Logos packs discovered."
nextAction={{ kind: "cli", command: "core pack validate <path>" }}
/>
);
}
return (
<div className="flex h-full min-h-0 flex-col">
<div className="min-h-0 flex-1">
<SplitPane direction="horizontal" id="logos" defaultSplit={34} minSize={300}>
<PackUniverse
packs={packs}
selectedPackId={selectedPackId}
onSelect={selectPack}
/>
<section className="h-full min-h-0 overflow-y-auto pl-3">
<Workspace
selectedPackId={selectedPackId}
overview={overviewQuery.data}
overviewLoading={overviewQuery.isLoading}
overviewError={overviewQuery.isError ? overviewQuery.error : null}
safety={safetyQuery.data}
safetyLoading={safetyQuery.isLoading}
safetyError={safetyQuery.isError ? safetyQuery.error : null}
/>
</section>
</SplitPane>
</div>
<StatusStrip
selectedPackId={selectedPackId}
overview={overviewQuery.data}
safety={safetyQuery.data}
/>
</div>
);
}

View file

@ -16,6 +16,7 @@ import { ReplayRoute } from "./replay/ReplayRoute";
import { DemoTheaterRoute } from "./demos/DemoTheaterRoute";
import { RunsRoute } from "./runs/RunsRoute";
import { PacksRoute } from "./packs/PacksRoute";
import { LogosRoute } from "./logos/LogosRoute";
import { VaultRoute } from "./vault/VaultRoute";
import { CalibrationRoute } from "./calibration/CalibrationRoute";
import { SettingsRoute } from "./settings/SettingsRoute";
@ -194,6 +195,15 @@ const MOUNT_ROUTES: MountRouteSpec[] = [
emptyStatement: "No packs discovered.",
emptyCommand: "core pack validate <path>",
},
{
name: "CORE-Logos",
element: <LogosRoute />,
path: "/logos/:logosPackId?",
initialEntry: "/logos",
loadingLabel: "Loading CORE-Logos packs...",
emptyStatement: "No CORE-Logos packs discovered.",
emptyCommand: "core pack validate <path>",
},
{
name: "Vault",
element: <VaultRoute />,

View file

@ -235,6 +235,19 @@ export const WORKBENCH_ROUTES: readonly WorkbenchRoute[] = [
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: "settings",
path: "/settings",

View file

@ -5,6 +5,7 @@ import {
groundingSourceMeta,
normativeClearanceMeta,
reviewStateMeta,
safetyVerdictMeta,
} from "./mappings";
function expectExactCoverage(name: string, engineValues: string[], uiValues: string[]) {
@ -43,4 +44,12 @@ describe("build-time enum coverage", () => {
Object.keys(groundingSourceMeta),
);
});
it("tracks every ratified SafetyVerdict value exactly once", () => {
expectExactCoverage(
"SafetyVerdict",
snapshot.SafetyVerdict,
Object.keys(safetyVerdictMeta),
);
});
});

View file

@ -3,6 +3,7 @@ import {
groundingSourceMeta,
normativeClearanceMeta,
reviewStateMeta,
safetyVerdictMeta,
} from "./mappings";
import { InfoBadge } from "./Badge";
import {
@ -10,6 +11,7 @@ import {
GroundingSource,
NormativeClearance,
ReviewState,
SafetyVerdict,
} from "./types";
export {
@ -17,6 +19,7 @@ export {
GroundingSource,
NormativeClearance,
ReviewState,
SafetyVerdict,
};
export function EpistemicStateBadge({ value }: { value: EpistemicState }) {
@ -35,6 +38,10 @@ export function GroundingSourceBadge({ value }: { value: GroundingSource }) {
return <InfoBadge {...groundingSourceMeta[value]} />;
}
export function SafetyVerdictBadge({ value }: { value: SafetyVerdict }) {
return <InfoBadge {...safetyVerdictMeta[value]} />;
}
export function TraceHashBadge({
value,
truncate = 12,

View file

@ -3,6 +3,7 @@ import {
GroundingSource,
NormativeClearance,
ReviewState,
SafetyVerdict,
type BadgeMeta,
} from "./types";
@ -46,3 +47,10 @@ export const groundingSourceMeta = {
[GroundingSource.OOV]: { label: "OOV", colorToken: "--color-grounding-oov", meaning: "Out-of-vocabulary grounding was encountered.", adr: "ADR-0160 / ADR-0162", evidence: "grounding_source is oov." },
[GroundingSource.NONE]: { label: "None", colorToken: "--color-grounding-none", meaning: "No grounding source was present.", adr: "ADR-0160 / ADR-0162", evidence: "grounding_source is none." },
} satisfies BadgeMeta<GroundingSource>;
export const safetyVerdictMeta = {
[SafetyVerdict.CLEAR]: { label: "Clear", colorToken: "--color-state-verified", meaning: "The reported Logos safety check has no recorded warning or failure.", adr: "ADR-0162 / CORE-Logos LG-2", evidence: "SafetyVerdict is clear." },
[SafetyVerdict.WARNING]: { label: "Warning", colorToken: "--color-state-warning-text", meaning: "The reported Logos safety check found reviewable gaps or link issues; this is not clear.", adr: "ADR-0162 / CORE-Logos LG-2", evidence: "SafetyVerdict is warning." },
[SafetyVerdict.FAILED]: { label: "Failed", colorToken: "--color-state-danger-text", meaning: "The reported Logos safety check failed a blocking contract.", adr: "ADR-0162 / CORE-Logos LG-2", evidence: "SafetyVerdict is failed." },
[SafetyVerdict.UNKNOWN]: { label: "Unknown", colorToken: "--color-state-undetermined", meaning: "The reported Logos safety check lacks proof evidence; this is not clear.", adr: "ADR-0162 / CORE-Logos LG-2", evidence: "SafetyVerdict is unknown." },
} satisfies BadgeMeta<SafetyVerdict>;

View file

@ -39,6 +39,13 @@ export enum GroundingSource {
NONE = "none",
}
export enum SafetyVerdict {
CLEAR = "clear",
WARNING = "warning",
FAILED = "failed",
UNKNOWN = "unknown",
}
export type BadgeMeta<T extends string> = Record<
T,
{

View file

@ -52,11 +52,11 @@ describe("CommandPalette keyboard contract", () => {
expect(screen.getByRole("button", { name: "Open Trace" })).toBeInTheDocument();
expect(screen.getByRole("button", { name: "Open Replay" })).toBeInTheDocument();
// One Navigate command per palette-visible route (14), derived from the
// route registry — Demos, Calibration, Contemplation, and Tour are included
// (the prior hand-maintained list of 10 dropped them).
// One Navigate command per palette-visible route (15), derived from the
// route registry — Demos, Calibration, Contemplation, Tour, and CORE-Logos
// are included (the prior hand-maintained list of 10 dropped them).
const items = dialog.querySelectorAll('[role="option"]');
expect(items.length).toBe(14);
expect(items.length).toBe(15);
const lastIndex = items.length - 1;
// Initially first item (index 0) is focused — check aria-selected

View file

@ -21,20 +21,7 @@ import { describe, expect, it } from "vitest";
// Shrink-only debt: backend schemas shipped ahead of their TS mirror. A class
// gaining a TS interface while still listed here fails the gate.
// CORE-Logos read models (LG-1): backend readers shipped without the /logos
// frontend route; LG-2 adds the TS interfaces and removes each entry here.
const NOT_YET_MIRRORED = new Set<string>([
"LogosPackSummary",
"LogosPackOverview",
"LogosPackContents",
"LogosLexiconRow",
"LogosGlossRow",
"LogosMorphologyRow",
"LogosAlignmentRow",
"LogosMorphologyLinkIssue",
"LogosAlignmentTargetIssue",
"LogosSafetyReport",
]);
const NOT_YET_MIRRORED = new Set<string>([]);
const UI_ROOT = join(__dirname, "..", "..", "..");
const snapshot: Record<string, string[]> = JSON.parse(

View file

@ -302,6 +302,7 @@ export interface AuditEvent {
}
export type PackSource = "language_pack" | "runtime_pack";
export type SafetyVerdict = "clear" | "warning" | "failed" | "unknown";
export interface PackSummary {
pack_id: string;
@ -320,6 +321,130 @@ export interface PackDetail extends PackSummary {
manifest: Record<string, unknown>;
}
export interface LogosPackSummary {
pack_id: string;
language: string | null;
role: string | null;
script: string | null;
version: string | null;
determinism_class: string | null;
gate_engaged: boolean;
oov_policy: string | null;
lexicon_count: number;
gloss_count: number;
morphology_count: number;
frame_count: number;
composition_count: number;
alignment_edge_count: number;
holonomy_case_count: number;
safety_status: SafetyVerdict;
manifest_digest: string;
manifest_path: string;
}
export interface LogosPackOverview extends LogosPackSummary {
schema_version: "logos_pack_overview_v1";
normalization_policy: string | null;
source_manifest: string | null;
known_gaps: string[];
}
export interface LogosLexiconRow {
entry_id: string;
surface: string;
lemma: string;
language: string;
part_of_speech: string | null;
pos: string | null;
morphology_id: string | null;
morphology_tags: string[];
semantic_domains: string[];
provenance_ids: string[];
epistemic_status: string;
}
export interface LogosGlossRow {
gloss_id: string;
lemma: string;
gloss: string;
pos: string | null;
entry_ids: string[];
provenance_ids: string[];
epistemic_status: string | null;
raw: Record<string, unknown>;
}
export interface LogosMorphologyRow {
morphology_id: string;
surface: string;
lemma: string;
language: string;
root: string | null;
prefix_chain: string[];
stem: string | null;
inflection: Record<string, string>;
suffix_chain: string[];
}
export interface LogosAlignmentRow {
edge_id: string;
source_id: string;
target_id: string;
relation: string;
weight: number;
evidence_ids: string[];
target_pack_id: string | null;
target_resolved: boolean;
invalid_target: boolean;
}
export interface LogosPackContents {
schema_version: "logos_pack_contents_v1";
pack_id: string;
manifest: Record<string, unknown>;
lexicon: LogosLexiconRow[];
glosses: LogosGlossRow[];
morphology: LogosMorphologyRow[];
frames: Record<string, unknown>[];
compositions: Record<string, unknown>[];
alignment_edges: LogosAlignmentRow[];
holonomy_cases: Record<string, unknown>[];
}
export interface LogosMorphologyLinkIssue {
entry_id: string;
morphology_id: string;
}
export interface LogosAlignmentTargetIssue {
edge_id: string;
source_id: string;
target_id: string;
relation: string;
target_pack_id: string | null;
}
export interface LogosSafetyReport {
schema_version: "logos_safety_report_v1";
pack_id: string;
checksum_status: SafetyVerdict;
checksum_errors: string[];
domain_contract: Record<string, unknown>;
domain_contract_status: SafetyVerdict;
oov_policy_ok: boolean;
gate_policy_ok: boolean;
path_safety_ok: boolean;
dangling_morphology_links: LogosMorphologyLinkIssue[];
invalid_alignment_targets: LogosAlignmentTargetIssue[];
missing_holonomy_refs: SafetyVerdict;
epistemic_status_counts: Record<string, number>;
speculative_entries: string[];
contested_entries: string[];
falsified_entries: string[];
known_gaps: string[];
verdict: SafetyVerdict;
}
export type ArtifactKind =
| "trace"
| "eval_result"