Context. surface customer · domain veritas · route /veritas/provenance · auth signed-in · source apps/oshun/web/src/app/veritas/provenance/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#
The provenance receipt for a piece: the steps Lilith took to assemble it, what
was checked, what was deliberately not checked, what it cost in compute and
time, and the C2PA bundle so a reader can verify the signature. Cross-references
the Sophia provenance surface. Thin server component awaits getProvenance()
and renders VeritasProvenance.
Entry points#
- Linked from any Veritas story — verify whether a "Receipt" / "Behind the
headline" link is exposed in
/veritas,/veritas/claim, or/veritas/story(not wired in the room components in code) - Linked from
/veritas/retraction— when a piece is corrected, the receipt explains what changed (verify) - Direct URL / bookmark — yes (auth required)
- Cross-link from Sophia provenance trail — Sophia's grounding/provenance views may link to this Veritas-side receipt (per V1/features.md Sophia substrate)
Layout regions#
page.tsx awaits getProvenance() → <VeritasProvenance>. The component
mounts LWebShell with LCustomerNav active="library".
- Header: Lilith customer nav (Library tab active)
- Masthead (
VrMast):Veritas · behind the headline | provenance · piece <data.pieceId> | how this story was assembled, display title "Behind the headline.", italic lede ("A receipt for the piece. What the assistant did, what was checked, what was not, and what it cost in compute and time. Always available, never required.") - Two-column grid (1.3fr / 1fr):
- Left column — Steps timeline:
VrHead:I · Steps Lilith took · In order, with what fell out.- Vertical timeline (1px rule on the left); each step is a dot, a timestamp
code (
data.steps[i].time), an italic step description, and a→ <outcome>line beneath
- Right column — Limits + Receipt + C2PA:
VrHead:II · What was not done · The honest gaps.- "declared limits of this piece" card (medium-confidence border): italic
list of
data.declaredLimits[] VrHead:III · Receipt · Compute · time · model.- 2×N grid of receipt items (
data.receipt[][k, v]): each pair shows an eyebrow label and an italic value - C2PA bundle card: eyebrow
C2PA bundle, mono text block with<data.c2pa.hash> · sig ✓,editor: <data.c2pa.editor>,<data.c2pa.signedAt>, then two ghost buttons: Verify signature and Open bundle
- Left column — Steps timeline:
States#
- Loading —
getProvenance()awaited server-side; no client skeleton - Populated — fixture renders steps, declared limits, receipt grid, and C2PA bundle
- No declared limits — verify whether
data.declaredLimitscan be empty and how the panel renders (currently maps unconditionally) - C2PA signature invalid — the text shows "sig ✓" unconditionally; verify the data model and what happens when verification fails
- Error (recoverable) —
getProvenance()rejects → nearesterror.tsx - Offline — cached HTML; the Verify-signature button has no client handler in code, so offline behaviour is N/A
- Standalone PWA — verify the 1.3fr/1fr grid collapses correctly at narrow widths (no explicit responsive rule in this component)
- Empty — N/A; fixture always returns at least one step
- Gated — none coded
Interactions#
Steps timeline (left)#
- Step row — non-interactive in code; verify whether timeline steps should be linkable (e.g., "open the source this step referenced")
Declared-limits card#
- List of italic lines — non-interactive; verify SR list semantics
(currently
<div>s, not a<ul>)
Receipt grid#
- Pair (k, v) — non-interactive; verify SR pairs read as label/value
(currently
LEyebrow+ italic div, no<dl>)
C2PA card#
- Verify signature (
LBtn kind="ghost" size="sm")- Function: no
onClickin code — verify what the design intends (likely a cryptographic check againstdata.c2pa.hashusing a wallet/manifest inspector) - Keyboard: Enter/Space activates; included in tab order
- Disabled when: signature already known invalid (not implemented)
- Function: no
- Open bundle (
LBtn kind="ghost" size="sm")- Function: no
onClickin code — verify whether this opens the raw C2PA manifest in a new tab, an in-app modal, or a download
- Function: no
Data & contracts#
- Reads:
getProvenance()from@/lib/lilith-data/veritas-depth— returnsProvenanceData({ pieceId, steps[].{time, step, outcome}, declaredLimits[], receipt[][k, v], c2pa.{hash, editor, signedAt} }) - Writes: none in this view (the verify/open buttons are unwired)
- Realtime: none
- Caching: server fetch
- Auth/role check: shell middleware (verify)
- Page metadata:
title: "Veritas · provenance", description "Receipt for a piece — steps Lilith took, declared limits, compute spent, and the C2PA bundle.",alternates.canonical: /veritas/provenance
Cross-references#
- Component:
apps/oshun/web/src/components/lilith/veritas.tsx—VeritasProvenance(lines 1601–1767) - Data:
apps/oshun/web/src/lib/lilith-data/veritas-depth.ts(getProvenance) - Sophia counterpart: V1/features.md — Sophia provenance substrate (citation trails, grounding receipts) — the C2PA hash here is likely emitted by Sophia
- Sibling routes:
- Feature spec:
V1/features.md - Architecture:
V1/ARCHITECTURE.md
Open questions / known gaps#
- Both action buttons (
Verify signature,Open bundle) lackonClick— the page is currently a specimen. Confirm whether the V1 plan is to wire these to Sophia's verification endpoint or to a manifest viewer - Receipt grid is rendered as nested
<div>s withLEyebrowlabels; consider whether a<dl>would serve assistive tech better - The C2PA "sig ✓" badge is unconditional in the template — confirm the data
type permits a
signatureValid: booleanand update the render - No
dynamicdirective; confirm whether this view should be ISR-cached (provenance is durable per-piece, not per-user) -
LCustomerNav active="library"— consistent with the/veritashub and the other depth views, which all use Library (no Explore inconsistency)