/** * /bureau — Investigation Bureau hub. * * Full listing of every artefact: evidence, hypotheses, contradictions, * witnesses, outliers, case reports, recent jobs. Each anchor-section * matches the hash-links from the homepage's counter row. */ import Link from "next/link"; import { pgQuery } from "@/lib/retrieval/db"; import { AuthBar } from "@/components/auth-bar"; export const runtime = "nodejs"; export const dynamic = "force-dynamic"; interface EvidenceRow { evidence_id: string; grade: string; verbatim_excerpt: string; source_page_id: string; confidence_band: string | null; } interface HypothesisRow { hypothesis_id: string; question: string; position: string; prior: number | string | null; posterior: number | string | null; confidence_band: string | null; status: string; reviewed_by: string | null; created_at: string; } interface ContradictionRow { contradiction_id: string; topic: string; resolution_status: string; chunks: unknown; } interface GapRow { gap_id: string; description: string; scope: unknown; status: string; suggested_next_move: string | null; } interface WitnessRow { witness_id: string; canonical_name: string | null; entity_id: string | null; credibility: string | null; verdict: string | null; } interface JobRow { job_id: string; kind: string; status: string; payload: Record | null; created_at: string; finished_at: string | null; triggered_by: string | null; } const BAND_TONE: Record = { high: "text-[#06d6a0] border-[#06d6a0]", medium: "text-[#3fde6a] border-[#3fde6a]", low: "text-[#ffa500] border-[#ffa500]", speculation: "text-[#ff6ec7] border-[#ff6ec7]", }; const GRADE_TONE: Record = { A: "text-[#06d6a0] border-[#06d6a0]", B: "text-[#3fde6a] border-[#3fde6a]", C: "text-[#ffa500] border-[#ffa500]", }; export default async function BureauPage() { // All artefacts. Server component — single round per query, no n+1. const [hyp, ev, ctr, gap, wit, jobs] = await Promise.all([ pgQuery( `SELECT hypothesis_id, question, position, prior, posterior, confidence_band, status, reviewed_by, created_at FROM public.hypotheses ORDER BY created_at DESC LIMIT 100`, ).catch(() => []), pgQuery( `SELECT evidence_id, grade, verbatim_excerpt, source_page_id, confidence_band FROM public.evidence ORDER BY created_at DESC LIMIT 100`, ).catch(() => []), pgQuery( `SELECT contradiction_id, topic, resolution_status, chunks FROM public.contradictions ORDER BY created_at DESC LIMIT 100`, ).catch(() => []), pgQuery( `SELECT gap_id, description, scope, status, suggested_next_move FROM public.gaps ORDER BY created_at DESC LIMIT 100`, ).catch(() => []), pgQuery( `SELECT w.witness_id, e.canonical_name, e.entity_id, w.credibility, w.verdict FROM public.witnesses w LEFT JOIN public.entities e ON e.entity_pk = w.person_entity_pk ORDER BY w.created_at DESC LIMIT 100`, ).catch(() => []), pgQuery( `SELECT job_id, kind, status, payload, created_at, finished_at, triggered_by FROM public.investigation_jobs ORDER BY created_at DESC LIMIT 25`, ).catch(() => []), ]); const { readdir, stat, readFile } = await import("node:fs/promises"); const path = await import("node:path"); const reportsDir = path.join(process.env.CASE_ROOT || "/data/ufo/case", "reports"); let reports: Array<{ slug: string; topic: string; mtimeMs: number; n_evidence: number; n_hypotheses: number }> = []; try { const files = await readdir(reportsDir); const items = await Promise.all( files.filter((f) => f.endsWith(".md")).map(async (f) => { const full = path.join(reportsDir, f); const st = await stat(full); const head = (await readFile(full, "utf-8")).slice(0, 2000); const topicMatch = head.match(/topic:\s*"([^"]+)"/); const eMatch = head.match(/n_evidence:\s*(\d+)/); const hMatch = head.match(/n_hypotheses:\s*(\d+)/); return { slug: f.replace(/\.md$/, ""), topic: topicMatch?.[1] ?? f, mtimeMs: st.mtimeMs, n_evidence: Number(eMatch?.[1] ?? 0), n_hypotheses: Number(hMatch?.[1] ?? 0), }; }), ); reports = items.sort((a, b) => b.mtimeMs - a.mtimeMs); } catch { /* fine */ } return (
disclosure.top / bureau

▍ The Investigation Bureau

Live case folder · {ev.length} evidence · {hyp.length} hypotheses · {ctr.length} contradictions ·{" "} {wit.length} witnesses · {gap.length} outliers · {reports.length} reports

{/* Case reports */}
{reports.length === 0 ? : reports.map((r) => (
/c/{r.slug}
{r.topic}
{r.n_hypotheses} hypotheses · {r.n_evidence} evidence
))}
{/* Hypotheses */}
{hyp.length === 0 ? : hyp.map((h) => { const post = h.posterior !== null ? Number(h.posterior) : null; const prior = h.prior !== null ? Number(h.prior) : null; const delta = post !== null && prior !== null ? post - prior : null; const bandTone = (h.confidence_band && BAND_TONE[h.confidence_band]) || "text-[#9aa6b8] border-[#9aa6b8]"; return (
{h.hypothesis_id} · {h.status}
{h.confidence_band && ( {h.confidence_band} )} {h.reviewed_by && ( ↳ {h.reviewed_by} )}
{h.position}
prior {prior?.toFixed(2) ?? "—"} → posterior {post?.toFixed(2) ?? "—"} {delta !== null && 0 ? " text-[#06d6a0]" : delta < 0 ? " text-[#ff6ec7]" : ""}> · Δ {delta >= 0 ? "+" : ""}{delta.toFixed(3)}}
); })}
{/* Evidence */}
{ev.length === 0 ? : ev.map((e) => { const tone = (e.grade && GRADE_TONE[e.grade]) || "text-[#9aa6b8] border-[#9aa6b8]"; return (
{e.evidence_id} · {e.source_page_id} Grade {e.grade}
“{e.verbatim_excerpt}”
); })}
{/* Contradictions */}
{ctr.length === 0 ? : ctr.map((c) => { const n = Array.isArray(c.chunks) ? c.chunks.length : 0; return (
{c.contradiction_id} {n} positions · {c.resolution_status}
{c.topic}
); })}
{/* Outliers */}
{gap.length === 0 ? : gap.map((g) => { const s = (g.scope ?? {}) as Record; const title = (s.title as string) || g.description; const isOutlier = s.kind === "outlier"; return (
{g.gap_id}{isOutlier && " · outlier"} {g.status}
{title}
{s.why_surprising !== undefined && (
{String(s.why_surprising)}
)} {g.suggested_next_move && (
→ {g.suggested_next_move}
)}
); })}
{/* Witnesses */}
{wit.length === 0 ? : wit.map((w) => (
{w.witness_id} {w.credibility ?? "—"}
{w.entity_id ? {w.canonical_name ?? w.entity_id} : (w.canonical_name ?? "—")}
{w.verdict &&
{w.verdict}
}
))}
{/* Recent jobs */}
{jobs.length === 0 ? : (
{jobs.map((j) => ( ))}
job kind status created
{j.job_id.slice(0, 8)}… {j.kind} {j.status} {new Date(j.created_at).toLocaleString("pt-BR")}
)}
); } function Section({ id, title, color, children }: { id: string; title: string; color: string; children: React.ReactNode }) { return (

// {title}

{children}
); } function Empty() { return
_(none yet)_
; }