V1 Web PWA · Surface walkthrough

Operator · Isis provenance inspector

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

walked
8sections5 minread

On this page

Context. surface operator · domain operator (isis provenance — hash-chain ledger inspector) · route /operator/admin/isis/provenance · auth signed-in · source apps/oshun/web/src/app/operator/admin/isis/provenance/page.tsx

Last walked. 2026-06-25 provenance route-state addendum — direct clean, empty, unavailable, unknown-bundle, broken-tenant, tenant-preserving link, anonymous redirect, bundle-row timestamp, and generated-artifact inspector states are covered in citation-drift-resolution.spec.ts. Earlier: 2026-05-29 automated runtime walk (Playwright) — defect fixed & re-verified: render+data OK, 0 page/console errors; live SR/touch/offline/telemetry pending manual AT pass. Evidence: WALKTHROUGH/results/runtime-sweep-2026-05-29.md; content re-verified 2026-06-03 against current source

Purpose#

Inspect per-generation provenance bundles and verify the immutable Isis ledger hash chain. The page composes two inspectors stacked: the IsisProvenanceInspector (bundle index + verification verdict + per- bundle field detail) and the GeneratedArtifactProvenanceInspector (artifact-side provenance for operator-editorial surfaces). Robots-noindex.

Entry points#

  • From /operator/admin (the admin inbox) — citation-drift incident detail links here with ?inc=<INC>; current bundle selection happens in the inspector
  • Direct URL with ?tenant=X and/or ?bundle=Y query params — parameters drive loadIsisProvenanceData({ tenantId, selectedBundleId })
  • Deep link from incident detail — INC tickets referencing citation drift / model lineage hand off here; INC-2041 is covered in citation-drift-resolution.spec.ts
  • Internal docs / runbooks linking to specific bundle IDs

Layout regions#

The page is two stacked <article> regions inside a <> fragment, with the inspector following the artifact provenance inspector below.

  • IsisProvenanceInspector (server-data-driven, presentational):
    • Header (<header>) — h2 "Isis provenance inspector" + intro paragraph
    • Verification card (<article aria-live="polite" data-verification-ok="true|false">) — h3 "Ledger verification" with a <dl>:
      • Status — "CLEAN — hash chain intact" OR "BROKEN at index N"
      • Tenant scope — tenantId or (no tenant — platform ledger)
      • Chain length — integer
      • Last checked — ISO timestamp <time> element
    • Recent bundles index (<article>) — h3 "Recent bundles":
      • If empty: data-testid="isis-provenance-empty-state" paragraph
      • Otherwise: <ol> of bundle rows; each row has <a href={searchHref(bundle.bundleId)}> linking back with preserved tenant param
      • Row content: bold bundle ID + model@version (modality) · ISO time
    • Selected bundle detail (<article data-bundle-id=...>) — h3 = bundle ID:
      • <dl> of 16 fields from FIELD_LABELS: Bundle ID, Generation ID, Invoking user, Tenant, Consent ID, Prompt hash, Model ID, Model version, Modality, Watermark hash, Endpoint, Region, Bundle fingerprint, Chain fingerprint, Prior fingerprint, Sequence
      • Plus computed "Emitted at" — ISO from emittedAtUnixSeconds * 1000
      • Each <dd> has data-testid="isis-provenance-field-<key>" for ctrl-F-able testing hooks
      • If no selection: empty detail article with prompt copy
  • GeneratedArtifactProvenanceInspector — artifact-side surface (surfaceId="operator-isis-provenance", surfaceRole="editorial", title="Operator artifact provenance"). Inspect this component separately when authoring per-artifact walkthroughs.

States#

  • Loading — source-verified: page is RSC; awaits loadIsisProvenanceData server-side; no client skeleton
  • Anonymous user — Playwright verifies sessionless users redirect to /welcome before either provenance inspector renders
  • Signed-in user — renders (session-gated only; no operator-role gate in the proxy)
  • No tenant query param — Playwright verifies platform-ledger scope text: "(no tenant — platform ledger)"
  • Tenant param + bundle param — Playwright verifies tenant-preserving bundle links navigate to a full detail pane
  • Tenant param, no bundle — Playwright verifies the bundles list renders and the detail pane prompts "Select a bundle..."
  • Unknown bundle param — Playwright verifies the platform index remains visible and the detail pane falls back to the empty selection prompt
  • Empty bundlesdata-testid="isis-provenance-empty-state" paragraph: "No provenance bundles persisted for this tenant yet."
  • Chain verification OKdata-verification-ok="true"; announces "CLEAN — hash chain intact" via aria-live="polite"
  • Chain verification brokendata-verification-ok="false"; announces "BROKEN at index N"
  • loadIsisProvenanceData fails — page catches loader errors and renders the accessible "Provenance ledger unavailable" retry state

