Context. surface customer · domain veritas · route /veritas/counterclaims · auth signed-in · source apps/oshun/web/src/app/veritas/counterclaims/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
Purpose#
When a story has more than one telling, Veritas does not pick. This view lays
two competing sides side by side — what each one rests on, where each is
weakest, and the Veritas verdict ("including 'not yet decided'"). The thin
server component awaits getCounterclaims() and renders VeritasCounter.
Entry points#
- Linked from
/veritas/story— the timeline surfaces "contested" entries that point to this view (verify the link) - Linked from
/veritas/claim— when a claim has dissent (verify) - Direct URL / bookmark — yes (auth required)
- Cross-link from
/domains/veritas/claims/[claimId]— the counterclaims tab inVeritasClaimDetailWorkspaceshares the same fixture surface (verify whether it links back here)
Layout regions#
page.tsx is a thin server component: await getCounterclaims() →
<VeritasCounter>. Mounted in LWebShell with LCustomerNav active="library".
- Header: Lilith customer nav (Library tab active)
- Masthead (
VrMast):Veritas · counterclaims | story · cable outage 9 mar | two sources · open dispute, display title "Two sources, disagreeing.", italic lede - Section header (
VrHead):— · The contested claim · <data.contestedClaim> - Side-by-side grid (
auto-fit, minmax(320px, 1fr), markeddata-veritas-counterclaims-side-by-side): one card per side- Per-side card (marked
data-veritas-counterclaim-sideanddata-veritas-counterclaim-id):- Header row:
side <A|B>code,data.sides[].whoname (large serif), stance eyebrow,VrBandchip on the right (data-veritas-counterclaim-side-quality) - Pull quote (italic serif, accent left border)
- "What the side rests on" — list of
<details>elements per evidence item, first one open by default (markeddata-veritas-counterclaim-evidence={side-N}); each<summary>has the evidence name +VrBand+inspectlabel; the open body shows description, inspection note, provenance, reviewer attestation, and excerpt hash (markeddata-veritas-counterclaim-evidence-inspection={side-N}) - "where this side is weakest" dashed-border panel
(
data-veritas-counterclaim-inspection-panel): weakness copy, source quality rationale (data-veritas-counterclaim-source-rationale), reviewer attribution, inspected timestamp, and resolution action (data-veritas-counterclaim-resolution-action)
- Header row:
- Per-side card (marked
- Verdict block (
data-veritas-counterclaim-verdict): full-width card with a 2px accent border:- "Veritas · what we have decided" eyebrow +
data.verdict.headline(italic serif), updated-at code on the right data.verdict.bodyparagraphdata.verdict.nextStepsrendered as " · " separated italic items
- "Veritas · what we have decided" eyebrow +
States#
- Loading —
getCounterclaims()awaited server-side; no client skeleton - Populated (two sides) — fixture renders both side cards plus the verdict block
- Verdict: not yet decided — verify the verdict surface for that case (fixture currently shows a concrete headline; check the data type)
- Error (recoverable) —
getCounterclaims()rejects → nearesterror.tsx - Offline — cached HTML; the
<details>toggles are native and work offline - Standalone PWA — the grid is
auto-fit, minmax(320px, 1fr), so the cards stack on narrow screens; verify - Empty — N/A; the fixture always returns two sides
- Gated — none in this page
Interactions#
Side card — evidence accordions#
- Evidence
<details>summary (per evidence item)- Function: native
<details>toggle opens/closes the inspection body - Keyboard: Enter/Space toggles; included in tab order by default
- Screen reader: announces "
, source quality, inspect, summary" (verify SR behaviour on bare <summary>) - First evidence per side is
openby default (open={j === 0}) - Telemetry: none wired in code
- Function: native
-
VrBandchip inside summary — non-interactive; verify SR text on the band swatch (currently relies on the descriptor) -
inspectcode label — text only; not a button
Side card — weakness panel#
- Static text block — non-interactive; verify the
data-veritas-counterclaim-resolution-actionattribute is read by the shell or analytics layer
Verdict block#
- Static card — no buttons; the next-steps are rendered as text-only list items separated by " · "
Data & contracts#
- Reads:
getCounterclaims()from@/lib/lilith-data/veritas-depth— returnsCounterclaimsData({ contestedClaim, sides[], verdict })sides[].evidence[]includesexcerptHash,provenance,reviewerAttestation,inspectionNotesides[].inspection.{counterclaimId, sourceQualityRationale, reviewer, inspectedAt, resolutionAction}
- Writes: none
- Realtime: none
- Caching: server fetch; revalidation per fixture policy
- Auth/role check: shell middleware (verify)
- Page metadata:
title: "Veritas · counterclaims", description "Two sources, side by side, with what each rests on, where each is weakest, and Veritas's verdict.",alternates.canonical: /veritas/counterclaims
Cross-references#
- Component:
apps/oshun/web/src/components/lilith/veritas.tsx—VeritasCounter(lines 1076–1349) - Data:
apps/oshun/web/src/lib/lilith-data/veritas-depth.ts(getCounterclaims) - Sibling routes:
veritas.md— domain hubveritas-claim.md— claim mode for an individual claimveritas-story.md— story over time (contested entries link here)
- Internal namespace counterpart:
/domains/veritas/claims/[claimId](VeritasClaimDetailWorkspace) renders a counterclaims tab using the same domain types - Feature spec:
V1/features.md
Open questions / known gaps#
- The
data-veritas-counterclaim-*attributes look like instrumentation hooks (analytics or E2E) but no client handler is wired in this file — confirm where they are consumed - No "open full inspection" affordance besides
<details>toggles; compare with/domains/veritas/claims/[claimId]which has anInspect counterclaimbutton + overlay (VeritasInspectionOverlay) — should this view share that flow? - Verdict block: no action buttons (no "follow this dispute" or "open claim detail"); confirm whether that is intentional for the broadsheet surface
-
LCustomerNav active="library"— consistent with/veritas/claimand the/veritashub, which all useactive="library"(no Explore inconsistency)