@zephytiju/prism-evidence-list
v0.1.0
Published
Platform Prism evidence-list micro-UI (component id "evidence-list"): GeoVision v7 provenance panel — source rows with reliability + credibility badges (semantic ok/warn/threat tokens via a config-mapped gradingTokens table or the default mapping), per-ro
Readme
PrismEvidenceListMicroUI
Platform Prism evidence-list micro-UI. Component id: evidence-list.
Published to npm as @zephytiju/prism-evidence-list.
The evidence list renders a subject's provenance: the panel header (title / subtitle / subject pill), a source
count, and one row per provenance record — the source name, reliability + credibility badges colored through
SEMANTIC theme tokens (ok / warn / threat via a gradingTokens configuration or the curated default
mapping, muted for unmapped grades), the entity ref id in mono, and the record's claims list. It is a
pure consumer: the list subscribes to the global search-results.selected-entity Prism channel (an
EntityReference), and on every selection change fetches the bounded provenance projection through the
generated IEvidenceSource client bound to the host Lattice transport. Loading skeleton, empty (no selection /
no records) and error + retry states are all first-class. Composed applications (for example Guanlan) consume
it as-is; the component is platform-owned.
Configuration keys
| Prop | Meaning |
| --- | --- |
| locale | UI locale for the component-fixed strings: "en" \| "zh-CN" (default "en") — see i18n |
| title | Panel header title — composition-authored override; when omitted the locale bundle's title default renders (EVIDENCE & PROVENANCE / 证据与溯源) |
| subtitle | Panel header mono subtitle — composition-authored override; when omitted the locale bundle's subtitle default renders (SOURCE RELIABILITY / 来源可靠性) |
| gradingTokens | Grade value → SEMANTIC color token for the reliability/credibility badges, keyed by the uppercased grade (e.g. { HIGH: "ok", MEDIUM: "warn", LOW: "threat" }); unlisted grades fall through to the curated default mapping and then to muted |
Channel contract
| Direction | Kind | Id | Payload |
| --- | --- | --- | --- |
| consumes | state | search-results.selected-entity | EntityReference \| null — selection change triggers a refetch; null returns the list to the empty state |
The list publishes nothing: no channels, no Prism events, no audit records. Busy/error are local component state, so the list never re-renders anyone else and no host contract is implied beyond the consumed selection. The one channel id is a string literal at its single call-site so the build-time channel-graph scanner can derive the edge.
Lattice binding
createEvidenceSourceClient(useLatticeTransport()) from @zephytiju/lattice-common-interfaces — every fetch
goes through the per-method route interfaces/IEvidenceSource/evidence with full server-side validation. No
URLs, credentials, or generic invokes. The request is exactly { refs: [selected] }; stale responses are
discarded via a fetch sequence guard so a rapid re-selection never renders the wrong subject's rows.
Audit rule
Provenance viewing is NOT audit-worthy. This component emits NO audit event and no Prism event of any kind.
Internationalization (i18n)
The component ships en and zh-CN locale bundles — src/locales/en.json / src/locales/zh-CN.json —
and every component-fixed UI string is resolved from them (the panel header title/subtitle defaults,
the empty-selection notice, the loading label, the error title, RETRY, the no-records notice, the
REL/CRED badge prefixes, the CLAIMS label, the SOURCES count suffix, the panel aria label and the
non-Error fetch fallback). The component renders no hardcoded copy.
{
"evidence-list": {
"title": "EVIDENCE & PROVENANCE",
"subtitle": "SOURCE RELIABILITY",
"emptySelection": "no subject selected — awaiting search-results selection",
"loading": "loading provenance…",
"errorTitle": "PROVENANCE ERROR",
"retry": "RETRY",
"noData": "no provenance records for subject",
"reliabilityLabel": "REL",
"credibilityLabel": "CRED",
"claimsLabel": "CLAIMS",
"sourcesLabel": "SOURCES",
"panelAriaLabel": "Evidence and provenance",
"fetchFailed": "Evidence request failed"
}
}locale?: "en" | "zh-CN"prop (default"en") selects the string table per instance — it is a per-instance prop, so two instances in one host may render differing languages.- Every visible string — including the default header — is locale-driven.
title/subtitleare optional composition-authored overrides: a host that passes them wins per locale, and a host that omits them gets the locale-bundled defaults, so a singlelocaleswitch localizes the whole panel. - Locale bundles are namespaced under the component id (
"evidence-list") so a composer can deep-merge every component's bundle into ONE UI language bundle without collisions:
import { locales as evidenceListLocales } from "@zephytiju/prism-evidence-list";
// evidenceListLocales.en -> { "evidence-list": { … } }
// evidenceListLocales["zh-CN"] -> { "evidence-list": { … } }
const uiBundle = deepMerge(hostStrings, evidenceListLocales.en, queryBoxLocales.en);The parsed bundles are exported from the package entry (locales, en, zhCN, stringsForLocale), and the
raw JSONs are also served by the ./locales/* exports subpath
(e.g. @zephytiju/prism-evidence-list/locales/zh-CN.json); files ships both dist and locales.
Theme
No palette is hardcoded. Every color resolves to SEMANTIC theme tokens (ok, accent, threat, warn,
signal, card, card-dark, input, border, line, text, muted, deep, panel) consumed as CSS
variables, plus --mantine-font-family-monospace for the mono typography — the palette is supplied entirely by
the host's MantineProvider. Reliability/credibility grades map onto those tokens through the
gradingTokens configuration with a curated default (HIGH/CONFIRMED/A/RELIABLE → ok,
MEDIUM/PROBABLE/B/PARTIAL → warn, LOW/POSSIBLE/C/UNVERIFIED/DISPUTED → threat; exported helpers
gradeTokenFor + DEFAULT_GRADING_TOKENS), and unmapped grades fall back to the neutral muted token —
never a raw color. The local demo ships TWO themes, both defined in src/demo.tsx: geovisionTheme (dark),
mapping each semantic token onto the exact :root variables of the CONFIRMED GeoVision v7 design, and the
contrasting latticeLightTheme (light), mapping the SAME semantic token keys onto a different palette — the
component is skinned purely through the surrounding MantineProvider.
Source layout
src/ is strictly two parts:
- Component source (what the package compiles):
EvidenceList.tsx,index.ts(public entry),src/locales/(en.json,zh-CN.json,index.ts— the i18n string bundles and their resolver), andsrc/shims/node-crypto.ts(browser-build shim for the digest import — build infrastructure). There is notypes.ts: the list publishes no channel payloads, so it declares no wire types of its own — it consumesEntityReference/EvidenceProvenancefrom@zephytiju/lattice-common-interfaces. - Demo: exactly ONE file,
src/demo.tsx— the two host themes (GeoVision v7 + Lattice Light), the mock host action executor (createDemoExecutor, answeringinterfaces/IEvidenceSource/evidence) and all demo test data (sample subjects, thedemoGradingTokensconfiguration, sample provenance rows), the SELECT SUBJECT control that plays the search-results publisher cycling sampleEntityReferences onto the global channel viawriteChannel(including a*-FAILsubject to exercise the error path), the channel monitor, and the demo page rendering multipleEvidenceListinstances side by side behind a global EN | 中文 language switcher (plus per-instance switches).
The npm package ships dist (compiled component + type declarations + locale JSONs) and the top-level
locales/ directory (the raw JSON bundles, served by the ./locales/* exports subpath); no demo code is
published. scripts/copy-locales.mjs copies the JSON bundles into both locations during npm run build.
Local development
npm install
npm run typecheck
npm test
npm run dev
npm run shot-demonpm install pulls the platform peers (@zephytiju/prism-react,
@zephytiju/lattice-common-interfaces) from the npm registry, along with the host-side peer dependencies
(react, react-dom, @mantine/core). When consuming the published package, install it directly
(npm install @zephytiju/prism-evidence-list) and provide those peer dependencies in the host application.
The demo (npm run dev, entry src/demo.tsx) renders TWO EvidenceList instances side by side, each inside
its own scoped MantineProvider with a different theme (GeoVision v7 dark left, Lattice Light right), behind
an EN | 中文 segmented control — the GLOBAL switch sets the locale prop of BOTH instances at once, and each
instance carries its own per-instance control so the two hosts can render DIFFERING locales simultaneously.
The SELECT SUBJECT control publishes the global search-results.selected-entity channel (both lists consume
it and refetch through the mock executor); select NET-9902-FAIL to exercise the error path and RETRY, and
CLEAR SELECTION to return both lists to the empty state. npm run shot-demo boots the vite dev server, drives
both instances in headless Chrome (sets the LEFT instance to en and the RIGHT instance to zh-CN, publishes
the seeded subject selection) and captures the language switcher plus both instances in one shot to
/tmp/guanlan-review/demo-evidence-list-v2.png.
Design record
https://qcnwge0wy4s0.feishu.cn/wiki/K40nwA5TZiUE7Nk5hK6cE0W8nTe — §7 (channel contracts) and §8 (Lattice
transport and interface clients). Visual reference: CONFIRMED GeoVision v7 design
(nexus-geovision-v7-standalone.html, provenance/evidence panel region).
