---
path: /domains/veritas/fact-check
surface: customer
domain: veritas
auth: signed-in
source: apps/oshun/web/src/app/domains/veritas/fact-check/page.tsx
status: walked
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. 2026-06-27
  Codex Fact Checker addendum — signed-in results desk, search/no-results,
  verdict filters, keyboard dossier open, close/back, reduced-motion confidence
  gauge, both-sides expansion, evidence-card expansion, source credibility
  search/detail, AI ranker, source chain, conversation follow-up/send,
  cross-reference drill-in, standalone PWA launch, offline mobile use,
  no-horizontal-overflow checks, and serious axe scan are covered by the E2E
  evidence below. 2026-06-30 Codex addendum — added and covered Fact Checker
  entry links from `/domains/veritas` shell tools and the `/veritas` broadsheet
  subnav.
---

# Fact Checker · Veritas

## Purpose

The Veritas Fact Checker — a full-screen overlay that surfaces fact-check
results, detail dossiers, source credibility analysis, an AI evidence ranker, a
conversational "Ask Veritas" surface backed by a chat-like message list, and a
cross-reference view that compares claim treatment across sources.

## Entry points

- **`/domains/veritas` shell surface** — More verification tools exposes a "Fact
  Checker" link (`data-veritas-secondary-tool-link="fact-check"`) to
  `/domains/veritas/fact-check`
- **`/veritas` broadsheet subnav** — "Fact checker"
  (`data-lilith-subnav-item-id="fact-check"`) links to
  `/domains/veritas/fact-check`
- **Direct URL / bookmark** — yes (auth required)

The current Claim Tracker route does not include a direct handoff to the Fact
Checker route; if V1 later requires that transition, it should be wired as its
own visible affordance and covered separately.

## Layout regions

