Context. surface operator · domain operator (metis — institutional dashboard) · route /operator/metis · auth signed-in · source apps/oshun/web/src/app/operator/metis/page.tsx
Last walked. 2026-06-25 Metis stable-anchor addendum — page/header/KPI/review-row/side-panel anchors, full row-cell assertions, OneRoster sync card, tutor telemetry, Themis flags, and anonymous redirect-before-render covered in apps/oshun/web/e2e/metis-byom-ingest.spec.ts. Evidence: WALKTHROUGH/results/v1-real-infra-run-2026-06-22.md §87; 2026-06-26 Themis appeal review addendum — live queue/read/resolve UI covered in apps/oshun/web/e2e/operator-metis-themis-review.spec.ts; 2026-06-27 OneRoster live-card addendum — real apply -> /operator/metis card read-back covered in apps/oshun/web/e2e/tenant-oneroster-metis-card.spec.ts
Purpose#
The institutional Metis dashboard for school/tenant operators: lesson review
queue, OneRoster sync, tutor telemetry, and Themis academic-integrity flags.
"The schoolroom, behind the curtain." Robots-noindex. Backed by
getMetisOperator() and rendered by MetisOperator (defined at metis.tsx:940
in the ~1115-LOC Lilith design-system room).
Entry points#
- From
/operator(index) — surface card - Profile menu → Operator → Metis
- Direct URL — session-gated only (
proxy.tsredirects sessionless →/welcome?redirect=); no operator-role gate in the proxy - OneRoster sync alerts — auto-deep-link from notification → here
- Themis flag notifications — academic integrity issues route here
Layout regions#
The component uses Lilith primitives (LGraphPaper, LOperatorBar, LEyebrow,
LCode, L, SERIF_L) and exposes stable data-operator-metis-* anchors for
the page, header, KPI grid, review queue, side panel, OneRoster card, tutor
card, and Themis card.
- Top:
LOperatorBar— product="Oshun Studio", section="Metis", breadcrumb="Authoring · institutional" - Header band (
data-operator-metis-header):- Eyebrow accent "Authoring · Metis · institutional"
- Garamond 28 line: "The schoolroom, behind the curtain."
- Right-aligned
LCodemuted: "tenant · concord public library · 14 schools"
- KPI grid (
data-operator-metis-kpi-grid) — 5-column, inline-borders, paper background, italic Garamond 32 values; values of "✓" render inL.ok(success green). Each cell carriesdata-operator-metis-kpi-cellanddata-operator-metis-kpi-value. - Two-column section (1.5fr 1fr):
- Left (1.5fr): "Generated lessons · review queue" — table with columns
Course / Lesson / Sources / Quality / State, dotted row dividers, row anchors for course/state, and cell anchors for course, lesson, sources, quality, and state. - Right (1fr) (
data-operator-metis-side-panel): OneRoster sync card (fixture fields for normal signed-in renders, live BFFLast commit,Tenants,Users, andEnrollmentsfields for admin renders), tutor telemetry 24-hour sparkline withtutor · 1,820, Themis flags (Originality < 0.6,Tutor wrote answer,Quotation unverified), and the live Themis appeal review panel.
- Left (1.5fr): "Generated lessons · review queue" — table with columns
- Themis appeal review (
data-operator-metis-themis-appeal-panel) — client panel fetchesGET /v1/metis/integrity/appealswith operator scope, renders each real appeal workspace row withdata-operator-metis-themis-appeal-row,data-operator-metis-themis-appeal-id, status, subject, claimant, evidence count, timeline deadline summary, due-process summary, resolution note field, and a resolve submit region withdata-operator-metis-themis-appeal-submit-state. - Total page padding
24px 28px 60px
States#
- Loading — source-verified: no local
loading.tsx;page.tsxawaitsgetMetisOperator()server-side before rendering. - Anonymous user — redirected to
/welcome?redirect=byproxy.tsbefore[data-operator-metis-page]or review rows render (Playwright, 2026-06-25) - Signed-in user — renders (session-gated only; no operator-role gate in the proxy)
- Tenant set + healthy — KPI grid populated; all five queue rows visible with stable row/cell anchors (Playwright, 2026-06-25)
- Empty review queue — table without body rows
- Themis flags present — side panel shows all three fixture flag rows (Playwright, 2026-06-25)
- Themis appeal review present — when the BFF contains an academic- integrity appeal, the operator panel renders the live dispute row, evidence count, timeline deadline summary, due-process summary, and resolve controls (Playwright, 2026-06-26).
- OneRoster sync status — sync card surfaces fixture last-sync, class/student deltas, and zero conflicts for regular signed-in renders (Playwright, 2026-06-25).
- Live OneRoster projection — with a tenant-console admin cookie,
getMetisOperator()readsGET /v1/admin/lms/oneroster; after a real apply the card exposes BFF source, aggregate counts, and the committed tenant summary (Playwright, 2026-06-27). - OneRoster out of sync warning — no warning variant is present in the current fixture.
-
getMetisOperator()fails — no local segmenterror.tsxis present; failure boundary remains unverified. - Different tenant context — page re-renders with new institution name + KPIs
Interactions#
Header band#
- Tenant code (
LCode) — non-interactive label; Playwright verifies the exact tenant label viadata-operator-metis-tenant-code
KPI grid#
- Each KPI cell — non-interactive numeric display; Playwright verifies
all five fixture labels and values via
data-operator-metis-kpi-value.✓renders in success green. - Keyboard / SR: cells are part of natural reading order; consider a list semantic if these are status-bearing
Review queue table#
- Column headers (
Course / Lesson / Sources / Quality / State) — non-interactive - Each row — all five fixture rows render as non-link, non-button rows;
the separate
MetisByomDecisionPanelhandles approve/request/reject for the first pending item. - Sources column — citation-count plus source-quality label verified for all rows.
- Quality column — Sophia-style band plus decimal score verified for all rows.
- State column —
LDecisionChiptext verified asapproved,review, andchanges.
OneRoster sync card#
- Sync status —
Last sync,Classes,Students, andConflictsrows verified through stable field anchors. - Live projection read-back — a real OneRoster apply is visible through
data-operator-metis-oneroster-source="bff"and per-tenant row anchors. - Retry sync action — no retry action is present in the current component.
Themis flags#
- Flag rows — academic-integrity flags for originality, tutor-written answers, and unverified quotations verified through stable field anchors.
- Appeal review read —
MetisThemisAppealReviewPanelloads the live operator queue fromGET /v1/metis/integrity/appeals; the row renders the canonical dispute, evidence, timeline, and due-process profile. - Resolve appeal — operator enters a resolution note; blank notes keep
the submit region blocked, valid notes call
POST /v1/metis/integrity/appeals/:appealId/resolve, and the row updates tostatus=closedwith the returned note. - Dedicated uphold / dismiss / escalate verdict actions — distinct
verdict-class adjudication controls remain outside the current component;
teacher override/upheld verdict classes are covered by direct real-BFF
HTTP in
integrity-appeal.spec.ts.
Tutor telemetry#
- Tutor metrics — 24-hour sparkline plus
tutor · 1,820label verified through stable anchors.
E2E coverage#
apps/oshun/web/e2e/metis-byom-ingest.spec.tscovers signed-in/operator/metis, the page/header anchors, tenant label, all KPI labels and values, review table headers, all five review rows cell-by-cell, state-chip distribution, OneRoster sync card, tutor telemetry sparkline, Themis flag fields, and anonymous redirect-before-render.apps/oshun/web/e2e/metis-byom-decision.spec.tscovers the real approve/request-changes/reject decision island over/v1/admin/metis/byom/decision.apps/oshun/web/e2e/operator-metis-themis-review.spec.tsseeds a real academic-integrity verdict + appeal through the BFF, opens/operator/metis, verifies the live appeal row, and resolves it through the browser panel.apps/oshun/web/e2e/tenant-oneroster-metis-card.spec.tscommits a clean OneRoster import through the real BFF, opens/operator/metis, and verifies the live roster card source/count attributes plus the committed tenant summary row.
Data & contracts#
- Reads:
getMetisOperator()from@/lib/lilith-data/metis-depthreturningMetisOperatorData(kpi, queue, OneRoster status). It falls back to the static fixture for non-admin/missing-BFF renders, and for tenant-console admin renders adaptsGET /v1/admin/lms/onerosterinto the OneRoster card. The live Themis appeal panel additionally readsGET /v1/metis/integrity/appealsfrom the BFF. - Writes: BYOM approval/request-changes/reject through
MetisByomDecisionPanel; Themis appeal resolution throughPOST /v1/metis/integrity/appeals/:appealId/resolve. OneRoster retry is not present in the route component. - Realtime: Themis flags may stream in; verify Psyche channel
- Caching: server-rendered; no SW caching for operator routes
- Auth/role check: session-gated only (
proxy.tsredirects sessionless →/welcome?redirect=); no operator-role gate in the proxy
Cross-references#
- Parent:
operator-overview.md - Sibling operator routes:
- Customer-side Metis:
../customer/08-metis/ - Themis is referenced in V1/features.md as the academic-integrity adjudication substrate for Metis assessments
- Component source:
apps/oshun/web/src/components/lilith/metis.tsx(line 940:MetisOperator) - Feature spec:
V1/features.md - Architecture:
V1/ARCHITECTURE.md
Open questions / known gaps#
- Walk the bottom half of
MetisOperatorto enumerate the OneRoster sync card, tutor telemetry, and Themis flag list (2026-06-25) - Confirm the relationship between this operator surface and the Themis adjudication backend; document the contract (2026-06-26)
- Document the OneRoster sync action flow (retry, force-resync, reset)
- Verify tenant-context switching is wired (the
tenant · concord public library · 14 schoolslabel suggests a multi-tenant view; no switcher visible in the fixture) - An operator-role gate appears absent —
proxy.tsonly redirects sessionless users to/welcome; no role check in the proxy or page component (possible gap vs intended scope)