V1 Web PWA · Surface walkthrough

Veritas · source profile

A per-surface walkthrough of the V1 Web PWA customer surface: layout, states, interactions, data, and cross-references.

walked
8sections5 minread

On this page

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 /veritas evidence rail — verify whether LSourceItem rows link here (not wired in VeritasRoom)
  • Linked from /veritas/claim — selected-claim card source rows are anchors with stable data-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/source loads 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 from data.name
    • data.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:
        • VrBand chip 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
    • 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, optional pct in accent mono
      • Below: Notable retractions accent eyebrow followed by left-accent-rule blocks; each shows the retraction date and an italic note
    • 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
  • 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, 90px VrPip confidence chip (high / med / low)

States#

  • LoadinggetSourceProfile() awaited server-side; no client skeleton
  • Populated — fixture renders all four sections fully
  • Source band D (unverified) — verify rendering when band is D (the VrBand colours change; the "Why band D" copy should remain coherent)
  • No notable retractionsdata.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 → nearest error.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#

  • VrBand chip — 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/retraction style 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

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)
  • VrPip confidence chip — non-interactive

Data & contracts#

  • Reads: getSourceProfile(sourceId?) from @/lib/lilith-data/veritas-depth — returns SourceProfileData ({ 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.you implies per-user data, so the caching key must include user identity
  • Page metadata: title: "Veritas · source profile" on the fallback page and title: "Veritas · <source name>" on the source-id page; canonical is /veritas/source or /veritas/source/<sourceId> respectively.

Cross-references#

  • Component: apps/oshun/web/src/components/lilith/veritas.tsxVeritasSource (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/source remains 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.you is 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 /veritas hub and the other depth views, which all use Library (no Explore inconsistency)