`page.tsx` is a `'use client'` component that renders an `sr-only` `<h1>` ("Fact
Checker · Veritas · OSHUN") then mounts
`<VeritasFactChecker onClose={() => router.back()} />`. Overlay is fixed
full-screen.

- **Header**: title "Veritas Fact Checker", responsive wrap behavior, and a
  44px-minimum Close button (`aria-label="Close Fact Checker"`).
- **Nav tablist**: six tabs with `role="tab"`, `aria-selected`, and stable
  `data-veritas-fact-check-tab` hooks.
- **Body**: focusable scrollable region labelled "Fact checker workspace";
  current view is driven by `view: FactCheckView`.
  - **Claim Results** (`results`) — list of `ClaimVerification` rows with
    verdict badges (`VerdictBadge`) and filter by verdict
  - **Claim Detail** (`detail`) — dossier for `selectedClaim` (a single
    `ClaimVerification`), reached via `handleSelectClaim → setView('detail')`
  - **Source Credibility** (`credibility`) — list / detail for `selectedSource`
    (`SourceCredibility`)
  - **AI Evidence Ranker** (`ai-ranker`) — ranked evidence panels
  - **Ask Veritas** (`conversational`) — chat-style message log backed by
    `conversationMessages: ConversationalMessage[]` (initial state from
    `SAMPLE_CONVERSATION`)
  - **Cross-Reference** (`cross-reference`) — comparison of how multiple sources
    treat the same claim

State drivers: `view`, `selectedClaim`, `filterVerdict`, `showBothSides`,
`conversationMessages`, `credibilitySearch`, and `selectedSource`.

## States

- [x] **Loading** — overlay renders synchronously; no async fetch.
- [x] **Results view, populated** — fixture verifications render with
      `VerdictBadge`s
      (`verified | likely_true | inconclusive | likely_false |     debunked`)
      and result-count hooks.
- [x] **Results view, filtered to no matches** — search branch renders "No
      claims match your search criteria."
- [x] **Detail view** — reached from a keyboardable list row; direct tab also
      falls back to the first fixture claim when `selectedClaim` is null.
- [x] **Credibility view** — source search and keyboard source-detail expansion
      are verified.
- [x] **AI Evidence Ranker** — ranked evidence, credibility analysis, verdict
      generation, reasoning chain, and source verification chain render.
- [x] **Ask Veritas view** — `SAMPLE_CONVERSATION` renders, follow-up prompts
      reuse the input, and send appends a local user/assistant pair.
- [x] **Cross-Reference view** — related-claim matrix renders and keyboard
      drill-in opens the referenced claim detail.
- [x] **Confidence gauge animation** — animates by default and now removes the
      arc transition under `prefers-reduced-motion: reduce`.
- [x] **Offline** — client-only search/detail/ranker interactions remain usable
      after `context.setOffline(true)`.
- [x] **Standalone PWA** — `/?surface=pwa` restores to
      `/domains/veritas/fact-check` and matches standalone display-mode.
- [x] **Reduced motion** — E2E emulates reduced motion and verifies the
      confidence arc transition is effectively zero.

## Interactions

### Header

- [x] **Close Fact Checker** (button, `aria-label="Close Fact Checker"`, X icon)
  - Function: keyboard Enter calls `onClose()` → `router.back()`
- [x] **Nav tablist** (`navItems`):
  - `results` — `FileText`, "Claim Results"
  - `detail` — `Eye`, "Claim Detail"
  - `credibility` — `Shield`, "Source Credibility"
  - `ai-ranker` — `Brain`, "AI Evidence Ranker"
  - `conversational` — `MessageSquare`, "Ask Veritas"
  - `cross-reference` — `Link2`, "Cross-Reference"

### Results view

- [x] **Search input** — filters claim text and exposes a no-results state.
- [x] **Verdict filter** (`filterVerdict`) —
      `all | verified | likely_true |     inconclusive | likely_false | debunked`.
- [x] **Claim row** — click/Enter/Space calls `setSelectedClaim` and switches
      view to `detail`.
- [x] **VerdictBadge** — colour and icon per `VERDICT_CONFIG[verdict]`.

### Detail view

- [x] **Confidence gauge** (`ConfidenceGauge`) — half-circle arc animates to
      score unless reduced motion is requested; colour ramp ≥80 ok, ≥60 warn,
      ≥40 alert, else alert.
- [x] **See Both Sides toggle** — opens supporting and contradicting argument
      columns.
- [x] **Evidence card** — click/Enter/Space expands ranking explanation,
      relevance, credibility, author, and date details.
- [x] **Back to results** — tab click returns to the results view.
- [x] **Trust rule callout** — built via `buildFactCheckTrustRule` (uses
      `resolveWebVeritasTrustRule` with `surface: 'assistant-evidence'`).

### Credibility view

- [x] **Source search** — filters by source name/domain.
- [x] **Source row** — click/Enter/Space sets `selectedSource` and shows the
      credibility detail.
- [x] **Source detail** — renders description, factual reporting, bias lean, and
      fact-check count.

### AI Evidence Ranker view

- [x] Ranked panels with evidence items — fixture rank order, overall trust, AI
      verdict generation, limitations, reasoning chain, and source-chain steps
      render.

### Ask Veritas (conversational) view

- [x] **Message log** — renders `conversationMessages` initialised from
      `SAMPLE_CONVERSATION`.
- [x] **Follow-up prompt** — clicking an assistant prompt copies it into the
      compose input.
- [x] **Compose input + send button** — sending appends local user and assistant
      entries via `setConversationMessages`.
- [x] **Each message** — exposes role-coded user vs assistant hooks.

### Cross-Reference view

- [x] Cross-reference matrix renders claims with relationship labels and
      similarity values; click/Enter/Space on a related claim opens its detail.

## Current E2E evidence

- `apps/oshun/web/e2e/veritas-fact-checker.spec.ts` —
  `opens from Veritas shell tools and the broadsheet subnav` covers opening the
  route from `/domains/veritas` via More verification tools, Close/browser
  history return to `/domains/veritas`, and opening the same checker from the
  `/veritas` broadsheet subnav.
- `apps/oshun/web/e2e/veritas-fact-checker.spec.ts` —
  `filters fixture claims, opens a dossier by keyboard, expands evidence, and closes by keyboard`
  covers signed-in navigation from `/library`, initial result counts, close
  target size/name, no-results search, text search, debunked verdict filtering,
  keyboard row open, detail claim state, confidence gauge/reduced-motion
  behavior, evidence-chain counts, both-sides expansion, evidence-card
  expansion, and keyboard close/back behavior.
- `apps/oshun/web/e2e/veritas-fact-checker.spec.ts` —
  `audits credibility, AI evidence ranking, and cross-reference drill-in views`
  covers the credibility tab, source search, keyboard source-detail expansion,
  AI evidence ranker, credibility analysis, verdict generation, source
  verification chain, cross-reference matrix, relationship hooks, and keyboard
  related-claim drill-in.
- `apps/oshun/web/e2e/veritas-fact-checker.spec.ts` —
  `sends a local Ask Veritas message and reuses follow-up prompts` covers the
  conversation tab, fixture message count, follow-up prompt reuse, send action,
  and appended user/assistant messages.
- `apps/oshun/web/e2e/veritas-fact-checker.spec.ts` —
  `restores standalone, remains usable offline, and avoids mobile overflow`
  covers standalone PWA launch restoration, offline search/detail/ranker
  interactions, mobile no-horizontal-overflow checks, and the route-level
  serious axe scan.

## Data & contracts

- **Reads**: fixture imports — `SAMPLE_CONVERSATION` and other sample data
  (`SAMPLE_CLAIMS`, `SAMPLE_CREDIBILITY`, etc.; verify exact imports inside the
  file)
- **Writes**: none externally; local state mutations only. Ask Veritas appends
  local messages; no Sophia/BFF assistant request is made.
- **Realtime**: none (conversational view is local-only)
- **Caching**: not applicable
- **Auth/role check**: shell middleware (verify)
- **Trust helpers**: `buildFactCheckTrustRule` →
  `resolveWebVeritasTrustRule({ surface: 'assistant-evidence', ... })` from
  `./veritasTrustLabels`
- **Telemetry**: no `track*` imports in this file.
- **Page metadata**: not set (client component); sr-only `<h1>` reads "Fact
  Checker · Veritas · OSHUN"

## Cross-references

- Component:
  `apps/oshun/web/src/components/domains/veritas/VeritasFactChecker.tsx`
- Type: `FactCheckView` (lines 66–72) — six-option enum
- `navItems` declaration — six-option visible nav
- Route E2E: `apps/oshun/web/e2e/veritas-fact-checker.spec.ts`
- Sub-components: `VerdictBadge` (lines 93–121), `ConfidenceGauge` (lines
  123–~189), `BreakdownBar`
- Sibling tools:
  - [`domains-veritas-claims.md`](./domains-veritas-claims.md),
    [`domains-veritas-articles.md`](./domains-veritas-articles.md),
    [`domains-veritas-headlines.md`](./domains-veritas-headlines.md),
    [`domains-veritas-research.md`](./domains-veritas-research.md)
- Customer-facing Veritas claim views: [`veritas-claim.md`](./veritas-claim.md)
- Feature spec: [`V1/features.md`](../../../V1/features.md#veritas)

## Open questions / known gaps

- [ ] No telemetry on tab switches or claim selection — surprising given the
      assistant-evidence surface is exactly what `resolveWebVeritasTrustRule` is
      set up to measure
- [ ] Ask Veritas view writes to a local array; decide whether V1 wires this to
      a real Sophia-backed assistant endpoint
- [ ] Direct `detail` tab with no selected claim falls back to
      `SAMPLE_CLAIMS[0]` instead of disabling the tab or showing an explicit
      empty-detail state
