Context. surface customer · domain veritas · route /veritas/source · auth signed-in · source apps/oshun/web/src/app/veritas/source/page.tsx; apps/oshun/web/src/app/veritas/source/[sourceId]/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; source-id route verified 2026-06-23 by veritas-evidence-trail.spec.ts
Purpose#
A single source profile: its trust band (A–D), its track record, declared
conflicts of interest, what Veritas verifies it against, and the history of the
things it has said over the last 12 months. /veritas/source is the default
Statnett profile fallback; /veritas/source/[sourceId] renders the matching
source profile for a selected citation row. Thin server components await
getSourceProfile(sourceId?) and render VeritasSource.
Entry points#
- Linked from
/veritasevidence rail — verify whetherLSourceItemrows link here (not wired inVeritasRoom) - Linked from
/veritas/claim— selected-claim card source rows are anchors with stabledata-veritas-selected-source-row,data-veritas-source-name,data-veritas-source-band, and source-id hrefs such as/veritas/source/statnett-operator-data - Linked from
/veritas/counterclaims— per-side evidence band could point here (not wired) - Sub-nav "Sources" tab on
/veritas— verify which route the tab ultimately targets - Direct URL / bookmark — yes;
/veritas/sourceloads the default profile and/veritas/source/[sourceId]loads the selected source profile (auth required)
Layout regions#
page.tsx awaits getSourceProfile() → <VeritasSource>. The source-id page
awaits getSourceProfile(params.sourceId) → <VeritasSource>. The component
mounts LWebShell with LCustomerNav active="library" and sets
data-veritas-source-profile="<sourceId>".
- Header: Lilith customer nav (Library tab active)
- Masthead (
VrMast):Veritas · the source | profile · public record | cited Nx by you · M,MMMx across Veritas, display title constructed fromdata.namedata.description(e.g., first word of name + em-styled "the X"), italic lede
- Three-column grid (1fr / 1fr / 1fr):
- Column I — At a glance (
VrHead "I · At a glance · The card."):- Card with accent border + paper background containing:
VrBandchip showing the source's band (A–D)- Source name (30px serif), description (italic)
- 2-column facts grid (
data.facts[][k, v]) — eyebrow + italic value Why band <data.band>block — italic explanation paragraph
- Card with accent border + paper background containing:
- Column II — Track record
(
VrHead "II · Track record · When this source has been right — and not." right="last 24 mo."):- Per-row entry: eyebrow label, large serif
n, optionalpctin accent mono - Below:
Notable retractionsaccent eyebrow followed by left-accent-rule blocks; each shows the retraction date and an italic note
- Per-row entry: eyebrow label, large serif
- Column III — Conflicts · declared
(
VrHead "III · Conflicts · declared · What this source has at stake."):- Italic conflicts lede card
- Per-row entry: eyebrow + italic value (
data.conflicts[][k, v]) - "What we still verify against" block: per-source entry with name +
description +
VrBand
- Column I — At a glance (
- Section IV — History (full-width, below the columns)
(
VrHead "IV · Things this source has said · last 12 months · The history, stripped."):- One row per history item: 70px date column (
LCode), italic statement span, 90pxVrPipconfidence chip (high / med / low)
- One row per history item: 70px date column (
States#
- Loading —
getSourceProfile()awaited server-side; no client skeleton - Populated — fixture renders all four sections fully
- Source band D (unverified) — verify rendering when band is D (the
VrBandcolours change; the "Why band D" copy should remain coherent) - No notable retractions —
data.notableRetractions[]empty; the block currently maps unconditionally so it would render an empty list (verify graceful behaviour) - No declared conflicts — same caveat for
data.conflicts[] - Error (recoverable) —
getSourceProfile()rejects → nearesterror.tsx - Offline — cached HTML; nothing client-side
- Standalone PWA — 3-column grid; verify behaviour at narrow widths (no explicit responsive media queries in this component)
- Empty — N/A; both route variants always load one source profile
- Gated — none coded
Interactions#
Column I — Source card#
-
VrBandchip — non-interactive; verify SR readability of the coloured swatch (currently relies on the italic descriptor) - Facts grid pairs — non-interactive; eyebrow label + italic value
- Why band
— italic paragraph; non-interactive
Column II — Track record#
- Row (label, n, pct) — non-interactive
Column II — Notable retractions#
- Each retraction block — left-accent rule; date + italic note; not a
link in code; verify whether the design intends each row to link to the
/veritas/retractionstyle detail or to the source's specific retraction record
Column III — Conflicts#
- Lede card — italic paragraph; non-interactive
- Conflict row (k, v) — non-interactive
Column III — What we still verify against#
- Verify-against row (per cross-check source)
- Function: not a link in code; verify the design intent — each named
cross-check source likely deserves a link to its own
/veritas/source?id=<other>profile
- Function: not a link in code; verify the design intent — each named
cross-check source likely deserves a link to its own
Section IV — History#
- History row (per statement)
- Function: not a link in code; verify the design intent (each italic statement should arguably link to the specific story where the source said it)
-
VrPipconfidence chip — non-interactive
Data & contracts#
- Reads:
getSourceProfile(sourceId?)from@/lib/lilith-data/veritas-depth— returnsSourceProfileData({ id, name, description, band, facts[][k, v], whyBand, citationCount.{you, corpus}, trackRecord[].{label, n, pct?}, notableRetractions[].{date, note}, conflictsLede, conflicts[][k, v], checkedAgainst[].{name, description, band}, history[].{date, statement, level} }) - Writes: none
- Realtime: none
- Caching: server fetch; revalidation per fixture policy
- Auth/role check: shell middleware (verify);
citationCount.youimplies per-user data, so the caching key must include user identity - Page metadata:
title: "Veritas · source profile"on the fallback page andtitle: "Veritas · <source name>"on the source-id page; canonical is/veritas/sourceor/veritas/source/<sourceId>respectively.
Cross-references#
- Component:
apps/oshun/web/src/components/lilith/veritas.tsx—VeritasSource(lines 537–845) - Routes:
apps/oshun/web/src/app/veritas/source/page.tsx,apps/oshun/web/src/app/veritas/source/[sourceId]/page.tsx - Data:
apps/oshun/web/src/lib/lilith-data/veritas-depth.ts(getSourceProfile) - Sibling routes:
- Internal namespace alternate:
/domains/veritas/research(research papers),/domains/veritas/knowledge-graph(entity profile view) — both may surface a different shape of "source profile" - Feature spec:
V1/features.md
Open questions / known gaps#
- The URL is
/veritas/source(singular, no id) but the data shape clearly models a single source — fixed 2026-06-23./veritas/source/[sourceId]exists, citation rows link to source ids, and/veritas/sourceremains a default profile fallback. - Cross-check sources, retractions, and history rows all look like they should link to deeper detail but are static text in code; document as wiring gaps
-
citationCount.youis per-user data — verify the BFF/caching layer handles that correctly - 3-column desktop layout will collapse awkwardly on small widths; verify and add responsive rules if needed
-
LCustomerNav active="library"— consistent with the/veritashub and the other depth views, which all use Library (no Explore inconsistency)