Interactions#

Verification card#

  • aria-live="polite" region — Playwright verifies the verification article carries aria-live="polite"; no recheck action exists yet
  • <time> elementdateTime attribute is the ISO of verification.checkedAt

Bundles index <ol>#

  • Each bundle row link (<a href={searchHref(bundle.bundleId)}>)
    • Function: navigates to same page with ?bundle=X (and preserves tenant=)
    • Keyboard: native anchor tab/enter behavior
    • SR: announces bundle ID as the accessible name
    • Touch: native text link; no custom 44 px target treatment
    • Telemetry: none on the page; tracking via server logs
  • <time> per rowdateTime attribute is the ISO derived from emittedAtUnixSeconds

Selected bundle detail <dl>#

  • Non-interactive read-only listing; copy operations work via the browser's native text selection
  • Test hooks: data-testid="isis-provenance-field-<key>" for each field; useful for automated provenance verification flows
  • Watermark hash — when present, shown verbatim; absence reflected as
  • Prior fingerprint — first bundle in chain shows ; others show prior bundle's fingerprint

GeneratedArtifactProvenanceInspector#

  • Inspect separately. Its surfaceId is operator-isis-provenance and surfaceRole is editorial.

Data & contracts#

  • Reads: loadIsisProvenanceData({ tenantId, selectedBundleId }) from @/lib/server/isis-provenance-loader — returns { bundles[], selectedBundle, verification }
  • Writes: none on this page (ledger is append-only; writes happen via the generation API in Isis)
  • Realtime: none on this page; ledger updates are eventually- consistent
  • Caching: page is RSC; awaits server data; searchParams is a Promise<> (Next.js 15 pattern); no SW caching for /operator/*
  • Auth/role check: session-gated only (proxy.ts redirects sessionless → /welcome?redirect=); no operator-role gate in the proxy

Provenance bundle contract#

The IsisProvenanceBundleView interface defines 17 fields: bundleId, generationId, invokingUserId, tenantId, consentId, promptHash, modelId, modelVersion, modality (text | image | audio | video | 3d-mesh | embedding), watermarkHash, endpointId, region, emittedAtUnixSeconds, fingerprint, chainFingerprint, priorFingerprint, sequence.

IsisProvenanceVerification has ok, brokenAtIndex, checkedAt, tenantId, chainLength.

Cross-references#

  • Parent: operator-overview.md, operator-admin.md
  • Component sources:
    • apps/oshun/web/src/components/admin/IsisProvenanceInspector.tsx (167 lines)
    • apps/oshun/web/src/components/provenance/GeneratedArtifactProvenanceInspector.tsx
  • Data: apps/oshun/web/src/lib/server/isis-provenance-loader.ts
  • Tests: apps/oshun/web/src/components/admin/__tests__/IsisProvenanceInspector.test.tsx, apps/oshun/web/e2e/citation-drift-resolution.spec.ts
  • Feature spec: V1/features.md
  • Architecture: V1/ARCHITECTURE.md

Open questions / known gaps#

  • Runtime walk (2026-05-29) — defect FIXED & verified: the page crashed to the generic error boundary when the provenance ledger store was unconfigured/unreachable (loadIsisProvenanceData threw, server component had no catch). Now wrapped in try/catch with a clear, accessible "provenance ledger unavailable" + retry state. Re-walked: no error boundary, HTTP 200. rendered. Status kept drafted until fixed.
  • Document the recheck affordance (if any) that re-runs hash-chain verification — current code only renders the verdict from server data
  • Confirm how the page is reached: the /operator/admin citation-drift detail card now exposes "Open provenance" with data-operator-incident-provenance-link="INC-2041" and the E2E clicks through to /operator/admin/isis/provenance?inc=INC-2041.
  • Walk GeneratedArtifactProvenanceInspector separately when authoring artifact-side provenance walkthroughs (it appears on multiple operator surfaces)
  • Test what happens with unknown ?bundle= — current server loader keeps the bundle index visible and gracefully shows the empty detail prompt
  • An operator-role gate appears absent — proxy.ts only redirects sessionless users to /welcome; no role check in the proxy or page component (possible gap vs intended scope)