Context. surface customer · domain metis · route /metis/assessment · auth signed-in · source apps/oshun/web/src/app/metis/assessment/page.tsx
Last walked. 2026-05-29 automated runtime walk (Playwright headless) — render, /v1 data (2xx), console/page-errors, expected content, screenshot verified; live screen-reader, touch, offline, and telemetry-delivery checks pending a manual AT pass. Evidence: WALKTHROUGH/results/runtime-sweep-2026-05-29.md; content re-verified 2026-06-03 against current source; submit→Themis verdict re-verified 2026-06-26 by metis-assessment-submit.spec.ts
Purpose#
Short-answer assessment with rubric preview and a Themis academic-integrity notice. Fixture: PHL.102 · A2, "Apatheia, in your own words." — 200-word short answer with citation requirements.
Entry points#
- Metis schoolroom — "Begin" primary button on
metis.mdsidebar —LBtn href="/metis/assessment" - Direct URL / bookmark — yes (auth required via shell middleware)
Layout regions#
page.tsx is a thin server component: await getMetisAssessment() →
<MetisAssessment data={data} />.
Inside MetisAssessment (metis.tsx, line 439):
- Web shell top —
LCustomerNav active="library" - Header row (
gridTemplateColumns: '1fr auto'):- Left — title — eyebrow "PHL.102 · A2 · short answer",
LDisplayheadline "Apatheia, in your own words." - Right — meta —
LStatusPill status="ok""Auto-saved 14:22",LCode"due Sun · 11 May"
- Left — title — eyebrow "PHL.102 · A2 · short answer",
- Two-column body (
gridTemplateColumns: '1.6fr 1fr'):- Left — prompt + answer editor:
- Prompt card (
LCard) — italic "In 200 words, explain what the Stoics meant by apatheia, …"; meta row "min · 180 w / max · 220 w / citations · 1+ / rubric · 4 dims" - Answer panel — ruled-paper styled (
repeating-linear-gradientevery 27/28 px) with a real<textarea aria-label="Assessment answer">, eyebrow "Your answer ·/ 220", live citation count, Save draft, Submit, and Reopen draft controls - Themis result — after a successful submit, the answer locks read-only
and a compact
data-metis-assessment-themis-resultpanel shows verdict class, severity, signal count, source of record, recommended action, and an appeal link whenappealAllowed=true
- Prompt card (
- Right column — rubric preview (4 dimensions) + Themis academic-integrity notice + draft history / actions
- Left — prompt + answer editor:
States#
- Loaded —
getMetisAssessment()resolves before render; route covered bymetis-assessment-submit.spec.ts. - Draft saved locally — editor writes the draft to
oshun.metis.assessment.draft.v1.<assessmentId>and updates the local "auto-saved" time - Word count progress — eyebrow "Your answer ·
/ 220" - Under min words — below 180 words shows "below minimum" and keeps Submit rubric-gated
- Over max words — over 220 words shows "over maximum" and keeps Submit rubric-gated
- No citation yet — citation count below the requirement keeps Submit in "Submit · check rubric"
- Themis integrity notice present — right rail copy renders: "This is your work. Quoting is allowed; cite the source. Tutor (✻) may help you understand, but may not write the answer for you." No policy link is wired in this card.
- Submitted state — successful BFF submit locks the editor read-only, persists the Themis result locally, and exposes verdict / appeal metadata
- Submit failure — failed Themis submit leaves the textarea editable and renders the returned error
- Reduced motion — composes static Lilith primitives; the former decorative blinking cursor span is gone because the editor is a real textarea/read-only record.
Interactions#
Header#
-
LDisplay— non-interactive.
Auto-save chip#
-
LStatusPill— non-interactive route-level fixture chip; the editor's own autosave timestamp updates from local draft persistence.
Prompt card#
- Prompt — non-interactive.
- Meta row — non-interactive (min / max / citations / rubric).
Answer panel#
- Answer text —
MetisAssessmentEditormounts a real<textarea aria-label="Assessment answer">while editable and a read-only serif record after successful submit - Draft auto-save — localStorage draft persistence is implemented; no BFF draft auto-save endpoint is wired yet
- Citation insertion — Insert citation appends a citation placeholder and updates the citation count
Right column#
- Rubric preview (4 dimensions) — static dimension rows with percentage bars; no expansion controls are wired in V1.
- Themis integrity notice — exact visible copy is documented above; no integrity-policy link is wired.
- Submit — posts to
POST /v1/metis/assessment-submissions; read-back includes detection signals and a canonical Themis adjudication - Save draft / discard — Save draft persists the current textarea value to localStorage; no discard control is present.
Data & contracts#
- Reads:
getMetisAssessment()from@/lib/lilith-data/metis-depth— returnsMetisAssessmentData(verify shape: prompt, meta, current draft, word count, rubric, integrity notice) - Writes: draft save is localStorage; submit uses
POST /v1/metis/assessment-submissionswith{ assessmentId, courseId, answer, submittedAt }and returns{ submission, detection, adjudication } - Realtime: None observed in this view.
- Caching: server fetch
- Auth/role check: shell middleware
Cross-references#
- Sibling Metis routes:
- Cross-domain partners: Nisaba (
../07-nisaba/) for citations; Themis surfaces (verify location) - Component sources:
apps/oshun/web/src/components/lilith/metis.tsx(MetisAssessmentline 439)
- Feature spec:
V1/features.md#metis
Open questions / known gaps#
- Confirm whether the answer panel is a live editor in V1 or remains a display specimen with a blinking-cursor element — it is a real textarea while editable
- BFF draft auto-save is not wired by design in this V1 page; draft persistence is localStorage-only until product requires a server draft record.
- Document the submit endpoint —
POST /v1/metis/assessment-submissions - Rubric preview is static labels + bars; no expandable dimension details.
- Themis academic-integrity notice exact copy is documented; it carries no link.