"use client" import type { ReactNode } from "react" import { useEffect, useMemo, useState } from "react" import { BarChart3, ClipboardCheck, GitCompareArrows, ShieldCheck } from "lucide-react" import { useAudienceMode } from "@/components/audience-mode-provider" import { Badge } from "@/components/ui/badge" import { Button } from "@/components/ui/button" import type { ComparabilityCorpusBlock, CompletenessCorpusBlock, CorpusAggregates, ProvenanceCorpusBlock, ReproducibilityCorpusBlock, } from "@/lib/backend-artifacts" import { getCategoryColor } from "@/lib/benchmark-schema" import { formatFieldLabel, formatPercent, } from "./signal-utils" const CATEGORY_ORDER = ["agentic", "general", "knowledge", "reasoning", "safety", "other"] const SOURCE_COLORS: Record = { first_party: "bg-amber-500", third_party: "bg-emerald-500", collaborative: "bg-sky-500", unspecified: "bg-stone-400", } export function CorpusDashboard({ aggregates, completenessScores, }: { aggregates: CorpusAggregates completenessScores: number[] }) { const { mode } = useAudienceMode() const [view, setView] = useState<"overall" | "category">("overall") useEffect(() => { setView(mode === "research" ? "category" : "overall") }, [mode]) const categoryKeys = useMemo( () => CATEGORY_ORDER.filter((category) => aggregates.reproducibility.by_category[category] || aggregates.completeness.by_category[category] || aggregates.provenance.by_category[category] || aggregates.comparability.by_category[category] ), [aggregates] ) return (
Interpretive signals

Corpus Dashboard

Corpus-level rollups for reproducibility, documentation completeness, source provenance, and comparability.

Signals v{aggregates.signal_version} Generated {formatGeneratedDate(aggregates.generated_at)}
{view === "overall" ? (
) : (
{categoryKeys.map((category) => ( ))}
)}
) } function ReproducibilitySection({ block }: { block: ReproducibilityCorpusBlock }) { return ( } title="Reproducibility" subtitle="Reported scores with enough setup documentation to re-run." headline={formatPercent(block.reproducibility_gap_rate)} headlineLabel={`${block.triples_with_reproducibility_gap.toLocaleString()} of ${block.total_triples.toLocaleString()} reported scores have gaps`} >
{Object.entries(block.per_field_missingness).slice(0, 10).map(([field, value]) => ( ))}
) } function CompletenessSection({ block, scores, }: { block: CompletenessCorpusBlock scores: number[] }) { return ( } title="Reporting Completeness" subtitle="How much benchmark documentation is populated." headline={formatPercent(block.completeness_score_mean)} headlineLabel={`Median ${formatPercent(block.completeness_score_median)} across ${block.total_benchmarks.toLocaleString()} benchmarks`} > {scores.length > 0 && }
{Object.entries(block.per_field_population).slice(0, 10).map(([field, value]) => (
{formatFieldLabel(field)} {formatPercent(value.mean_score)}
))}
) } function ProvenanceSection({ block }: { block: ProvenanceCorpusBlock }) { const distribution = block.source_type_distribution const total = Object.values(distribution).reduce((sum, value) => sum + value, 0) return ( } title="Provenance" subtitle="Who reported the scores, and whether groups have multiple sources." headline={formatPercent(block.multi_source_rate)} headlineLabel="of (model, benchmark, metric) groups have multiple reporting sources" >
{Object.entries(distribution).map(([sourceType, count]) => (
0 ? `${(count / total) * 100}%` : "0%" }} title={`${sourceType.replace(/_/g, " ")}: ${count}`} /> ))}
) } function ComparabilitySection({ block }: { block: ComparabilityCorpusBlock }) { return ( } title="Comparability" subtitle="Eligible groups where scores diverge across setups or reporting organizations." headline={formatNullableRate(block.variant_divergence_rate)} headlineLabel={`${block.variant_divergent_groups.toLocaleString()} of ${block.variant_eligible_groups.toLocaleString()} setup-eligible groups diverge`} >
) } function CategoryPanel({ category, reproducibility, completeness, provenance, comparability, }: { category: string reproducibility?: ReproducibilityCorpusBlock completeness?: CompletenessCorpusBlock provenance?: ProvenanceCorpusBlock comparability?: ComparabilityCorpusBlock }) { const categoryLabel = `${category.charAt(0).toUpperCase()}${category.slice(1)}` return (

{categoryLabel}

{categoryLabel}
{comparability?.cross_party_divergence_rate == null && (
Cross-party divergence: N/A - not enough multi-org coverage.
)}
) } function DashboardSection({ icon, title, subtitle, headline, headlineLabel, children, }: { icon: ReactNode title: string subtitle: string headline: string headlineLabel: string children: ReactNode }) { return (
{icon}

{title}

{subtitle}

{headline}
{headlineLabel}
{children}
) } function MetricBar({ label, value, detail, compact = false, }: { label: string value: number | null detail?: string compact?: boolean }) { const percent = value == null ? 0 : Math.max(0, Math.min(100, value * 100)) return (
{label} {formatPercent(value)}
{detail &&
{detail}
}
) } function Histogram({ scores }: { scores: number[] }) { const buckets = Array.from({ length: 10 }, (_, index) => ({ label: `${index * 10}-${(index + 1) * 10}%`, count: 0, })) for (const score of scores) { if (!Number.isFinite(score)) continue const bucket = Math.min(9, Math.max(0, Math.floor(score * 10))) buckets[bucket].count += 1 } const maxCount = Math.max(...buckets.map((bucket) => bucket.count), 1) return (
Benchmark completeness distribution
{buckets.map((bucket) => (
{bucket.label.split("-")[0]}
))}
) } function RatioTile({ label, value, count }: { label: string; value: number | null; count: number }) { return (
{label}
{formatPercent(value)} {count.toLocaleString()} groups
) } function ComparabilityRateCard({ title, rate, eligible, divergent, }: { title: string rate: number | null eligible: number divergent: number }) { if (rate == null) { return (
{title}
N/A - not enough data to compute this rate.
) } return (
{title}
{formatPercent(rate)}
{divergent.toLocaleString()} of {eligible.toLocaleString()} eligible groups
) } function MiniMetric({ label, value }: { label: string; value: string }) { return (
{label}
{value}
) } function formatNullableRate(value: number | null | undefined) { return value == null ? "N/A" : formatPercent(value) } function formatGeneratedDate(value: string) { const date = new Date(value) if (Number.isNaN(date.getTime())) { return value } return date.toLocaleDateString("en-US", { year: "numeric", month: "short", day: "numeric", }) }