@validation-os/dashboard 0.15.6 → 0.16.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/dashboard-app.tsx","../src/labels.ts","../src/assumption-detail.tsx","../src/breadcrumb.tsx","../src/evidence-composition.ts","../src/derived-views.ts","../src/confidence-explainer.ts","../src/markdown.tsx","../src/glossary-text.tsx","../src/primitives.ts","../src/glossary.ts","../src/record-view.ts","../src/columns.ts","../src/use-records.ts","../src/edit.ts","../src/assumptions-surface.tsx","../src/next-move.ts","../src/cold-start.ts","../src/pipeline.ts","../src/recommended-experiments.ts","../src/stage-meters.ts","../src/stage-grid-model.ts","../src/experiment-detail.tsx","../src/confidence-donut.tsx","../src/experiments-surface.tsx","../src/reading-detail.tsx","../src/readings-surface.tsx","../src/record-page.tsx","../src/detail-fields.ts","../src/edit-fields.tsx","../src/journey.ts","../src/cycles.ts","../src/journey-surface.tsx","../src/step-in-forms.tsx","../src/drawer-shell.tsx","../src/field-styles.ts","../src/use-mutations.ts","../src/primitives-view.tsx","../src/understanding.ts","../src/understanding-panel.tsx","../src/list-surface.ts","../src/belief-verdicts.tsx","../src/register-browser.tsx","../src/register-table.tsx","../src/record-drawer.tsx","../src/record-form.tsx","../src/form-fields.ts","../src/relation-editor.tsx","../src/link-choices.ts","../src/use-saved-views.ts","../src/route.ts","../src/sidebar-nav.tsx","../src/use-counts.ts","../src/connect.ts","../src/connect-claude-code.tsx","../src/surface-placeholder.tsx","../src/pipeline-surface.tsx","../src/register-counts.tsx","../src/next-move-surface.tsx","../src/stage-grid-surface.tsx"],"sourcesContent":["import { useCallback, useEffect, useState } from \"react\";\nimport type { Collection } from \"@validation-os/core\";\nimport { REGISTER_ORDER, REGISTER_SUBTITLE } from \"./labels.js\";\nimport { AssumptionDetail } from \"./assumption-detail.js\";\nimport { AssumptionsSurface } from \"./assumptions-surface.js\";\nimport { ExperimentDetail } from \"./experiment-detail.js\";\nimport { ExperimentsSurface } from \"./experiments-surface.js\";\nimport { ReadingDetail } from \"./reading-detail.js\";\nimport { ReadingsSurface } from \"./readings-surface.js\";\nimport { RecordPage } from \"./record-page.js\";\nimport { RegisterBrowser } from \"./register-browser.js\";\nimport { formatRoute, parseRoute, type Route } from \"./route.js\";\nimport { SidebarNav } from \"./sidebar-nav.js\";\nimport { useCounts, useNeedsHuman } from \"./use-counts.js\";\n\n/**\n * Everything the instance passes — config only, never secrets. The API base\n * path points at where the Clerk-gated `@validation-os/api` routes are mounted;\n * the backend label (from the connector config) shows in the topbar; branding\n * and the signed-in user are optional cosmetics. Auth is the instance's Clerk\n * provider that this renders within — no credential reaches the package.\n */\nexport interface DashboardConfig {\n /** Where the API is mounted (default `/api`). */\n basePath?: string;\n /** Topbar backend indicator, e.g. \"Firestore · my-register\". */\n backendLabel?: string;\n /** Optional product branding for the sidebar. */\n branding?: {\n /** Product name shown next to the mark (default \"Validation-OS\"). */\n name?: string;\n /** One or two letters for the square mark (default \"V\"). */\n initials?: string;\n /** A logo image for the square mark; overrides `initials` when set. */\n logoUrl?: string;\n };\n /** Optional agent label shown in the topbar, e.g. \"Claude Code\". */\n agentLabel?: string;\n /** The signed-in user, for the topbar avatar + name. */\n user?: { name?: string; caption?: string };\n /** Restrict/reorder the registers shown; defaults to all, in order. */\n registers?: Collection[];\n}\n\nexport interface ValidationOSDashboardProps {\n config?: DashboardConfig;\n}\n\n/** Two letters from a name for the avatar, e.g. \"Benji Fisher\" → \"BF\". */\nfunction initialsOf(name: string): string {\n const parts = name.trim().split(/\\s+/);\n const first = parts[0]?.[0] ?? \"\";\n const last = parts.length > 1 ? (parts[parts.length - 1]?.[0] ?? \"\") : \"\";\n return (first + last).toUpperCase() || \"?\";\n}\n\n/**\n * The entire styled dashboard as one mountable app (spec OPS-1280 / DEV-5879\n * redesign): the frame — a 3-item sidebar (Assumptions / Experiments /\n * Readings) plus a small Registers group for decisions + glossary, topbar with\n * the backend indicator and user — and the surfaces it routes between. The\n * Assumptions nav lands on the Lens × Stage grid; a \"Grid / View all\" toggle\n * switches to the pipeline board. Both drill into the same AssumptionDetail.\n * Experiments shows the live evidence plans; Readings shows the evidence log.\n * Each detail view is evidence-first: readings lead, bar lines are context.\n *\n * Navigation is owned here, not the host router: the active route lives in\n * client state, synced to the URL hash (OPS-1298), so the instance mounts this\n * at one route and wires no routing. Styled by the package's own token sheet —\n * the instance imports `styles.css` once and builds no UI.\n */\nexport function ValidationOSDashboard({ config = {} }: ValidationOSDashboardProps) {\n const {\n basePath = \"/api\",\n backendLabel,\n branding,\n agentLabel,\n user,\n registers = REGISTER_ORDER,\n } = config;\n\n const [route, setRoute] = useState<Route>(() =>\n typeof window === \"undefined\"\n ? { name: \"assumptions\" }\n : parseRoute(window.location.hash, registers),\n );\n const { counts } = useCounts(basePath);\n const { byRegister: needsHuman, liveExperimentCount } = useNeedsHuman(basePath);\n\n // The nav count must match what actually renders. `/counts` tallies every\n // stored row, but archived evidence plans never surface (OPS-1305), so the\n // experiments badge is corrected to the live-only count once it's known —\n // otherwise it reads e.g. 66 while the register shows a handful.\n const navCounts =\n counts && liveExperimentCount !== null\n ? { ...counts, experiments: liveExperimentCount }\n : counts;\n\n // Keep the route and the URL hash in step, so a deep link opens the right\n // surface and the browser back/forward buttons move between them. The hash is\n // the single source of truth: `navigate` only writes it, and this listener\n // reads it back into state.\n useEffect(() => {\n if (typeof window === \"undefined\") return;\n const onHash = () => setRoute(parseRoute(window.location.hash, registers));\n onHash();\n window.addEventListener(\"hashchange\", onHash);\n return () => window.removeEventListener(\"hashchange\", onHash);\n }, [registers]);\n\n const navigate = useCallback((next: Route) => {\n if (typeof window === \"undefined\") {\n setRoute(next);\n return;\n }\n window.location.hash = formatRoute(next);\n }, []);\n\n const toggleTheme = useCallback(() => {\n const root = document.documentElement;\n const current =\n root.getAttribute(\"data-theme\") ??\n (window.matchMedia(\"(prefers-color-scheme: dark)\").matches\n ? \"dark\"\n : \"light\");\n root.setAttribute(\"data-theme\", current === \"dark\" ? \"light\" : \"dark\");\n }, []);\n\n const brandName = branding?.name ?? \"Validation-OS\";\n const brandMark = branding?.initials ?? \"V\";\n\n return (\n <div className=\"vos-app\">\n <div className=\"vos-brand\">\n <span className=\"vos-brand-dot\">\n {branding?.logoUrl ? (\n <img src={branding.logoUrl} alt=\"\" />\n ) : (\n brandMark\n )}\n </span>{\" \"}\n {brandName}\n </div>\n\n <div className=\"vos-topbar\">\n <div className=\"vos-spacer\" />\n <button type=\"button\" className=\"vos-iconbtn\" onClick={toggleTheme}>\n ◐ Theme\n </button>\n {user?.name ? (\n <div className=\"vos-user\">\n <span className=\"vos-avatar\">{initialsOf(user.name)}</span>\n <div>\n <span className=\"vos-user-name\">{user.name}</span>\n {user.caption ? <small>{user.caption}</small> : null}\n </div>\n </div>\n ) : null}\n </div>\n\n <SidebarNav\n route={route}\n onNavigate={navigate}\n counts={navCounts}\n needsHuman={needsHuman}\n registers={registers}\n />\n\n <main className=\"vos-main\">\n {route.name === \"assumptions\" ? (\n <AssumptionsSurface\n key={`assumptions-${route.view ?? \"\"}-${route.lens ?? \"\"}-${route.stage ?? \"\"}`}\n basePath={basePath}\n onNavigate={navigate}\n view={route.view}\n lens={route.lens}\n stage={route.stage}\n />\n ) : route.name === \"experiments\" ? (\n <ExperimentsSurface\n key=\"experiments\"\n basePath={basePath}\n onNavigate={navigate}\n />\n ) : route.name === \"readings\" ? (\n <ReadingsSurface\n key=\"readings\"\n basePath={basePath}\n onNavigate={navigate}\n />\n ) : route.name === \"assumption\" ? (\n <AssumptionDetail\n key={`assumption-${route.id}`}\n assumptionId={route.id}\n basePath={basePath}\n onNavigate={navigate}\n />\n ) : route.name === \"experiment\" ? (\n <ExperimentDetail\n key={`experiment-${route.id}`}\n experimentId={route.id}\n basePath={basePath}\n onNavigate={navigate}\n />\n ) : route.name === \"reading\" ? (\n <ReadingDetail\n key={`reading-${route.id}`}\n readingId={route.id}\n basePath={basePath}\n onNavigate={navigate}\n />\n ) : route.name === \"records\" ? (\n <RegisterBrowser\n key={route.register + (route.lens ?? \"\") + (route.stage ?? \"\") + (route.view ?? \"\")}\n register={route.register}\n basePath={basePath}\n subtitle={REGISTER_SUBTITLE[route.register]}\n onOpenRecord={(id) => navigate({ name: \"record\", id })}\n lens={route.lens}\n stage={route.stage}\n />\n ) : route.name === \"record\" ? (\n <RecordPage\n key={route.id}\n recordId={route.id}\n onNavigate={navigate}\n backRegister={registers[0] ?? \"assumptions\"}\n basePath={basePath}\n />\n ) : (\n <AssumptionsSurface\n key=\"assumptions-fallback\"\n basePath={basePath}\n onNavigate={navigate}\n />\n )}\n </main>\n </div>\n );\n}\n","import type { Collection } from \"@validation-os/core\";\n\n/** Plain-language labels — the register is a surface a non-technical\n * teammate meets, so no jargon and no code-y plurals. */\nexport const REGISTER_LABEL: Record<Collection, string> = {\n assumptions: \"Assumptions\",\n // One container-agnostic lens now Goal is unified into Experiment (OPS-1299 /\n // OPS-1287 story 22): all plans browse in one place under this label.\n experiments: \"Evidence plans\",\n readings: \"Evidence\",\n decisions: \"Decisions\",\n glossary: \"Glossary\",\n};\n\n/** Singular labels — for \"New {thing}\" affordances (never a naive de-pluralise\n * that would read \"New Glossary\"). */\nexport const REGISTER_SINGULAR: Record<Collection, string> = {\n assumptions: \"Assumption\",\n experiments: \"Evidence plan\",\n readings: \"Evidence\",\n decisions: \"Decision\",\n glossary: \"Glossary term\",\n};\n\n/** The order tiles read left-to-right, top-to-bottom. */\nexport const REGISTER_ORDER: Collection[] = [\n \"assumptions\",\n \"experiments\",\n \"readings\",\n \"decisions\",\n \"glossary\",\n];\n\n/** A one-line description shown under each register's title (spec story 9). */\nexport const REGISTER_SUBTITLE: Record<Collection, string> = {\n assumptions:\n \"Falsifiable beliefs the plan rests on. Risk = Impact × (1 − max(0, Confidence)/100).\",\n experiments: \"The evidence plans that move Confidence in the beliefs.\",\n readings: \"The evidence logged against experiments and beliefs.\",\n decisions: \"The choices made, and what they rest on.\",\n glossary: \"The shared vocabulary for this venture.\",\n};\n\n/** A single-glyph icon per register for the sidebar nav (matches the prototype\n * feel; a glyph, not an icon font, so nothing external is pulled in). */\nexport const REGISTER_ICON: Record<Collection, string> = {\n assumptions: \"◎\",\n experiments: \"⚗\",\n readings: \"✦\",\n decisions: \"§\",\n glossary: \"A\",\n};\n\n/** The sidebar groups — all five registers now sit in one set (the retired\n * `people` reference collection was the only \"Reference\" member). */\nexport const REGISTER_GROUPS: { label: string; registers: Collection[] }[] = [\n {\n label: \"Registers\",\n registers: [\"assumptions\", \"experiments\", \"readings\", \"decisions\", \"glossary\"],\n },\n];\n\n/** The workflow surfaces the sidebar lists above the register tables\n * (OPS-1298 / DEV-5879 redesign): three top-level nav items — Assumptions\n * (the default landing, the Lens × Stage grid with a \"View all\" toggle to\n * the pipeline board), Experiments (the live evidence plans), and Evidence\n * (the evidence log). Kept beside the register presentation data so all\n * sidebar labels/icons live in one place. */\nexport interface WorkflowNavItem {\n /** The route this item selects. */\n route: \"assumptions\" | \"experiments\" | \"readings\";\n label: string;\n icon: string;\n /** The default landing — carries a \"home\" badge in the nav. */\n isDefault?: boolean;\n}\n\nexport const WORKFLOW_NAV: WorkflowNavItem[] = [\n { route: \"assumptions\", label: \"Assumptions\", icon: \"◎\", isDefault: true },\n { route: \"experiments\", label: \"Experiments\", icon: \"⚗\" },\n { route: \"readings\", label: \"Evidence\", icon: \"✦\" },\n];\n","import { useMemo } from \"react\";\nimport type { AnyRecord } from \"@validation-os/core\";\nimport { Breadcrumb } from \"./breadcrumb.js\";\nimport { buildEvidenceComposition, readingContributions, type ReadingContribution } from \"./evidence-composition.js\";\nimport { buildConfidenceExplainer } from \"./confidence-explainer.js\";\nimport { readingBeliefs, readingBeliefFor, liveExperiments } from \"./derived-views.js\";\nimport { EvidenceBody } from \"./markdown.js\";\nimport { GlossaryText } from \"./glossary-text.js\";\nimport { toGlossaryTerms } from \"./glossary.js\";\nimport { formatSigned, type Tone } from \"./primitives.js\";\nimport type { Route } from \"./route.js\";\nimport {\n buildRecordPage,\n type BacklinkItem,\n type Meter,\n type Pill,\n type RelatedSet,\n} from \"./record-view.js\";\nimport { useList } from \"./use-records.js\";\n\n/**\n * The assumption detail (DEV-5883): next-move panel at the top, score cards,\n * evidence composition (per-rung bars, lens-aware), body (Markdown with\n * glossary auto-linking), graph relations grouped by kind, linked experiments\n * with bar-line preview, evidence-first linked readings (each with its own\n * excerpt for this assumption).\n */\nexport interface AssumptionDetailProps {\n assumptionId: string;\n basePath?: string;\n onNavigate: (route: Route) => void;\n}\n\nexport function AssumptionDetail({\n assumptionId,\n basePath,\n onNavigate,\n}: AssumptionDetailProps) {\n const assumptions = useList(\"assumptions\", basePath);\n const experiments = useList(\"experiments\", basePath);\n const readings = useList(\"readings\", basePath);\n const decisions = useList(\"decisions\", basePath);\n const glossary = useList(\"glossary\", basePath);\n\n const loading =\n assumptions.loading && !assumptions.records;\n\n const related: RelatedSet = {\n assumptions: assumptions.records ?? [],\n experiments: experiments.records ?? [],\n readings: readings.records ?? [],\n decisions: decisions.records ?? [],\n glossary: glossary.records ?? [],\n };\n\n const record = useMemo(\n () => (assumptions.records ?? []).find((a) => String(a.id) === assumptionId) ?? null,\n [assumptions.records, assumptionId],\n );\n\n if (loading) {\n return (\n <div>\n <Breadcrumb trail={[{ label: \"Assumptions\", route: { name: \"assumptions\" } }]} onNavigate={onNavigate} />\n <p className=\"vos-muted\">Loading belief…</p>\n </div>\n );\n }\n if (!record) {\n return (\n <div>\n <Breadcrumb trail={[{ label: \"Assumptions\", route: { name: \"assumptions\" } }]} onNavigate={onNavigate} />\n <p className=\"vos-error\">Belief not found: {assumptionId}</p>\n </div>\n );\n }\n\n const page = buildRecordPage(\"assumptions\", record, related);\n const lens = String(record.Lens ?? \"—\");\n const stage = String(record.Stage ?? \"—\");\n const derived = (record.derived ?? {}) as {\n derivedImpact?: number;\n risk?: number;\n confidence?: number;\n completeness?: number;\n };\n const confidence = derived.confidence ?? 0;\n const risk = derived.risk ?? 0;\n const impact = derived.derivedImpact ?? 0;\n const framed = derived.completeness ?? 0;\n\n // Next move — derive a one-line next move from the page's meters, or fall\n // back to a stage-aware verb. (The existing nextMove lives in pipeline.ts;\n // for the detail we read the first meter that needs attention.)\n const nextMove = nextMoveFor(record, experiments.records ?? []);\n\n // Linked experiments testing this assumption — live only (exclude Archived).\n const linkedExperiments = liveExperiments(experiments.records ?? []).filter((e) => {\n const ids = Array.isArray(e.barLineAssumptionIds)\n ? (e.barLineAssumptionIds as string[])\n : [];\n return ids.includes(assumptionId);\n });\n\n // Linked readings — evidence-first: each reading that scores this assumption,\n // with the per-belief excerpt.\n const linkedReadings = (readings.records ?? [])\n .filter((r) => {\n const beliefs = readingBeliefs(r);\n return beliefs.some((b) => b.assumptionId === assumptionId);\n })\n .sort((a, b) => String(b.Date ?? \"\").localeCompare(String(a.Date ?? \"\")));\n\n // Graph relations — grouped by kind, then by entity type.\n const relations = relationsFor(record, related);\n\n // Glossary terms for auto-linking the body.\n const glossaryTerms = toGlossaryTerms(glossary.records ?? []);\n\n const title = String(record.Title ?? assumptionId);\n const statement = String(record.Description ?? title);\n\n return (\n <div>\n <Breadcrumb\n trail={[\n { label: \"Assumptions\", route: { name: \"assumptions\" } },\n { label: assumptionId, route: { name: \"assumption\", id: assumptionId } },\n ]}\n onNavigate={onNavigate}\n />\n\n <div className=\"vos-detail-head\">\n <span className=\"vos-detail-id vos-num\">{assumptionId}</span>\n <span className=\"vos-detail-tag\">{lens}</span>\n <span className=\"vos-detail-tag\">{stage}</span>\n </div>\n <div className=\"vos-detail-title\">{statement}</div>\n\n {/* Next move panel — accent-bordered, prominent */}\n <div className=\"vos-card vos-next-move\">\n <div className=\"vos-next-move-label\">Recommended next move</div>\n <div className=\"vos-next-move-text\">{nextMove}</div>\n </div>\n\n {/* Score cards */}\n <div className=\"vos-score-cards\">\n <ScoreCard label=\"Impact\" value={Math.round(impact)} />\n <ScoreCard label=\"Risk\" value={Math.round(risk)} tone={riskTone(risk)} />\n <ScoreCard label=\"Confidence\" value={formatSigned(confidence)} />\n <ScoreCard label=\"Framed\" value={`${Math.round(framed)}%`} />\n </div>\n\n {/* Evidence composition — per-rung bars, lens-aware (uses the real\n confidence attribution math, so contributions add up to Confidence) */}\n <EvidenceCompositionView assumption={record} readings={readings.records ?? []} />\n\n {/* Confidence explainer — the formula, per-rung W0s, anchors, and what\n each piece of evidence contributes. Demystifies how the number is\n calculated. */}\n <ConfidenceExplainerView assumption={record} readings={readings.records ?? []} />\n\n {/* Body — Markdown with glossary auto-linking */}\n {statement ? (\n <div className=\"vos-card vos-detail-section\">\n <div className=\"vos-detail-section-label\">Body</div>\n <GlossaryText text={statement} terms={glossaryTerms} selfId={assumptionId} />\n </div>\n ) : null}\n\n {/* Relations — grouped by kind, then by entity type */}\n {relations.length > 0 ? (\n <div className=\"vos-card vos-detail-section\">\n <div className=\"vos-detail-section-label\">Relations · {relations.length}</div>\n {([\"Depends on\", \"Enables\", \"Contradicts\"] as const).map((kind) => {\n const rels = relations.filter((r) => r.kind === kind);\n if (rels.length === 0) return null;\n const byType = groupBy(rels, (r) => r.targetType);\n return (\n <div key={kind} className=\"vos-rel-group\">\n <div className={`vos-rel-kind vos-rel-kind-${kindToClass(kind)}`}>{kind.toUpperCase()}</div>\n {Object.entries(byType).map(([type, items]) => (\n <div key={type} className=\"vos-rel-type\">\n <div className=\"vos-rel-type-label\">{type}s ({items.length})</div>\n {items.map((r) => (\n <RelationRow key={r.targetId} rel={r} onNavigate={onNavigate} />\n ))}\n </div>\n ))}\n </div>\n );\n })}\n </div>\n ) : null}\n\n {/* Linked experiments — with bar-line preview for this assumption */}\n {linkedExperiments.length > 0 ? (\n <div className=\"vos-card vos-detail-section\">\n <div className=\"vos-detail-section-label\">\n Experiments testing this · {linkedExperiments.length}\n </div>\n {linkedExperiments.map((e) => {\n const id = String(e.id ?? \"\");\n const bars = Array.isArray(e.barLines) ? e.barLines : [];\n const myBar = bars.find((b: any) => b?.assumptionId === assumptionId);\n const expConf = (e.derived as any)?.experimentConfidence ?? 50;\n return (\n <button\n key={id}\n type=\"button\"\n className=\"vos-linked-row\"\n onClick={() => onNavigate({ name: \"experiment\", id })}\n >\n <span className=\"vos-linked-gauge vos-num\">{Math.round(expConf)}</span>\n <span className=\"vos-linked-title\">{String(e.Title ?? id)}</span>\n {myBar ? (\n <span className=\"vos-linked-bar\">\n <strong>Right if:</strong> {String(myBar.rightIf ?? \"\")}\n {myBar.barVerdict ? (\n <span className={`vos-pill vos-pill-${verdictTone(myBar.barVerdict)}`}>\n {String(myBar.barVerdict)}\n </span>\n ) : null}\n </span>\n ) : null}\n </button>\n );\n })}\n </div>\n ) : null}\n\n {/* Evidence list — one row per piece of evidence, with per-belief\n excerpt, verdict, rung, anchor score and its contribution to Confidence. */}\n <EvidenceList\n assumptionId={assumptionId}\n readings={readings.records ?? []}\n onNavigate={onNavigate}\n />\n </div>\n );\n}\n\nfunction EvidenceList({\n assumptionId,\n readings,\n onNavigate,\n}: {\n assumptionId: string;\n readings: AnyRecord[];\n onNavigate: (route: Route) => void;\n}) {\n const linkedReadings = readings\n .filter((r) => readingBeliefs(r).some((b) => b.assumptionId === assumptionId))\n .sort((a, b) => String(b.Date ?? \"\").localeCompare(String(a.Date ?? \"\")));\n\n const contribById = useMemo(() => {\n const rec = readings.find((a) => String(a.id) === assumptionId);\n if (!rec) return new Map<string, ReadingContribution>();\n const rows = readingContributions(rec, readings);\n return new Map(rows.map((r) => [r.id, r]));\n }, [readings, assumptionId]);\n\n if (linkedReadings.length === 0) return null;\n\n return (\n <div className=\"vos-card vos-detail-section\">\n <div className=\"vos-detail-section-label\">\n Evidence · {linkedReadings.length} piece{linkedReadings.length === 1 ? \"\" : \"s\"} of evidence\n </div>\n {linkedReadings.map((r) => {\n const id = String(r.id ?? \"\");\n const belief = readingBeliefFor(r, assumptionId);\n if (!belief) return null;\n const result = String(belief.Result ?? \"Inconclusive\");\n const justification = String(belief[\"Grading justification\"] ?? \"\");\n const excerpt =\n typeof belief.excerpt === \"string\" && belief.excerpt !== \"\"\n ? belief.excerpt\n : snippetFromBody(String(r.body ?? \"\"), assumptionId);\n const rung = String(r.Rung ?? \"\");\n const source = String(r.Source ?? \"\");\n const expId = r.experimentId ? String(r.experimentId) : null;\n const c = contribById.get(id);\n return (\n <button\n key={id}\n type=\"button\"\n className={`vos-evidence-row vos-verdict-${verdictTone(result)}`}\n onClick={() => onNavigate({ name: \"reading\", id })}\n >\n <div className=\"vos-evidence-row-head\">\n <span className=\"vos-evidence-date vos-num\">{String(r.Date ?? \"\")}</span>\n <span className=\"vos-evidence-title\">{String(r.Title ?? id)}</span>\n <span className={`vos-pill vos-pill-${verdictTone(result)}`}>{result}</span>\n <span className=\"vos-rung-tag\">{rung}</span>\n {c && c.used ? (\n <span className={`vos-evidence-score vos-num vos-text-${contributionTone(c.contribution)}`}>\n {formatSigned(c.contribution)} confidence\n </span>\n ) : null}\n </div>\n {excerpt ? (\n <div className=\"vos-evidence-excerpt\">“{excerpt}”</div>\n ) : null}\n {justification ? (\n <div className={`vos-belief-rationale vos-verdict-border-${verdictTone(result)}`}>\n <span className=\"vos-belief-rationale-label\">grading rationale:</span>\n {justification}\n </div>\n ) : null}\n <div className=\"vos-evidence-source\">\n <span className=\"vos-evidence-source-link\" title={source}>{source}</span>\n {expId ? (\n <>\n {\" · from experiment \"}\n <span\n className=\"vos-link\"\n onClick={(ev) => {\n ev.stopPropagation();\n onNavigate({ name: \"experiment\", id: expId });\n }}\n >\n {expId}\n </span>\n </>\n ) : null}\n </div>\n </button>\n );\n })}\n </div>\n );\n}\n\nfunction contributionTone(v: number): Tone {\n if (v > 0) return \"good\";\n if (v < 0) return \"crit\";\n return \"neutral\";\n}\n\nfunction snippetFromBody(body: string, cue: string): string {\n if (!body) return \"\";\n const quoteMatch = body.match(/## Quote\\n+([\\s\\S]*?)(?=\\n## |\\n##$|$)/i);\n if (quoteMatch) {\n const q = quoteMatch[1]!.trim();\n return q.length > 220 ? q.slice(0, 217).trim() + \"…\" : q;\n }\n const sentences = body.split(/(?<=[.!?])\\s+/);\n const cueLower = cue.toLowerCase();\n for (const s of sentences) {\n if (s.toLowerCase().includes(cueLower)) return s.trim();\n }\n const first = sentences[0]?.trim() ?? \"\";\n return first.length > 220 ? first.slice(0, 217).trim() + \"…\" : first;\n}\n\n/* ── helpers ───────────────────────────────────────────────────────────── */\n\nfunction ScoreCard({\n label,\n value,\n tone,\n}: {\n label: string;\n value: number | string;\n tone?: \"good\" | \"warn\" | \"crit\";\n}) {\n const cls = tone ? `vos-score-value vos-text-${tone}` : \"vos-score-value\";\n return (\n <div className=\"vos-score-card\">\n <div className={cls}>{value}</div>\n <div className=\"vos-score-label\">{label}</div>\n </div>\n );\n}\n\nfunction riskTone(risk: number): \"good\" | \"warn\" | \"crit\" {\n if (risk >= 70) return \"crit\";\n if (risk >= 40) return \"warn\";\n return \"good\";\n}\n\nfunction verdictTone(verdict: string): \"good\" | \"crit\" | \"neutral\" {\n if (verdict === \"Validated\") return \"good\";\n if (verdict === \"Invalidated\") return \"crit\";\n return \"neutral\";\n}\n\nfunction kindToClass(kind: string): string {\n if (kind === \"Depends on\") return \"depends\";\n if (kind === \"Enables\") return \"enables\";\n return \"contradicts\";\n}\n\nfunction groupBy<T>(arr: T[], fn: (t: T) => string): Record<string, T[]> {\n const out: Record<string, T[]> = {};\n for (const x of arr) {\n const k = fn(x);\n if (!out[k]) out[k] = [];\n out[k].push(x);\n }\n return out;\n}\n\ninterface Relation {\n kind: \"Depends on\" | \"Enables\" | \"Contradicts\";\n targetId: string;\n targetType: \"assumption\" | \"decision\";\n targetTitle: string;\n}\n\nfunction relationsFor(record: AnyRecord, related: RelatedSet): Relation[] {\n const out: Relation[] = [];\n const push = (ids: unknown, kind: Relation[\"kind\"], type: Relation[\"targetType\"]) => {\n if (!Array.isArray(ids)) return;\n for (const id of ids) {\n const idStr = String(id);\n const target =\n type === \"assumption\"\n ? (related.assumptions ?? []).find((a) => String(a.id) === idStr)\n : (related.decisions ?? []).find((d) => String(d.id) === idStr);\n out.push({\n kind,\n targetId: idStr,\n targetType: type,\n targetTitle: target ? String(target.Title ?? idStr) : idStr,\n });\n }\n };\n push(record.dependsOnIds, \"Depends on\", \"assumption\");\n push(record.enablesIds, \"Enables\", \"assumption\");\n push(record.contradictsIds, \"Contradicts\", \"assumption\");\n // Decisions that resolve / are based-on this assumption aren't on the\n // assumption record's relation fields — skip for now.\n return out;\n}\n\nfunction RelationRow({\n rel,\n onNavigate,\n}: {\n rel: Relation;\n onNavigate: (route: Route) => void;\n}) {\n const isAssumption = rel.targetType === \"assumption\";\n return (\n <button\n type=\"button\"\n className=\"vos-rel-row\"\n disabled={!isAssumption}\n onClick={() => isAssumption && onNavigate({ name: \"assumption\", id: rel.targetId })}\n >\n <span className=\"vos-rel-id vos-num\">{rel.targetId}</span>\n <span className=\"vos-rel-title\">{rel.targetTitle}</span>\n {!isAssumption ? <span className=\"vos-rel-tag\">decision</span> : null}\n </button>\n );\n}\n\nfunction nextMoveFor(assumption: AnyRecord, experiments: AnyRecord[]): string {\n // A simple stage-aware next-move verb: if there's a live experiment testing\n // this assumption → \"Record a reading\"; if framed but no test → \"Design an\n // experiment\"; if not framed → \"Frame the belief\". (The full OPS-1292\n // ranking lives in core's rankNextMoves; this is the detail's one-liner.)\n const id = String(assumption.id ?? \"\");\n const framed = ((assumption.derived as any)?.completeness ?? 0) >= 100;\n const hasLiveTest = experiments.some((e) => {\n const status = String(e.Status ?? \"\");\n if (status === \"Archived\") return false;\n const ids = Array.isArray(e.barLineAssumptionIds)\n ? (e.barLineAssumptionIds as string[])\n : [];\n return ids.includes(id);\n });\n if (hasLiveTest) return \"Record a reading\";\n if (framed) return \"Design an experiment\";\n return \"Frame the belief\";\n}\n\n/* ── Confidence explainer — the formula + per-rung breakdown ───────────── */\n\nfunction ConfidenceExplainerView({\n assumption,\n readings,\n}: {\n assumption: AnyRecord;\n readings: AnyRecord[];\n}) {\n const view = useMemo(\n () => buildConfidenceExplainer(assumption, readings),\n [assumption, readings],\n );\n return (\n <details className=\"vos-card vos-detail-section vos-explainer\">\n <summary className=\"vos-explainer-summary\">\n <span className=\"vos-detail-section-label\">How Confidence is calculated</span>\n <span className=\"vos-explainer-conf vos-num\">{formatSigned(view.confidence)}</span>\n </summary>\n <div className=\"vos-explainer-body\">\n <p className=\"vos-explainer-formula\">{view.formula}</p>\n <p className=\"vos-explainer-summary-text\">{view.summary}</p>\n <div className=\"vos-explainer-rungs\">\n <div className=\"vos-explainer-rungs-head\">\n <span>Rung</span>\n <span>W0 (prior)</span>\n <span>Anchors (L/T/H)</span>\n <span>Evidence</span>\n <span>Contribution</span>\n </div>\n {view.rungs.map((r) => (\n <div\n key={r.rung}\n className={`vos-explainer-rung ${!r.inLens ? \"is-not-lens\" : \"\"} ${r.count > 0 ? \"has-evidence\" : \"\"}`}\n >\n <span className=\"vos-explainer-rung-name\" title={r.description}>\n {r.label}\n </span>\n <span className=\"vos-explainer-rung-w0 vos-num\">{r.w0}</span>\n <span className=\"vos-explainer-rung-anchors vos-num\">\n {r.anchors.Low}/{r.anchors.Typical}/{r.anchors.High}\n </span>\n <span className=\"vos-explainer-rung-count vos-num\">\n {r.count > 0 ? `${r.count} source${r.count === 1 ? \"\" : \"s\"}` : \"—\"}\n </span>\n <span className={`vos-explainer-rung-contrib vos-num ${r.contribution > 0 ? \"vos-text-good\" : r.contribution < 0 ? \"vos-text-crit\" : \"\"}`}>\n {r.count > 0 ? formatSigned(r.contribution) : \"—\"}\n </span>\n </div>\n ))}\n </div>\n <div className=\"vos-explainer-foot\">\n <p>\n <strong>W0</strong> = the prior weight for each rung — how many distinct\n sources it takes to approach that rung's cap. Desk research has a low W0\n (2 — one authoritative source nearly saturates it); Talk has a higher W0\n (6.5 — needs ~10 sources); do-rungs have high W0s (327 — needs ~20\n sources to reach 75% of the cap).\n </p>\n <p>\n <strong>Strength</strong> = the rung's anchor × the sign of the result\n (Validated = +, Invalidated = −, Inconclusive = 0). The anchor is the\n band (Low/Typical/High) the evidence lands at.\n </p>\n <p>\n <strong>Weight</strong> = |Strength| × source quality × commitment factor\n (1.0 for evidence linked to an experiment, 0.85 for found evidence).\n </p>\n <p>\n <strong>Contribution</strong> = (Weight × Strength) / denominator. The\n sum of all contributions equals Confidence. Evidence at a higher rung\n always outweighs evidence at a lower rung — the rung ladder dominates.\n </p>\n </div>\n </div>\n </details>\n );\n}\n\nfunction EvidenceCompositionView({\n assumption,\n readings,\n}: {\n assumption: AnyRecord;\n readings: AnyRecord[];\n}) {\n const comp = useMemo(\n () => buildEvidenceComposition(assumption, readings),\n [assumption, readings],\n );\n return (\n <div className=\"vos-card vos-detail-section\">\n <div className=\"vos-detail-section-label\">\n Evidence composition · Σ = {formatSigned(comp.totalContribution)} (adds to Confidence)\n </div>\n {comp.rungs.length === 0 ? (\n <div className=\"vos-muted\">No lens set — evidence composition needs a lens.</div>\n ) : (\n comp.rungs.map((r) => {\n const abs = Math.abs(r.contribution);\n const pct = r.cap > 0 ? Math.min(100, (abs / r.cap) * 100) : 0;\n const isEmpty = r.count === 0;\n const tone = r.contribution > 0 ? \"good\" : r.contribution < 0 ? \"crit\" : \"accent\";\n return (\n <div key={r.rung} className=\"vos-comp-row\">\n <span className={`vos-comp-rung ${isEmpty ? \"is-empty\" : \"\"}`}>{r.rung}</span>\n <div className=\"vos-comp-bar\">\n <i className={`vos-comp-fill vos-fill-${tone}`} style={{ width: `${isEmpty ? 0 : Math.max(4, pct)}%` }} />\n </div>\n <span className=\"vos-comp-val vos-num\">\n {isEmpty ? \"—\" : (\n <>\n <span className={`vos-text-${tone}`}>{formatSigned(r.contribution)}</span>\n <span style={{ color: \"var(--vos-faint)\" }}> · cap {r.cap}</span>\n </>\n )}\n </span>\n <span className=\"vos-comp-count vos-num\">\n {r.count} {r.count === 1 ? \"source\" : \"sources\"}\n </span>\n </div>\n );\n })\n )}\n </div>\n );\n}","import type { Route } from \"./route.js\";\n\n/**\n * A breadcrumb trail (DEV-5881). Each segment is a button that navigates to\n * its route; the last segment is rendered as plain text (the current page).\n */\nexport interface BreadcrumbProps {\n trail: { label: string; route: Route }[];\n onNavigate?: (route: Route) => void;\n}\n\nexport function Breadcrumb({ trail, onNavigate }: BreadcrumbProps) {\n return (\n <nav className=\"vos-crumb\" aria-label=\"Breadcrumb\">\n {trail.map((t, i) => {\n const isLast = i === trail.length - 1;\n return (\n <span key={i} className=\"vos-crumb-item\">\n {i > 0 ? <span className=\"vos-crumb-sep\" aria-hidden=\"true\">/</span> : null}\n {isLast || !onNavigate ? (\n <span className=\"vos-crumb-current\">{t.label}</span>\n ) : (\n <button\n type=\"button\"\n className=\"vos-crumb-link\"\n onClick={() => onNavigate(t.route)}\n >\n {t.label}\n </button>\n )}\n </span>\n );\n })}\n </nav>\n );\n}","/**\n * Evidence composition (DEV-5883) — the per-rung breakdown of what's moving an\n * assumption's Confidence. Uses the same `confidenceAttribution` math the\n * hero number uses (so the composition literally adds up to Confidence), not\n * raw strength sums. Each rung's `contribution` is its signed share of the\n * average; `cap` is the rung's Typical anchor (the practical ceiling for one\n * reading at that rung). Empty rungs (no evidence) are kept in the lens-aware\n * ladder order so the composition shows the gaps honestly.\n */\nimport type { AnyRecord } from \"@validation-os/core\";\nimport { scoreAndDedupe, w0ForRung, type AttributionReadingInput } from \"@validation-os/core/derivation\";\nimport { readingBeliefFor } from \"./derived-views.js\";\nimport { str } from \"./derived-views.js\";\n\nexport interface RungContribution {\n /** The rung name (e.g. \"Talk\", \"Desk research\", \"Signed up\"). */\n rung: string;\n /** The signed push on Confidence from this rung's readings. Sums to\n * totalContribution across all rungs. */\n contribution: number;\n /** The rung's Typical anchor — the practical ceiling for one reading. */\n cap: number;\n /** How many distinct readings at this rung scored this assumption. */\n count: number;\n}\n\nexport interface EvidenceCompositionView {\n /** One entry per rung in the lens-aware ladder (lens → its 4 rungs), in\n * ladder order, whether or not there's evidence. */\n rungs: RungContribution[];\n /** Σ contributions — equals the assumption's Confidence (the attribution\n * invariant). */\n totalContribution: number;\n}\n\nexport interface ReadingContribution {\n /** Reading id. */\n id: string;\n /** Signed contribution to the assumption's Confidence. */\n contribution: number;\n /** The absolute weight this reading received after deduplication. */\n weight: number;\n /** The signed strength used (rung anchor × result sign). */\n strength: number;\n /** Whether this reading was kept after deduplication. */\n used: boolean;\n}\n\nconst LENS_RUNGS: Record<string, string[]> = {\n Consumer: [\"Talk\", \"Desk research\", \"Signed up\", \"Observed usage\"],\n Commercial: [\"Talk\", \"Desk research\", \"Signed intent\", \"Paying users\"],\n};\nconst ALL_RUNGS = [\n \"Talk\",\n \"Desk research\",\n \"Signed up\",\n \"Observed usage\",\n \"Signed intent\",\n \"Paying users\",\n];\nconst RUNG_CAPS: Record<string, number> = {\n Talk: 6,\n \"Desk research\": 15,\n \"Signed up\": 50,\n \"Observed usage\": 50,\n \"Signed intent\": 50,\n \"Paying users\": 50,\n};\n\nfunction rungsForLens(lens: string): string[] {\n return LENS_RUNGS[lens] ?? ALL_RUNGS;\n}\n\nexport function buildEvidenceComposition(\n assumption: AnyRecord,\n readings: AnyRecord[],\n): EvidenceCompositionView {\n const id = str(assumption.id) ?? \"\";\n const lens = str(assumption.Lens) ?? \"\";\n const ladder = rungsForLens(lens);\n\n // Build the attribution inputs for THIS assumption only — fan each linked\n // reading's beliefs out, keep only the one that scores this assumption, and\n // feed those into the same scoreAndDedupe + per-rung contribution math the\n // confidence formula uses.\n const inputs: AttributionReadingInput[] = [];\n for (const r of readings) {\n const belief = readingBeliefFor(r, id);\n if (!belief) continue;\n const result = str(belief.Result) ?? \"Inconclusive\";\n if (result === \"Inconclusive\") continue;\n const rung = str(r.Rung) ?? \"Talk\";\n inputs.push({\n id: str(r.id) ?? \"\",\n source: str(r.Source) ?? null,\n rung: rung as AttributionReadingInput[\"rung\"],\n result: result as AttributionReadingInput[\"result\"],\n representativeness: Number(r.Representativeness) || 1.0,\n credibility: Number(r.Credibility) || 1.0,\n date: str(r.Date),\n magnitudeBand: r.magnitudeBand as AttributionReadingInput[\"magnitudeBand\"],\n experimentId: str(r.experimentId),\n });\n }\n\n // Dedupe to the winners (same math as confidence()) and compute the\n // per-rung contribution shares: cᵢ = (wᵢ·sᵢ) / den.\n const winners = scoreAndDedupe(inputs);\n const rungsPresent = new Set(winners.map((x) => x.input.rung));\n let den = 0;\n for (const rung of rungsPresent) den += w0ForRung(rung as any);\n for (const x of winners) den += x.weight;\n\n const perRung = new Map<string, { contribution: number; count: number }>();\n for (const x of winners) {\n const rung = x.input.rung as string;\n const cur = perRung.get(rung) ?? { contribution: 0, count: 0 };\n cur.contribution += (x.weight * x.strength) / den;\n cur.count += 1;\n perRung.set(rung, cur);\n }\n\n const rungs: RungContribution[] = ladder.map((rung) => {\n const e = perRung.get(rung);\n return {\n rung,\n contribution: e ? Math.round((e.contribution + Number.EPSILON) * 100) / 100 : 0,\n cap: RUNG_CAPS[rung] ?? 50,\n count: e?.count ?? 0,\n };\n });\n\n const total = rungs.reduce((s, r) => s + r.contribution, 0);\n return {\n rungs,\n totalContribution: Math.round((total + Number.EPSILON) * 100) / 100,\n };\n}\n\n/** Per-reading contribution breakdown for an assumption — used by the evidence\n * list to show how much each piece of evidence moved Confidence. Mirrors the\n * math in buildEvidenceComposition but returns one row per reading, including\n * readings that were deduped out (used=false). */\nexport function readingContributions(\n assumption: AnyRecord,\n readings: AnyRecord[],\n): ReadingContribution[] {\n const id = str(assumption.id) ?? \"\";\n const inputs: AttributionReadingInput[] = [];\n for (const r of readings) {\n const belief = readingBeliefFor(r, id);\n if (!belief) continue;\n const result = str(belief.Result) ?? \"Inconclusive\";\n if (result === \"Inconclusive\") continue;\n const rung = str(r.Rung) ?? \"Talk\";\n inputs.push({\n id: str(r.id) ?? \"\",\n source: str(r.Source) ?? null,\n rung: rung as AttributionReadingInput[\"rung\"],\n result: result as AttributionReadingInput[\"result\"],\n representativeness: Number(r.Representativeness) || 1.0,\n credibility: Number(r.Credibility) || 1.0,\n date: str(r.Date),\n magnitudeBand: r.magnitudeBand as AttributionReadingInput[\"magnitudeBand\"],\n experimentId: str(r.experimentId),\n });\n }\n\n const winners = scoreAndDedupe(inputs);\n const winnerIds = new Set(winners.map((w) => w.input.id));\n const rungsPresent = new Set(winners.map((x) => x.input.rung));\n let den = 0;\n for (const rung of rungsPresent) den += w0ForRung(rung as any);\n for (const x of winners) den += x.weight;\n\n return inputs.map((input) => {\n const w = winners.find((x) => x.input.id === input.id);\n const used = winnerIds.has(input.id);\n const strength = w\n ? w.strength\n : (input.result === \"Validated\" ? 1 : input.result === \"Invalidated\" ? -1 : 0) * (RUNG_CAPS[input.rung] ?? 0);\n const weight = w ? w.weight : 0;\n return {\n id: input.id,\n contribution: w && den > 0 ? Math.round(((w.weight * w.strength) / den) * 100) / 100 : 0,\n weight,\n strength,\n used,\n };\n });\n}","/**\n * Shared derived-view predicates — the small, pure \"is this record in this\n * state?\" helpers the ontology's derived views (`skills/_shared/ontology.yaml`\n * → `derived_views`) describe. Kept in one module so the list surface, the\n * record page, and the understanding layer read a state (kill lane, Testing, a\n * belief an experiment tests) the same way — a single definition to change, not\n * three. DOM-free and unit-tested through its callers' seams.\n */\nimport type { AnyRecord, BarLine, BeliefScore } from \"@validation-os/core\";\n\n/** The kill-zone Confidence threshold (ontology `kill_lane`): a Live belief at\n * or below this awaits a human kill verdict. */\nexport const KILL_ZONE = -50;\n\n// ── Reading beliefs (OPS-1305) ───────────────────────────────────────────────\n// A reading is one artifact ROW carrying a `beliefs[]` array — each entry scores\n// one assumption (its own Rung / Result / strength / justification). The scalar\n// r.assumptionId / r.Rung / r.Result are gone from the row; these helpers read a\n// belief off the array so every consumer resolves \"this reading's take on this\n// belief\" one way.\n\n/** The per-belief scores a reading row carries (one per assumption it grades). */\nexport function readingBeliefs(r: AnyRecord): BeliefScore[] {\n return Array.isArray(r.beliefs) ? (r.beliefs as BeliefScore[]) : [];\n}\n\n/** This reading's score for one belief, or undefined if it doesn't grade it. */\nexport function readingBeliefFor(\n r: AnyRecord,\n assumptionId: string,\n): BeliefScore | undefined {\n return readingBeliefs(r).find((b) => b.assumptionId === assumptionId);\n}\n\n/** Does this reading carry a score for this belief? */\nexport function readingGrades(r: AnyRecord, assumptionId: string): boolean {\n return readingBeliefFor(r, assumptionId) !== undefined;\n}\n\n// ── Archived experiments (OPS-1305) ──────────────────────────────────────────\n// Archived plans are a final product decision: they NEVER render — not in a\n// register table, not as a relation on any record, not as a mover behind a\n// belief. There is no \"show archived\" control anywhere. A future Running plan\n// appears; today, with every plan Archived, nothing experiment-shaped shows.\n\n/** An experiment retired from the frontend — never surfaced. */\nexport function isArchivedExperiment(e: AnyRecord): boolean {\n return str(e.Status) === \"Archived\";\n}\n\n/** The experiments the frontend may surface — everything but Archived. */\nexport function liveExperiments(experiments: AnyRecord[]): AnyRecord[] {\n return experiments.filter((e) => !isArchivedExperiment(e));\n}\n\n/**\n * A reading's evidence-ladder Rung — transitional across the 0.10 row-level\n * move. Rung describes the artifact/source (the same across all the beliefs one\n * reading grades), so it is becoming a row-level `Rung` on the reading. This\n * prefers that row value (the final shape) and falls back to the first belief\n * that still carries one, so the badge/column render correct Rung whether the\n * data is pre- or post-migration. The belief read is a defensive cast, never a\n * hard dependency on `BeliefScore.Rung`, so it survives that field's removal\n * from core.\n */\nexport function readingRung(r: AnyRecord): string | null {\n const row = str(r.Rung);\n if (row) return row;\n for (const b of readingBeliefs(r)) {\n const v = (b as { Rung?: unknown }).Rung;\n if (typeof v === \"string\" && v !== \"\") return v;\n }\n return null;\n}\n\n/**\n * A reading's magnitude band — the intensity paired with its Rung (0.10,\n * row-level). Same transitional shape as {@link readingRung}: prefers the\n * row-level `magnitudeBand`, falls back to the first belief that still carries\n * one, and reads the belief field through a defensive cast so it survives\n * `BeliefScore.magnitudeBand`'s removal from core.\n */\nexport function readingMagnitudeBand(r: AnyRecord): string | null {\n const row = str(r.magnitudeBand);\n if (row) return row;\n for (const b of readingBeliefs(r)) {\n const v = (b as { magnitudeBand?: unknown }).magnitudeBand;\n if (typeof v === \"string\" && v !== \"\") return v;\n }\n return null;\n}\n\n/** A non-empty string, else null — the guard every field read shares. */\nexport function str(v: unknown): string | null {\n return typeof v === \"string\" && v !== \"\" ? v : null;\n}\n/** A finite number off the record's `derived` tuple, else null. */\nexport function derivedNum(r: AnyRecord, key: string): number | null {\n const v = (r.derived as Record<string, unknown> | undefined)?.[key];\n return typeof v === \"number\" ? v : null;\n}\n/** The string members of an array field (id/relation lists, Theme, Owner). */\nexport function strList(v: unknown): string[] {\n return Array.isArray(v) ? v.filter((x): x is string => typeof x === \"string\") : [];\n}\n\n/** Does this experiment pre-register a bar line against the belief? Reads the\n * composed bar lines, falling back to the projected id list. */\nexport function testsAssumption(exp: AnyRecord, assumptionId: string): boolean {\n const bars = exp.barLines as BarLine[] | undefined;\n if (bars?.some((b) => b.assumptionId === assumptionId)) return true;\n return strList(exp.barLineAssumptionIds).includes(assumptionId);\n}\n\n/** Does this experiment hold a still-open bar line on the belief (no verdict)? */\nexport function hasOpenBarOn(exp: AnyRecord, assumptionId: string): boolean {\n const bars = exp.barLines as BarLine[] | undefined;\n return (\n bars?.some((b) => b.assumptionId === assumptionId && b.barVerdict == null) ??\n false\n );\n}\n\n/** Kill lane (ontology `kill_lane`): Live AND Confidence in the kill zone. */\nexport function inKillLane(a: AnyRecord): boolean {\n return str(a.Status) === \"Live\" && (derivedNum(a, \"confidence\") ?? 0) <= KILL_ZONE;\n}\n\n/** Testing (ontology `testing`): a Live belief with a Running plan holding an\n * open bar line on it. */\nexport function isTesting(a: AnyRecord, experiments: AnyRecord[]): boolean {\n if (str(a.Status) !== \"Live\") return false;\n return experiments.some(\n (e) => str(e.Status) === \"Running\" && hasOpenBarOn(e, a.id),\n );\n}\n","/**\n * Confidence explainer (DEV-5879) — a user-facing breakdown of how an\n * assumption's Confidence is calculated, showing the formula, the per-rung\n * W0 priors, the lens-aware rung ladder with anchors, and what each piece of\n * evidence contributes. The numbers come from the same `scoreAndDedupe` +\n * per-rung W0 math the hero number uses (via `buildEvidenceComposition`), so\n * the explainer literally adds up to Confidence.\n */\nimport type { AnyRecord } from \"@validation-os/core\";\nimport { RUNG_ANCHOR, W0_BY_RUNG } from \"@validation-os/core/derivation\";\nimport { buildEvidenceComposition, type RungContribution } from \"./evidence-composition.js\";\nimport { readingBeliefFor, str } from \"./derived-views.js\";\n\nexport interface RungExplainer {\n /** The rung name. */\n rung: string;\n /** The W0 prior weight for this rung (how many sources approach the cap). */\n w0: number;\n /** The anchor bands: Low / Typical / High. */\n anchors: { Low: number; Typical: number; High: number };\n /** The contribution this rung's evidence makes to Confidence. */\n contribution: number;\n /** How many distinct sources at this rung scored this assumption. */\n count: number;\n /** Whether this rung is in the assumption's lens ladder. */\n inLens: boolean;\n /** Plain-language label for the rung. */\n label: string;\n /** Plain-language description of what evidence at this rung means. */\n description: string;\n}\n\nexport interface ConfidenceExplainerView {\n /** The assumption's Confidence (the hero number). */\n confidence: number;\n /** The formula as a plain-language string. */\n formula: string;\n /** The per-rung breakdown (all 6 rungs, lens-aware order). */\n rungs: RungExplainer[];\n /** The total contribution (Σ = Confidence). */\n totalContribution: number;\n /** The denominator (Σ W0[rungs with evidence] + Σ weights). */\n denominator: number;\n /** Plain-language summary of what's moving the number. */\n summary: string;\n}\n\nconst RUNG_INFO: Record<string, { label: string; description: string }> = {\n Talk: {\n label: \"Talk\",\n description: \"Opinions, pitch reactions, anecdotes. Quick to get but slow to move the needle — needs ~10 distinct sources to approach the cap.\",\n },\n \"Desk research\": {\n label: \"Desk research\",\n description: \"Published sources, competitor analysis, market reports. Authoritative — 2 strong sources nearly saturate this rung.\",\n },\n \"Signed up\": {\n label: \"Signed up (Consumer)\",\n description: \"Consumers signing up for the product. A do-rung — 20 signups bring this to ~75% of its cap.\",\n },\n \"Observed usage\": {\n label: \"Observed usage (Consumer)\",\n description: \"Prototype usage, analytics, telemetry. A do-rung — 20 observed users bring this to ~75% of its cap.\",\n },\n \"Signed intent\": {\n label: \"Signed intent (Commercial)\",\n description: \"LOIs, signed letters of intent from businesses. A do-rung — 20 signed intents bring this to ~75% of its cap.\",\n },\n \"Paying users\": {\n label: \"Paying users (Commercial)\",\n description: \"Closed commitments — revenue. The strongest do-rung — 20 paying users bring this to ~75% of its cap.\",\n },\n};\n\nexport function buildConfidenceExplainer(\n assumption: AnyRecord,\n readings: AnyRecord[],\n): ConfidenceExplainerView {\n const comp = buildEvidenceComposition(assumption, readings);\n const lens = str(assumption.Lens) ?? \"\";\n const lensRungs = new Set(comp.rungs.map((r) => r.rung));\n\n // All 6 rungs in the canonical order, lens-aware.\n const allRungs = [\n \"Talk\",\n \"Desk research\",\n \"Signed up\",\n \"Observed usage\",\n \"Signed intent\",\n \"Paying users\",\n ];\n\n const rungs: RungExplainer[] = allRungs.map((rung) => {\n const e = comp.rungs.find((r) => r.rung === rung);\n const info = RUNG_INFO[rung] ?? { label: rung, description: \"\" };\n return {\n rung,\n w0: W0_BY_RUNG[rung as keyof typeof W0_BY_RUNG] ?? 100,\n anchors: RUNG_ANCHOR[rung as keyof typeof RUNG_ANCHOR] ?? { Low: 0, Typical: 0, High: 0 },\n contribution: e?.contribution ?? 0,\n count: e?.count ?? 0,\n inLens: lensRungs.has(rung),\n label: info.label,\n description: info.description,\n };\n });\n\n const confidence = ((assumption.derived as any)?.confidence) ?? 0;\n const totalContribution = comp.totalContribution;\n\n // The denominator: Σ W0[rungs with evidence] + Σ weights. We approximate\n // from the composition (the contribution = (w×s)/den, so den = (w×s)/c).\n // For the explainer, we show the rungs-with-evidence W0 sum + the total\n // weight as the denominator components.\n const rungsWithEvidence = rungs.filter((r) => r.count > 0);\n const w0Sum = rungsWithEvidence.reduce((s, r) => s + r.w0, 0);\n\n const summary =\n rungsWithEvidence.length === 0\n ? \"No concluded evidence yet. Confidence is 0 — the bet is open. Any Validated or Invalidated evidence at any rung will start moving this number.\"\n : rungsWithEvidence.length === 1\n ? `All evidence is at the ${rungsWithEvidence[0]!.rung} rung (${rungsWithEvidence[0]!.count} source${rungsWithEvidence[0]!.count === 1 ? \"\" : \"s\"}). ${rungsWithEvidence[0]!.description}`\n : `Evidence spans ${rungsWithEvidence.length} rungs. The strongest push comes from ${rungs.reduce((a, b) => (Math.abs(b.contribution) > Math.abs(a.contribution) ? b : a)).rung}.`;\n\n return {\n confidence,\n formula: \"Confidence = Σ(weight × strength) / (Σ W0[rungs with evidence] + Σ weights)\",\n rungs,\n totalContribution,\n denominator: w0Sum,\n summary,\n };\n}","/**\n * A tiny, dependency-free Markdown renderer (OPS-1305) — enough to render a\n * reading's quote (`body`) and an experiment's narrative (`body`) as formatted\n * prose without pulling a runtime dependency into a package that ships with\n * near-zero deps (only `@validation-os/core`). react-markdown + remark would add\n * a sizeable tree for a feature this small, so we hand-roll the common subset:\n * headings, bold / italic / inline code, links, ordered & unordered lists,\n * blockquotes, fenced code blocks and paragraphs.\n *\n * It is safe by construction: the output is React elements, never\n * `dangerouslySetInnerHTML`, and link hrefs are restricted to http(s)/mailto and\n * in-app (#, /) targets — a `javascript:` or other scheme renders as plain text.\n * Anything it doesn't recognise falls through as text, so no input is ever lost.\n */\nimport { useState, type ReactNode } from \"react\";\n\n/** A Markdown thematic break: `---`, `***` or `___` (3+), optionally spaced. */\nconst HR_RE = /^ {0,3}([-*_])(?: *\\1){2,} *$/;\n\n/** Render Markdown `text` into the package's prose styling. Empty → nothing. */\nexport function Markdown({ text }: { text: string }) {\n const trimmed = (text ?? \"\").trim();\n if (!trimmed) return null;\n return <div className=\"vos-md\">{renderBlocks(trimmed)}</div>;\n}\n\n/**\n * A reading/experiment body presented for scanning (OPS-1305 design pass). A\n * merged reading concatenates several per-finding write-ups joined by `---`\n * rules; rendered as one blob it reads as a wall. This splits on those rules\n * into distinct \"finding\" cards and, past the first, tucks the rest behind a\n * \"show full evidence\" toggle so the detail leads with a scannable summary, not\n * everything at once. A single-segment body (the common experiment narrative)\n * renders as plain prose with no chrome — no behaviour change there.\n */\nexport function EvidenceBody({\n text,\n partLabel = \"Part\",\n}: {\n text: string;\n /** Noun for each split segment, e.g. \"Finding\" on a reading. */\n partLabel?: string;\n}) {\n const [expanded, setExpanded] = useState(false);\n const trimmed = (text ?? \"\").trim();\n const parts = trimmed ? splitOnRules(trimmed) : [];\n if (parts.length === 0) return null;\n if (parts.length === 1) return <Markdown text={parts[0]!} />;\n\n const hidden = parts.length - 1;\n const visible = expanded ? parts : parts.slice(0, 1);\n return (\n <div className=\"vos-evidence\">\n <ol className=\"vos-evidence-parts\">\n {visible.map((p, n) => (\n <li key={n} className=\"vos-evidence-part\">\n <span className=\"vos-evidence-n\">\n {partLabel} {n + 1}\n <span className=\"vos-evidence-of\"> of {parts.length}</span>\n </span>\n <Markdown text={p} />\n </li>\n ))}\n </ol>\n <button\n type=\"button\"\n className=\"vos-btn vos-btn-ghost vos-btn-sm vos-evidence-more\"\n onClick={() => setExpanded((e) => !e)}\n aria-expanded={expanded}\n >\n {expanded\n ? \"Show less\"\n : `Show full evidence — ${hidden} more ${partLabel.toLowerCase()}${hidden === 1 ? \"\" : \"s\"}`}\n </button>\n </div>\n );\n}\n\n/** Split a body on thematic-break lines into trimmed, non-empty segments. */\nfunction splitOnRules(text: string): string[] {\n const lines = text.replace(/\\r\\n?/g, \"\\n\").split(\"\\n\");\n const parts: string[][] = [[]];\n for (const line of lines) {\n if (HR_RE.test(line)) parts.push([]);\n else parts[parts.length - 1]!.push(line);\n }\n return parts.map((p) => p.join(\"\\n\").trim()).filter((p) => p !== \"\");\n}\n\n// ── Blocks ────────────────────────────────────────────────────────────────────\n\nfunction renderBlocks(text: string): ReactNode[] {\n const lines = text.replace(/\\r\\n?/g, \"\\n\").split(\"\\n\");\n const out: ReactNode[] = [];\n let i = 0;\n let key = 0;\n\n while (i < lines.length) {\n const line = lines[i]!;\n\n // Blank line — skip.\n if (line.trim() === \"\") {\n i += 1;\n continue;\n }\n\n // Fenced code block: ``` … ```\n const fence = line.match(/^```/);\n if (fence) {\n const body: string[] = [];\n i += 1;\n while (i < lines.length && !/^```/.test(lines[i]!)) {\n body.push(lines[i]!);\n i += 1;\n }\n i += 1; // consume the closing fence (if present)\n out.push(\n <pre key={key++} className=\"vos-md-pre\">\n <code>{body.join(\"\\n\")}</code>\n </pre>,\n );\n continue;\n }\n\n // Thematic break: --- / *** / ___ (a stray one left in a single segment).\n if (HR_RE.test(line)) {\n out.push(<hr key={key++} className=\"vos-md-hr\" />);\n i += 1;\n continue;\n }\n\n // Heading: #… up to ######\n const heading = line.match(/^(#{1,6})\\s+(.*)$/);\n if (heading) {\n const level = heading[1]!.length;\n const Tag = `h${Math.min(level + 2, 6)}` as \"h3\" | \"h4\" | \"h5\" | \"h6\";\n out.push(<Tag key={key++}>{renderInline(heading[2]!)}</Tag>);\n i += 1;\n continue;\n }\n\n // Blockquote: consecutive `>` lines.\n if (/^>\\s?/.test(line)) {\n const quote: string[] = [];\n while (i < lines.length && /^>\\s?/.test(lines[i]!)) {\n quote.push(lines[i]!.replace(/^>\\s?/, \"\"));\n i += 1;\n }\n out.push(\n <blockquote key={key++} className=\"vos-md-quote\">\n {renderBlocks(quote.join(\"\\n\"))}\n </blockquote>,\n );\n continue;\n }\n\n // Unordered list: consecutive `- ` / `* ` / `+ ` lines.\n if (/^[-*+]\\s+/.test(line)) {\n const items: string[] = [];\n while (i < lines.length && /^[-*+]\\s+/.test(lines[i]!)) {\n items.push(lines[i]!.replace(/^[-*+]\\s+/, \"\"));\n i += 1;\n }\n out.push(\n <ul key={key++} className=\"vos-md-ul\">\n {items.map((it, n) => (\n <li key={n}>{renderInline(it)}</li>\n ))}\n </ul>,\n );\n continue;\n }\n\n // Ordered list: consecutive `1. ` lines.\n if (/^\\d+\\.\\s+/.test(line)) {\n const items: string[] = [];\n while (i < lines.length && /^\\d+\\.\\s+/.test(lines[i]!)) {\n items.push(lines[i]!.replace(/^\\d+\\.\\s+/, \"\"));\n i += 1;\n }\n out.push(\n <ol key={key++} className=\"vos-md-ol\">\n {items.map((it, n) => (\n <li key={n}>{renderInline(it)}</li>\n ))}\n </ol>,\n );\n continue;\n }\n\n // Paragraph: gather consecutive non-blank, non-structural lines.\n const para: string[] = [];\n while (\n i < lines.length &&\n lines[i]!.trim() !== \"\" &&\n !HR_RE.test(lines[i]!) &&\n !/^```|^#{1,6}\\s|^>\\s?|^[-*+]\\s+|^\\d+\\.\\s+/.test(lines[i]!)\n ) {\n para.push(lines[i]!);\n i += 1;\n }\n out.push(<p key={key++}>{renderInline(para.join(\" \"))}</p>);\n }\n\n return out;\n}\n\n// ── Inline ──────────────────────────────────────────────────────────────────\n\n/** Only these href shapes are allowed to become links; everything else stays\n * plain text so a `javascript:`/`data:` scheme can never be clicked. */\nfunction safeHref(href: string): string | null {\n if (/^(https?:\\/\\/|mailto:)/i.test(href)) return href;\n if (/^[#/]/.test(href)) return href; // in-app / anchor targets\n return null;\n}\n\ninterface InlineRule {\n re: RegExp;\n render: (m: RegExpExecArray, key: number) => ReactNode;\n /** Whether the captured inner text is itself parsed for inline markup. */\n recurse: boolean;\n inner?: (m: RegExpExecArray) => string;\n}\n\nconst INLINE_RULES: InlineRule[] = [\n // Inline code first — its contents are literal.\n {\n re: /`([^`]+)`/,\n render: (m, key) => (\n <code key={key} className=\"vos-md-code\">\n {m[1]}\n </code>\n ),\n recurse: false,\n },\n // Links: [text](href)\n {\n re: /\\[([^\\]]+)\\]\\(([^)\\s]+)\\)/,\n render: (m, key) => {\n const href = safeHref(m[2]!);\n if (!href) return <span key={key}>{m[1]}</span>;\n return (\n <a key={key} href={href} target=\"_blank\" rel=\"noopener noreferrer\">\n {m[1]}\n </a>\n );\n },\n recurse: false,\n },\n // Bold: **text** or __text__\n {\n re: /\\*\\*([^*]+)\\*\\*|__([^_]+)__/,\n render: (m, key) => <strong key={key}>{renderInline(m[1] ?? m[2] ?? \"\")}</strong>,\n recurse: true,\n inner: (m) => m[1] ?? m[2] ?? \"\",\n },\n // Italic: *text* or _text_\n {\n re: /\\*([^*]+)\\*|_([^_]+)_/,\n render: (m, key) => <em key={key}>{renderInline(m[1] ?? m[2] ?? \"\")}</em>,\n recurse: true,\n inner: (m) => m[1] ?? m[2] ?? \"\",\n },\n];\n\nfunction renderInline(text: string): ReactNode[] {\n const nodes: ReactNode[] = [];\n let rest = text;\n let key = 0;\n\n while (rest.length > 0) {\n // Find the earliest-starting match across every rule.\n let best: { rule: InlineRule; m: RegExpExecArray } | null = null;\n for (const rule of INLINE_RULES) {\n const m = new RegExp(rule.re).exec(rest);\n if (m && (best === null || m.index < best.m.index)) {\n best = { rule, m };\n }\n }\n\n if (!best) {\n nodes.push(rest);\n break;\n }\n\n const { rule, m } = best;\n if (m.index > 0) nodes.push(rest.slice(0, m.index));\n nodes.push(rule.render(m, key++));\n rest = rest.slice(m.index + m[0].length);\n }\n\n return nodes;\n}\n","/**\n * Renders prose with glossary terms auto-linked (OPS-1285). A thin wrapper over\n * the pure `linkify` view-model: it turns the node list into text runs and\n * dotted inline links, each with a hover/focus definition-preview popover\n * (definition + status pill + \"don't confuse with\" neighbour chips, the chips\n * themselves links). Nothing is stored — every render re-derives from the live\n * glossary. Styled with the package's own token sheet, no host Tailwind.\n */\nimport { Fragment } from \"react\";\nimport { statusTone } from \"./primitives.js\";\nimport { linkify, type GlossaryTerm, type TermPreview } from \"./glossary.js\";\n\nexport interface GlossaryTextProps {\n /** The prose to linkify — body text or a short-text field (story 27). */\n text: string;\n /** The live glossary, already normalised (see `toGlossaryTerms`). */\n terms: GlossaryTerm[];\n /** The record this prose belongs to — its own term never self-links. */\n selfId?: string;\n /** Open a term's record (from a link or a neighbour chip; story 30). */\n onOpenTerm?: (id: string) => void;\n}\n\nconst PILL_CLASS = {\n good: \"vos-pill vos-pill-good\",\n warn: \"vos-pill vos-pill-warn\",\n crit: \"vos-pill vos-pill-crit\",\n accent: \"vos-pill vos-pill-accent\",\n neutral: \"vos-pill vos-pill-neutral\",\n} as const;\n\nexport function GlossaryText({\n text,\n terms,\n selfId,\n onOpenTerm,\n}: GlossaryTextProps) {\n const nodes = linkify(text, terms, { selfId });\n return (\n <>\n {nodes.map((node, i) =>\n node.kind === \"text\" ? (\n <Fragment key={i}>{node.text}</Fragment>\n ) : (\n <TermLink\n key={i}\n text={node.text}\n term={node.term}\n onOpenTerm={onOpenTerm}\n />\n ),\n )}\n </>\n );\n}\n\n/** One dotted inline link with its hover/focus definition-preview popover. */\nfunction TermLink({\n text,\n term,\n onOpenTerm,\n}: {\n text: string;\n term: TermPreview;\n onOpenTerm?: (id: string) => void;\n}) {\n return (\n <span className=\"vos-gloss\">\n <button\n type=\"button\"\n className=\"vos-gloss-term\"\n onClick={onOpenTerm ? () => onOpenTerm(term.id) : undefined}\n >\n {text}\n </button>\n <span className=\"vos-gloss-pop\" role=\"tooltip\">\n <span className=\"vos-gloss-pop-head\">\n <b>{term.title}</b>\n <span className={PILL_CLASS[statusTone(term.status)]}>\n {term.status}\n </span>\n </span>\n <span className=\"vos-gloss-pop-def\">{term.definition || \"—\"}</span>\n {term.dontConfuseWith.length ? (\n <span className=\"vos-gloss-pop-neighbours\">\n <span className=\"vos-gloss-pop-label\">Don't confuse with</span>\n {term.dontConfuseWith.map((n) => (\n <button\n key={n.id}\n type=\"button\"\n className=\"vos-gloss-chip\"\n onClick={onOpenTerm ? () => onOpenTerm(n.id) : undefined}\n >\n {n.title}\n </button>\n ))}\n </span>\n ) : null}\n </span>\n </span>\n );\n}\n","/**\n * Pure presentation logic for the dashboard's visual primitives — status→tone,\n * risk→fraction/level, the sparkline path, and count/number formatting. Kept\n * free of React and the DOM so the mapping that drives every pill, bar and\n * sparkline is unit-tested at this seam (spec story 13), and the components stay\n * thin wrappers over it.\n */\n\n/** A pill/fill tone — maps onto the `--vos-good/warn/crit/accent` tokens. */\nexport type Tone = \"good\" | \"warn\" | \"crit\" | \"accent\" | \"neutral\";\n\n/** Statuses that read as settled/positive, whatever the register. */\nconst GOOD_STATUS = new Set([\n \"live\",\n \"concluded\",\n \"closed\",\n \"done\",\n \"resolved\",\n \"accepted\",\n \"adopted\",\n \"shipped\",\n]);\n/** Statuses that read as in-flight / not yet settled. */\nconst WARN_STATUS = new Set([\n \"testing\",\n \"running\",\n \"in progress\",\n \"in-progress\",\n \"draft\",\n]);\n/** Statuses that read as a problem. */\nconst CRIT_STATUS = new Set([\n \"invalidated\",\n \"rejected\",\n \"blocked\",\n \"failed\",\n \"at risk\",\n]);\n\n/**\n * A record's Status → a pill tone. Live/concluded read good, testing/running\n * read warn, invalidated/rejected read crit; everything else (Proposed, and any\n * status we don't recognise) stays neutral rather than guessing a colour. Case-\n * and whitespace-insensitive.\n */\nexport function statusTone(status: string | null | undefined): Tone {\n if (!status) return \"neutral\";\n const s = status.trim().toLowerCase();\n if (GOOD_STATUS.has(s)) return \"good\";\n if (WARN_STATUS.has(s)) return \"warn\";\n if (CRIT_STATUS.has(s)) return \"crit\";\n return \"neutral\";\n}\n\n/**\n * Risk band thresholds — Critical ≥ 70, High 40–69, Watch < 40 (OPS-1287). A\n * belief is critical at ≥ `RISK_CRIT`, watch/high at ≥ `RISK_WARN`. These are a\n * prioritisation setting (a config knob), not a record property; overriding them\n * is `configureRiskBands`. Kept dashboard-wide so the flat-table risk cell, the\n * group-by risk-band axis, and the hero meter all band a number the same way.\n */\nexport let RISK_CRIT = 70;\nexport let RISK_WARN = 40;\n\n/** The three fixed risk bands, strongest first (OPS-1287 story 19). */\nexport type RiskBand = \"Critical\" | \"High\" | \"Watch\";\n\n/**\n * Override the two risk-band thresholds (the config knob). Left as a setter over\n * module state rather than threaded through every call, so an instance can retune\n * the bands once at startup and every risk rendering follows.\n */\nexport function configureRiskBands(crit: number, warn: number): void {\n RISK_CRIT = crit;\n RISK_WARN = warn;\n}\n\n/** Risk (0–100) → its band label. Grouping uses this; sort stays continuous. */\nexport function riskBand(risk: number): RiskBand {\n if (risk >= RISK_CRIT) return \"Critical\";\n if (risk >= RISK_WARN) return \"High\";\n return \"Watch\";\n}\n\n/** Risk (0–100) → a tone for the bar fill and the number. */\nexport function riskLevel(risk: number): Tone {\n if (risk >= RISK_CRIT) return \"crit\";\n if (risk >= RISK_WARN) return \"warn\";\n return \"good\";\n}\n\n/** Risk (0–100) → the bar's fill fraction (0–1), clamped. */\nexport function riskFraction(risk: number): number {\n if (!Number.isFinite(risk)) return 0;\n return Math.max(0, Math.min(100, risk)) / 100;\n}\n\n/** Confidence (signed) → the tone for its number: negative reads crit. */\nexport function confidenceTone(confidence: number): Tone {\n return confidence < 0 ? \"crit\" : \"good\";\n}\n\n/**\n * The tone for a derived-hero number. Confidence reads crit when negative; Risk\n * reads by threshold; Derived Impact, Strength and anything else read neutral.\n * Pure, so the drawer's hero doesn't hand-roll this branching.\n */\nexport function derivedTone(field: string, value: number): Tone {\n if (field === \"confidence\") return confidenceTone(value);\n if (field === \"risk\") return riskLevel(value);\n return \"neutral\";\n}\n\n/**\n * Tone → the text-colour class for a derived-hero number. Only warn/crit are\n * tinted; a good or neutral number stays the default text colour (the hero\n * doesn't paint every number green the way the in-row cells do).\n */\nexport function heroToneClass(tone: Tone): string {\n if (tone === \"crit\") return \"vos-text-crit\";\n if (tone === \"warn\") return \"vos-text-warn\";\n return \"\";\n}\n\n/** A signed number rendered with an explicit sign: `+6`, `-3`, `0`. */\nexport function formatSigned(n: number): string {\n const r = Math.round(n);\n return r > 0 ? `+${r}` : String(r);\n}\n\n/** A count for the nav/tiles, thousands-separated. */\nexport function formatCount(n: number): string {\n return n.toLocaleString();\n}\n\n/**\n * An SVG polyline `d` for a sparkline over `values`, fit to a `width`×`height`\n * box with a 2px inset. The vertical domain defaults to the data's own range\n * (with 0 always included, so a signed series keeps its baseline meaningful);\n * pass `min`/`max` to pin it — e.g. −100…100 for Confidence. Returns \"\" for\n * fewer than two points (nothing to draw).\n */\nexport function sparklinePath(\n values: number[],\n width: number,\n height: number,\n min?: number,\n max?: number,\n): string {\n if (values.length < 2) return \"\";\n const lo = min ?? Math.min(...values, 0);\n const hi = max ?? Math.max(...values, 0);\n const span = hi - lo || 1;\n const inset = 2;\n return values\n .map((v, i) => {\n const x = (i / (values.length - 1)) * (width - inset * 2) + inset;\n const y = height - inset - ((v - lo) / span) * (height - inset * 2);\n return `${i ? \"L\" : \"M\"}${x.toFixed(1)} ${y.toFixed(1)}`;\n })\n .join(\" \");\n}\n\n/** The y for a value in the same box `sparklinePath` uses — for endpoint dots\n * and the zero baseline. */\nexport function sparklineY(\n value: number,\n height: number,\n lo: number,\n hi: number,\n): number {\n const span = hi - lo || 1;\n const inset = 2;\n return height - inset - ((value - lo) / span) * (height - inset * 2);\n}\n","/**\n * Glossary auto-linking (OPS-1285) — the pure render-time pass that turns\n * glossary Titles appearing in prose into links, computed fresh on every render\n * so renames / retirements / status changes are always reflected with nothing\n * stored. Kept DOM-free at this seam and unit-tested exactly like\n * `link-choices.ts`; the `GlossaryText` component renders what it returns.\n *\n * The four forks the OPS-1285 prototype resolved are the rules here:\n * - match on **Title only** (no alias list), case-insensitive, word-boundary,\n * **longest title wins** (Derived Impact over Impact), **every** occurrence;\n * - **Active + Provisional** terms link, **Superseded never**, and never a\n * term inside its own record;\n * - **no false-positive machinery** — a generic word that is a term links\n * harmlessly; the simplicity is the decision.\n */\nimport type { AnyRecord } from \"@validation-os/core\";\n\n/** A glossary term reduced to what linking needs — the normalised input. */\nexport interface GlossaryTerm {\n id: string;\n title: string;\n /** \"Active\" | \"Provisional\" | \"Superseded\". */\n status: string;\n definition: string;\n howItDiffers: string;\n}\n\n/** A \"don't confuse with\" neighbour — a chip that is itself a link. */\nexport interface NeighbourChip {\n id: string;\n title: string;\n}\n\n/** The definition-preview payload a link node carries (the hover popover). */\nexport interface TermPreview {\n id: string;\n title: string;\n status: string;\n definition: string;\n /** Neighbours named in this term's \"How it differs\" (story 29/30). */\n dontConfuseWith: NeighbourChip[];\n}\n\n/** One piece of linkified prose: literal text, or a link to a term. */\nexport type LinkifyNode =\n | { kind: \"text\"; text: string }\n | { kind: \"link\"; text: string; term: TermPreview };\n\nexport interface LinkifyOptions {\n /** The id of the record the prose belongs to — its own term never links. */\n selfId?: string;\n}\n\n/** Only Active and Provisional terms link (Superseded never; story 28). */\nfunction linkable(term: GlossaryTerm): boolean {\n return term.status === \"Active\" || term.status === \"Provisional\";\n}\n\n/** Escape a title for use inside a `RegExp`. */\nfunction escapeRegExp(s: string): string {\n return s.replace(/[.*+?^${}()|[\\]\\\\]/g, \"\\\\$&\");\n}\n\n/**\n * A matcher for a set of titles: longest-first alternation on word boundaries,\n * case-insensitive and global, so `exec` walks every occurrence and the longest\n * title wins at each position. Returns null when there is nothing to match.\n */\nfunction buildMatcher(titles: string[]): RegExp | null {\n const usable = titles.filter((t) => t.trim() !== \"\");\n if (usable.length === 0) return null;\n // Longest first: JS alternation takes the first matching branch at a\n // position, so ordering by length makes \"Derived Impact\" win over \"Impact\".\n const ordered = [...usable].sort((a, b) => b.length - a.length);\n const alt = ordered.map(escapeRegExp).join(\"|\");\n return new RegExp(`\\\\b(?:${alt})\\\\b`, \"gi\");\n}\n\n/**\n * The terms named in a term's \"How it differs\" prose — the neighbour chips.\n * Excludes the term itself and any non-linkable (Superseded) neighbour, and is\n * de-duplicated in first-appearance order.\n */\nexport function dontConfuseWith(\n term: GlossaryTerm,\n terms: GlossaryTerm[],\n): NeighbourChip[] {\n const others = terms.filter((t) => t.id !== term.id && linkable(t));\n const byLowerTitle = new Map(others.map((t) => [t.title.toLowerCase(), t]));\n const matcher = buildMatcher(others.map((t) => t.title));\n if (!matcher || !term.howItDiffers) return [];\n const seen = new Set<string>();\n const chips: NeighbourChip[] = [];\n for (const m of term.howItDiffers.matchAll(matcher)) {\n const hit = byLowerTitle.get(m[0].toLowerCase());\n if (hit && !seen.has(hit.id)) {\n seen.add(hit.id);\n chips.push({ id: hit.id, title: hit.title });\n }\n }\n return chips;\n}\n\n/**\n * Linkify `text` against the glossary. Returns an ordered list of text and link\n * nodes; a link node carries the term's definition-preview payload. Pure and\n * render-time — nothing is stored.\n */\nexport function linkify(\n text: string,\n terms: GlossaryTerm[],\n options: LinkifyOptions = {},\n): LinkifyNode[] {\n if (!text) return [];\n\n const candidates = terms.filter(\n (t) => linkable(t) && t.id !== options.selfId && t.title.trim() !== \"\",\n );\n const matcher = buildMatcher(candidates.map((t) => t.title));\n if (!matcher) return [{ kind: \"text\", text }];\n\n const byLowerTitle = new Map(candidates.map((t) => [t.title.toLowerCase(), t]));\n // Previews are the same for every occurrence of a term — compute once.\n const previewCache = new Map<string, TermPreview>();\n const previewFor = (term: GlossaryTerm): TermPreview => {\n let p = previewCache.get(term.id);\n if (!p) {\n p = {\n id: term.id,\n title: term.title,\n status: term.status,\n definition: term.definition,\n dontConfuseWith: dontConfuseWith(term, terms),\n };\n previewCache.set(term.id, p);\n }\n return p;\n };\n\n const nodes: LinkifyNode[] = [];\n let last = 0;\n for (const m of text.matchAll(matcher)) {\n const term = byLowerTitle.get(m[0].toLowerCase());\n if (!term) continue; // matched a non-candidate casing — leave as text\n const start = m.index;\n if (start > last) nodes.push({ kind: \"text\", text: text.slice(last, start) });\n nodes.push({ kind: \"link\", text: m[0], term: previewFor(term) });\n last = start + m[0].length;\n }\n if (last < text.length) nodes.push({ kind: \"text\", text: text.slice(last) });\n return nodes;\n}\n\n/** Normalise glossary records into the linking input, dropping blank-title\n * rows (they can never match). Tolerates missing optional fields. */\nexport function toGlossaryTerms(records: AnyRecord[]): GlossaryTerm[] {\n return records\n .map((r) => ({\n id: r.id,\n title: typeof r.Title === \"string\" ? r.Title : \"\",\n status: typeof r.Status === \"string\" ? r.Status : \"\",\n definition: typeof r.Definition === \"string\" ? r.Definition : \"\",\n howItDiffers:\n typeof r[\"How it differs\"] === \"string\"\n ? (r[\"How it differs\"] as string)\n : \"\",\n }))\n .filter((t) => t.title.trim() !== \"\");\n}\n","/**\n * The record-page view-model (OPS-1286) — the pure join behind the canonical\n * full record page. Given a record and the related registers, it computes the\n * header lane/queue pills (all derived), the leading-score meters per register,\n * the genuine human-input free-text remainder, and the backlink panels grouped\n * by relation (each row carrying a glance-readable score chip, an empty relation\n * kept as a \"none yet\" panel rather than dropped). DOM-free and unit-tested at\n * this seam; `RecordPage` renders what it returns and the understanding layer\n * supplies the \"Why?\" attribution unchanged.\n */\nimport type {\n AnyRecord,\n BarLine,\n Collection,\n Result,\n} from \"@validation-os/core\";\nimport { experimentProgress } from \"@validation-os/core/derivation\";\nimport {\n confidenceTone,\n formatSigned,\n riskLevel,\n statusTone,\n type Tone,\n} from \"./primitives.js\";\nimport { primaryLabel } from \"./columns.js\";\nimport {\n derivedNum,\n inKillLane,\n isArchivedExperiment,\n isTesting,\n liveExperiments,\n readingBeliefs,\n readingGrades,\n readingMagnitudeBand,\n readingRung,\n str,\n strList,\n testsAssumption,\n} from \"./derived-views.js\";\n\n// ── Related set ───────────────────────────────────────────────────────────────\n\n/** The registers a record page reads to resolve its relations. All optional —\n * a panel whose register is absent simply resolves to \"none yet\". */\nexport interface RelatedSet {\n assumptions?: AnyRecord[];\n experiments?: AnyRecord[];\n readings?: AnyRecord[];\n decisions?: AnyRecord[];\n glossary?: AnyRecord[];\n}\n\nexport interface RecordPageOptions {\n /** ISO date \"now\" for the Overdue pill; omitted → nothing reads overdue. */\n asOf?: string;\n}\n\n/** Records for a list of ids, in id order, skipping ids with no record. */\nfunction byIds(records: AnyRecord[] | undefined, ids: string[]): AnyRecord[] {\n const map = new Map((records ?? []).map((r) => [r.id, r]));\n return ids.map((id) => map.get(id)).filter((r): r is AnyRecord => r != null);\n}\n\n// ── Header pills ──────────────────────────────────────────────────────────────\n\n/** A header pill: a short derived label toned by meaning. */\nexport interface Pill {\n label: string;\n tone: Tone;\n}\n\n/**\n * The derived lane/queue pills for a record header (story 2). Every register\n * leads with its Status pill; assumptions add Moot / Kill lane / Testing,\n * experiments add Concluded / Overdue, decisions mark Standing. All derived —\n * none is a stored field.\n */\nexport function headerPills(\n register: Collection,\n record: AnyRecord,\n related: RelatedSet = {},\n options: RecordPageOptions = {},\n): Pill[] {\n const pills: Pill[] = [];\n const status = str(record.Status);\n if (status) pills.push({ label: status, tone: statusTone(status) });\n\n if (register === \"assumptions\") {\n if (record.moot === true) pills.push({ label: \"Moot\", tone: \"neutral\" });\n if (inKillLane(record)) pills.push({ label: \"Kill lane\", tone: \"crit\" });\n else if (isTesting(record, related.experiments ?? []))\n pills.push({ label: \"Testing\", tone: \"warn\" });\n } else if (register === \"experiments\") {\n // A candidate/designed plan sits in the test-next pool (ontology\n // `test_next_surface`); the prioritisation layer owns its exact rank.\n if (status === \"Draft\") pills.push({ label: \"Test-next\", tone: \"accent\" });\n if (status === \"Closed\") pills.push({ label: \"Concluded\", tone: \"good\" });\n const deadline = str(record.Deadline);\n if (\n options.asOf &&\n deadline &&\n status === \"Running\" &&\n deadline < options.asOf\n )\n pills.push({ label: \"Overdue\", tone: \"crit\" });\n } else if (register === \"decisions\") {\n if (status === \"Active\") pills.push({ label: \"Standing\", tone: \"good\" });\n } else if (register === \"readings\") {\n // Rung + magnitude band are the reading's own evidence tier + intensity\n // (0.10, row-level) — one per artifact, so they lead the header as a single\n // paired badge (\"Talk · High\"), not the per-belief cards. Both fall\n // back to a belief's value on pre-migration data.\n const rung = readingRung(record);\n const band = readingMagnitudeBand(record);\n const label = [rung, band].filter(Boolean).join(\" · \");\n if (label) pills.push({ label, tone: \"accent\" });\n }\n return pills;\n}\n\n// ── Leading-score meters ──────────────────────────────────────────────────────\n\n/** A leading-score meter. `bar`/`signed` carry a number in a min…max domain;\n * `pill` carries a categorical value shown as a toned pill. */\nexport interface Meter {\n key: string;\n label: string;\n kind: \"bar\" | \"signed\" | \"pill\";\n /** Number (bar/signed) or category (pill); null when the record has no value. */\n value: number | string | null;\n tone: Tone;\n /** For bar/signed: the domain the fill maps onto. */\n min?: number;\n max?: number;\n /** True when a \"Why?\" attribution is available (Confidence only). */\n hasWhy?: boolean;\n}\n\n/**\n * The register's leading scores as meters (story 4). Reads only what the\n * migrated schema actually stores — a derived number becomes a bar/signed meter,\n * a categorical leading field becomes a pill; nothing is invented where the\n * schema carries no number. Confidence is flagged `hasWhy` — the understanding\n * layer decomposes it.\n */\nexport function leadingMeters(register: Collection, record: AnyRecord): Meter[] {\n switch (register) {\n case \"assumptions\":\n return [\n {\n key: \"confidence\",\n label: \"Confidence\",\n kind: \"signed\",\n value: derivedNum(record, \"confidence\"),\n tone: confidenceTone(derivedNum(record, \"confidence\") ?? 0),\n min: -100,\n max: 100,\n hasWhy: true,\n },\n {\n key: \"risk\",\n label: \"Risk\",\n kind: \"bar\",\n value: derivedNum(record, \"risk\"),\n tone: riskLevel(derivedNum(record, \"risk\") ?? 0),\n max: 100,\n },\n {\n key: \"derivedImpact\",\n label: \"Derived Impact\",\n kind: \"bar\",\n value: derivedNum(record, \"derivedImpact\"),\n tone: \"neutral\",\n max: 100,\n },\n ];\n case \"readings\":\n // Strength and Result are per belief now (OPS-1305) — they live in the\n // per-belief verdict list (`readingBeliefVerdicts`), not as row meters.\n // Source quality is the only row-level score left.\n return [\n {\n key: \"sourceQuality\",\n label: \"Source quality\",\n kind: \"bar\",\n // Stored 0–1; show as a 0–100 fill.\n value:\n derivedNum(record, \"sourceQuality\") === null\n ? null\n : Math.round((derivedNum(record, \"sourceQuality\") ?? 0) * 100),\n tone: \"neutral\",\n max: 100,\n },\n ];\n case \"experiments\": {\n const bars = (record.barLines as BarLine[] | undefined) ?? [];\n const progress = experimentProgress(bars);\n return [\n {\n key: \"maturity\",\n label: \"Maturity\",\n kind: \"bar\",\n value: progress.total ? Math.round((progress.settled / progress.total) * 100) : null,\n tone: progress.concluded ? \"good\" : \"warn\",\n max: 100,\n },\n {\n key: \"Feasibility\",\n label: \"Feasibility\",\n kind: \"pill\",\n value: str(record.Feasibility),\n tone: \"neutral\",\n },\n ];\n }\n case \"decisions\":\n return [\n {\n key: \"Status\",\n label: \"Status\",\n kind: \"pill\",\n value: str(record.Status),\n tone: statusTone(str(record.Status) ?? \"\"),\n },\n ];\n case \"glossary\":\n return [\n {\n key: \"Status\",\n label: \"Status\",\n kind: \"pill\",\n value: str(record.Status),\n tone: statusTone(str(record.Status) ?? \"\"),\n },\n ];\n }\n}\n\n// ── Human-input free text (story 7) ──────────────────────────────────────────\n\n/** The genuine human-input free-text remainder — clearly separated from what\n * the system computed. Auto-linked against the glossary at render time. */\nexport interface HumanText {\n key: string;\n label: string;\n text: string;\n}\n\nconst HUMAN_FIELDS: Record<Collection, { key: string; label: string }[]> = {\n assumptions: [{ key: \"Scoring justification\", label: \"Scoring justification\" }],\n // A reading's grading justification is per belief now (OPS-1305) — it renders\n // in the verdict cards (`BeliefVerdicts`), so surfacing a stale row-level copy\n // here too would double up. The row carries no other genuine human free-text.\n readings: [],\n decisions: [\n { key: \"Statement\", label: \"Statement\" },\n { key: \"Unanimity justification\", label: \"Unanimity justification\" },\n ],\n experiments: [{ key: \"Instrument\", label: \"Instrument\" }],\n glossary: [\n { key: \"Definition\", label: \"Definition\" },\n { key: \"How it differs\", label: \"How it differs\" },\n ],\n};\n\n/** The human-input fields a register carries text for (empty ones dropped). */\nexport function humanInputFields(\n register: Collection,\n record: AnyRecord,\n): HumanText[] {\n return HUMAN_FIELDS[register]\n .map((f) => ({ key: f.key, label: f.label, text: str(record[f.key]) ?? \"\" }))\n .filter((f) => f.text !== \"\");\n}\n\n// ── Per-belief verdict list (reading detail) ─────────────────────────────────\n\n/** One belief a reading grades, prepared for the reading detail's verdict list\n * (OPS-1305). Modelled on the experiment bar-line view: the assumption resolved\n * to a title + navigable id, plus this belief's own Result / derived Strength\n * and the grading justification. Rung AND magnitude band are NOT here — they are\n * row-level attributes of the artifact now (0.10), the same for every belief the\n * reading grades, so they show once at the reading level, not per card. */\nexport interface BeliefVerdict {\n assumptionId: string;\n /** The belief's title if it's in the loaded set, else its bare id. */\n title: string;\n /** True when the assumption resolved — drives whether the title links. */\n linked: boolean;\n result: Result | null;\n /** Derived per-belief strength (signed −100…100). */\n strength: number | null;\n justification: string;\n /** Verbatim quote/excerpt for this belief, if recorded. */\n excerpt: string;\n}\n\n/** The per-belief verdicts a reading carries, in stored order — the reading\n * detail's answer to \"what did this artifact say about each belief?\". Pure:\n * resolves each belief-score against the loaded assumptions for its title. */\nexport function readingBeliefVerdicts(\n reading: AnyRecord,\n assumptions: AnyRecord[] = [],\n): BeliefVerdict[] {\n const byId = new Map(assumptions.map((a) => [a.id, a]));\n return readingBeliefs(reading).map((b) => {\n const hit = byId.get(b.assumptionId);\n const strength =\n b.derived && typeof b.derived.strength === \"number\"\n ? b.derived.strength\n : null;\n return {\n assumptionId: b.assumptionId,\n title: hit ? primaryLabel(hit) : b.assumptionId,\n linked: hit != null,\n result: (b.Result as Result | undefined) ?? null,\n strength,\n justification:\n typeof b[\"Grading justification\"] === \"string\"\n ? b[\"Grading justification\"]\n : \"\",\n excerpt:\n typeof b.excerpt === \"string\" && b.excerpt !== \"\"\n ? b.excerpt\n : snippetFromBody(String(reading.body ?? \"\"), b.assumptionId),\n };\n });\n}\n\n/** Pull a short quote-like snippet from a reading body as a fallback excerpt.\n * Prefers text inside a `## Quote` block, then a sentence mentioning the\n * assumption title or id, then the first sentence. */\nfunction snippetFromBody(body: string, cue: string): string {\n if (!body) return \"\";\n const quoteMatch = body.match(/## Quote\\n+([\\s\\S]*?)(?=\\n## |\\n##$|$)/i);\n if (quoteMatch) {\n const q = quoteMatch[1]!.trim();\n return q.length > 220 ? q.slice(0, 217).trim() + \"…\" : q;\n }\n const sentences = body.split(/(?<=[.!?])\\s+/);\n const cueLower = cue.toLowerCase();\n for (const s of sentences) {\n if (s.toLowerCase().includes(cueLower)) return s.trim();\n }\n const first = sentences[0]?.trim() ?? \"\";\n return first.length > 220 ? first.slice(0, 217).trim() + \"…\" : first;\n}\n\n/** A reading's verdicts tallied by result — the one-line \"what did this say?\"\n * summary above the per-belief list (OPS-1305 design pass). `inconclusive`\n * folds every non-Validated/Invalidated verdict (Inconclusive or ungraded) so\n * the three counts always sum to `total`. */\nexport interface BeliefSummary {\n total: number;\n validated: number;\n invalidated: number;\n inconclusive: number;\n}\n\n/** Tally a reading's per-belief verdicts by result. Pure over the same input\n * the verdict list reads, so the headline and the cards never disagree. */\nexport function readingBeliefSummary(\n reading: AnyRecord,\n assumptions: AnyRecord[] = [],\n): BeliefSummary {\n const verdicts = readingBeliefVerdicts(reading, assumptions);\n let validated = 0;\n let invalidated = 0;\n for (const v of verdicts) {\n if (v.result === \"Validated\") validated += 1;\n else if (v.result === \"Invalidated\") invalidated += 1;\n }\n return {\n total: verdicts.length,\n validated,\n invalidated,\n inconclusive: verdicts.length - validated - invalidated,\n };\n}\n\n// ── Backlink panels ───────────────────────────────────────────────────────────\n\n/** A glance-readable score chip for a linked record (story 9). */\nexport interface ScoreChip {\n label: string;\n value: string;\n tone: Tone;\n}\n\nexport interface BacklinkItem {\n id: string;\n register: Collection;\n title: string;\n chip: ScoreChip;\n}\n\n/** A relation panel — the inbound/outbound edges of one relation, grouped and\n * labelled. Kept even when empty (story 10). */\nexport interface RelationPanel {\n id: string;\n label: string;\n register: Collection;\n items: BacklinkItem[];\n}\n\n/** The linked record's headline score, glance-readable (story 9). */\nexport function scoreChip(register: Collection, record: AnyRecord): ScoreChip {\n if (register === \"assumptions\") {\n const c = derivedNum(record, \"confidence\") ?? 0;\n return { label: \"Confidence\", value: formatSigned(c), tone: confidenceTone(c) };\n }\n if (register === \"readings\") {\n // Strength is per belief now (OPS-1305); the row's glance score is its\n // Source quality (0–1 → 0–100), a property of the artifact, not a belief.\n const sq = derivedNum(record, \"sourceQuality\");\n return {\n label: \"Source quality\",\n value: sq === null ? \"—\" : String(Math.round(sq * 100)),\n tone: \"neutral\",\n };\n }\n const status = str(record.Status) ?? \"—\";\n return { label: \"Status\", value: status, tone: statusTone(status) };\n}\n\ninterface PanelDef {\n id: string;\n label: string;\n register: Collection;\n resolve: (record: AnyRecord, related: RelatedSet) => AnyRecord[];\n}\n\nconst PANELS: Record<Collection, PanelDef[]> = {\n assumptions: [\n {\n id: \"readings\",\n label: \"Readings\",\n register: \"readings\",\n resolve: (r, rel) =>\n (rel.readings ?? []).filter((x) => readingGrades(x, r.id)),\n },\n {\n id: \"depends-on\",\n label: \"Depends on\",\n register: \"assumptions\",\n resolve: (r, rel) => byIds(rel.assumptions, strList(r.dependsOnIds)),\n },\n {\n id: \"enables\",\n label: \"Enables\",\n register: \"assumptions\",\n resolve: (r, rel) => byIds(rel.assumptions, strList(r.enablesIds)),\n },\n {\n id: \"contradicts\",\n label: \"Contradicts\",\n register: \"assumptions\",\n resolve: (r, rel) => byIds(rel.assumptions, strList(r.contradictsIds)),\n },\n {\n id: \"tested-by\",\n label: \"Tested by\",\n register: \"experiments\",\n // Archived plans never surface as a relation (OPS-1305) — live plans only.\n resolve: (r, rel) =>\n liveExperiments(rel.experiments ?? []).filter((e) =>\n testsAssumption(e, r.id),\n ),\n },\n {\n id: \"decisions-based\",\n label: \"Decisions based on this\",\n register: \"decisions\",\n resolve: (r, rel) =>\n (rel.decisions ?? []).filter((d) => strList(d.basedOnIds).includes(r.id)),\n },\n {\n id: \"resolved-by\",\n label: \"Resolved by\",\n register: \"decisions\",\n resolve: (r, rel) =>\n (rel.decisions ?? []).filter((d) => strList(d.resolvesIds).includes(r.id)),\n },\n ],\n readings: [\n {\n id: \"assumption\",\n label: \"Beliefs\",\n register: \"assumptions\",\n // A reading grades several beliefs now (OPS-1305) — resolve them all.\n resolve: (r, rel) => byIds(rel.assumptions, strList(r.assumptionIds)),\n },\n {\n id: \"experiment\",\n label: \"Evidence plan\",\n register: \"experiments\",\n // Only ever surface a NON-archived plan (OPS-1305): an archived origin\n // reads as no plan at all, never a leaked backlink.\n resolve: (r, rel) =>\n byIds(rel.experiments, [str(r.experimentId) ?? \"\"].filter(Boolean)).filter(\n (e) => !isArchivedExperiment(e),\n ),\n },\n ],\n experiments: [\n {\n id: \"readings\",\n label: \"Readings\",\n register: \"readings\",\n resolve: (r, rel) => (rel.readings ?? []).filter((x) => x.experimentId === r.id),\n },\n {\n id: \"assumptions-tested\",\n label: \"Beliefs tested\",\n register: \"assumptions\",\n resolve: (r, rel) => {\n const bars = (r.barLines as BarLine[] | undefined) ?? [];\n const ids = bars.length\n ? bars.map((b) => b.assumptionId)\n : strList(r.barLineAssumptionIds);\n return byIds(rel.assumptions, ids);\n },\n },\n ],\n decisions: [\n {\n id: \"based-on\",\n label: \"Based on\",\n register: \"assumptions\",\n resolve: (r, rel) => byIds(rel.assumptions, strList(r.basedOnIds)),\n },\n {\n id: \"resolves\",\n label: \"Resolves\",\n register: \"assumptions\",\n resolve: (r, rel) => byIds(rel.assumptions, strList(r.resolvesIds)),\n },\n ],\n glossary: [],\n};\n\n/** The backlink panels for a record, grouped by relation, each row carrying a\n * score chip. Empty relations are kept (items: []) so a missing connection reads\n * as \"none yet\", not an absent section (story 8/10). */\nexport function backlinkPanels(\n register: Collection,\n record: AnyRecord,\n related: RelatedSet = {},\n): RelationPanel[] {\n return PANELS[register].map((def) => ({\n id: def.id,\n label: def.label,\n register: def.register,\n items: def.resolve(record, related).map((rec) => ({\n id: rec.id,\n register: def.register,\n title: primaryLabel(rec),\n chip: scoreChip(def.register, rec),\n })),\n }));\n}\n\n// ── The assembled page model ──────────────────────────────────────────────────\n\nexport type RecordTabId = \"overview\" | \"evidence\" | \"connections\" | \"history\";\n\nexport interface RecordPageModel {\n register: Collection;\n title: string;\n pills: Pill[];\n meters: Meter[];\n humanText: HumanText[];\n panels: RelationPanel[];\n /** The tabs this record shows, in order (story 3 + 11). */\n tabs: RecordTabId[];\n /** True when the belief journey drill-in can mount here (story 13). */\n hasJourney: boolean;\n}\n\n/** The registers whose record page carries an Evidence tab (story 3/14). */\nfunction hasEvidenceTab(register: Collection): boolean {\n return register === \"assumptions\" || register === \"experiments\";\n}\n\n/** Assemble the whole record-page model. Pure: same record + related always\n * gives the same page. */\nexport function buildRecordPage(\n register: Collection,\n record: AnyRecord,\n related: RelatedSet = {},\n options: RecordPageOptions = {},\n): RecordPageModel {\n const tabs: RecordTabId[] = [\"overview\"];\n if (hasEvidenceTab(register)) tabs.push(\"evidence\");\n tabs.push(\"connections\", \"history\");\n return {\n register,\n title: primaryLabel(record),\n pills: headerPills(register, record, related, options),\n meters: leadingMeters(register, record),\n humanText: humanInputFields(register, record),\n panels: backlinkPanels(register, record, related),\n tabs,\n hasJourney: register === \"assumptions\",\n };\n}\n","/**\n * Per-register table columns and value formatting — the presentational shape\n * of the browse tables, kept as pure data/functions so it is unit-testable\n * without a DOM. The register is a surface a non-technical teammate meets, so\n * headers are plain language and derived numbers are shown, never hidden.\n */\nimport type { AnyRecord, Collection } from \"@validation-os/core\";\nimport { readingMagnitudeBand, readingRung } from \"./derived-views.js\";\n\n/**\n * How a cell renders. `text` is plain formatted text; `status` is a colored\n * pill; `risk` is a threshold-toned bar + number; `confidence` is a signed\n * number (with a sparkline when a trajectory is available). Keeping this on the\n * column — not branching by key in the table — is what makes the visual\n * treatment declarative and testable at this seam (spec story 13).\n */\nexport type CellKind = \"text\" | \"status\" | \"risk\" | \"confidence\";\n\nexport interface ColumnDef {\n /** Stable key; also the default field read from the record. */\n key: string;\n /** Plain-language column header. */\n header: string;\n /** Pull the display value from a record (defaults to `record[key]`). */\n accessor?: (record: AnyRecord) => unknown;\n /** Numeric columns right-align for a clean column of figures. */\n align?: \"left\" | \"right\";\n /** Marks a column whose value is computed, never hand-typed (spec story 4). */\n derived?: boolean;\n /** How the cell renders; defaults to `text`. */\n kind?: CellKind;\n}\n\n/** Read a nested `derived` number off a record, tolerating a missing tuple. */\nfunction derivedField(field: string): (r: AnyRecord) => unknown {\n return (r) => (r.derived as Record<string, unknown> | undefined)?.[field];\n}\n\n/**\n * The columns each register shows, left-to-right. The first column is always\n * the record's headline (Title, or Name for people); assumptions additionally\n * surface Impact, Confidence and Risk at a glance (spec user story 2).\n */\nconst COLUMNS: Record<Collection, ColumnDef[]> = {\n assumptions: [\n { key: \"Title\", header: \"Belief\" },\n {\n key: \"Status\",\n header: \"Status\",\n kind: \"status\",\n },\n { key: \"Impact\", header: \"Impact\", align: \"right\" },\n {\n key: \"confidence\",\n header: \"Confidence\",\n align: \"right\",\n derived: true,\n kind: \"confidence\",\n accessor: derivedField(\"confidence\"),\n },\n {\n key: \"risk\",\n header: \"Risk\",\n align: \"right\",\n derived: true,\n kind: \"risk\",\n accessor: derivedField(\"risk\"),\n },\n ],\n experiments: [\n { key: \"Title\", header: \"Evidence plan\" },\n { key: \"Status\", header: \"Status\", kind: \"status\" },\n { key: \"Feasibility\", header: \"Feasibility\" },\n ],\n readings: [\n { key: \"Title\", header: \"Reading\" },\n { key: \"Source\", header: \"Source\" },\n { key: \"Date\", header: \"Date\" },\n // Rung + magnitude band are row-level attributes of the artifact (0.10): the\n // evidence tier and its intensity, one per reading, not per belief. They lead\n // the row's evidential weight, so each earns a column. Both helpers fall back\n // to a belief's value on pre-migration data so the columns are never blank\n // during the rollout.\n { key: \"Rung\", header: \"Rung\", accessor: (r) => readingRung(r) },\n { key: \"magnitudeBand\", header: \"Band\", accessor: (r) => readingMagnitudeBand(r) },\n // The row's per-belief Result / Strength stay in the reading detail's\n // verdict list (OPS-1305). The table previews the quote (`body`) so a row is\n // legible at a glance; assumption chips (see `readingAssumptionChips`)\n // disambiguate same-titled readings.\n {\n key: \"body\",\n header: \"Quote\",\n accessor: (r) => bodyPreview(r.body),\n },\n ],\n decisions: [\n { key: \"Title\", header: \"Decision\" },\n { key: \"Status\", header: \"Status\", kind: \"status\" },\n ],\n glossary: [\n { key: \"Title\", header: \"Term\" },\n { key: \"Status\", header: \"Status\", kind: \"status\" },\n ],\n};\n\n/** The columns to render for a register. */\nexport function columnsFor(register: Collection): ColumnDef[] {\n return COLUMNS[register];\n}\n\n/** A one-line, length-capped preview of a reading's free-text `body` (its\n * quote), for the readings table. Collapses whitespace and ellipsises; a\n * missing/empty body reads as the empty string (formatted to an em dash). */\nexport function bodyPreview(value: unknown, max = 80): string {\n if (typeof value !== \"string\") return \"\";\n const oneLine = value.replace(/\\s+/g, \" \").trim();\n if (oneLine.length <= max) return oneLine;\n return `${oneLine.slice(0, max - 1).trimEnd()}…`;\n}\n\n/** The belief chips for a reading row — the assumptions it grades, resolved to\n * titles when a lookup is given, else their bare ids. Disambiguates readings\n * that share a Title by showing which belief(s) each one actually scored. */\nexport function readingAssumptionChips(\n record: AnyRecord,\n titleById: Map<string, string> = new Map(),\n): string[] {\n const ids = Array.isArray(record.assumptionIds)\n ? record.assumptionIds.filter((x): x is string => typeof x === \"string\")\n : [];\n return ids.map((id) => titleById.get(id) ?? id);\n}\n\n/** Read a column's raw value from a record (accessor, else `record[key]`). */\nexport function cellValue(column: ColumnDef, record: AnyRecord): unknown {\n return column.accessor ? column.accessor(record) : record[column.key];\n}\n\n/** Format any stored value for display; empty/missing reads as an em dash. */\nexport function formatValue(value: unknown): string {\n if (value === null || value === undefined || value === \"\") return \"—\";\n if (typeof value === \"boolean\") return value ? \"Yes\" : \"No\";\n if (Array.isArray(value)) {\n return value.length ? value.map(formatScalar).join(\", \") : \"—\";\n }\n return formatScalar(value);\n}\n\nfunction formatScalar(value: unknown): string {\n if (value === null || value === undefined) return \"—\";\n if (typeof value === \"number\") return String(value);\n if (typeof value === \"object\") return JSON.stringify(value);\n return String(value);\n}\n\n/** The record's headline for a row/drawer: Title, else Name, else its id. */\nexport function primaryLabel(record: AnyRecord): string {\n const title = record.Title ?? record.Name;\n return typeof title === \"string\" && title.trim() ? title : record.id;\n}\n\n// ── Field labels ────────────────────────────────────────────────────────────\n// The register is a surface a non-technical teammate meets, so field names are\n// shown in plain language, never as raw camelCase keys. This is the single\n// source for both the drawer's field list and its computed-numbers block.\n\n/** Labels for the computed `derived` tuple. Both `derivedImpact` (the\n * derivation module's name) and `impact` (the migrated data's name, pending the\n * OPS-1273 schema ripple) map to one label so the drawer reads cleanly either\n * way. */\nconst DERIVED_LABEL: Record<string, string> = {\n confidence: \"Confidence\",\n risk: \"Risk\",\n derivedImpact: \"Derived Impact\",\n impact: \"Derived Impact\",\n completeness: \"Completeness %\",\n sourceQuality: \"Source quality\",\n strength: \"Strength\",\n};\n\n/** Plain-language names for the camelCase id/relation fields; Title-cased\n * fields (Title, Status, Impact, Owner…) already read cleanly and pass through. */\nconst FIELD_LABEL: Record<string, string> = {\n dependsOnIds: \"Depends on\",\n enablesIds: \"Enables\",\n contradictsIds: \"Contradicts\",\n readingIds: \"Readings\",\n assumptionId: \"Assumption\",\n assumptionIds: \"Beliefs\",\n experimentId: \"Evidence plan\",\n body: \"Quote\",\n contextLinks: \"Context links\",\n basedOnIds: \"Based on\",\n resolvesIds: \"Resolves\",\n barLineAssumptionIds: \"Assumptions tested\",\n closureReason: \"Closure reason\",\n magnitudeBand: \"Magnitude band\",\n moot: \"Moot\",\n};\n\n/** A record field's display label — an override, else a humanised key. */\nexport function fieldLabel(key: string): string {\n const override = FIELD_LABEL[key];\n if (override) return override;\n if (/^[A-Z]/.test(key)) return key; // already Title-cased, reads fine\n const spaced = key.replace(/([a-z0-9])([A-Z])/g, \"$1 $2\").toLowerCase();\n return spaced.charAt(0).toUpperCase() + spaced.slice(1);\n}\n\n/** A computed (`derived`) field's display label. */\nexport function derivedLabel(key: string): string {\n return DERIVED_LABEL[key] ?? fieldLabel(key);\n}\n","import { useCallback, useEffect, useState } from \"react\";\nimport type { AnyRecord, Collection } from \"@validation-os/core\";\nimport { CONFLICT_MESSAGE } from \"./edit.js\";\n\n/**\n * Client hooks that read the register over HTTP through the API read routes\n * (`GET {basePath}/{register}` and `GET {basePath}/{register}/{id}`). The API\n * reaches Firestore server-side through the adapter, so no backend credentials\n * ever reach the browser — the browser only ever speaks to the Clerk-gated API.\n */\n\ninterface AsyncState<T> {\n data: T | null;\n loading: boolean;\n error: string | null;\n}\n\n/** Both read routes wrap their payload in a `{ data }` envelope. */\nfunction pickData<T>(body: unknown): T {\n return (body as { data: T }).data;\n}\n\n/**\n * Fetch one JSON resource, tracking loading/error. A null `url` means \"idle\"\n * (nothing to load yet) — the drawer's get hook uses this until a row is\n * clicked. Returns a `refresh` that re-runs the fetch. This is the shared\n * engine behind both `useList` and `useRecord`.\n */\nfunction useJsonResource<T>(url: string | null): AsyncState<T> & {\n refresh: () => void;\n} {\n const [state, setState] = useState<AsyncState<T>>({\n data: null,\n loading: url !== null,\n error: null,\n });\n const [tick, setTick] = useState(0);\n\n useEffect(() => {\n if (url === null) {\n setState({ data: null, loading: false, error: null });\n return;\n }\n let live = true;\n setState((s) => ({ ...s, loading: true }));\n fetch(url)\n .then(async (res) => {\n if (!res.ok) throw new Error(`Request to ${url} failed (${res.status})`);\n return pickData<T>(await res.json());\n })\n .then((data) => live && setState({ data, loading: false, error: null }))\n .catch(\n (e: unknown) =>\n live &&\n setState({\n data: null,\n loading: false,\n error: e instanceof Error ? e.message : \"Failed to load\",\n }),\n );\n return () => {\n live = false;\n };\n }, [url, tick]);\n\n const refresh = useCallback(() => setTick((t) => t + 1), []);\n return { ...state, refresh };\n}\n\nexport interface UseListResult {\n records: AnyRecord[] | null;\n loading: boolean;\n error: string | null;\n refresh: () => void;\n}\n\n/**\n * Fetch every row of a register. `enabled` (default true) gates the fetch: pass\n * false to keep the hook idle — the list-surface loads a *context* register\n * (e.g. experiments, for the assumptions \"Testing\" view) only when the current\n * register's tabs actually need it, without breaking the rules-of-hooks.\n */\nexport function useList(\n register: Collection,\n basePath = \"/api\",\n enabled = true,\n): UseListResult {\n const { data, loading, error, refresh } = useJsonResource<AnyRecord[]>(\n enabled ? `${basePath}/${register}` : null,\n );\n return { records: data, loading, error, refresh };\n}\n\nexport interface UseRecordResult {\n record: AnyRecord | null;\n loading: boolean;\n error: string | null;\n /** Re-fetch the record — the re-fetch path after a save or edit conflict. */\n refresh: () => void;\n}\n\n/**\n * Fetch one record by id. `id` may be null (nothing open) — the hook stays\n * idle until an id is supplied, so it drives a drawer that opens on row click.\n * `refresh` re-fetches: the edit flow calls it after a save, and it's the\n * re-fetch path offered when a write hits a concurrent-edit conflict.\n */\nexport function useRecord(\n register: Collection,\n id: string | null,\n basePath = \"/api\",\n): UseRecordResult {\n const url = id\n ? `${basePath}/${register}/${encodeURIComponent(id)}`\n : null;\n const { data, loading, error, refresh } = useJsonResource<AnyRecord>(url);\n return { record: data, loading, error, refresh };\n}\n\n/** The outcome of a save: the recomputed record, or a rejection with a\n * plain-language message (a concurrent-edit conflict, or another failure). */\nexport type SaveResult =\n | { ok: true; record: AnyRecord }\n | { ok: false; conflict: boolean; message: string };\n\nconst SAVE_FAILED = \"Couldn't save your changes — please try again.\";\n\n/**\n * Map an update response (status + parsed body) to a `SaveResult`. Pure, so\n * the 409/error/ok branching is unit-testable without a DOM. A 409 is a\n * concurrent-edit conflict, surfaced in the API's plain-language copy (or the\n * `CONFLICT_MESSAGE` fallback) — never version jargon (spec user story 12).\n */\nexport function interpretSave(status: number, body: unknown): SaveResult {\n if (status >= 200 && status < 300) {\n return { ok: true, record: pickData<AnyRecord>(body) };\n }\n const message = (body as { message?: unknown } | null)?.message;\n const text = typeof message === \"string\" ? message : null;\n if (status === 409) {\n return { ok: false, conflict: true, message: text ?? CONFLICT_MESSAGE };\n }\n return { ok: false, conflict: false, message: text ?? SAVE_FAILED };\n}\n\nexport interface UseUpdateResult {\n /** PATCH `{ version, ...patch }`; resolves to the recomputed record or a\n * rejection. Never throws — callers branch on `result.ok`. */\n save: (id: string, patch: Record<string, unknown>) => Promise<SaveResult>;\n saving: boolean;\n /** Plain-language conflict prompt when a concurrent edit was detected. */\n conflict: string | null;\n /** Plain-language message for any other save failure. */\n error: string | null;\n /** Clear conflict/error state (e.g. when re-entering edit mode). */\n reset: () => void;\n}\n\n/**\n * Version-guarded update over the API write route. A stale version comes back\n * as a 409, which we surface as a gentle, jargon-free `conflict` message (spec\n * user story 12) — the API sends the copy, and `CONFLICT_MESSAGE` is the\n * fallback. Derived values are recomputed server-side, so the returned record\n * carries the authoritative numbers, never anything the client computed.\n */\nexport function useUpdate(\n register: Collection,\n basePath = \"/api\",\n): UseUpdateResult {\n const [saving, setSaving] = useState(false);\n const [conflict, setConflict] = useState<string | null>(null);\n const [error, setError] = useState<string | null>(null);\n\n const save = useCallback(\n async (id: string, patch: Record<string, unknown>): Promise<SaveResult> => {\n setSaving(true);\n setConflict(null);\n setError(null);\n try {\n const res = await fetch(\n `${basePath}/${register}/${encodeURIComponent(id)}`,\n {\n method: \"PATCH\",\n headers: { \"content-type\": \"application/json\" },\n body: JSON.stringify(patch),\n },\n );\n const body = await res.json().catch(() => null);\n const result = interpretSave(res.status, body);\n if (!result.ok && result.conflict) setConflict(result.message);\n else if (!result.ok) setError(result.message);\n return result;\n } catch (e) {\n const message =\n e instanceof Error ? e.message : \"Couldn't save your changes.\";\n setError(message);\n return { ok: false, conflict: false, message };\n } finally {\n setSaving(false);\n }\n },\n [register, basePath],\n );\n\n const reset = useCallback(() => {\n setConflict(null);\n setError(null);\n }, []);\n\n return { save, saving, conflict, error, reset };\n}\n","/**\n * The pure edit-logic seam — which fields a register lets you edit, how a\n * form draft maps back to a version-guarded patch, and the plain-language\n * conflict copy. Kept as pure data/functions (no DOM) so the edit behaviour\n * is unit-testable exactly like `columns.ts`; the drawer component consumes it.\n *\n * Derived numbers (Confidence, Risk, Derived Impact, Strength) are never\n * editable — they are computed server-side on write (spec user story 4/11),\n * so they never appear here. Relation links are set through `link`, a separate\n * story, so relation-id fields aren't editable inputs either.\n */\nimport type { AnyRecord, Collection } from \"@validation-os/core\";\n\n/** The plain-language conflict prompt — never version jargon (user story 12).\n * The API returns its own copy on a 409; this is the client-side fallback. */\nexport const CONFLICT_MESSAGE =\n \"Someone edited this while you had it open — your changes are safe, \" +\n \"take a look before saving again.\";\n\nexport type FieldKind = \"text\" | \"textarea\" | \"number\" | \"select\";\n\nexport interface FieldEditor {\n /** The record key this editor writes. */\n key: string;\n /** Plain-language label shown beside the input. */\n label: string;\n kind: FieldKind;\n /** For `select`: the allowed options (a leading blank = \"unset\"). */\n options?: readonly string[];\n /** An empty input clears the field to `null` rather than \"\". */\n nullable?: boolean;\n /** For `number`: the inclusive range a hand-scored value must sit in\n * (e.g. Impact 0–100, `registry-schema.md`). Omitted = unbounded. */\n min?: number;\n max?: number;\n}\n\nconst t = (key: string, label: string): FieldEditor => ({ key, label, kind: \"text\" });\nconst area = (key: string, label: string): FieldEditor => ({\n key,\n label,\n kind: \"textarea\",\n});\nconst num = (\n key: string,\n label: string,\n range: { min?: number; max?: number } = {},\n): FieldEditor => ({\n key,\n label,\n kind: \"number\",\n nullable: true,\n ...range,\n});\nconst sel = (\n key: string,\n label: string,\n options: readonly string[],\n nullable = false,\n): FieldEditor => ({ key, label, kind: \"select\", options, nullable });\n\nconst SOURCE_QUALITY = [\"1\", \"0.7\", \"0.5\"] as const;\n\n/**\n * The editable fields per register, in the order they render. Hand-scored and\n * descriptive fields only — derived numbers, ids/timestamps, and relation\n * links are deliberately excluded.\n */\nconst EDITORS: Record<Collection, FieldEditor[]> = {\n assumptions: [\n t(\"Title\", \"Assumption\"),\n area(\"Description\", \"Description\"),\n // The only hand-scored number in the registry (`registry-schema.md`) — a\n // 0–100 severity-if-false seed. Every other number (Confidence, Derived\n // Impact, Risk, Strength, Source quality, Completeness %) is computed on\n // write and deliberately absent from this list.\n num(\"Impact\", \"Impact\", { min: 0, max: 100 }),\n sel(\"Status\", \"Status\", [\"Draft\", \"Live\", \"Invalidated\"]),\n t(\"Lens\", \"Lens\"),\n area(\"Scoring justification\", \"Scoring justification\"),\n // `moot` is deliberately not editable here — mooting an assumption is a\n // gated business action (see core `relations.ts`), not a free-form toggle.\n // 5 Whys / Metric for truth / Gaps are gone (OPS-1305); readiness is the\n // derived Completeness %, and the why-trace lives in Depends on / Enables.\n ],\n experiments: [\n t(\"Title\", \"Experiment\"),\n t(\"Instrument\", \"Instrument\"),\n sel(\"Feasibility\", \"Feasibility\", [\"High\", \"Medium\", \"Low\"], true),\n sel(\"Status\", \"Status\", [\"Draft\", \"Running\", \"Closed\"]),\n sel(\n \"closureReason\",\n \"Closure reason\",\n [\"Completed\", \"Early-stop\", \"Kill\"],\n true,\n ),\n // Deadline + Outcome: the commitment-grade fields folded in from the\n // retired Goal record (OPS-1305). Outcome is null until Closed.\n t(\"Deadline\", \"Deadline\"),\n sel(\"Outcome\", \"Outcome\", [\"Achieved\", \"Missed\", \"Dropped\"], true),\n t(\"Date\", \"Date\"),\n ],\n readings: [\n t(\"Title\", \"Reading\"),\n t(\"Source\", \"Source\"),\n // Rung / Result / Magnitude band / Grading justification are PER BELIEF now\n // (OPS-1305) — they live in each entry of `beliefs[]`, not on the row, so\n // they are deliberately absent here rather than writing dead row-level\n // fields. Editing a reading's per-belief scores is a deferred follow-up (a\n // `beliefs[]` editor); this form edits only the row-level fields that remain.\n sel(\"Representativeness\", \"Representativeness\", SOURCE_QUALITY),\n sel(\"Credibility\", \"Credibility\", SOURCE_QUALITY),\n area(\"body\", \"Quote\"),\n t(\"Date\", \"Date\"),\n ],\n decisions: [\n t(\"Title\", \"Decision\"),\n area(\"Statement\", \"Statement\"),\n sel(\"Status\", \"Status\", [\"Active\", \"Provisional\", \"Superseded\", \"Reversed\"]),\n ],\n glossary: [\n t(\"Title\", \"Term\"),\n sel(\"Status\", \"Status\", [\"Active\", \"Provisional\", \"Superseded\"]),\n area(\"Definition\", \"Definition\"),\n area(\"How it differs\", \"How it differs\"),\n ],\n};\n\n/** The fields a register lets you edit, in render order. */\nexport function editableFields(register: Collection): FieldEditor[] {\n return EDITORS[register];\n}\n\n/** A form draft is a plain string map keyed by field — what the inputs hold. */\nexport type Draft = Record<string, string>;\n\n/** Build the initial form draft from a record: every editable field becomes a\n * string input value, and missing values become empty inputs. */\nexport function draftFrom(register: Collection, record: AnyRecord): Draft {\n const draft: Draft = {};\n for (const f of editableFields(register)) {\n const value = record[f.key];\n draft[f.key] = value === null || value === undefined ? \"\" : String(value);\n }\n return draft;\n}\n\n/** Coerce one draft value back to its stored shape, honouring kind/nullable. */\nfunction coerce(field: FieldEditor, raw: string): unknown {\n const str = String(raw);\n if (field.kind === \"number\") {\n if (str.trim() === \"\") return null;\n const n = Number(str);\n return Number.isNaN(n) ? null : n;\n }\n // An empty select is \"unset\" → null; an empty nullable text field clears too.\n if (str === \"\" && (field.kind === \"select\" || field.nullable)) return null;\n return str;\n}\n\n/** Absent and empty values compare equal, so an untouched field isn't a change. */\nfunction norm(value: unknown): unknown {\n return value === undefined || value === \"\" ? null : value;\n}\n\n/**\n * The plain-language validation error for one field's draft value, or `null`\n * when it's fine. Only `number` fields with a `min`/`max` are checked — an\n * empty input always clears to `null` (allowed; there's no \"required\" seed).\n * Kept pure so the Save button can gate on it without touching the DOM.\n */\nexport function fieldError(field: FieldEditor, raw: string): string | null {\n if (field.kind !== \"number\") return null;\n const str = String(raw ?? \"\").trim();\n if (str === \"\") return null;\n const n = Number(str);\n if (Number.isNaN(n)) return `${field.label} must be a number.`;\n if (field.min !== undefined && n < field.min) {\n return `${field.label} must be at least ${field.min}.`;\n }\n if (field.max !== undefined && n > field.max) {\n return `${field.label} must be at most ${field.max}.`;\n }\n return null;\n}\n\n/**\n * Every field in a draft that currently fails validation, keyed by field —\n * what the record page/drawer show inline and gate Save on (spec: seed\n * Impact is the only hand-scored number, and it must stay in 0–100).\n */\nexport function draftErrors(\n register: Collection,\n draft: Draft,\n): Record<string, string> {\n const errors: Record<string, string> = {};\n for (const field of editableFields(register)) {\n const message = fieldError(field, draft[field.key] ?? \"\");\n if (message) errors[field.key] = message;\n }\n return errors;\n}\n\n/**\n * A version-guarded patch from a draft: the loaded `version` plus only the\n * fields whose value actually changed (so an untouched save doesn't churn\n * unrelated fields). The API rejects a stale version with a 409.\n */\nexport function buildPatch(\n register: Collection,\n original: AnyRecord,\n draft: Draft,\n): Record<string, unknown> {\n const patch: Record<string, unknown> = { version: original.version };\n for (const field of editableFields(register)) {\n const next = coerce(field, draft[field.key] ?? \"\");\n if (norm(next) !== norm(original[field.key])) patch[field.key] = next;\n }\n return patch;\n}\n\n/** Whether a draft differs from the record it was loaded from. */\nexport function hasEdits(\n register: Collection,\n original: AnyRecord,\n draft: Draft,\n): boolean {\n return Object.keys(buildPatch(register, original, draft)).length > 1;\n}\n","import { useMemo, useState, type ReactNode } from \"react\";\nimport type { AnyRecord } from \"@validation-os/core\";\nimport { coldStartFor, FIRST_RUN_LINE } from \"./cold-start.js\";\nimport { EvidenceBody } from \"./markdown.js\";\nimport { buildPipeline, type PipelineRow } from \"./pipeline.js\";\nimport { buildRecommendedExperiments, buildNeedsFraming, type RecommendedExperiment, type NeedsFramingItem } from \"./recommended-experiments.js\";\nimport { stageMeters } from \"./stage-meters.js\";\nimport {\n buildStageGrid,\n cellAt,\n NO_LENS,\n NO_STAGE,\n rankByRisk,\n STAGE_GLOSS,\n STAGE_ORDER,\n type StageGridCell,\n} from \"./stage-grid-model.js\";\nimport type { Route } from \"./route.js\";\nimport { useList } from \"./use-records.js\";\nimport { formatSigned, type Tone } from \"./primitives.js\";\n\n/**\n * The Assumptions nav surface (DEV-5881 + DEV-5882): the Lens × Stage grid as\n * the default landing, with a \"Grid / View all\" toggle. \"View all\" switches to\n * the pipeline board (hero burn-up + pipeline rows + recommended experiments).\n * A single-cell click (one assumption) opens the AssumptionDetail directly; a\n * multi-assumption cell opens the pipeline view filtered to that cell.\n *\n * Lazy-loads the assumption + experiment registers and derives everything\n * through the pure `buildStageGrid` + `buildPipeline` +\n * `buildRecommendedExperiments` view-models.\n */\nexport interface AssumptionsSurfaceProps {\n basePath?: string;\n onNavigate: (route: Route) => void;\n /** `\"all\"` shows the pipeline board; undefined shows the grid. */\n view?: \"all\";\n /** When set, the pipeline board filters to this lens × stage. */\n lens?: string;\n stage?: string;\n}\n\nexport function AssumptionsSurface({\n basePath,\n onNavigate,\n view,\n lens,\n stage,\n}: AssumptionsSurfaceProps) {\n const assumptions = useList(\"assumptions\", basePath);\n const experiments = useList(\"experiments\", basePath);\n const readings = useList(\"readings\", basePath);\n\n const loading =\n assumptions.loading || experiments.loading || readings.loading;\n const error = assumptions.error || experiments.error || readings.error;\n\n const showPipeline = view === \"all\" || (lens !== undefined && stage !== undefined);\n\n return (\n <div>\n <div className=\"vos-head\">\n <div>\n <h1>Assumptions — where your bets cluster</h1>\n <p>\n Every falsifiable belief the business depends on, cross-tabbed by\n the actor it's about (Lens) and the kind of response it tests\n (Stage). The grid is the filter; Risk is the rank.\n </p>\n </div>\n <div className=\"vos-spacer\" />\n <div className=\"vos-seg\" role=\"tablist\" aria-label=\"Assumptions view\">\n <button\n type=\"button\"\n className={`vos-seg-btn ${!showPipeline ? \"is-active\" : \"\"}`}\n role=\"tab\"\n aria-selected={!showPipeline}\n onClick={() => onNavigate({ name: \"assumptions\" })}\n >\n Grid\n </button>\n <button\n type=\"button\"\n className={`vos-seg-btn ${showPipeline ? \"is-active\" : \"\"}`}\n role=\"tab\"\n aria-selected={showPipeline}\n onClick={() => onNavigate({ name: \"assumptions\", view: \"all\" })}\n >\n View all\n </button>\n </div>\n </div>\n\n {loading && !assumptions.records ? (\n <p className=\"vos-muted\">Reading where your bets cluster…</p>\n ) : error ? (\n <p className=\"vos-error\">{error}</p>\n ) : showPipeline ? (\n <PipelineBoard\n assumptions={assumptions.records ?? []}\n experiments={experiments.records ?? []}\n readings={readings.records ?? []}\n onNavigate={onNavigate}\n filterLens={lens}\n filterStage={stage}\n />\n ) : (\n <GridPane\n assumptions={assumptions.records ?? []}\n experiments={experiments.records ?? []}\n readings={readings.records ?? []}\n onNavigate={onNavigate}\n />\n )}\n </div>\n );\n}\n\n/* ── Grid pane ─────────────────────────────────────────────────────────── */\n\nfunction GridPane({\n assumptions,\n experiments,\n readings,\n onNavigate,\n}: {\n assumptions: AnyRecord[];\n experiments: AnyRecord[];\n readings: AnyRecord[];\n onNavigate: (route: Route) => void;\n}) {\n const view = useMemo(() => buildStageGrid(assumptions), [assumptions]);\n const recs = useMemo(\n () => buildRecommendedExperiments(assumptions, experiments),\n [assumptions, experiments],\n );\n const needsFraming = useMemo(\n () => buildNeedsFraming(assumptions),\n [assumptions],\n );\n\n const cold = coldStartFor({\n assumptions,\n experiments,\n readings,\n decisions: [],\n });\n if (cold.cold) {\n return (\n <>\n <div className=\"vos-firstrun\">{FIRST_RUN_LINE}</div>\n <div className=\"vos-card vos-cold vos-cold-stage-grid\">\n <span className=\"vos-cold-eyebrow\">No bets yet</span>\n <p className=\"vos-cold-body\">\n The Lens × Stage grid reads your business state off where your bets\n cluster. Write your first belief and the grid fills in — the\n densest cell per row is where that part of the business is.\n </p>\n <button\n type=\"button\"\n className=\"vos-btn\"\n onClick={() => onNavigate({ name: \"records\", register: \"assumptions\", view: \"all\" })}\n >\n Write your first bet\n </button>\n </div>\n </>\n );\n }\n\n function cellClick(cell: StageGridCell) {\n if (cell.count === 0) return;\n if (cell.count === 1) {\n const id = String(cell.assumptions[0]?.id ?? \"\");\n if (id) onNavigate({ name: \"assumption\", id });\n } else {\n onNavigate({\n name: \"assumptions\",\n lens: cell.lens === NO_LENS ? undefined : cell.lens,\n stage: cell.stage === NO_STAGE ? undefined : cell.stage,\n });\n }\n }\n\n return (\n <>\n <div className=\"vos-card vos-stage-grid-card\">\n <div className=\"vos-stage-grid-scroll\">\n <table className=\"vos-stage-grid\" role=\"grid\" aria-label=\"Lens × Stage heatmap\">\n <thead>\n <tr>\n <th scope=\"col\" className=\"vos-stage-grid-corner\">Lens ↓ / Stage →</th>\n {view.stages.map((s) => (\n <th key={s} scope=\"col\" className=\"vos-stage-grid-col\">\n <span className=\"vos-stage-grid-stagename\">{s}</span>\n <span className=\"vos-stage-grid-stagegloss\">{STAGE_GLOSS[s]}</span>\n </th>\n ))}\n </tr>\n </thead>\n <tbody>\n {view.lenses.map((lens) => (\n <tr key={lens}>\n <th scope=\"row\" className=\"vos-stage-grid-rowhead\">{lens}</th>\n {view.stages.map((s) => {\n const cell = cellAt(view, lens, s)!;\n return (\n <td key={s} className=\"vos-stage-grid-cell\">\n <button\n type=\"button\"\n className={`vos-stage-grid-btn vos-heat-${heatLevel(cell.density)}`}\n disabled={cell.count === 0}\n onClick={() => cellClick(cell)}\n aria-label={`${cell.count} assumptions in ${lens} × ${s}`}\n >\n {cell.count === 0 ? \"·\" : cell.count === 1 ? \"1\" : String(cell.count)}\n </button>\n </td>\n );\n })}\n </tr>\n ))}\n </tbody>\n </table>\n </div>\n <p className=\"vos-hint vos-stage-grid-foot\">\n The densest cell per row is where that part of the business is. Click a\n cell to drill into its assumptions, ranked by Risk; a single-assumption\n cell opens the detail directly.\n </p>\n </div>\n\n {/* Next moves — two columns: top 2 assumptions needing framing + top 2\n proposed experiments. This is where the action is on the grid home. */}\n {(needsFraming.length > 0 || recs.length > 0) ? (\n <NextMovesSection\n needsFraming={needsFraming}\n recs={recs}\n onOpenAssumption={(id) => onNavigate({ name: \"assumption\", id })}\n />\n ) : null}\n </>\n );\n}\n\nfunction heatLevel(density: number): 0 | 1 | 2 | 3 | 4 {\n if (density <= 0) return 0;\n if (density < 0.25) return 1;\n if (density < 0.5) return 2;\n if (density < 0.75) return 3;\n return 4;\n}\n\n/* ── Pipeline board ────────────────────────────────────────────────────── */\n\nfunction PipelineBoard({\n assumptions,\n experiments,\n readings,\n onNavigate,\n filterLens,\n filterStage,\n}: {\n assumptions: AnyRecord[];\n experiments: AnyRecord[];\n readings: AnyRecord[];\n onNavigate: (route: Route) => void;\n filterLens?: string;\n filterStage?: string;\n}) {\n const filtered = useMemo(() => {\n if (filterLens === undefined && filterStage === undefined) return assumptions;\n return assumptions.filter((a) => {\n const l = String(a.Lens ?? NO_LENS);\n const s = String(a.Stage ?? NO_STAGE);\n return (\n (filterLens === undefined || l === filterLens) &&\n (filterStage === undefined || s === filterStage)\n );\n });\n }, [assumptions, filterLens, filterStage]);\n\n const view = useMemo(\n () => buildPipeline(filtered, experiments),\n [filtered, experiments],\n );\n const { progress, rows } = view;\n\n const crumb =\n filterLens !== undefined || filterStage !== undefined ? (\n <Breadcrumb\n trail={[\n { label: \"Assumptions\", route: { name: \"assumptions\" } },\n {\n label: `${filterLens ?? \"—\"} × ${filterStage ?? \"—\"}`,\n route: { name: \"assumptions\" },\n },\n ]}\n />\n ) : null;\n\n return (\n <>\n {crumb}\n <section className=\"vos-card vos-pipe-hero vos-pipe-hero-board\">\n <div className=\"vos-pipe-read\">\n <div className=\"vos-pipe-eyebrow\">Risk bought down</div>\n <div className=\"vos-pipe-big vos-num\">\n {Math.round(progress.percent)}<span>%</span>\n </div>\n <div className=\"vos-pipe-sub\">\n {Math.round(progress.retired)} retired · {Math.round(progress.identified - progress.retired)} at risk · {rows.length} beliefs\n </div>\n </div>\n </section>\n\n <div className=\"vos-card vos-pipe-board\">\n <div className=\"vos-pipe-boardhead\">\n <div className=\"vos-pipe-bt\">\n Pipeline <span>· {rows.length} live {rows.length === 1 ? \"belief\" : \"beliefs\"}</span>\n </div>\n <div className=\"vos-pipe-sortnote\">sorted by live risk — riskiest first</div>\n </div>\n {rows.length === 0 ? (\n <div className=\"vos-empty\" style={{ margin: 16 }}>\n No live beliefs {filterLens || filterStage ? \"in this cell\" : \"\"} — nothing to test right now.\n </div>\n ) : (\n rows.map((row) => (\n <PipelineRowView\n key={row.id}\n row={row}\n onOpen={() => onNavigate({ name: \"assumption\", id: row.id })}\n />\n ))\n )}\n </div>\n </>\n );\n}\n\n/* The pipeline row — 4px risk stripe + belief + 2-segment meter + next-move.\n * The meter is 2 segments only (Framed + Known) — Planned and Tested are\n * dropped per the collapsed pipeline model (DEV-5879). */\nfunction PipelineRowView({ row, onOpen }: { row: PipelineRow; onOpen: () => void }) {\n const stripeTone: Tone = row.riskTone;\n const knownPct = Math.max(0, Math.min(100, Math.abs(row.confidence)));\n const knownSign = row.confSign;\n return (\n <div className=\"vos-pipe-row vos-pipe-row-2seg\">\n <div className={`vos-pipe-stripe vos-fill-${stripeTone}`} />\n <button type=\"button\" className=\"vos-pipe-belief\" onClick={onOpen}>\n <span className=\"vos-pipe-id vos-num\">{row.id}</span>\n <span className=\"vos-pipe-stmt\">{row.statement || row.id}</span>\n <span className=\"vos-pipe-bmeta\">\n <span className=\"vos-num\">impact {Math.round(row.impact)}</span>\n <span className={`vos-num vos-text-${row.riskTone}`}>risk {Math.round(row.risk)}</span>\n <span className=\"vos-num\">conf {formatSigned(row.confidence)}</span>\n </span>\n </button>\n <div className=\"vos-pipe-prog-2seg\" aria-label=\"Evidence progress (Framed + Known)\">\n <Meter2Seg framed={row.framed} knownPct={knownPct} knownSign={knownSign} />\n </div>\n <div className=\"vos-pipe-actions\">\n <button type=\"button\" className=\"vos-btn vos-btn-sm vos-btn-accent\" onClick={onOpen}>\n {row.nextMove}\n </button>\n </div>\n </div>\n );\n}\n\nfunction Meter2Seg({\n framed,\n knownPct,\n knownSign,\n}: {\n framed: number;\n knownPct: number;\n knownSign: \"pos\" | \"neg\" | \"zero\";\n}) {\n const knownTone = knownSign === \"neg\" ? \"crit\" : knownPct > 30 ? \"good\" : \"warn\";\n return (\n <div className=\"vos-meter2\">\n <div className=\"vos-meter2-track\">\n <div className=\"vos-meter2-seg vos-meter2-framed\">\n <i className=\"vos-meter2-fill-accent\" style={{ width: `${Math.min(100, framed)}%` }} />\n </div>\n <div className=\"vos-meter2-seg vos-meter2-known\">\n {knownSign !== \"zero\" ? (\n <i className={`vos-meter2-fill-${knownTone}`} style={{ width: `${knownPct}%` }} />\n ) : null}\n </div>\n </div>\n <div className=\"vos-meter2-caps\">\n <span className=\"vos-meter2-cap\">Framed</span>\n <span className=\"vos-meter2-cap\">Known</span>\n </div>\n </div>\n );\n}\n\n/* ── Next moves section — two columns: needs framing + proposed experiments ── */\n\nfunction NextMovesSection({\n needsFraming,\n recs,\n onOpenAssumption,\n}: {\n needsFraming: NeedsFramingItem[];\n recs: RecommendedExperiment[];\n onOpenAssumption: (id: string) => void;\n}) {\n const [openRec, setOpenRec] = useState<RecommendedExperiment | null>(null);\n return (\n <div className=\"vos-next-moves\">\n <div className=\"vos-next-moves-head\">Next moves</div>\n <div className=\"vos-next-moves-cols\">\n {/* Left column — top 1 assumption needing framing per lens */}\n <div className=\"vos-card vos-next-moves-col\">\n <div className=\"vos-next-moves-col-label\">Needs framing · one per lens</div>\n {needsFraming.length === 0 ? (\n <div className=\"vos-muted vos-next-moves-empty\">Every belief is fully framed.</div>\n ) : (\n needsFraming.map((a) => (\n <button\n key={a.id}\n type=\"button\"\n className=\"vos-next-moves-item\"\n onClick={() => onOpenAssumption(a.id)}\n >\n <div className=\"vos-next-moves-item-head\">\n <span\n className=\"vos-next-moves-lens\"\n style={{ background: `${a.lensColour}20`, color: a.lensColour, borderColor: `${a.lensColour}40` }}\n >\n {a.lens}\n </span>\n <span className={`vos-next-moves-item-risk vos-num vos-text-${riskToneClass(a.risk)}`}>\n {Math.round(a.risk)} risk\n </span>\n </div>\n <div className=\"vos-next-moves-item-title\">\n <span className=\"vos-next-moves-item-id vos-num\">{a.id}</span> · {a.title}\n </div>\n <div className=\"vos-next-moves-item-hint\">{a.hint}</div>\n </button>\n ))\n )}\n </div>\n\n {/* Right column — compact proposed-experiment cards; click opens a drawer */}\n <div className=\"vos-card vos-next-moves-col\">\n <div className=\"vos-next-moves-col-label\">Proposed experiments · one per lens</div>\n {recs.length === 0 ? (\n <div className=\"vos-muted vos-next-moves-empty\">Every risk has a live test.</div>\n ) : (\n recs.map((rec) => (\n <button\n key={rec.id}\n type=\"button\"\n className=\"vos-next-moves-rec vos-next-moves-rec-compact\"\n onClick={() => setOpenRec(rec)}\n >\n <div className=\"vos-next-moves-rec-head\">\n <span\n className=\"vos-next-moves-lens\"\n style={{ background: `${rec.lensColour}20`, color: rec.lensColour, borderColor: `${rec.lensColour}40` }}\n >\n {rec.lens}\n </span>\n <span className=\"vos-next-moves-rec-type\">{rec.type}</span>\n <span className=\"vos-next-moves-rec-risk vos-num\">{Math.round(rec.maxRisk)} risk</span>\n </div>\n <div className=\"vos-next-moves-rec-title\">{rec.title}</div>\n <span className=\"vos-next-moves-rec-open\" aria-hidden=\"true\">→</span>\n </button>\n ))\n )}\n </div>\n </div>\n\n {openRec ? (\n <RecommendedExperimentDrawer\n rec={openRec}\n onOpenAssumption={onOpenAssumption}\n onClose={() => setOpenRec(null)}\n />\n ) : null}\n </div>\n );\n}\n\n/* Side drawer for a recommended experiment — slides in from the right using the\n * existing .vos-drawer / .vos-scrim classes. Shows the full experiment detail\n * (rationale, bar preview, assumption chips, generated body) and the accept\n * action, instead of expanding the card inline. */\nfunction RecommendedExperimentDrawer({\n rec,\n onOpenAssumption,\n onClose,\n}: {\n rec: RecommendedExperiment;\n onOpenAssumption: (id: string) => void;\n onClose: () => void;\n}) {\n return (\n <>\n <div className=\"vos-scrim\" onClick={onClose} aria-hidden=\"true\" />\n <aside\n className=\"vos-drawer vos-rec-drawer\"\n role=\"dialog\"\n aria-modal=\"true\"\n aria-label={`Proposed experiment: ${rec.title}`}\n >\n <div className=\"vos-drawer-header\">\n <div>\n <div className=\"vos-drawer-eyebrow\">Proposed experiment</div>\n <h2 className=\"vos-drawer-title\">{rec.title}</h2>\n </div>\n <div style={{ marginLeft: \"auto\", display: \"flex\", gap: 8, alignItems: \"center\" }}>\n <span\n className=\"vos-next-moves-lens\"\n style={{ background: `${rec.lensColour}20`, color: rec.lensColour, borderColor: `${rec.lensColour}40` }}\n >\n {rec.lens}\n </span>\n <span className=\"vos-next-moves-rec-type\">{rec.type}</span>\n <span className=\"vos-next-moves-rec-risk vos-num\">{Math.round(rec.maxRisk)} risk</span>\n <button type=\"button\" className=\"vos-btn vos-btn-sm\" onClick={onClose} aria-label=\"Close\">✕</button>\n </div>\n </div>\n\n <div className=\"vos-drawer-body\">\n <div className=\"vos-rec-drawer-section\">\n <div className=\"vos-drawer-eyebrow\">Why this test</div>\n <p className=\"vos-rec-drawer-rationale\">{rec.rationale}</p>\n </div>\n\n <div className=\"vos-rec-drawer-section\">\n <div className=\"vos-drawer-eyebrow\">Bar</div>\n <div className=\"vos-rec-drawer-bar\">\n <strong>Right if:</strong> {rec.barPreview}\n </div>\n </div>\n\n <div className=\"vos-rec-drawer-section\">\n <div className=\"vos-drawer-eyebrow\">Assumptions</div>\n <div className=\"vos-next-moves-rec-chips\">\n {rec.assumptionIds.map((id) => (\n <button\n key={id}\n type=\"button\"\n className=\"vos-next-moves-rec-chip\"\n onClick={() => onOpenAssumption(id)}\n >\n {id}\n </button>\n ))}\n </div>\n </div>\n\n <div className=\"vos-rec-drawer-section\">\n <div className=\"vos-drawer-eyebrow\">Protocol</div>\n <div className=\"vos-rec-drawer-body\">\n <EvidenceBody text={rec.body} />\n </div>\n </div>\n </div>\n\n <div className=\"vos-drawer-footer\">\n <button type=\"button\" className=\"vos-btn vos-btn-sm vos-btn-accent\">\n Accept & create experiment\n </button>\n </div>\n </aside>\n </>\n );\n}\n\nfunction riskToneClass(risk: number): string {\n if (risk >= 70) return \"crit\";\n if (risk >= 40) return \"warn\";\n return \"good\";\n}\n\n/* ── Recommended experiments section (standalone — used on the pipeline board) ── */\n\nfunction RecommendedExperimentsSection({\n recs,\n onOpenAssumption,\n}: {\n recs: RecommendedExperiment[];\n onOpenAssumption: (id: string) => void;\n}) {\n return (\n <div className=\"vos-card vos-pipe-recs\">\n <div className=\"vos-pipe-recs-head\">\n Next moves · recommended experiments · one per lens (top {recs.length})\n </div>\n <div className=\"vos-pipe-recs-list\">\n {recs.map((rec) => (\n <div key={rec.id} className=\"vos-pipe-rec vos-pipe-rec-flat\">\n <div className=\"vos-pipe-rec-head\">\n <span\n className=\"vos-next-moves-lens\"\n style={{ background: `${rec.lensColour}20`, color: rec.lensColour, borderColor: `${rec.lensColour}40` }}\n >\n {rec.lens}\n </span>\n <span className=\"vos-pipe-rec-type\">{rec.type}</span>\n <span className=\"vos-pipe-rec-title\">{rec.title}</span>\n <span className=\"vos-pipe-rec-risk vos-num\">{Math.round(rec.maxRisk)} risk</span>\n </div>\n <div className=\"vos-pipe-rec-body-inner\">\n <div className=\"vos-pipe-rec-rationale\">{rec.rationale}</div>\n <div className=\"vos-pipe-rec-chips\">\n {rec.assumptionIds.map((id) => (\n <button\n key={id}\n type=\"button\"\n className=\"vos-pipe-rec-chip\"\n onClick={() => onOpenAssumption(id)}\n >\n {id}\n </button>\n ))}\n </div>\n <div className=\"vos-pipe-rec-bar\">\n <strong>Right if:</strong> {rec.barPreview}\n </div>\n {/* The generated experiment body — protocol, questions, how to run */}\n <div className=\"vos-pipe-rec-body\">\n <EvidenceBody text={rec.body} />\n </div>\n {/* Accept action visible without expanding */}\n <div className=\"vos-pipe-rec-actions\">\n <button type=\"button\" className=\"vos-btn vos-btn-sm\">Accept & create experiment</button>\n </div>\n </div>\n </div>\n ))}\n </div>\n </div>\n );\n}\n\n/* ── Breadcrumb ────────────────────────────────────────────────────────── */\n\nfunction Breadcrumb({\n trail,\n}: {\n trail: { label: string; route: Route }[];\n}) {\n return (\n <nav className=\"vos-crumb\" aria-label=\"Breadcrumb\">\n {trail.map((t, i) => (\n <span key={i} className=\"vos-crumb-item\">\n {i > 0 ? <span className=\"vos-crumb-sep\">/</span> : null}\n <span className={i === trail.length - 1 ? \"vos-crumb-current\" : \"vos-crumb-link\"}>\n {t.label}\n </span>\n </span>\n ))}\n </nav>\n );\n}","/**\n * Front-door presentation logic for the next-move ranking (build OPS-1304).\n * Two pure seams, kept free of React/DOM so they're unit-tested like\n * `columns.ts` / `primitives.ts`:\n *\n * - `toNextMoveInput` maps the fetched register records onto the shape\n * `packages/core`'s `rankNextMoves` consumes (the ranking rule itself lives\n * once in core — `ontology.yaml → derived_views.next_move`, OPS-1292);\n * - `movePresentation` maps each act to its front-door copy and whether it's a\n * human step-in form or an agent-run act shown for review (OPS-1291/1294).\n */\nimport type { AnyRecord, Feasibility } from \"@validation-os/core\";\nimport {\n isConcluded,\n type MoveKind,\n type NextMoveInput,\n} from \"@validation-os/core/derivation\";\nimport { readingBeliefs } from \"./derived-views.js\";\n\nfunction str(record: AnyRecord, key: string): string | null {\n const v = record[key];\n return typeof v === \"string\" ? v : null;\n}\nfunction numOrNull(record: AnyRecord, key: string): number | null {\n const v = record[key];\n return typeof v === \"number\" ? v : null;\n}\nfunction idList(record: AnyRecord, key: string): string[] {\n const v = record[key];\n return Array.isArray(v) ? v.filter((x): x is string => typeof x === \"string\") : [];\n}\n\n/** The four registers the ranking reads, as fetched from the API. */\nexport interface NextMoveRecords {\n assumptions: AnyRecord[];\n experiments: AnyRecord[];\n readings: AnyRecord[];\n decisions: AnyRecord[];\n}\n\n/**\n * Fold the fetched records into `rankNextMoves`' input: the derived Risk /\n * Confidence come straight off each assumption (the server keeps them current,\n * OPS-1251 — never recomputed here), and concluded readings are counted per\n * belief so the stage logic can tell \"no evidence yet\" from \"evidence in\".\n */\nexport function toNextMoveInput(records: NextMoveRecords): NextMoveInput {\n const concludedByAssumption = new Map<string, number>();\n for (const r of records.readings) {\n // A reading row scores several beliefs at once (OPS-1305); each concluded\n // belief-score counts toward its own assumption's \"evidence is in\" tally.\n for (const b of readingBeliefs(r)) {\n if (!b.assumptionId || !isConcluded(b.Result)) continue;\n concludedByAssumption.set(\n b.assumptionId,\n (concludedByAssumption.get(b.assumptionId) ?? 0) + 1,\n );\n }\n }\n\n return {\n assumptions: records.assumptions.map((a) => {\n const derived =\n a.derived && typeof a.derived === \"object\"\n ? (a.derived as Record<string, unknown>)\n : {};\n return {\n id: a.id,\n title: str(a, \"Title\") ?? a.id,\n status: str(a, \"Status\") ?? \"\",\n impact: numOrNull(a, \"Impact\"),\n moot: a.moot === true,\n risk: typeof derived.risk === \"number\" ? derived.risk : 0,\n confidence: typeof derived.confidence === \"number\" ? derived.confidence : 0,\n concludedReadings: concludedByAssumption.get(a.id) ?? 0,\n };\n }),\n experiments: records.experiments.map((e) => ({\n status: str(e, \"Status\") ?? \"\",\n feasibility: (str(e, \"Feasibility\") as Feasibility | null) ?? null,\n assumptionIds: idList(e, \"barLineAssumptionIds\"),\n })),\n decisions: records.decisions.map((d) => ({\n status: str(d, \"Status\") ?? \"\",\n assumptionIds: [...idList(d, \"basedOnIds\"), ...idList(d, \"resolvesIds\")],\n })),\n };\n}\n\n/** Which step-in form an act opens, or null for an agent-run act. */\nexport type StepInForm = \"score-impact\" | \"write-decision\";\n\nexport interface MovePresentation {\n /** Imperative CTA on the hero's act button. */\n cta: string;\n /** Short label for the \"On deck\" act pill. */\n pill: string;\n /**\n * A human step-in form (the dashboard is a review surface, OPS-1294) vs an\n * agent-run act the front door only visualises for review.\n */\n steppable: boolean;\n /** The form the act opens when steppable; null for agent-run acts. */\n form: StepInForm | null;\n}\n\nconst PRESENTATION: Record<MoveKind, MovePresentation> = {\n \"score-impact\": {\n cta: \"Score its impact\",\n pill: \"Score impact\",\n steppable: true,\n form: \"score-impact\",\n },\n \"design-experiment\": {\n cta: \"Design the test\",\n pill: \"Design test\",\n steppable: false,\n form: null,\n },\n \"record-reading\": {\n cta: \"See the test\",\n pill: \"Testing\",\n steppable: false,\n form: null,\n },\n decide: {\n cta: \"Make the call\",\n pill: \"Decide\",\n steppable: true,\n form: \"write-decision\",\n },\n retest: {\n cta: \"Kill or re-test\",\n pill: \"Re-test\",\n steppable: true,\n form: \"write-decision\",\n },\n};\n\n/** The front-door copy + step-in modality for one act. */\nexport function movePresentation(kind: MoveKind): MovePresentation {\n return PRESENTATION[kind];\n}\n","/**\n * The cross-surface cold-start view-model (OPS-1331) — pure, no React, no I/O,\n * so the \"what does the dashboard show before any beliefs exist?\" mapping is\n * unit-tested at this seam (like `next-move.ts` / `pipeline.ts` / `journey.ts`).\n *\n * The dashboard has three workflow surfaces, and each one had a basic one-line\n * empty state from its own build (OPS-1304 front door, OPS-1300 pipeline). Now\n * that all three surfaces exist (OPS-1330 journey landed), this replaces them\n * with one designed pass: a founder who opens the dashboard before any beliefs\n * exist is *guided in* rather than shown blank meters.\n *\n * Two cold states, one module:\n *\n * - **Cross-surface cold start** — zero beliefs exist. The front door and the\n * pipeline each get a designed empty state (a hero with a first-bet CTA, an\n * honest 0% burn-up with an invitation), and a shared first-run onboarding\n * line ties the three surfaces together. Trigger: `records.assumptions`\n * is empty.\n * - **Journey no-history cold state** — a belief exists but has no evidence\n * yet (no score, no test, no reading). The rail renders honestly (framed at\n * its completeness %, 0/0 bars); the story's cold-state copy names the\n * belief's first move in plain language, rather than showing two sparse\n * events with nothing between. Trigger: the story has only the structural\n * `bet` + `now` events.\n *\n * No number is invented: the pipeline's cold burn-up reads 0% because there is\n * no risk to retire; the journey's cold rail reads the belief's real framing %\n * and 0/0 tests. The copy is plain and consistent across both themes (it\n * carries no tone — these are invitations, not status).\n */\nimport type { JourneyView } from \"./journey.js\";\nimport { movePresentation, type NextMoveRecords } from \"./next-move.js\";\n\n/** The cross-surface cold start — zero beliefs exist. */\nexport interface ColdStart {\n /** True when no assumptions exist in the register. */\n cold: boolean;\n /** The first-run onboarding line — shared across every cold surface. */\n onboarding: string;\n /** The front-door hero copy. */\n next: NextColdStart;\n /** The pipeline cold-board copy. */\n pipeline: PipelineColdStart;\n}\n\n/** The front-door cold-start hero copy. */\nexport interface NextColdStart {\n /** The hero's eyebrow — a small label above the headline. */\n eyebrow: string;\n /** The hero's headline — the one line a founder reads. */\n headline: string;\n /** The hero's supporting line, under the headline. */\n body: string;\n /** The primary CTA on the cold hero. */\n cta: string;\n}\n\n/** The pipeline cold-start copy. */\nexport interface PipelineColdStart {\n /** The burn-up's headline reading (honest: 0%, no risk to retire). */\n headline: string;\n /** The line under the 0% — what the founder does next. */\n invitation: string;\n /** The empty board's body copy. */\n boardBody: string;\n /** The empty board's CTA. */\n boardCta: string;\n}\n\n/** The journey's no-history cold-state copy. */\nexport interface JourneyColdState {\n /** True when the belief has no evidence yet (only the structural events). */\n cold: boolean;\n /** The eyebrow on the cold-state card. */\n eyebrow: string;\n /** The cold-state body — names the belief's first move in plain language. */\n body: string;\n}\n\n/** The shared first-run onboarding line — one tone across all three surfaces. */\nexport const FIRST_RUN_LINE =\n \"This is your validation dashboard — three views over one loop. \" +\n \"Write your first bet to bring it to life.\";\n\n/** The front-door cold-start hero copy. */\nconst NEXT_COLD: NextColdStart = {\n eyebrow: \"Before there's evidence\",\n headline: \"No beliefs yet — write your first bet.\",\n body: \"Every belief the plan rests on starts here. Name one falsifiable assumption, score its impact, and the dashboard takes it from there: the pipeline shows where it stands, and its journey tells the story as evidence lands.\",\n cta: \"Write your first bet\",\n};\n\n/** The pipeline cold-start copy. */\nconst PIPELINE_COLD: PipelineColdStart = {\n headline: \"0%\",\n invitation: \"No risk to retire yet — write your first bet and it shows here.\",\n boardBody:\n \"Every belief you write lands here with its risk, its four loop meters, and its next move. Nothing to show until then.\",\n boardCta: \"Write your first bet\",\n};\n\n/** A cold start with every surface's copy filled in. */\nconst COLD_START: ColdStart = {\n cold: true,\n onboarding: FIRST_RUN_LINE,\n next: NEXT_COLD,\n pipeline: PIPELINE_COLD,\n};\n\n/** A warm start (beliefs exist) — every surface renders its real content. */\nconst WARM_START: ColdStart = {\n cold: false,\n onboarding: \"\",\n next: {\n eyebrow: \"\",\n headline: \"\",\n body: \"\",\n cta: \"\",\n },\n pipeline: {\n headline: \"\",\n invitation: \"\",\n boardBody: \"\",\n boardCta: \"\",\n },\n};\n\n/**\n * The cross-surface cold start, derived from the fetched registers. Cold when\n * no assumptions exist; warm otherwise. Pure — the surfaces branch on `cold`\n * and read the copy off the result.\n */\nexport function coldStartFor(records: NextMoveRecords): ColdStart {\n return records.assumptions.length === 0 ? COLD_START : WARM_START;\n}\n\n/**\n * The journey's no-history cold state. Cold when the belief's story has only\n * the two structural events (the `bet` it opened with and the `now` that\n * anchors today) — no score, no test, no reading, no confidence-cross. The\n * rail still renders honestly (its real framing % and 0/0 tests); this only\n * shapes the story's copy so a founder with one fresh belief isn't shown two\n * sparse events with nothing between.\n *\n * The body names the belief's own next move in plain language when one exists,\n * so the cold state still points forward.\n */\nexport function journeyColdState(\n journey: JourneyView,\n): JourneyColdState {\n const evidenceEvents = journey.events.filter(\n (e) => e.kind !== \"bet\" && e.kind !== \"now\",\n );\n const cold = evidenceEvents.length === 0;\n if (!cold) {\n return { cold: false, eyebrow: \"\", body: \"\" };\n }\n const move = journey.nextMove;\n const body = move\n ? `${move.reason} Your next move: ${movePresentation(move.move).cta.toLowerCase()} — the dashboard takes it from there.`\n : \"No evidence has landed yet. Score its impact, then design a test to start moving it.\";\n return {\n cold: true,\n eyebrow: \"No evidence yet\",\n body,\n };\n}\n","/**\n * The portfolio pipeline's view-model (OPS-1300) — pure, no React, no I/O, so\n * the whole \"where does everything stand\" mapping is unit-tested at this seam\n * (like `understanding.ts` for the drawer). It joins the assumption, reading\n * and experiment registers into: one row per live belief carrying the four\n * loop meters (Framed → Planned → Tested → Known) and its stage-aware next\n * move, the resolved beliefs set apart, and the portfolio burn-up headline.\n *\n * Every number is derived through `@validation-os/core` — the stored per-belief\n * derived numbers, `assumptionCompleteness` for Framed, and `portfolioProgress`\n * for the cross-belief roll-up — so the pipeline reconciles with the drawer and\n * the agent, and computes fresh on read.\n */\nimport {\n assumptionCompleteness,\n readingBeliefInputs,\n type AnyRecord,\n type BarLine,\n type BeliefReadingInput,\n} from \"@validation-os/core\";\nimport {\n beliefRisk,\n beliefTestMeters,\n confidence,\n deriveBeliefStage,\n portfolioProgress,\n risk as riskOf,\n type PortfolioBeliefInput,\n type PortfolioProgress,\n type StageExperimentInput,\n type StageKey,\n type TestMeter,\n} from \"@validation-os/core/derivation\";\nimport { liveExperiments } from \"./derived-views.js\";\nimport { riskLevel, type Tone } from \"./primitives.js\";\n\n/** The four loop stages a belief travels, in order (OPS-1293). */\nexport type { StageKey };\n\n/** One live belief's row on the board. */\nexport interface PipelineRow {\n id: string;\n statement: string;\n /** Derived Impact — shown only as a faint bar (machinery, not the move). */\n impact: number;\n risk: number;\n /** crit / warn / good — the severity stripe, risk number and bar tone. */\n riskTone: Extract<Tone, \"crit\" | \"warn\" | \"good\">;\n confidence: number;\n /** Sign bucket for the confidence chip / Known gauge direction. */\n confSign: \"pos\" | \"neg\" | \"zero\";\n /** Conf ≤ −50 — the Known meter flips to a red re-test flag. */\n killZone: boolean;\n /** Meter 1 — framing completeness, 0–100. */\n framed: number;\n /** Meter 2 — a test with a bar line naming this belief has been designed. */\n planned: boolean;\n /** Meter 3 — pre-registered bars settled / total, across all experiments. */\n tested: { settled: number; total: number };\n /** The stage-aware verb the front door offers (navigates to the record). */\n nextMove: string;\n}\n\n/** A belief taken off the board — killed (Invalidated) or made moot. */\nexport interface ResolvedRow {\n id: string;\n statement: string;\n kind: \"killed\" | \"moot\";\n /** Risk retired by resolving it. */\n retired: number;\n}\n\nexport interface PipelineView {\n /** Live beliefs, riskiest first. */\n rows: PipelineRow[];\n /** Resolved beliefs, set apart. */\n resolved: ResolvedRow[];\n /** The burn-up headline: identified / retired / live / percent. */\n progress: PortfolioProgress;\n /** Σ risk retired across the resolved set — the disclosure's summary. */\n resolvedRetired: number;\n}\n\nfunction num(v: unknown): number {\n const n = Number(v);\n return Number.isFinite(n) ? n : 0;\n}\n\nfunction str(v: unknown): string {\n return typeof v === \"string\" ? v : \"\";\n}\n\n/** The three stored derived numbers off an assumption record. */\nfunction derivedOf(rec: AnyRecord): {\n derivedImpact: number;\n risk: number;\n confidence: number;\n} {\n const d = (rec.derived ?? {}) as Record<string, unknown>;\n return {\n derivedImpact: num(d.derivedImpact),\n risk: num(d.risk),\n confidence: num(d.confidence),\n };\n}\n\n/** killed = Invalidated, moot = the moot flag; moot wins if somehow both. */\nexport function resolvedKind(rec: AnyRecord): \"killed\" | \"moot\" | null {\n if (rec.moot === true) return \"moot\";\n if (rec.Status === \"Invalidated\") return \"killed\";\n return null;\n}\n\n/**\n * Reduce an experiment record to the shape the shared meter logic reads: each\n * bar line naming a belief (with whether it has settled) plus the convenience\n * projection. Shared with the journey view-model so the board and a belief's\n * rail derive test state one way.\n */\nexport function toStageExperimentInput(exp: AnyRecord): StageExperimentInput {\n const bars = (exp.barLines as BarLine[] | undefined) ?? [];\n return {\n bars: bars.map((b) => ({\n assumptionId: b.assumptionId,\n settled: typeof b.barVerdict === \"string\" && b.barVerdict.trim() !== \"\",\n })),\n plannedAssumptionIds:\n (exp.barLineAssumptionIds as string[] | undefined) ?? [],\n };\n}\n\n/**\n * The stage-aware next move — the same ladder the prototype walks, now driven\n * by the shared stage classification plus the kill-zone overlay.\n */\nfunction nextMove(stage: StageKey, killZone: boolean): string {\n if (killZone) return \"Decide / kill\";\n switch (stage) {\n case \"framed\":\n return \"Finish framing\";\n case \"planned\":\n return \"Design test\";\n case \"tested\":\n return \"Record reading\";\n case \"known\":\n return \"Decide / bank it\";\n }\n}\n\n/**\n * Build the whole board from the three registers. Pass the full assumption\n * register (resolved rows included) — `portfolioProgress` needs the whole set\n * or the burn-up denominator understates.\n */\nexport function buildPipeline(\n assumptions: AnyRecord[],\n experiments: AnyRecord[],\n): PipelineView {\n // \"Evidence ≠ tested\" (OPS-1305): a belief's Planned / Tested stage is driven\n // by a LIVE plan's bar lines, never by whether readings exist. Archived plans\n // are dropped here, so a belief whose only plan is archived (or that has bare\n // readings but no live plan) reads as Framed → \"Design test\", not Tested.\n const tests = beliefTestMeters(\n liveExperiments(experiments).map(toStageExperimentInput),\n );\n\n const rows: PipelineRow[] = [];\n const resolved: ResolvedRow[] = [];\n const portfolioInput: PortfolioBeliefInput[] = [];\n let resolvedRetired = 0;\n\n for (const a of assumptions) {\n const d = derivedOf(a);\n const kind = resolvedKind(a);\n const input: PortfolioBeliefInput = {\n id: a.id,\n derivedImpact: d.derivedImpact,\n seedImpact: a.Impact == null ? null : num(a.Impact),\n risk: d.risk,\n resolved: kind !== null,\n };\n portfolioInput.push(input);\n\n if (kind) {\n const retired = beliefRisk(input).retired;\n resolvedRetired += retired;\n resolved.push({\n id: a.id,\n statement: str(a.Title),\n kind,\n retired,\n });\n continue;\n }\n\n const test: TestMeter = tests.get(a.id) ?? {\n planned: false,\n settled: 0,\n total: 0,\n };\n const framed = assumptionCompleteness(a as Record<string, unknown>);\n const stage = deriveBeliefStage({ framed, confidence: d.confidence, test });\n rows.push({\n id: a.id,\n statement: str(a.Title),\n impact: d.derivedImpact,\n risk: d.risk,\n riskTone: riskLevel(d.risk) as PipelineRow[\"riskTone\"],\n confidence: stage.confidence,\n confSign: stage.confSign,\n killZone: stage.killZone,\n framed: stage.framed,\n planned: stage.planned,\n tested: stage.tested,\n nextMove: nextMove(stage.stage, stage.killZone),\n });\n }\n\n // Riskiest first; ties broken toward the more-negative Confidence, then id,\n // so the order is stable.\n rows.sort(\n (a, b) =>\n b.risk - a.risk ||\n a.confidence - b.confidence ||\n a.id.localeCompare(b.id),\n );\n\n return {\n rows,\n resolved,\n progress: portfolioProgress(portfolioInput),\n resolvedRetired: Math.round(resolvedRetired),\n };\n}\n\n/**\n * The headline's \"this week\" delta, in percentage points, or null when it\n * can't be told honestly. It time-travels through the readings' own dates:\n * recompute every belief's Confidence (and thus Risk) from only the readings\n * dated on or before a cutoff, roll the portfolio up at \"now\" and at a week\n * ago, and report the change. Structure and resolved-status are held at their\n * current value (the system keeps no history of those), so this is the\n * evidence-driven movement, not a full snapshot diff — hence \"this week\" reads\n * as \"what landing evidence moved\", which is the honest claim.\n *\n * Returns null when no reading carries a parseable date (nothing to travel\n * through) — the surface then simply omits the delta rather than inventing one.\n */\nexport function weekOverWeekDelta(\n assumptions: AnyRecord[],\n readings: AnyRecord[],\n now: Date,\n): number | null {\n const anyDated = readings.some((r) => {\n const t = Date.parse(str(r.Date));\n return !Number.isNaN(t);\n });\n if (!anyDated) return null;\n\n const cutoff = now.getTime() - 7 * 24 * 60 * 60 * 1000;\n // Fan every reading row out into one input per belief, then group by the\n // belief it scores — a single row can now score several beliefs (OPS-1305).\n const byAssumption = new Map<string, BeliefReadingInput[]>();\n for (const input of readings.flatMap(readingBeliefInputs)) {\n if (!input.assumptionId) continue;\n const arr = byAssumption.get(input.assumptionId);\n if (arr) arr.push(input);\n else byAssumption.set(input.assumptionId, [input]);\n }\n\n const percentAsOf = (limit: number | null): number => {\n const inputs: PortfolioBeliefInput[] = assumptions.map((a) => {\n const d = derivedOf(a);\n const mine = (byAssumption.get(a.id) ?? []).filter((i) => {\n if (limit === null) return true;\n const t = Date.parse(i.date ?? \"\");\n return !Number.isNaN(t) && t <= limit;\n });\n const conf = confidence(mine);\n return {\n id: a.id,\n derivedImpact: d.derivedImpact,\n seedImpact: a.Impact == null ? null : num(a.Impact),\n risk: riskOf(d.derivedImpact, conf),\n resolved: resolvedKind(a) !== null,\n };\n });\n return portfolioProgress(inputs).percent;\n };\n\n return Math.round(percentAsOf(null) - percentAsOf(cutoff));\n}\n","/**\n * Recommended experiments (DEV-5882) — a UI-side derivation from the assumption\n * register, not a stored entity. For each cluster of risk-related assumptions\n * that share a Lens × Stage and lack a *live* experiment testing them, propose\n * one experiment (Test / Observation / Desk research / Survey) with a bar\n * preview. The user can \"Accept\" to create the experiment.\n *\n * Pure: no I/O, no React. The surface mounts thinly over this. Clusters are\n * ranked by max risk (riskiest first), so the board's \"Recommended\n * experiments\" section leads with the test that buys down the most risk.\n */\nimport type { AnyRecord } from \"@validation-os/core\";\nimport { derivedNum, str } from \"./derived-views.js\";\n\nexport type RecommendedExperimentType =\n | \"Test\"\n | \"Observation\"\n | \"Desk research\"\n | \"Survey\";\n\nexport interface RecommendedExperiment {\n /** Stable id derived from the cluster's assumption ids (so React keys are stable). */\n id: string;\n /** The experiment type — picked from the lens's do-rungs when the cluster has no evidence. */\n type: RecommendedExperimentType;\n /** One-line title, e.g. \"Test 2 Consumer · Discovery beliefs\". */\n title: string;\n /** The assumption ids this experiment would test. */\n assumptionIds: string[];\n /** The max risk across the cluster's assumptions — drives ranking. */\n maxRisk: number;\n /** Why this test, in plain language. */\n rationale: string;\n /** The pre-registered bar preview (\"Right if: …\"). */\n barPreview: string;\n /** The generated experiment body — a protocol with questions, what it tests, how to run it. */\n body: string;\n /** The lens this cluster belongs to — for tagging. */\n lens: string;\n /** Display colour for the lens tag. */\n lensColour: string;\n}\n\n/** The max number of recommended experiments to show (one per lens, up to 3). */\nexport const MAX_RECOMMENDED = 3;\n\n/** The max assumptions per cluster (tight groups, not whole cells). */\nconst MAX_CLUSTER_SIZE = 3;\n\n/** The max number of \"needs framing\" assumptions to show (one per lens, up to 3). */\nexport const MAX_NEEDS_FRAMING = 3;\n\n/** Lens display colours — one per lens for clear tagging. */\nconst LENS_COLOUR: Record<string, string> = {\n Consumer: \"#8b83f5\",\n Commercial: \"#38c793\",\n Investor: \"#e6a23c\",\n};\n\n/**\n * The \"needs framing\" list — the riskiest live, non-moot assumption *per lens*\n * whose completeness is below 100% (the belief is written but not fully framed:\n * missing the 5 Whys, the metric for truth, or the scoring justification).\n * These are the beliefs where the next move is \"frame the belief\", not \"design\n * an experiment\". At most one assumption per lens, capped at MAX_NEEDS_FRAMING\n * (3 lenses), riskiest-first across lenses.\n */\nexport interface NeedsFramingItem {\n id: string;\n title: string;\n risk: number;\n completeness: number;\n lens: string;\n stage: string;\n /** What's missing — a plain-language hint. */\n hint: string;\n /** Display colour for the lens tag. */\n lensColour: string;\n}\n\nexport function buildNeedsFraming(\n assumptions: AnyRecord[],\n): NeedsFramingItem[] {\n const live = assumptions.filter((a) => {\n const status = str(a.Status);\n const moot = a.moot === true;\n return !moot && (status === \"Live\" || status === \"Draft\");\n });\n\n const items = live\n .map((a) => {\n const id = str(a.id) ?? \"\";\n const completeness = derivedNum(a, \"completeness\") ?? 0;\n const risk = derivedNum(a, \"risk\") ?? 0;\n const lens = str(a.Lens) ?? \"—\";\n const stage = str(a.Stage) ?? \"—\";\n const title = str(a.Title) ?? id;\n const hint = framingHint(a, completeness);\n const lensColour = LENS_COLOUR[lens] ?? LENS_COLOUR[\"Investor\"] ?? \"#6b7484\";\n return { id, title, risk, completeness, lens, stage, hint, lensColour };\n })\n .filter((a) => a.completeness < 100);\n\n // Group by lens; from each lens pick the riskiest unframed assumption.\n // Then take up to MAX_NEEDS_FRAMING lenses, riskiest-first across lenses.\n const byLens = new Map<string, NeedsFramingItem>();\n for (const item of items) {\n const existing = byLens.get(item.lens);\n if (!existing || item.risk > existing.risk) {\n byLens.set(item.lens, item);\n }\n }\n\n return [...byLens.values()]\n .sort((a, b) => b.risk - a.risk)\n .slice(0, MAX_NEEDS_FRAMING);\n}\n\nfunction framingHint(a: AnyRecord, completeness: number): string {\n const hasScoring = Boolean(str(a[\"Scoring justification\"]));\n const hasDescription = Boolean(str(a.Description));\n if (completeness < 50) {\n return hasDescription\n ? \"The belief is written but incomplete — fill in the scoring justification and any missing framing fields.\"\n : \"The belief needs a description — what exactly is being claimed, in falsifiable terms.\";\n }\n if (!hasScoring) {\n return \"Add a scoring justification — why is the Impact seed scored as it is?\";\n }\n return \"Nearly framed — check the 5 Whys and the metric for truth are complete.\";\n}\n\n/**\n * The lens → do-rung mapping (DEV-5879 spec). The lens determines which \"do\"\n * rungs are available; Talk + Desk work for any lens. This is a grading\n * guideline, not a schema constraint. The recommended-experiment type is\n * picked from the lens's first do-rung when the cluster has no evidence:\n *\n * Consumer → Observation (Observed usage)\n * Commercial → Test (Signed intent)\n * any other lens → Desk research (the safe default)\n */\nconst LENS_TO_TYPE: Record<string, RecommendedExperimentType> = {\n Consumer: \"Observation\",\n Commercial: \"Test\",\n};\n\n/**\n * Build recommended experiments from the assumption + experiment registers.\n *\n * A cluster is a TIGHT group of the riskiest live, non-moot assumptions sharing\n * a Lens × Stage pair, none of which has a *live* (non-Archived) experiment\n * testing it. One recommended experiment per cluster, max 3 assumptions per\n * cluster (the riskiest ones), max 2 recommendations total (the riskiest\n * clusters). Each recommendation carries a generated experiment body — a\n * protocol with what it tests, how to run it, and the questions to ask.\n */\nexport function buildRecommendedExperiments(\n assumptions: AnyRecord[],\n experiments: AnyRecord[],\n): RecommendedExperiment[] {\n const liveAssumptions = assumptions.filter((a) => {\n const status = str(a.Status);\n const moot = a.moot === true;\n return !moot && (status === \"Live\" || status === \"Draft\");\n });\n\n // The set of assumption ids that already have a *live* experiment testing\n // them — those are covered, not candidates for a recommendation.\n const testedByLive = new Set<string>();\n for (const e of experiments) {\n const status = str(e.Status);\n if (status === \"Archived\") continue;\n const ids = Array.isArray(e.barLineAssumptionIds)\n ? (e.barLineAssumptionIds as string[])\n : [];\n for (const id of ids) testedByLive.add(id);\n }\n\n // Cluster by Lens × Stage, keeping only assumptions not covered by a live\n // experiment. Then take the riskiest MAX_CLUSTER_SIZE per cluster.\n const clusters = new Map<string, AnyRecord[]>();\n for (const a of liveAssumptions) {\n const id = str(a.id) ?? \"\";\n if (testedByLive.has(id)) continue;\n const lens = str(a.Lens) ?? \"—\";\n const stage = str(a.Stage) ?? \"—\";\n const key = `${lens}×${stage}`;\n const bucket = clusters.get(key);\n if (bucket) bucket.push(a);\n else clusters.set(key, [a]);\n }\n\n // Rank assumptions within each cluster by risk, keep the top 3.\n // Then pick one cluster per lens (the riskiest), ranked by max risk.\n const rankedClusters = [...clusters.entries()]\n .map(([key, cluster]) => {\n const ranked = cluster\n .sort((a, b) => (derivedNum(b, \"risk\") ?? 0) - (derivedNum(a, \"risk\") ?? 0))\n .slice(0, MAX_CLUSTER_SIZE);\n const maxRisk = Math.max(...ranked.map((a) => derivedNum(a, \"risk\") ?? 0), 0);\n return { key, cluster: ranked, maxRisk };\n })\n .sort((a, b) => b.maxRisk - a.maxRisk);\n\n const byLens = new Map<string, typeof rankedClusters[0]>();\n for (const entry of rankedClusters) {\n const lens = entry.key.split(\"×\")[0] ?? \"—\";\n if (!byLens.has(lens)) byLens.set(lens, entry);\n }\n const clusterEntries = [...byLens.values()]\n .sort((a, b) => b.maxRisk - a.maxRisk)\n .slice(0, MAX_RECOMMENDED);\n\n const recs: RecommendedExperiment[] = [];\n for (const { key, cluster, maxRisk } of clusterEntries) {\n const lens = key.split(\"×\")[0] ?? \"—\";\n const stage = key.split(\"×\")[1] ?? \"—\";\n const assumptionIds = cluster\n .map((a) => str(a.id) ?? \"\")\n .filter(Boolean)\n .sort();\n const type = LENS_TO_TYPE[lens ?? \"\"] ?? \"Desk research\";\n const title =\n cluster.length === 1\n ? `Test ${assumptionIds[0]}`\n : `Test ${cluster.length} ${lens} · ${stage} beliefs`;\n const rationale =\n cluster.length === 1\n ? `One belief (${assumptionIds[0]}) at ${Math.round(maxRisk)} risk with no live test. Designing an experiment here would buy down the most risk.`\n : `${cluster.length} beliefs share ${lens} · ${stage}, the riskiest at ${Math.round(maxRisk)} risk. One experiment can address them all.`;\n const barPreview = `The riskiest belief moves out of the kill zone, or stays in it.`;\n const body = generateExperimentBody(type, lens, stage, cluster, maxRisk);\n const lensColour = LENS_COLOUR[lens] ?? LENS_COLOUR[\"Investor\"] ?? \"#6b7484\";\n recs.push({\n id: assumptionIds.join(\"+\"),\n type,\n title,\n assumptionIds,\n maxRisk,\n rationale,\n barPreview,\n body,\n lens,\n lensColour,\n });\n }\n\n // Riskiest first; stable tie-break by id.\n recs.sort((a, b) =>\n a.maxRisk !== b.maxRisk\n ? b.maxRisk - a.maxRisk\n : a.id.localeCompare(b.id),\n );\n\n return recs;\n}\n\n/**\n * Generate a plain-language experiment body — a protocol with what it tests,\n * how to run it, and the questions to ask. This is a UI-side draft, not a\n * stored entity; the user accepts it to create the experiment (and can edit\n * the body before running).\n */\nfunction generateExperimentBody(\n type: RecommendedExperimentType,\n lens: string,\n stage: string,\n cluster: AnyRecord[],\n maxRisk: number,\n): string {\n const beliefs = cluster\n .map((a) => `- **${str(a.id)}**: ${str(a.Title) ?? str(a.id) ?? \"\"}`)\n .join(\"\\n\");\n const rung = type === \"Observation\" ? \"Observed usage\" : type === \"Test\" ? \"Signed intent\" : \"Desk research\";\n\n return `## What this tests\n\nThis ${type.toLowerCase()} addresses ${cluster.length} ${lens} · ${stage} belief${cluster.length === 1 ? \"\" : \"s\"} at ${Math.round(maxRisk)} risk — the riskiest untested cluster on the board.\n\n${beliefs}\n\n## How to run it\n\n${\n type === \"Observation\"\n ? `Set up a prototype or analytics instrument that captures real user behaviour. Watch how ${cluster.length === 1 ? \"this belief plays out\" : \"these beliefs play out\"} in actual usage — not what people say they'd do, but what they actually do. Log each observation as evidence at the **${rung}** rung.`\n : type === \"Test\"\n ? `Reach out to potential ${lens === \"Consumer\" ? \"customers\" : \"businesses\"} and seek a signed commitment — a letter of intent, a pre-order, a pilot agreement. The commitment is the evidence; it lands at the **${rung}** rung.`\n : `Research published sources, competitor behaviour, and market data. Find external evidence that bears on ${cluster.length === 1 ? \"this belief\" : \"these beliefs\"}. Log each source as evidence at the **Desk research** rung.`\n}\n\n## Questions to answer\n\n${cluster.map((a, i) => `${i + 1}. Does ${str(a.Title) ?? str(a.id) ?? \"\"} hold — or does the evidence break it?`).join(\"\\n\")}\n\n## Pre-registered bars\n\n- **Right if:** the riskiest belief moves out of the kill zone (Confidence > 0).\n- **Wrong if:** the evidence invalidates the riskiest belief (Confidence enters the kill zone).\n`;\n}","/**\n * The four loop meters as data — the Framed → Planned → Tested → Known spine\n * turned into captions and fills, once (OPS-1330).\n *\n * Two surfaces draw the same four meters for one belief: the pipeline board's\n * row (OPS-1300, the cross-belief altitude) and the journey rail (this ticket,\n * the same spine zoomed to one belief). The *classification* is already shared\n * in core (`deriveBeliefStage`, OPS-1329); this shares the layer above it — what\n * each meter is captioned and how full it reads — so a board row and a rail can\n * never disagree about a belief while looking at the same numbers.\n *\n * Only the mapping is shared, not the markup: each surface renders these its own\n * way (the board as a compact horizontal track, the rail as the labelled spine).\n * Pure, so the captions are unit-tested here rather than through two DOMs.\n */\nimport type { ConfSign, StageKey } from \"@validation-os/core/derivation\";\nimport { formatSigned } from \"./primitives.js\";\n\n/**\n * How a meter fills: `fill` runs left→right (0–100%); `signed` is anchored at\n * the middle and leans by sign — the Known gauge, which never \"completes\".\n */\nexport type MeterKind = \"fill\" | \"signed\";\n\n/** One meter, ready to render. */\nexport interface StageMeterView {\n /** Its place on the spine, \"1\"–\"4\" — the caption's index. */\n n: string;\n /** The stage it meters. */\n key: StageKey;\n /** Its display name — \"Framed\", \"Planned\", \"Tested\", \"Known\". */\n name: string;\n /** The caption: \"Framed 60%\", \"No test\", \"Tested 1/3\", \"Known +40\". */\n label: string;\n /**\n * How full it reads, as a percentage of the track. A `signed` meter fills\n * from the midpoint, so its span is 0–50 (a full lean is half the track).\n */\n pct: number;\n /** Nothing has happened on this meter yet — the caption reads muted. */\n muted: boolean;\n kind: MeterKind;\n /** Replaces the caption when set — the Known meter's kill-zone re-test flag. */\n flag?: string;\n /** Which way a `signed` meter leans. */\n sign?: ConfSign;\n}\n\n/**\n * The meter fields a belief carries. Both `BeliefStage` (the rail) and\n * `PipelineRow` (the board) satisfy this structurally, so neither has to be\n * converted before rendering.\n */\nexport interface StageMeterInput {\n framed: number;\n planned: boolean;\n tested: { settled: number; total: number };\n confidence: number;\n confSign: ConfSign;\n killZone: boolean;\n}\n\nfunction clamp(pct: number): number {\n if (!Number.isFinite(pct)) return 0;\n return Math.max(0, Math.min(100, pct));\n}\n\n/**\n * One belief's four meters, in spine order. Nothing is derived here — the\n * numbers arrive already computed (`deriveBeliefStage`); this only decides how\n * each one reads.\n */\nexport function stageMeters(input: StageMeterInput): StageMeterView[] {\n const { framed, planned, tested, confidence, confSign, killZone } = input;\n return [\n {\n n: \"1\",\n key: \"framed\",\n name: \"Framed\",\n label: `Framed ${framed}%`,\n pct: clamp(framed),\n muted: framed < 100,\n kind: \"fill\",\n },\n {\n n: \"2\",\n key: \"planned\",\n name: \"Planned\",\n label: planned ? \"Planned\" : \"No test\",\n pct: planned ? 100 : 0,\n muted: !planned,\n kind: \"fill\",\n },\n {\n n: \"3\",\n key: \"tested\",\n name: \"Tested\",\n label: tested.total\n ? `Tested ${tested.settled}/${tested.total}`\n : \"Untested\",\n pct: tested.total\n ? clamp(Math.round((tested.settled / tested.total) * 100))\n : 0,\n muted: tested.total === 0,\n kind: \"fill\",\n },\n {\n n: \"4\",\n key: \"known\",\n name: \"Known\",\n label: `Known ${formatSigned(confidence)}`,\n // A full lean is half the track — the gauge is anchored at zero and\n // signed, so it reads direction, not completion (it never \"completes\").\n pct: Math.min(50, (Math.abs(confidence) / 100) * 50),\n muted: confSign === \"zero\",\n kind: \"signed\",\n sign: confSign,\n // In the kill zone the caption gives way to the flag: the number stops\n // being the point once the evidence has turned.\n ...(killZone ? { flag: \"re-test\" } : {}),\n },\n ];\n}\n","/**\n * The Lens × Stage heatmap view-model (docs/stage-policy.md §The dashboard\n * surface) — pure, no React, no I/O, so the grid's shape and the drill-\n * through's Risk-ranked list are unit-tested at this seam (like\n * `pipeline.ts` / `journey.ts` / `next-move.ts`).\n *\n * The grid is the **filter**, Risk is the **rank**. Where the pipeline board\n * reads \"where every belief stands\" row-by-row, this reads the same beliefs\n * cross-tabbed by Lens (the actor — who the belief is about) × Stage (the\n * kind of response — engage / pay / scale / defend). The densest cell per\n * row is where that part of the business is — no flag, no declaration, the\n * density tells you. Click a cell → the assumptions in it, ranked by Risk.\n *\n * Pure and computed fresh on read (like `pipeline.ts`): it only reads numbers\n * already kept current (`derived.risk`), so it stays out of the OPS-1251\n * on-write recompute. The Lens list comes from the caller (the surface\n * supplies the workspace's configured vocabulary); the Stage list is fixed\n * (the four discovery stages — see `ontology.yaml §vocabularies.stage`).\n */\nimport type { AnyRecord } from \"@validation-os/core\";\nimport { derivedNum, str } from \"./derived-views.js\";\n\n/** The four discovery stages, in their canonical ordinal order (1→4). The\n * stored value is the name; the ordinal is for sort/display only. */\nexport const STAGE_ORDER = [\n \"Discovery\",\n \"Validation\",\n \"Scale\",\n \"Maturity\",\n] as const;\nexport type StageValue = (typeof STAGE_ORDER)[number];\n\n/** A short, plain-language gloss for each stage — the column header's\n * subtitle and the cell tooltip. Drawn from docs/stage-policy.md. */\nexport const STAGE_GLOSS: Record<StageValue, string> = {\n Discovery: \"Problem-solution fit — will they engage, care, disclose?\",\n Validation: \"Product-market fit — will they pay, sign, stay?\",\n Scale: \"Growth — can we acquire efficiently, does CAC<LTV hold at volume?\",\n Maturity: \"Defense — will incumbents respond, will regulators accept?\",\n};\n\n/** One cell of the Lens × Stage grid. */\nexport interface StageGridCell {\n /** The Lens (row) this cell sits under. */\n lens: string;\n /** The Stage (column) this cell sits under — one of the four canonical\n * stages, or the `NO_STAGE` (\"—\") sentinel for records with no/invalid\n * Stage (the gate-leakage bucket, only emitted when needed). */\n stage: StageValue | typeof NO_STAGE;\n /** How many assumptions hold this Lens × Stage pair. */\n count: number;\n /** The assumptions in this cell, ranked by Risk (highest first). Empty\n * when `count` is 0. The rank is the cell's drill-through order. */\n assumptions: AnyRecord[];\n /** Density in [0, 1] — `count / maxCellCount` across the whole grid, for\n * the heatmap colour scale. 0 for an empty cell. */\n density: number;\n}\n\n/** The grid view-model — rows per Lens, columns per Stage, cells with counts\n * and Risk-ranked drill-through lists. */\nexport interface StageGridView {\n /** The Lens values, in first-appearance order (the configured vocabulary\n * order is the caller's job; the grid keeps the order it sees). Includes\n * a trailing \"—\" row for assumptions with no Lens set. */\n lenses: string[];\n /** The four stages in their canonical ordinal order. */\n stages: StageValue[];\n /** One cell per (lens, stage) pair, in row-major order: lens-first,\n * stage-within-lens. */\n cells: StageGridCell[];\n /** The maximum cell count across the grid — what `density` is normalised\n * against. 0 when the grid is empty. */\n maxCellCount: number;\n /** Total assumptions counted in the grid (every cell's count summed).\n * Equal to the input length minus any rows with neither Lens nor Stage\n * set, which fall in the \"—\" row / \"—\" cell. */\n total: number;\n}\n\nconst NO_LENS = \"—\";\nconst NO_STAGE = \"—\";\n\n/** A stage value from a record, validated against the fixed vocabulary.\n * Returns null for an empty or unrecognised value — the caller decides\n * whether to bucket those or drop them. */\nexport function stageOf(record: AnyRecord): StageValue | null {\n const v = str(record.Stage);\n if (!v) return null;\n return (STAGE_ORDER as readonly string[]).includes(v)\n ? (v as StageValue)\n : null;\n}\n\n/** Sort a list of assumptions by Risk, highest first. Stable on tie by id —\n * matches the pipeline board's \"riskiest first\" convention. Pure: returns a\n * new array, leaves the input alone. */\nexport function rankByRisk(records: AnyRecord[]): AnyRecord[] {\n return [...records]\n .map((r) => ({ r, risk: derivedNum(r, \"risk\") ?? 0 }))\n .sort((a, b) =>\n a.risk !== b.risk ? b.risk - a.risk : a.r.id.localeCompare(b.r.id),\n )\n .map((x) => x.r);\n}\n\n/**\n * Build the Lens × Stage grid from the assumption register. Pure — no I/O,\n * no React. The Lens list is read off the records in first-appearance order\n * (the configured vocabulary order is the caller's concern; the grid keeps\n * what it sees, so a workspace with no Commercial-stage-4 bets simply shows\n * a 0 cell, never a missing row). A record with no Lens set falls into a\n * trailing \"—\" row; a record with no Stage set (or an unrecognised Stage)\n * falls into a trailing \"—\" column. The \"—\"/\"—\" cell holds the records the\n * gate would have caught — write-time enforcement is the gate's job, this\n * just surfaces them honestly.\n *\n * The \"—\" row and \"—\" column are **only emitted when needed** — i.e. when at\n * least one record has a missing Lens (resp. Stage). A clean register\n * renders a pure Lens × 4-Stage matrix; a register with gate-leakage gets\n * the diagnostic row/column added. This keeps the matrix rectangular and\n * matches the spec (\"if a claim doesn't fit any stage, it falls out\" — the\n * \"—\" column is a diagnostic, not a feature).\n *\n * Each cell's `assumptions` list is ranked by Risk (highest first), so the\n * drill-through reads \"the riskiest belief in this cell\" first — the grid is\n * the filter, Risk is the rank. `density` is `count / maxCellCount` across\n * the whole grid, for the heatmap colour scale; an empty cell reads 0.\n */\nexport function buildStageGrid(assumptions: AnyRecord[]): StageGridView {\n // Lens order: first-appearance, with \"—\" last (only if needed).\n const lensOrder: string[] = [];\n const seenLens = new Set<string>();\n const pushLens = (lens: string) => {\n if (!seenLens.has(lens)) {\n seenLens.add(lens);\n lensOrder.push(lens);\n }\n };\n\n // Bucket every assumption into (lens, stage).\n const buckets = new Map<string, Map<StageValue | typeof NO_STAGE, AnyRecord[]>>();\n const ensureLens = (lens: string): Map<StageValue | typeof NO_STAGE, AnyRecord[]> => {\n let m = buckets.get(lens);\n if (!m) {\n m = new Map();\n buckets.set(lens, m);\n }\n return m;\n };\n\n let hasNoLens = false;\n let hasNoStage = false;\n for (const a of assumptions) {\n const lens = str(a.Lens) ?? NO_LENS;\n const stage = stageOf(a) ?? NO_STAGE;\n if (lens === NO_LENS) hasNoLens = true;\n if (stage === NO_STAGE) hasNoStage = true;\n pushLens(lens);\n const byStage = ensureLens(lens);\n let list = byStage.get(stage);\n if (!list) {\n list = [];\n byStage.set(stage, list);\n }\n list.push(a);\n }\n\n // \"—\" lens row goes last.\n if (hasNoLens) {\n lensOrder.splice(lensOrder.indexOf(NO_LENS), 1);\n lensOrder.push(NO_LENS);\n } else {\n // No record needed a \"—\" row — drop it from the lens order so the grid\n // renders a pure Lens × Stage matrix.\n const idx = lensOrder.indexOf(NO_LENS);\n if (idx >= 0) lensOrder.splice(idx, 1);\n }\n\n // Stage order: the four canonical stages, then \"—\" last (only if needed).\n const stageOrder: (StageValue | typeof NO_STAGE)[] = [...STAGE_ORDER];\n if (hasNoStage) stageOrder.push(NO_STAGE);\n\n const cells: StageGridCell[] = [];\n let maxCellCount = 0;\n let total = 0;\n for (const lens of lensOrder) {\n const byStage = buckets.get(lens) ?? new Map();\n for (const stage of stageOrder) {\n const records = byStage.get(stage) ?? [];\n const ranked = rankByRisk(records);\n const count = ranked.length;\n maxCellCount = Math.max(maxCellCount, count);\n total += count;\n cells.push({\n lens,\n stage,\n count,\n assumptions: ranked,\n // density filled in a second pass once maxCellCount is known.\n density: 0,\n });\n }\n }\n\n // Second pass: normalise density against the grid's max cell count.\n const norm = maxCellCount > 0 ? 1 / maxCellCount : 0;\n for (const cell of cells) {\n cell.density = cell.count * norm;\n }\n\n return {\n lenses: lensOrder,\n stages: [...STAGE_ORDER],\n cells,\n maxCellCount,\n total,\n };\n}\n\n/** The cell at a given (lens, stage) — null if no such cell (e.g. a stage\n * not in the canonical order). The \"—\" row / \"—\" column are addressable\n * with the `NO_LENS` / `NO_STAGE` sentinels. */\nexport function cellAt(\n view: StageGridView,\n lens: string,\n stage: StageValue | typeof NO_STAGE,\n): StageGridCell | null {\n return view.cells.find((c) => c.lens === lens && c.stage === stage) ?? null;\n}\n\n/** Export the sentinel so the surface can address the \"no lens\" / \"no stage\"\n * buckets without hard-coding the em dash. */\nexport { NO_LENS, NO_STAGE };","import { useMemo, useState } from \"react\";\nimport type { AnyRecord, BarLine, Result } from \"@validation-os/core\";\nimport { Breadcrumb } from \"./breadcrumb.js\";\nimport { readingBeliefs } from \"./derived-views.js\";\nimport { EvidenceBody } from \"./markdown.js\";\nimport { formatSigned } from \"./primitives.js\";\nimport { ConfidenceDonut } from \"./confidence-donut.js\";\nimport type { Route } from \"./route.js\";\nimport { useList } from \"./use-records.js\";\n\n/**\n * The evidence-first experiment detail (DEV-5884): readings lead, each showing\n * date, title, and a single set of per-belief verdict cards (assumption link,\n * verdict, rung, grading rationale, bar-line context). Unstarted bars (bars\n * with no readings yet) are in a separate section below with dashed outlines.\n */\nexport interface ExperimentDetailProps {\n experimentId: string;\n basePath?: string;\n onNavigate: (route: Route) => void;\n}\n\nexport function ExperimentDetail({\n experimentId,\n basePath,\n onNavigate,\n}: ExperimentDetailProps) {\n const experiments = useList(\"experiments\", basePath);\n const readings = useList(\"readings\", basePath);\n const assumptions = useList(\"assumptions\", basePath);\n\n const loading = experiments.loading && !experiments.records;\n\n const experiment = useMemo(\n () => (experiments.records ?? []).find((e) => String(e.id) === experimentId) ?? null,\n [experiments.records, experimentId],\n );\n\n if (loading) {\n return (\n <div>\n <Breadcrumb trail={[{ label: \"Experiments\", route: { name: \"experiments\" } }]} onNavigate={onNavigate} />\n <p className=\"vos-muted\">Loading experiment…</p>\n </div>\n );\n }\n if (!experiment) {\n return (\n <div>\n <Breadcrumb trail={[{ label: \"Experiments\", route: { name: \"experiments\" } }]} onNavigate={onNavigate} />\n <p className=\"vos-error\">Experiment not found: {experimentId}</p>\n </div>\n );\n }\n\n const title = String(experiment.Title ?? experimentId);\n const status = String(experiment.Status ?? \"\");\n const body = String(experiment.body ?? \"\");\n const barLines = Array.isArray(experiment.barLines) ? (experiment.barLines as BarLine[]) : [];\n const expConf = (experiment.derived as any)?.experimentConfidence ?? 50;\n\n // Readings linked to this experiment — the evidence-first content.\n const expReadings = (readings.records ?? [])\n .filter((r) => String(r.experimentId ?? \"\") === experimentId)\n .sort((a, b) => String(b.Date ?? \"\").localeCompare(String(a.Date ?? \"\")));\n\n // Classify each bar by what the READINGS say (not just the barVerdict field,\n // which is only set at closure). A bar is validated/invalidated if any\n // reading's belief for it has that Result; in-progress if it has a reading\n // but no settled verdict; unstarted if no reading touches it.\n const validatedBars = barLines.filter((b) =>\n expReadings.some((r) =>\n readingBeliefs(r).some(\n (bl) => bl.assumptionId === b.assumptionId && bl.Result === \"Validated\",\n ),\n ),\n );\n const invalidatedBars = barLines.filter((b) =>\n expReadings.some((r) =>\n readingBeliefs(r).some(\n (bl) => bl.assumptionId === b.assumptionId && bl.Result === \"Invalidated\",\n ),\n ),\n );\n const readingAssumptionIds = new Set<string>();\n for (const r of expReadings) {\n for (const b of readingBeliefs(r)) readingAssumptionIds.add(b.assumptionId);\n }\n const inProgressBars = barLines.filter(\n (b) =>\n !validatedBars.includes(b) &&\n !invalidatedBars.includes(b) &&\n readingAssumptionIds.has(b.assumptionId),\n );\n const unstartedBars = barLines.filter(\n (b) => !readingAssumptionIds.has(b.assumptionId),\n );\n const settledBars = [...validatedBars, ...invalidatedBars];\n const validatedCount = validatedBars.length;\n const invalidatedCount = invalidatedBars.length;\n\n return (\n <div>\n <Breadcrumb\n trail={[\n { label: \"Experiments\", route: { name: \"experiments\" } },\n { label: experimentId, route: { name: \"experiment\", id: experimentId } },\n ]}\n onNavigate={onNavigate}\n />\n\n <div className=\"vos-detail-head\">\n <span className=\"vos-detail-id vos-num\">{experimentId}</span>\n <span className={`vos-pill ${status === \"Running\" ? \"vos-pill-good\" : \"vos-pill-neutral\"}`}>\n {status}\n </span>\n </div>\n <div className=\"vos-detail-title\">{title}</div>\n\n {/* Confidence gauge + coverage bar */}\n <div className=\"vos-card vos-exp-head\">\n <div className=\"vos-exp-gauge\">\n <ConfidenceDonut value={expConf} size={80} />\n <div className=\"vos-gauge-label\">exp confidence (50 = neutral)</div>\n </div>\n <div className=\"vos-exp-coverage\">\n <div className=\"vos-coverage-label\">\n COVERAGE · {settledBars.length}/{barLines.length} bars settled\n </div>\n <div className=\"vos-coverage-bar\">\n <i className=\"vos-coverage-good\" style={{ width: `${pct(validatedCount, barLines.length)}%` }} />\n <i className=\"vos-coverage-crit\" style={{ width: `${pct(invalidatedCount, barLines.length)}%` }} />\n <i className=\"vos-coverage-warn\" style={{ width: `${pct(inProgressBars.length, barLines.length)}%` }} />\n <i className=\"vos-coverage-empty\" style={{ width: `${pct(unstartedBars.length, barLines.length)}%` }} />\n </div>\n <div className=\"vos-coverage-legend\">\n <span><i className=\"vos-dot-good\" /> {validatedCount} validated</span>\n <span><i className=\"vos-dot-crit\" /> {invalidatedCount} invalidated</span>\n <span><i className=\"vos-dot-warn\" /> {inProgressBars.length} in progress</span>\n <span><i className=\"vos-dot-empty\" /> {unstartedBars.length} unstarted</span>\n </div>\n </div>\n </div>\n\n {/* Plan body */}\n {body ? (\n <div className=\"vos-card vos-detail-section\">\n <div className=\"vos-detail-section-label\">Plan body</div>\n <EvidenceBody text={body} />\n </div>\n ) : null}\n\n {/* Readings — evidence-first: readings lead, bar lines as context per reading */}\n <div className=\"vos-card vos-detail-section\">\n <div className=\"vos-detail-section-label\">\n Evidence · {expReadings.length} piece{expReadings.length === 1 ? \"\" : \"s\"} from this experiment\n </div>\n {expReadings.length === 0 ? (\n <div className=\"vos-muted vos-empty\">No evidence yet — experiment is running.</div>\n ) : (\n expReadings.map((r) => {\n const beliefs = readingBeliefs(r);\n const rDate = String(r.Date ?? \"\");\n const rTitle = String(r.Title ?? r.id);\n const rId = String(r.id);\n return (\n <details key={rId} className=\"vos-reading-card vos-reading-collapse\">\n <summary className=\"vos-reading-card-summary\">\n <span className=\"vos-reading-date vos-num\">{rDate}</span>\n <span className=\"vos-reading-title\">{rTitle}</span>\n <span className=\"vos-reading-beliefs-count vos-num\">\n {beliefs.length} belief{beliefs.length === 1 ? \"\" : \"s\"}\n </span>\n </summary>\n <div className=\"vos-reading-card-body\">\n <div className=\"vos-reading-head\">\n <span className=\"vos-reading-source\">{String(r.Source ?? \"\")}</span>\n <button\n type=\"button\"\n className=\"vos-link\"\n onClick={() => onNavigate({ name: \"reading\", id: rId })}\n >\n open reading →\n </button>\n </div>\n {/* Per-belief verdict cards — merged: assumption link, verdict,\n rung, bar-line context, and grading rationale. The\n Grading justification is the grader's rationale, NOT a\n quote; actual quotes live in the reading's body shown in\n the reading detail's Context section. */}\n {beliefs.map((b) => {\n const bl = barLines.find((x) => x.assumptionId === b.assumptionId);\n const a = (assumptions.records ?? []).find((x) => String(x.id) === b.assumptionId);\n const justification = String(b[\"Grading justification\"] ?? \"\");\n return (\n <div key={b.assumptionId} className={`vos-belief-card vos-verdict-border-${verdictTone(b.Result)}`}>\n <div className=\"vos-belief-head\">\n <button\n type=\"button\"\n className=\"vos-belief-id\"\n onClick={() => onNavigate({ name: \"assumption\", id: b.assumptionId })}\n >\n {b.assumptionId}\n </button>\n <span className=\"vos-belief-title\">{String(a?.Title ?? b.assumptionId)}</span>\n <span className={`vos-pill vos-pill-${verdictTone(b.Result)}`}>{b.Result}</span>\n <span className=\"vos-rung-tag\">{String(r.Rung ?? \"\")}</span>\n </div>\n {typeof b.excerpt === \"string\" && b.excerpt !== \"\" ? (\n <div className={`vos-belief-excerpt vos-verdict-border-${verdictTone(b.Result)}`}>\n “{b.excerpt}”\n </div>\n ) : justification ? (\n <div className={`vos-belief-rationale vos-verdict-border-${verdictTone(b.Result)}`}\n >\n <span className=\"vos-belief-rationale-label\">grading rationale:</span>\n {justification}\n </div>\n ) : null}\n {bl ? (\n <div className=\"vos-belief-bar\">\n <div className=\"vos-belief-bar-label\">Pre-registered bar</div>\n <div><strong>Right if:</strong> {String(bl.rightIf ?? \"\")}</div>\n {bl.wrongIf ? <div><strong>Wrong if:</strong> {String(bl.wrongIf)}</div> : null}\n {bl.barVerdict ? (\n <div className={`vos-text-${verdictTone(bl.barVerdict)}`}>\n Bar verdict: <strong>{bl.barVerdict}</strong>\n </div>\n ) : null}\n </div>\n ) : null}\n </div>\n );\n })}\n </div>\n </details>\n );\n })\n )}\n </div>\n\n {/* Unstarted bars — separate section below, dashed outlines */}\n {unstartedBars.length > 0 ? (\n <div className=\"vos-card vos-detail-section vos-unstarted\">\n <div className=\"vos-detail-section-label\">\n Not yet tested · {unstartedBars.length} bar{unstartedBars.length === 1 ? \"\" : \"s\"} with no evidence\n </div>\n {unstartedBars.map((bl) => {\n const a = (assumptions.records ?? []).find((x) => String(x.id) === bl.assumptionId);\n return (\n <div key={bl.assumptionId} className=\"vos-unstarted-bar\">\n <div className=\"vos-belief-head\">\n <button\n type=\"button\"\n className=\"vos-belief-id\"\n onClick={() => onNavigate({ name: \"assumption\", id: bl.assumptionId })}\n >\n {bl.assumptionId}\n </button>\n <span className=\"vos-belief-title\">{String(a?.Title ?? bl.assumptionId)}</span>\n <span className=\"vos-rung-tag\">{String(bl.plannedRung ?? \"\")}</span>\n <span className=\"vos-muted\">◌ no evidence</span>\n </div>\n <div className=\"vos-belief-bar\">\n <div><strong>Right if:</strong> {String(bl.rightIf ?? \"\")}</div>\n {bl.wrongIf ? <div><strong>Wrong if:</strong> {String(bl.wrongIf)}</div> : null}\n </div>\n </div>\n );\n })}\n </div>\n ) : null}\n </div>\n );\n}\n\nfunction pct(n: number, total: number): number {\n return total === 0 ? 0 : (n / total) * 100;\n}\n\nfunction verdictTone(verdict: Result | string | null | undefined): \"good\" | \"crit\" | \"neutral\" {\n if (verdict === \"Validated\") return \"good\";\n if (verdict === \"Invalidated\") return \"crit\";\n return \"neutral\";\n}","/**\n * A confidence donut gauge (DEV-5882 redesign) — a minimal ring gauge that\n * fills from 12 o'clock clockwise, proportional to the value (0–100, 50 = neutral).\n * The stroke is deliberately thin so the gauge reads as a subtle status\n * accent, not a pie chart. A larger centered number dominates the interior.\n * Used on the experiment list rows (56px) + the experiment detail header (80px).\n */\nexport function ConfidenceDonut({\n value,\n size = 56,\n}: {\n value: number;\n size?: number;\n}) {\n // Thin stroke keeps it elegant; radius stays well inside the square.\n const stroke = size > 60 ? 4 : 3;\n const r = (size - stroke * 3) / 2;\n const cx = size / 2;\n const cy = size / 2;\n const circumference = 2 * Math.PI * r;\n const pct = Math.max(0, Math.min(100, value)) / 100;\n const dash = pct * circumference;\n const color =\n value >= 67\n ? \"var(--vos-good)\"\n : value >= 33\n ? \"var(--vos-warn)\"\n : \"var(--vos-crit)\";\n return (\n <div className=\"vos-donut\" style={{ width: size, height: size }}>\n <svg width={size} height={size} aria-hidden=\"true\">\n <circle\n cx={cx}\n cy={cy}\n r={r}\n fill=\"none\"\n stroke=\"var(--vos-border)\"\n strokeWidth={stroke}\n />\n {value > 0 ? (\n <circle\n cx={cx}\n cy={cy}\n r={r}\n fill=\"none\"\n stroke={color}\n strokeWidth={stroke}\n strokeDasharray={`${dash} ${circumference - dash}`}\n strokeDashoffset={0}\n strokeLinecap=\"round\"\n transform={`rotate(-90 ${cx} ${cy})`}\n />\n ) : null}\n </svg>\n <span\n className=\"vos-donut-num vos-num\"\n style={{ fontSize: size > 60 ? 22 : 15 }}\n >\n {Math.round(value)}\n </span>\n </div>\n );\n}","import type { AnyRecord } from \"@validation-os/core\";\nimport { liveExperiments } from \"./derived-views.js\";\nimport type { Route } from \"./route.js\";\nimport { useList } from \"./use-records.js\";\nimport { Breadcrumb } from \"./breadcrumb.js\";\nimport { ConfidenceDonut } from \"./confidence-donut.js\";\n\n/**\n * The Experiments nav surface (DEV-5881): the live evidence plans list, with\n * bigger rows carrying a donut gauge + bar-line stats. Each row is a button;\n * clicking opens the evidence-first ExperimentDetail.\n */\nexport function ExperimentsSurface({\n basePath,\n onNavigate,\n}: {\n basePath?: string;\n onNavigate: (route: Route) => void;\n}) {\n const experiments = useList(\"experiments\", basePath);\n\n if (experiments.loading && !experiments.records) {\n return (\n <div>\n <Breadcrumb trail={[{ label: \"Experiments\", route: { name: \"experiments\" } }]} />\n <p className=\"vos-muted\">Loading experiments…</p>\n </div>\n );\n }\n if (experiments.error) {\n return (\n <div>\n <Breadcrumb trail={[{ label: \"Experiments\", route: { name: \"experiments\" } }]} />\n <p className=\"vos-error\">{experiments.error}</p>\n </div>\n );\n }\n\n const live = liveExperiments(experiments.records ?? []);\n\n return (\n <div>\n <Breadcrumb trail={[{ label: \"Experiments\", route: { name: \"experiments\" } }]} />\n <div className=\"vos-head\">\n <div>\n <h1>Experiments — the live evidence plans</h1>\n <p>{live.length} running {live.length === 1 ? \"plan\" : \"plans\"} · click to open the evidence-first view.</p>\n </div>\n </div>\n {live.length === 0 ? (\n <div className=\"vos-card vos-empty\">\n No running experiments. Design one from a belief's next move.\n </div>\n ) : (\n <div className=\"vos-card vos-exp-list\">\n {live.map((e) => {\n const id = String(e.id ?? \"\");\n const title = String(e.Title ?? id);\n const bars = Array.isArray(e.barLines) ? e.barLines.length : 0;\n const settled = Array.isArray(e.barLines)\n ? e.barLines.filter((b: any) => b?.barVerdict).length\n : 0;\n const status = String(e.Status ?? \"\");\n const expConf = (e.derived as any)?.experimentConfidence ?? 50;\n const instrument = String(e.Instrument ?? \"\");\n return (\n <button\n key={id}\n type=\"button\"\n className=\"vos-exp-row\"\n onClick={() => onNavigate({ name: \"experiment\", id })}\n >\n <ConfidenceDonut value={expConf} size={56} />\n <div className=\"vos-exp-row-body\">\n <div className=\"vos-exp-row-title\">{title}</div>\n <div className=\"vos-exp-row-meta vos-num\">\n {instrument && <span>{instrument} · </span>}\n {bars} bars · {settled} settled\n {e.Deadline ? <span> · deadline {String(e.Deadline)}</span> : null}\n </div>\n </div>\n <span className={`vos-pill ${status === \"Running\" ? \"vos-pill-good\" : \"vos-pill-neutral\"}`}>\n {status}\n </span>\n </button>\n );\n })}\n </div>\n )}\n </div>\n );\n}","import { useMemo } from \"react\";\nimport type { AnyRecord } from \"@validation-os/core\";\nimport { Breadcrumb } from \"./breadcrumb.js\";\nimport { readingBeliefs } from \"./derived-views.js\";\nimport { EvidenceBody } from \"./markdown.js\";\nimport type { Route } from \"./route.js\";\nimport { useList } from \"./use-records.js\";\n\n/**\n * The per-belief reading detail (DEV-5885): a shared Context section (who,\n * what, source — formerly \"Evidence body\") separate from per-belief verdict\n * cards. Each belief is a card with assumption link, verdict, rung, excerpt\n * (the per-assumption quote, color-coded by result), grading justification,\n * and bar-line context (if from an experiment). Multi-belief readings show all\n * beliefs as separate cards. Provenance: linked experiment with gauge, or\n * \"found evidence\" note.\n */\nexport interface ReadingDetailProps {\n readingId: string;\n basePath?: string;\n onNavigate: (route: Route) => void;\n}\n\nexport function ReadingDetail({\n readingId,\n basePath,\n onNavigate,\n}: ReadingDetailProps) {\n const readings = useList(\"readings\", basePath);\n const experiments = useList(\"experiments\", basePath);\n const assumptions = useList(\"assumptions\", basePath);\n\n const loading = readings.loading && !readings.records;\n\n const reading = useMemo(\n () => (readings.records ?? []).find((r) => String(r.id) === readingId) ?? null,\n [readings.records, readingId],\n );\n\n if (loading) {\n return (\n <div>\n <Breadcrumb trail={[{ label: \"Evidence\", route: { name: \"readings\" } }]} onNavigate={onNavigate} />\n <p className=\"vos-muted\">Loading evidence…</p>\n </div>\n );\n }\n if (!reading) {\n return (\n <div>\n <Breadcrumb trail={[{ label: \"Evidence\", route: { name: \"readings\" } }]} onNavigate={onNavigate} />\n <p className=\"vos-error\">Evidence not found: {readingId}</p>\n </div>\n );\n }\n\n const title = String(reading.Title ?? readingId);\n const source = String(reading.Source ?? \"\");\n const body = String(reading.body ?? \"\");\n const expId = reading.experimentId ? String(reading.experimentId) : null;\n const experiment = expId\n ? (experiments.records ?? []).find((e) => String(e.id) === expId) ?? null\n : null;\n const beliefs = readingBeliefs(reading);\n const rung = String(reading.Rung ?? \"\");\n\n return (\n <div>\n <Breadcrumb\n trail={[\n { label: \"Evidence\", route: { name: \"readings\" } },\n { label: readingId, route: { name: \"reading\", id: readingId } },\n ]}\n onNavigate={onNavigate}\n />\n\n <div className=\"vos-detail-head\">\n <span className=\"vos-detail-id vos-num\">{readingId}</span>\n <span className=\"vos-reading-source\">{source}</span>\n {expId ? (\n <span className=\"vos-pill vos-pill-accent\">from experiment</span>\n ) : (\n <span className=\"vos-pill vos-pill-neutral\">found evidence</span>\n )}\n </div>\n <div className=\"vos-detail-title\">{title}</div>\n\n {/* Context — shared (who, what, source). Replaces \"Evidence body\". */}\n <div className=\"vos-card vos-detail-section\">\n <div className=\"vos-detail-section-label\">Context</div>\n {body ? <EvidenceBody text={body} /> : <div className=\"vos-muted\">No context recorded.</div>}\n </div>\n\n {/* Per-belief verdicts — rich cards with excerpt + bar-line context */}\n <div className=\"vos-card vos-detail-section\">\n <div className=\"vos-detail-section-label\">\n What this evidence says · {beliefs.length} belief{beliefs.length === 1 ? \"\" : \"s\"} · each with its own quote\n </div>\n {beliefs.length === 0 ? (\n <div className=\"vos-muted\">No beliefs scored in this evidence.</div>\n ) : (\n beliefs.map((b) => {\n const a = (assumptions.records ?? []).find((x) => String(x.id) === b.assumptionId);\n const bl = experiment && Array.isArray(experiment.barLines)\n ? (experiment.barLines as any[]).find((x) => x?.assumptionId === b.assumptionId)\n : null;\n const result = String(b.Result ?? \"Inconclusive\");\n const justification = String(b[\"Grading justification\"] ?? \"\");\n return (\n <div key={b.assumptionId} className={`vos-belief-card vos-verdict-border-${verdictTone(result)}`}>\n <div className=\"vos-belief-head\">\n <button\n type=\"button\"\n className=\"vos-belief-id\"\n onClick={() => onNavigate({ name: \"assumption\", id: b.assumptionId })}\n >\n {b.assumptionId}\n </button>\n <span className=\"vos-belief-title\">{String(a?.Title ?? b.assumptionId)}</span>\n <span className={`vos-pill vos-pill-${verdictTone(result)}`}>{result}</span>\n <span className=\"vos-rung-tag\">{rung}</span>\n </div>\n {/* Grading rationale — why this evidence scores this belief\n this way. NOT a quote; the actual quotes live in the\n Context section above (the reading's body). */}\n {typeof b.excerpt === \"string\" && b.excerpt !== \"\" ? (\n <div className={`vos-belief-excerpt vos-verdict-border-${verdictTone(result)}`}>\n “{b.excerpt}”\n </div>\n ) : body ? (\n <div className={`vos-belief-excerpt vos-verdict-border-${verdictTone(result)}`}>\n “{snippetFromReadingBody(body, b.assumptionId)}”\n </div>\n ) : null}\n {justification ? (\n <div className={`vos-belief-rationale vos-verdict-border-${verdictTone(result)}`}>\n <span className=\"vos-belief-rationale-label\">grading rationale:</span>\n {justification}\n </div>\n ) : null}\n {/* Bar-line context (if from an experiment) */}\n {bl ? (\n <div className=\"vos-belief-bar\">\n <div className=\"vos-belief-bar-label\">Pre-registered bar</div>\n <div><strong>Right if:</strong> {String(bl.rightIf ?? \"\")}</div>\n {bl.wrongIf ? <div><strong>Wrong if:</strong> {String(bl.wrongIf)}</div> : null}\n {bl.barVerdict ? (\n <div className={`vos-text-${verdictTone(bl.barVerdict)}`}>\n Bar verdict: <strong>{String(bl.barVerdict)}</strong>\n </div>\n ) : null}\n </div>\n ) : null}\n </div>\n );\n })\n )}\n </div>\n\n {/* Provenance — linked experiment with gauge, or \"found evidence\" note */}\n {experiment ? (\n <div className=\"vos-card vos-detail-section\">\n <div className=\"vos-detail-section-label\">From experiment</div>\n <button\n type=\"button\"\n className=\"vos-linked-row\"\n onClick={() => onNavigate({ name: \"experiment\", id: String(experiment.id) })}\n >\n <span className=\"vos-linked-gauge vos-num\">\n {Math.round((experiment.derived as any)?.experimentConfidence ?? 50)}\n </span>\n <span className=\"vos-linked-title\">{String(experiment.Title ?? experiment.id)}</span>\n <span className=\"vos-link\">→ experiment</span>\n </button>\n </div>\n ) : (\n <div className=\"vos-card vos-detail-section\">\n <div className=\"vos-detail-section-label\">Provenance</div>\n <div className=\"vos-muted\">\n Found evidence — not linked to an experiment. This was logged directly\n (desk research, found interview, observation).\n </div>\n </div>\n )}\n </div>\n );\n}\n\nfunction verdictTone(verdict: string | null | undefined): \"good\" | \"crit\" | \"neutral\" {\n if (verdict === \"Validated\") return \"good\";\n if (verdict === \"Invalidated\") return \"crit\";\n return \"neutral\";\n}\n\nfunction snippetFromReadingBody(body: string, cue: string): string {\n if (!body) return \"\";\n const quoteMatch = body.match(/## Quote\\n+([\\s\\S]*?)(?=\\n## |\\n##$|$)/i);\n if (quoteMatch) {\n const q = quoteMatch[1]!.trim();\n return q.length > 220 ? q.slice(0, 217).trim() + \"…\" : q;\n }\n const sentences = body.split(/(?<=[.!?])\\s+/);\n const cueLower = cue.toLowerCase();\n for (const s of sentences) {\n if (s.toLowerCase().includes(cueLower)) return s.trim();\n }\n const first = sentences[0]?.trim() ?? \"\";\n return first.length > 220 ? first.slice(0, 217).trim() + \"…\" : first;\n}\n","import type { AnyRecord } from \"@validation-os/core\";\nimport type { Route } from \"./route.js\";\nimport { useList } from \"./use-records.js\";\nimport { Breadcrumb } from \"./breadcrumb.js\";\n\n/**\n * The Readings nav surface (DEV-5881): the evidence log list, sorted by date\n * desc. Each row is a button with the reading's date + title + a \"exp\"/\"found\"\n * tag + the belief count; clicking opens the per-belief ReadingDetail.\n */\nexport function ReadingsSurface({\n basePath,\n onNavigate,\n}: {\n basePath?: string;\n onNavigate: (route: Route) => void;\n}) {\n const readings = useList(\"readings\", basePath);\n\n if (readings.loading && !readings.records) {\n return (\n <div>\n <Breadcrumb trail={[{ label: \"Readings\", route: { name: \"readings\" } }]} />\n <p className=\"vos-muted\">Loading readings…</p>\n </div>\n );\n }\n if (readings.error) {\n return (\n <div>\n <Breadcrumb trail={[{ label: \"Readings\", route: { name: \"readings\" } }]} />\n <p className=\"vos-error\">{readings.error}</p>\n </div>\n );\n }\n\n const sorted = [...(readings.records ?? [])].sort((a, b) => {\n const da = String(a.Date ?? \"\");\n const db = String(b.Date ?? \"\");\n return db.localeCompare(da);\n });\n\n return (\n <div>\n <Breadcrumb trail={[{ label: \"Readings\", route: { name: \"readings\" } }]} />\n <div className=\"vos-head\">\n <div>\n <h1>Readings — the evidence log</h1>\n <p>{sorted.length} {sorted.length === 1 ? \"reading\" : \"readings\"} · click to open the per-belief view.</p>\n </div>\n </div>\n {sorted.length === 0 ? (\n <div className=\"vos-card vos-empty\">No readings logged yet.</div>\n ) : (\n <div className=\"vos-card vos-list-card\">\n {sorted.map((r) => {\n const id = String(r.id ?? \"\");\n const title = String(r.Title ?? id);\n const date = String(r.Date ?? \"\");\n const hasExperiment = Boolean(r.experimentId);\n const beliefCount = Array.isArray(r.beliefs) ? r.beliefs.length : 0;\n return (\n <button\n key={id}\n type=\"button\"\n className=\"vos-list-row\"\n onClick={() => onNavigate({ name: \"reading\", id })}\n >\n <span className=\"vos-list-row-date vos-num\">{date}</span>\n <span className=\"vos-list-row-title\">{title}</span>\n <span className={`vos-pill ${hasExperiment ? \"vos-pill-accent\" : \"vos-pill-neutral\"}`}>\n {hasExperiment ? \"exp\" : \"found\"}\n </span>\n <span className=\"vos-list-row-meta vos-num\">\n {beliefCount} belief{beliefCount === 1 ? \"\" : \"s\"}\n </span>\n </button>\n );\n })}\n </div>\n )}\n </div>\n );\n}","import { useMemo, useState } from \"react\";\nimport type { AnyRecord, BarLine, Collection } from \"@validation-os/core\";\nimport { REGISTERS } from \"@validation-os/core\";\nimport { formatValue } from \"./columns.js\";\nimport { resolveBarLines } from \"./detail-fields.js\";\nimport { buildPatch, draftErrors, draftFrom, type Draft } from \"./edit.js\";\nimport { EditFields } from \"./edit-fields.js\";\nimport { GlossaryText } from \"./glossary-text.js\";\nimport { toGlossaryTerms } from \"./glossary.js\";\nimport { buildJourney } from \"./journey.js\";\nimport { BeliefJourney } from \"./journey-surface.js\";\nimport { REGISTER_LABEL, REGISTER_SINGULAR } from \"./labels.js\";\nimport { readingBeliefs } from \"./derived-views.js\";\nimport { nestReadingsByPlan } from \"./list-surface.js\";\nimport { EvidenceBody } from \"./markdown.js\";\nimport { BeliefVerdicts } from \"./belief-verdicts.js\";\nimport {\n formatSigned,\n riskFraction,\n type Tone,\n} from \"./primitives.js\";\nimport {\n buildRecordPage,\n type BacklinkItem,\n type Meter,\n type Pill,\n type RecordTabId,\n type RelatedSet,\n type RelationPanel,\n} from \"./record-view.js\";\nimport type { Route } from \"./route.js\";\nimport { UnderstandingPanel } from \"./understanding-panel.js\";\nimport { useList, useUpdate } from \"./use-records.js\";\n\nexport interface RecordPageProps {\n /** The record being drilled into (`#record/<id>`). */\n recordId: string;\n /** Navigate elsewhere — the breadcrumb, backlinks and glossary links use it. */\n onNavigate: (route: Route) => void;\n /** Where the \"Records\" breadcrumb returns to before the record's own register\n * is known (resolved once the record loads). */\n backRegister: Collection;\n /** API base path (default `/api`). */\n basePath?: string;\n}\n\n/**\n * The record page's own edit affordance (OPS-1346) — genuine hand-input\n * fields only (seed Impact chief among them), wired through the same\n * `edit.ts`/`EditFields`/`useUpdate` seam the drawer uses. Bundled into one\n * prop so `RecordBody` doesn't grow a dozen individual callbacks.\n */\ninterface EditState {\n editing: boolean;\n draft: Draft;\n /** Validation messages keyed by field (e.g. Impact outside 0–100). */\n errors: Record<string, string>;\n saving: boolean;\n conflict: string | null;\n saveError: string | null;\n onEdit: () => void;\n onCancel: () => void;\n onSave: () => void;\n onReload: () => void;\n onField: (key: string, value: string) => void;\n}\n\nconst TAB_LABEL: Record<RecordTabId, string> = {\n overview: \"Overview\",\n evidence: \"Evidence\",\n connections: \"Connections\",\n history: \"History\",\n};\n\nconst PILL_CLASS: Record<Tone, string> = {\n good: \"vos-pill vos-pill-good\",\n warn: \"vos-pill vos-pill-warn\",\n crit: \"vos-pill vos-pill-crit\",\n accent: \"vos-pill vos-pill-accent\",\n neutral: \"vos-pill vos-pill-neutral\",\n};\n\n/**\n * The canonical full record page (OPS-1286) — promoted from the enriched drawer\n * to the one place a record lives, reachable identically from a table, a\n * backlink or a search (story 12). It loads the registers once (the related set\n * every panel reads), resolves which register the id belongs to, and renders the\n * pure `buildRecordPage` model: a status + derived lane/queue header, leading\n * scores as meters with a \"Why?\" attribution (reusing the understanding layer),\n * the genuine human-input free text (glossary auto-linked), backlink panels\n * grouped by relation with score chips, and a history/audit view. A belief's\n * page also hosts the per-belief journey (built by the OPS-1289 map).\n */\nexport function RecordPage({\n recordId,\n onNavigate,\n backRegister,\n basePath,\n}: RecordPageProps) {\n const lists = {\n assumptions: useList(\"assumptions\", basePath),\n experiments: useList(\"experiments\", basePath),\n readings: useList(\"readings\", basePath),\n decisions: useList(\"decisions\", basePath),\n glossary: useList(\"glossary\", basePath),\n };\n const [tab, setTab] = useState<RecordTabId>(\"overview\");\n const [asOf] = useState(() => new Date().toISOString().slice(0, 10));\n\n const anyLoading = REGISTERS.some((r) => lists[r].loading && !lists[r].records);\n const related: RelatedSet = {\n assumptions: lists.assumptions.records ?? [],\n experiments: lists.experiments.records ?? [],\n readings: lists.readings.records ?? [],\n decisions: lists.decisions.records ?? [],\n glossary: lists.glossary.records ?? [],\n };\n\n // Resolve the record and its register by scanning the loaded lists.\n let register: Collection | null = null;\n let record: AnyRecord | null = null;\n for (const r of REGISTERS) {\n const hit = (lists[r].records ?? []).find((x) => x.id === recordId);\n if (hit) {\n register = r;\n record = hit;\n break;\n }\n }\n\n // The per-belief journey (OPS-1330) — only a belief travels the loop, so this\n // is null for any other register. \"Now\" is supplied here so the view-model\n // stays pure (it never reads a clock); the story's last event is today.\n const journey = useMemo(() => {\n if (register !== \"assumptions\" || !record) return null;\n return buildJourney(\n recordId,\n {\n assumptions: related.assumptions ?? [],\n experiments: related.experiments ?? [],\n readings: related.readings ?? [],\n decisions: related.decisions ?? [],\n },\n asOf,\n );\n }, [register, record, recordId, asOf, related]);\n\n const refreshAll = () => {\n lists.assumptions.refresh();\n lists.experiments.refresh();\n lists.readings.refresh();\n lists.decisions.refresh();\n lists.glossary.refresh();\n };\n\n const terms = toGlossaryTerms(related.glossary ?? []);\n const openTerm = (id: string) => onNavigate({ name: \"record\", id });\n\n // Editing (OPS-1346): the record page's own edit affordance for genuine\n // hand-input fields — seed Impact on an assumption above all (the only\n // hand-scored number, `registry-schema.md`). Same edit/patch/save seam the\n // drawer uses (`edit.ts`, `EditFields`, `useUpdate`), so the two surfaces\n // never drift into different forms; derived numbers stay absent from\n // `editableFields` and so never appear here either.\n const [editing, setEditing] = useState(false);\n const [draft, setDraft] = useState<Draft>({});\n // The record as it was when editing began — diffing against this (not the\n // live `record`) means a concurrent teammate edit to an untouched field\n // survives a reload-and-retry (mirrors the drawer's conflict handling).\n const [baseline, setBaseline] = useState<AnyRecord | null>(null);\n const { save, saving, conflict, error: saveError, reset } = useUpdate(\n register ?? backRegister,\n basePath,\n );\n\n function startEditing() {\n if (!record || !register) return;\n setBaseline(record);\n setDraft(draftFrom(register, record));\n reset();\n setEditing(true);\n }\n\n function cancelEditing() {\n setEditing(false);\n reset();\n }\n\n async function onSaveEdit() {\n if (!record || !register || !baseline) return;\n // Out-of-range values (e.g. Impact outside 0–100) never reach the API —\n // the server's own check is a backstop, not the first line of defence.\n if (Object.keys(draftErrors(register, draft)).length > 0) return;\n const patch = buildPatch(register, baseline, draft);\n patch.version = record.version; // write on top of the freshest known version\n if (Object.keys(patch).length <= 1) {\n setEditing(false); // only `version` present — nothing actually changed\n return;\n }\n const result = await save(record.id, patch);\n if (result.ok) {\n setEditing(false);\n refreshAll(); // pull the recomputed record back in\n }\n // On conflict/error the hook holds the message; stay in edit mode with\n // the draft intact so nothing typed is lost.\n }\n\n function reloadLatest() {\n reset();\n refreshAll();\n }\n\n const setField = (key: string, value: string) =>\n setDraft((d) => ({ ...d, [key]: value }));\n\n const editErrors = editing && register ? draftErrors(register, draft) : {};\n const edit: EditState = {\n editing,\n draft,\n errors: editErrors,\n saving,\n conflict,\n saveError,\n onEdit: startEditing,\n onCancel: cancelEditing,\n onSave: onSaveEdit,\n onReload: reloadLatest,\n onField: setField,\n };\n\n return (\n <div>\n <nav className=\"vos-crumbs\" aria-label=\"Breadcrumb\">\n <button\n type=\"button\"\n onClick={() =>\n onNavigate({ name: \"records\", register: register ?? backRegister })\n }\n >\n {REGISTER_LABEL[register ?? backRegister]}\n </button>\n <span aria-hidden=\"true\">›</span>\n <span className=\"vos-rid\">{record ? formatValue(record.Title) : recordId}</span>\n </nav>\n\n {anyLoading ? (\n <p className=\"vos-muted\">Loading record…</p>\n ) : !record || !register ? (\n <div className=\"vos-empty\">\n Couldn't find a record with id <b>{recordId}</b>.\n </div>\n ) : (\n <RecordBody\n register={register}\n record={record}\n related={related}\n asOf={asOf}\n terms={terms}\n tab={tab}\n onTab={setTab}\n onOpenRecord={(id) => onNavigate({ name: \"record\", id })}\n onOpenTerm={openTerm}\n basePath={basePath}\n journey={journey}\n onJourneyChanged={refreshAll}\n onNavigate={onNavigate}\n edit={edit}\n />\n )}\n </div>\n );\n}\n\nfunction RecordBody({\n register,\n record,\n related,\n asOf,\n terms,\n tab,\n onTab,\n onOpenRecord,\n onOpenTerm,\n basePath,\n journey,\n onJourneyChanged,\n onNavigate,\n edit,\n}: {\n register: Collection;\n record: AnyRecord;\n related: RelatedSet;\n asOf: string;\n terms: ReturnType<typeof toGlossaryTerms>;\n tab: RecordTabId;\n onTab: (t: RecordTabId) => void;\n onOpenRecord: (id: string) => void;\n onOpenTerm: (id: string) => void;\n basePath?: string;\n journey: ReturnType<typeof buildJourney>;\n onJourneyChanged: () => void;\n onNavigate: (route: Route) => void;\n edit: EditState;\n}) {\n const page = buildRecordPage(register, record, related, { asOf });\n const activeTab = page.tabs.includes(tab) ? tab : \"overview\";\n const description = typeof record.Description === \"string\" ? record.Description : \"\";\n const bodyText = typeof record.body === \"string\" ? record.body : \"\";\n const hasErrors = Object.keys(edit.errors).length > 0;\n\n return (\n <>\n <div className=\"vos-head vos-record-head\">\n <div>\n <p className=\"vos-drawer-eyebrow\">{REGISTER_SINGULAR[register]}</p>\n <h1>{page.title}</h1>\n <div className=\"vos-pill-row\">\n {page.pills.map((p, i) => (\n <PillView key={i} pill={p} />\n ))}\n </div>\n </div>\n <div className=\"vos-spacer\" />\n <span className=\"vos-verbadge\">v{formatValue(record.version)}</span>\n {!edit.editing ? (\n <button\n type=\"button\"\n onClick={edit.onEdit}\n className=\"vos-btn vos-btn-ghost vos-btn-sm\"\n >\n Edit\n </button>\n ) : null}\n </div>\n\n <div className=\"vos-tabs\" role=\"tablist\" aria-label=\"Record sections\">\n {page.tabs.map((t) => (\n <button\n key={t}\n type=\"button\"\n role=\"tab\"\n aria-selected={t === activeTab}\n className={`vos-tab ${t === activeTab ? \"is-active\" : \"\"}`}\n onClick={() => onTab(t)}\n >\n {TAB_LABEL[t]}\n </button>\n ))}\n </div>\n\n {activeTab === \"overview\" ? (\n <div className=\"vos-record-cols\">\n <section className=\"vos-meter-grid\">\n {page.meters.map((m) => (\n <MeterView\n key={m.key}\n meter={m}\n assumption={m.hasWhy ? record : null}\n basePath={basePath}\n />\n ))}\n </section>\n {edit.editing ? (\n <section className=\"vos-record-editor\">\n <h3 className=\"vos-section-title\">Edit</h3>\n {edit.conflict ? (\n <ConflictBanner message={edit.conflict} onReload={edit.onReload} />\n ) : null}\n {edit.saveError ? (\n <p role=\"alert\" className=\"vos-error\">\n {edit.saveError}\n </p>\n ) : null}\n <EditFields\n register={register}\n draft={edit.draft}\n errors={edit.errors}\n onField={edit.onField}\n />\n <footer className=\"vos-drawer-footer\">\n <button\n type=\"button\"\n onClick={edit.onCancel}\n disabled={edit.saving}\n className=\"vos-btn vos-btn-ghost vos-btn-sm\"\n >\n Cancel\n </button>\n <button\n type=\"button\"\n onClick={edit.onSave}\n disabled={edit.saving || hasErrors}\n title={hasErrors ? \"Fix the highlighted field before saving\" : undefined}\n className=\"vos-btn vos-btn-sm\"\n >\n {edit.saving ? \"Saving…\" : \"Save\"}\n </button>\n </footer>\n </section>\n ) : (\n <>\n {description ? (\n <section className=\"vos-record-prose\">\n <h3 className=\"vos-section-title\">Description</h3>\n <p>\n <GlossaryText\n text={description}\n terms={terms}\n selfId={register === \"glossary\" ? record.id : undefined}\n onOpenTerm={onOpenTerm}\n />\n </p>\n </section>\n ) : null}\n {bodyText ? (\n <section className=\"vos-record-prose\">\n <h3 className=\"vos-section-title\">\n {register === \"readings\" ? \"Quote\" : \"Narrative\"}\n </h3>\n <EvidenceBody\n text={bodyText}\n partLabel={register === \"readings\" ? \"Finding\" : \"Part\"}\n />\n </section>\n ) : null}\n {register === \"readings\" ? (\n <section className=\"vos-record-prose vos-verdicts-section\">\n <h3 className=\"vos-section-title\">Per-belief verdicts</h3>\n <BeliefVerdicts\n reading={record}\n assumptions={related.assumptions ?? []}\n onOpenRecord={onOpenRecord}\n />\n </section>\n ) : null}\n {page.humanText.length ? (\n <section className=\"vos-record-prose\">\n <h3 className=\"vos-section-title\">\n From a human <span className=\"vos-hint\">— not computed</span>\n </h3>\n {page.humanText.map((h) => (\n <div key={h.key} className=\"vos-human-field\">\n <div className=\"vos-detail-k\">{h.label}</div>\n <p>\n <GlossaryText\n text={h.text}\n terms={terms}\n selfId={register === \"glossary\" ? record.id : undefined}\n onOpenTerm={onOpenTerm}\n />\n </p>\n </div>\n ))}\n </section>\n ) : null}\n </>\n )}\n </div>\n ) : null}\n\n {activeTab === \"evidence\" ? (\n <EvidenceTab\n register={register}\n record={record}\n related={related}\n onOpenRecord={onOpenRecord}\n basePath={basePath}\n />\n ) : null}\n\n {activeTab === \"connections\" ? (\n <div className=\"vos-panels\">\n {page.panels.map((panel) => (\n <PanelView key={panel.id} panel={panel} onOpenRecord={onOpenRecord} />\n ))}\n </div>\n ) : null}\n\n {activeTab === \"history\" ? (\n <section className=\"vos-detail-list\">\n <div className=\"vos-detail-row\">\n <span className=\"vos-detail-k\">Created</span>\n <span className=\"vos-detail-v\">{formatValue(record.createdAt)}</span>\n </div>\n <div className=\"vos-detail-row\">\n <span className=\"vos-detail-k\">Last updated</span>\n <span className=\"vos-detail-v\">{formatValue(record.updatedAt)}</span>\n </div>\n <div className=\"vos-detail-row\">\n <span className=\"vos-detail-k\">Version</span>\n <span className=\"vos-detail-v\">{formatValue(record.version)}</span>\n </div>\n <p className=\"vos-hint\">\n The full change trail lands here as the API exposes version history;\n this absorbs the retired provenance prose.\n </p>\n </section>\n ) : null}\n\n {page.hasJourney && journey ? (\n <section className=\"vos-journey-host\">\n <h3 className=\"vos-section-title\">Validation journey</h3>\n <BeliefJourney\n journey={journey}\n assumption={record}\n basePath={basePath}\n onNavigate={onNavigate}\n onChanged={onJourneyChanged}\n />\n </section>\n ) : page.hasJourney ? (\n <section className=\"vos-journey-host\">\n <h3 className=\"vos-section-title\">Validation journey</h3>\n <p className=\"vos-hint\">\n The per-belief journey (Framed → Planned → Tested → Known) mounts here\n — built by the workflow-first map (OPS-1289). This page is its host.\n </p>\n </section>\n ) : null}\n </>\n );\n}\n\nfunction PillView({ pill }: { pill: Pill }) {\n return <span className={PILL_CLASS[pill.tone]}>{pill.label}</span>;\n}\n\n/** The plain-language conflict prompt (spec user story 12) — a concurrent\n * edit surfaced gently, with a re-fetch path, never version jargon. Mirrors\n * the drawer's banner so the two edit surfaces read identically. */\nfunction ConflictBanner({\n message,\n onReload,\n}: {\n message: string;\n onReload: () => void;\n}) {\n return (\n <div role=\"alert\" className=\"vos-banner vos-banner-warn\">\n <div className=\"vos-banner-body\">\n <span>{message}</span>\n </div>\n <button type=\"button\" onClick={onReload}>\n Review the latest\n </button>\n </div>\n );\n}\n\n/** One leading-score meter — a bar (fraction fill), a signed value (centre\n * baseline fill) or a categorical pill, with an optional \"Why?\" reveal that\n * opens the understanding layer for Confidence. */\nfunction MeterView({\n meter,\n assumption,\n basePath,\n}: {\n meter: Meter;\n assumption: AnyRecord | null;\n basePath?: string;\n}) {\n const [why, setWhy] = useState(false);\n const textTone =\n meter.tone === \"crit\"\n ? \"vos-text-crit\"\n : meter.tone === \"warn\"\n ? \"vos-text-warn\"\n : \"\";\n\n return (\n <div className=\"vos-meter\">\n <div className=\"vos-meter-head\">\n <span className=\"vos-meter-label\">{meter.label}</span>\n {meter.hasWhy && assumption ? (\n <button\n type=\"button\"\n className=\"vos-why\"\n onClick={() => setWhy((w) => !w)}\n aria-expanded={why}\n >\n Why? {why ? \"▴\" : \"▾\"}\n </button>\n ) : null}\n </div>\n\n {meter.value === null ? (\n <div className=\"vos-meter-val vos-muted\">—</div>\n ) : meter.kind === \"pill\" ? (\n <span className={PILL_CLASS[meter.tone]}>{meter.value}</span>\n ) : meter.kind === \"signed\" ? (\n <>\n <div className={`vos-meter-val ${textTone}`}>\n {formatSigned(Number(meter.value))}\n </div>\n <span className=\"vos-track vos-signed\">\n <SignedFill value={Number(meter.value)} min={meter.min ?? -100} max={meter.max ?? 100} />\n </span>\n </>\n ) : (\n <>\n <div className={`vos-meter-val ${textTone}`}>\n {Math.round(Number(meter.value))}\n </div>\n <span className=\"vos-risk-bar\">\n <i\n className={\n meter.tone === \"crit\"\n ? \"vos-fill-crit\"\n : meter.tone === \"warn\"\n ? \"vos-fill-warn\"\n : \"vos-fill-good\"\n }\n style={{ width: `${Math.round(riskFraction(Number(meter.value)) * 100)}%` }}\n />\n </span>\n </>\n )}\n\n {why && assumption ? (\n <div className=\"vos-why-panel\">\n <UnderstandingPanel assumption={assumption} basePath={basePath} />\n </div>\n ) : null}\n </div>\n );\n}\n\n/** A signed meter fill: from the centre, right (green) for positive, left (red)\n * for negative — the direction the evidence pushed the number. */\nfunction SignedFill({ value, min, max }: { value: number; min: number; max: number }) {\n const span = Math.max(Math.abs(min), Math.abs(max)) || 1;\n const width = Math.round((Math.min(Math.abs(value), span) / span) * 50);\n const up = value >= 0;\n const style = up\n ? { left: \"50%\", width: `${width}%`, background: \"var(--vos-good)\" }\n : { right: \"50%\", width: `${width}%`, background: \"var(--vos-crit)\" };\n return width > 0 ? <i style={style} /> : null;\n}\n\n/** One backlink panel — a relation's rows with score chips, or \"none yet\". */\nfunction PanelView({\n panel,\n onOpenRecord,\n}: {\n panel: RelationPanel;\n onOpenRecord: (id: string) => void;\n}) {\n return (\n <section className=\"vos-panel\">\n <h3 className=\"vos-panel-head\">\n {panel.label}\n <span className=\"vos-group-n\">{panel.items.length}</span>\n </h3>\n {panel.items.length === 0 ? (\n <p className=\"vos-hint\">None yet.</p>\n ) : (\n <ul className=\"vos-backlinks\">\n {panel.items.map((item) => (\n <BacklinkRow key={item.id} item={item} onOpenRecord={onOpenRecord} />\n ))}\n </ul>\n )}\n </section>\n );\n}\n\nfunction BacklinkRow({\n item,\n onOpenRecord,\n}: {\n item: BacklinkItem;\n onOpenRecord: (id: string) => void;\n}) {\n return (\n <li>\n <button\n type=\"button\"\n className=\"vos-backlink\"\n onClick={() => onOpenRecord(item.id)}\n >\n <span className=\"vos-backlink-title\">{item.title}</span>\n <span className={`vos-chip ${PILL_CLASS[item.chip.tone]}`}>\n <span className=\"vos-chip-k\">{item.chip.label}</span>\n {item.chip.value}\n </span>\n </button>\n </li>\n );\n}\n\n/** The Evidence tab — for a belief, the understanding-layer \"Why?\"; for an\n * evidence plan, its bar lines with readings nested underneath. */\nfunction EvidenceTab({\n register,\n record,\n related,\n onOpenRecord,\n basePath,\n}: {\n register: Collection;\n record: AnyRecord;\n related: RelatedSet;\n onOpenRecord: (id: string) => void;\n basePath?: string;\n}) {\n if (register === \"assumptions\") {\n return (\n <section className=\"vos-why-panel\">\n <UnderstandingPanel assumption={record} basePath={basePath} />\n </section>\n );\n }\n\n // Experiments: bar lines + readings nested under this plan. Each bar line\n // is resolved against the loaded assumptions (OPS-1345) so it links the\n // belief's title, never its bare `assumptionId`.\n const bars = resolveBarLines(\n (record.barLines as BarLine[] | undefined) ?? [],\n related,\n );\n const mine = (related.readings ?? []).filter((r) => r.experimentId === record.id);\n const nested = nestReadingsByPlan(mine, [record]);\n return (\n <div className=\"vos-record-cols\">\n <section>\n <h3 className=\"vos-section-title\">Bar lines</h3>\n {bars.length === 0 ? (\n <p className=\"vos-hint\">No pre-registered bars.</p>\n ) : (\n <ul className=\"vos-bars\">\n {bars.map((b, i) => (\n <li key={i} className=\"vos-bar-line\">\n <span className=\"vos-bar-if\">{b.rightIf || \"—\"}</span>\n {b.assumption ? (\n <button\n type=\"button\"\n className=\"vos-inline-link\"\n onClick={() => onOpenRecord(b.assumption!.id)}\n >\n {b.assumption.title}\n </button>\n ) : null}\n <span\n className={\n b.barVerdict\n ? \"vos-pill vos-pill-good\"\n : \"vos-pill vos-pill-neutral\"\n }\n >\n {b.barVerdict ?? \"open\"}\n </span>\n </li>\n ))}\n </ul>\n )}\n </section>\n <section>\n <h3 className=\"vos-section-title\">Readings</h3>\n {nested.length === 0 ? (\n <p className=\"vos-hint\">No readings logged yet.</p>\n ) : (\n <ul className=\"vos-backlinks\">\n {nested[0]!.readings.map((r) => (\n <li key={r.id}>\n <button\n type=\"button\"\n className=\"vos-backlink\"\n onClick={() => onOpenRecord(r.id)}\n >\n <span className=\"vos-backlink-title\">{formatValue(r.Title)}</span>\n {/* A reading grades per belief now (OPS-1305) — the verdict is\n no longer a row scalar; open the reading for its verdicts.\n The chip shows how many beliefs it scored. */}\n <span className=\"vos-chip vos-pill vos-pill-neutral\">\n {readingBeliefs(r).length} belief\n {readingBeliefs(r).length === 1 ? \"\" : \"s\"}\n </span>\n </button>\n </li>\n ))}\n </ul>\n )}\n </section>\n </div>\n );\n}","/**\n * The record drawer's generic field list (OPS-1345) — the pure view-model\n * behind the \"everything else\" rows a record carries beyond its meters/\n * human-text/panels. `RecordDrawer` iterates a record's own keys (skipping\n * provenance/meta), and this module decides how each one reads: a relation\n * id/id-list (`Depends on`, `Readings`, `Assumption`…) resolves to the linked\n * record's title, `Owner`/`Agreed by` (stored as dashboard-user objects,\n * `{id, name}` — `connectors/nosql-schema.md`) reads as name(s) only, and\n * `barLines` (the embedded per-belief pre-registration on an experiment)\n * reads as structured rows with a linked assumption title — never the raw\n * stored JSON or an internal id, per this project's \"explain visually, hide\n * complexity\" bias. Everything else still formats through `columns.ts`.\n * DOM-free and unit-tested at this seam; `record-drawer.tsx` renders what it\n * returns.\n */\nimport type { AnyRecord, BarLine, Collection } from \"@validation-os/core\";\nimport { fieldLabel, formatValue, primaryLabel } from \"./columns.js\";\nimport { isArchivedExperiment } from \"./derived-views.js\";\nimport type { RelatedSet } from \"./record-view.js\";\n\nexport type { RelatedSet };\n\n/** Provider-owned/meta fields — never a content row. */\nexport const META_FIELDS = new Set([\n \"id\",\n \"version\",\n \"createdAt\",\n \"updatedAt\",\n \"derived\",\n]);\n\n/**\n * Fields dropped from the generic list because a richer row already carries\n * the same information: `barLineAssumptionIds` is a convenience projection of\n * `barLines[].assumptionId` (`connectors/nosql-schema.md`), and the `bar-lines`\n * row below already links each assumption.\n */\nconst SUPPRESSED_FIELDS = new Set([\n \"barLineAssumptionIds\",\n // A reading's `beliefs[]` is rendered as the richer per-belief verdict list\n // (OPS-1305), never as raw JSON in the generic row list.\n \"beliefs\",\n // `body` (a reading's quote / an experiment's narrative) renders as Markdown\n // in its own block, not as a raw-text row.\n \"body\",\n]);\n\n/** Which register a relation id/id-list field points at (mirrors the `from`\n * side of `RELATIONS` in `@validation-os/core`, plus the inverse single-id\n * fields `RELATIONS` only states from the other end). */\nconst RELATION_TARGET: Partial<Record<string, Collection>> = {\n dependsOnIds: \"assumptions\",\n enablesIds: \"assumptions\",\n contradictsIds: \"assumptions\",\n readingIds: \"readings\",\n assumptionId: \"assumptions\",\n assumptionIds: \"assumptions\",\n experimentId: \"experiments\",\n basedOnIds: \"assumptions\",\n resolvesIds: \"assumptions\",\n};\n\n/** Dashboard-user reference fields — an array of `{id, name}`, never a\n * navigable record (there is no `people` register, `OPS-1305`). */\nconst OWNER_FIELDS = new Set([\"Owner\", \"Agreed by\"]);\n\nexport type DetailRowKind = \"text\" | \"relation\" | \"owner\" | \"bar-lines\";\n\n/** One resolved relation target — a title to show, an id to navigate to. */\nexport interface DetailRelationItem {\n id: string;\n register: Collection;\n title: string;\n}\n\n/** One bar line, human-readable: the belief it tests resolved to a title. */\nexport interface ResolvedBarLine {\n rightIf: string;\n wrongIf: string | null;\n plannedRung: string;\n barVerdict: string | null;\n assumption: DetailRelationItem | null;\n}\n\nexport interface DetailRow {\n key: string;\n label: string;\n kind: DetailRowKind;\n /** `kind: \"text\"` — the formatted display string. */\n text?: string;\n /** `kind: \"relation\"` — the resolved link targets, in stored order. */\n items?: DetailRelationItem[];\n /** `kind: \"owner\"` — the dashboard-user name(s), never the id/object. */\n names?: string[];\n /** `kind: \"bar-lines\"` — the embedded pre-registration, resolved. */\n bars?: ResolvedBarLine[];\n}\n\nfunction relatedList(related: RelatedSet, register: Collection): AnyRecord[] {\n return related[register] ?? [];\n}\n\n/** Resolve one id against its target register's loaded rows. Falls back to\n * the bare id only when the record isn't in the loaded set (defensive — the\n * data has no dangling refs; this keeps a stale/partial fetch from crashing\n * the row rather than silently mis-linking). */\nfunction resolveItem(\n related: RelatedSet,\n register: Collection,\n id: string,\n): DetailRelationItem {\n const hit = relatedList(related, register).find((r) => r.id === id);\n return { id, register, title: hit ? primaryLabel(hit) : id };\n}\n\n/** The string ids a relation field carries — a list field or a single\n * (possibly nullable) id field, normalised the same way. */\nfunction idsOf(value: unknown): string[] {\n if (Array.isArray(value)) {\n return value.filter((v): v is string => typeof v === \"string\");\n }\n return typeof value === \"string\" && value ? [value] : [];\n}\n\n/** The dashboard-user name(s) off an `Owner`/`Agreed by` value — the stored\n * shape is `{id, name}[]`; a bare string is tolerated as a fallback. */\nexport function ownerNames(value: unknown): string[] {\n if (!Array.isArray(value)) return [];\n return value.map((v) => {\n if (v && typeof v === \"object\") {\n const name = (v as { name?: unknown }).name;\n if (typeof name === \"string\" && name) return name;\n const id = (v as { id?: unknown }).id;\n return typeof id === \"string\" ? id : \"—\";\n }\n return typeof v === \"string\" ? v : \"—\";\n });\n}\n\n/** Bar lines resolved against the loaded assumptions — shared by the drawer's\n * generic list and the record page's Evidence tab so the two never drift. */\nexport function resolveBarLines(\n bars: BarLine[],\n related: RelatedSet,\n): ResolvedBarLine[] {\n return bars.map((b) => ({\n rightIf: b.rightIf ?? \"\",\n wrongIf: b.wrongIf ?? null,\n plannedRung: b.plannedRung ?? \"\",\n barVerdict: b.barVerdict ?? null,\n assumption: b.assumptionId\n ? resolveItem(related, \"assumptions\", b.assumptionId)\n : null,\n }));\n}\n\n/**\n * The record's own fields, beyond its meta/derived tuple, as rows a drawer\n * can render directly — relation fields resolved to a title + navigate\n * target, `Owner`/`Agreed by` to plain names, `barLines` to structured rows.\n * Everything else still formats through `formatValue` (spec stories 1–3).\n */\nexport function detailRows(\n register: Collection,\n record: AnyRecord,\n related: RelatedSet = {},\n): DetailRow[] {\n const keys = Object.keys(record).filter(\n (k) => !META_FIELDS.has(k) && !SUPPRESSED_FIELDS.has(k),\n );\n\n return keys.map((key) => {\n const value = record[key];\n const label = fieldLabel(key);\n\n const target = RELATION_TARGET[key];\n if (target) {\n let items = idsOf(value).map((id) => resolveItem(related, target, id));\n // Archived plans never surface as a relation (OPS-1305): drop any\n // experiment target that resolves to an Archived record.\n if (target === \"experiments\") {\n const archived = new Set(\n (related.experiments ?? [])\n .filter((e) => isArchivedExperiment(e))\n .map((e) => e.id),\n );\n items = items.filter((it) => !archived.has(it.id));\n }\n return { key, label, kind: \"relation\", items };\n }\n\n if (OWNER_FIELDS.has(key)) {\n return { key, label, kind: \"owner\", names: ownerNames(value) };\n }\n\n if (key === \"barLines\" && Array.isArray(value)) {\n return {\n key,\n label,\n kind: \"bar-lines\",\n bars: resolveBarLines(value as BarLine[], related),\n };\n }\n\n return { key, label, kind: \"text\", text: formatValue(value) };\n });\n}\n","import type { Collection } from \"@validation-os/core\";\nimport { editableFields, type Draft, type FieldEditor } from \"./edit.js\";\n\n/**\n * The editable-field stack for a register — the inputs an edit form is made of,\n * driven by `edit.ts`'s schema (which fields are editable, and as what control).\n *\n * Factored out of the record drawer so the drawer and the journey's \"edit the\n * bet\" step-in (OPS-1330) render the same controls from the same schema: two\n * surfaces editing one register should never drift into two different forms.\n * Derived numbers are never here — they are computed on write (OPS-1251).\n */\nexport function EditFields({\n register,\n draft,\n errors,\n onField,\n}: {\n register: Collection;\n draft: Draft;\n /** Per-field validation messages (keyed by field), e.g. Impact out of\n * 0–100 — `edit.ts`'s `draftErrors`. Absent/empty = every field is valid. */\n errors?: Record<string, string>;\n onField: (key: string, value: string) => void;\n}) {\n return (\n <div className=\"vos-field-stack\">\n {editableFields(register).map((field) => (\n <FieldInput\n key={field.key}\n field={field}\n value={draft[field.key]}\n error={errors?.[field.key]}\n onChange={(v) => onField(field.key, v)}\n />\n ))}\n </div>\n );\n}\n\n/** One editable field, as the control its `kind` calls for. */\nexport function FieldInput({\n field,\n value,\n error,\n onChange,\n}: {\n field: FieldEditor;\n value: string | undefined;\n /** A validation message shown under the control, e.g. \"Impact must be at\n * most 100.\" — never blocks typing, only the Save the caller gates on it. */\n error?: string;\n onChange: (value: string) => void;\n}) {\n // Field keys can contain spaces (\"Scoring justification\"); slugify for a\n // valid DOM id.\n const id = `field-${field.key.replace(/\\s+/g, \"-\")}`;\n return (\n <div className=\"vos-field\">\n <label htmlFor={id}>{field.label}</label>\n {field.kind === \"textarea\" ? (\n <textarea\n id={id}\n value={String(value ?? \"\")}\n onChange={(e) => onChange(e.target.value)}\n rows={3}\n className=\"vos-input\"\n aria-invalid={error ? true : undefined}\n />\n ) : field.kind === \"select\" ? (\n <select\n id={id}\n value={String(value ?? \"\")}\n onChange={(e) => onChange(e.target.value)}\n className=\"vos-input\"\n >\n {field.nullable ? <option value=\"\">—</option> : null}\n {field.options?.map((opt) => (\n <option key={opt} value={opt}>\n {opt}\n </option>\n ))}\n </select>\n ) : (\n <input\n id={id}\n type={field.kind === \"number\" ? \"number\" : \"text\"}\n min={field.kind === \"number\" ? field.min : undefined}\n max={field.kind === \"number\" ? field.max : undefined}\n value={String(value ?? \"\")}\n onChange={(e) => onChange(e.target.value)}\n className=\"vos-input\"\n aria-invalid={error ? true : undefined}\n />\n )}\n {error ? (\n <p role=\"alert\" className=\"vos-field-error\">\n {error}\n </p>\n ) : null}\n </div>\n );\n}\n","/**\n * The per-belief journey view-model (OPS-1329) — pure, no React, no I/O, so the\n * whole \"story of one belief travelling the loop\" mapping is unit-tested at this\n * seam (like `understanding.ts` / `pipeline.ts`). It composes, for one belief:\n *\n * - the **rail** — its stage + four meters on the same spine the pipeline uses\n * (the single-belief `deriveBeliefStage`, so board and rail agree);\n * - the **story** — its life ordered into dated events (`assembleJourney`),\n * each given front-door copy here (the assembler stays label-free);\n * - the **next-move card** — the same OPS-1292 ranking the front door reads,\n * filtered to this belief;\n * - the **cycles** (OPS-1347) — the same history regrouped into rounds\n * (`cycles.ts`): one per Experiment run against this belief, plus one\n * closing bucket for bare/direct evidence. Where the story is a flat dated\n * log and `understanding.ts` ranks by how hard each mover pushes, this is\n * the round-by-round shape the operator asked for — \"show each cycle\".\n *\n * The `.tsx` rail + story UI (OPS-1330) mounts thinly over this. Every number is\n * derived through `@validation-os/core`, computed fresh on read, out of the\n * OPS-1251 on-write recompute.\n */\nimport {\n assumptionCompleteness,\n readingBeliefInputs,\n type AnyRecord,\n} from \"@validation-os/core\";\nimport {\n assembleJourney,\n beliefTestMeters,\n deriveBeliefStage,\n emptyTestMeter,\n rankNextMoves,\n type BeliefStage,\n type JourneyEvent,\n type JourneyEventKind,\n type NextMove,\n} from \"@validation-os/core/derivation\";\nimport { resolvedKind, toStageExperimentInput } from \"./pipeline.js\";\nimport { toNextMoveInput, type NextMoveRecords } from \"./next-move.js\";\nimport type { Tone } from \"./primitives.js\";\nimport { liveExperiments, testsAssumption } from \"./derived-views.js\";\nimport { buildCycles, type CycleView } from \"./cycles.js\";\n\n/** A journey event with its front-door copy attached. */\nexport interface JourneyEventView extends JourneyEvent {\n /** Plain-language label the story renders. */\n label: string;\n}\n\nexport interface JourneyView {\n id: string;\n /** The belief statement — the drill-in's headline. */\n statement: string;\n /** The rail: where the belief sits at rest, with its four meters. */\n stage: BeliefStage;\n /** The story: the belief's life, oldest first, `now` last. */\n events: JourneyEventView[];\n /** The loop's rounds, oldest first (OPS-1347) — the same history the story\n * tells, regrouped by Experiment run instead of by dated event. */\n cycles: CycleView[];\n /** The ranked next move for this belief; null once it is resolved. */\n nextMove: NextMove | null;\n /** Killed (Invalidated) / moot / null — the drill-in's terminal state. */\n resolved: \"killed\" | \"moot\" | null;\n}\n\nfunction str(v: unknown): string {\n return typeof v === \"string\" ? v : \"\";\n}\n\n/** The front-door copy for one event kind (the assembler stays label-free). */\nfunction labelFor(event: JourneyEvent): string {\n switch (event.kind) {\n case \"bet\":\n return \"Bet written\";\n case \"score\":\n return \"Impact scored\";\n case \"experiment\":\n return \"Test designed\";\n case \"reading\":\n return event.result ? `Reading — ${event.result}` : \"Reading\";\n case \"confidence-cross\":\n return \"Confidence crossed into the kill zone\";\n case \"now\":\n return \"Now\";\n }\n}\n\n/** The dot's tone against an event — how that moment read for the belief. */\nexport function eventTone(event: JourneyEvent): Tone {\n switch (event.kind) {\n case \"reading\":\n if (event.result === \"Validated\") return \"good\";\n if (event.result === \"Invalidated\") return \"crit\";\n return \"neutral\"; // Inconclusive — it landed, but moved nothing\n case \"confidence-cross\":\n return \"crit\";\n case \"now\":\n return \"accent\";\n default:\n return \"neutral\";\n }\n}\n\n/**\n * The step-in an event offers (OPS-1294's human set: assumption edit · score\n * impact · write decision), or null for an event there is nothing to act on.\n *\n * The story is where step-in lives — the rail is pure status (OPS-1297). Two\n * acts are deliberately absent: designing a test (no experiment-design form on\n * this surface) and recording a reading (its form lives with the evidence, not\n * the narrative). An unscored belief has no `score` event at all, so its\n * score-impact act rides the next-move card instead.\n */\nexport function eventStepIn(\n kind: JourneyEventKind,\n): { form: StoryStepIn; cta: string } | null {\n switch (kind) {\n case \"bet\":\n return { form: \"edit-belief\", cta: \"Edit the bet\" };\n case \"score\":\n return { form: \"score-impact\", cta: \"Re-score\" };\n case \"confidence-cross\":\n return { form: \"write-decision\", cta: \"Kill or re-test\" };\n default:\n return null;\n }\n}\n\n/** The forms the story can open — the OPS-1294 set, minus experiment design. */\nexport type StoryStepIn = \"edit-belief\" | \"score-impact\" | \"write-decision\";\n\n/**\n * Build one belief's journey from the four registers. Returns null when the\n * belief id isn't in the assumptions register. `now` is passed in (an ISO date)\n * so the view-model stays pure — the surface supplies it.\n */\nexport function buildJourney(\n assumptionId: string,\n records: NextMoveRecords,\n now: string,\n): JourneyView | null {\n const belief = records.assumptions.find((a) => a.id === assumptionId);\n if (!belief) return null;\n\n const derived =\n belief.derived && typeof belief.derived === \"object\"\n ? (belief.derived as Record<string, unknown>)\n : {};\n const confidence =\n typeof derived.confidence === \"number\" ? derived.confidence : 0;\n\n // The rail's test meters read only LIVE plans (OPS-1305): an archived plan is\n // no longer a test in flight, so a belief whose only plan is archived reads as\n // Planned (design a test), never Tested — the \"evidence ≠ tested\" rule.\n const live = liveExperiments(records.experiments);\n const test =\n beliefTestMeters(live.map(toStageExperimentInput)).get(assumptionId) ??\n emptyTestMeter();\n const framed = assumptionCompleteness(belief as Record<string, unknown>);\n const stage = deriveBeliefStage({ framed, confidence, test });\n\n const myReadingInputs = records.readings\n .flatMap(readingBeliefInputs)\n .filter((i) => i.assumptionId === assumptionId);\n const myExperiments = live\n .filter((e) => testsAssumption(e, assumptionId))\n .map((e) => ({ id: e.id, date: str(e.Date) || str(e.createdAt) || null }));\n\n const events = assembleJourney({\n belief: {\n createdAt: str(belief.createdAt) || null,\n impactScored: belief.Impact != null,\n },\n readings: myReadingInputs,\n experiments: myExperiments,\n now,\n }).map((event) => ({ ...event, label: labelFor(event) }));\n\n const nextMove =\n rankNextMoves(toNextMoveInput(records)).find(\n (m) => m.assumptionId === assumptionId,\n ) ?? null;\n\n const cycles = buildCycles(assumptionId, records.readings, records.experiments);\n\n return {\n id: assumptionId,\n statement: str(belief.Title),\n stage,\n events,\n cycles,\n nextMove,\n resolved: resolvedKind(belief),\n };\n}\n","/**\n * The per-belief cycles view-model (OPS-1347) — the validation loop's rounds,\n * not just the belief's flat dated event log (`journey.ts`) or the\n * strongest-push-first attribution list (`understanding.ts`). Grounded\n * directly in the registry model (`registry-schema.md`):\n *\n * - a **cycle** is one round of the loop — an Experiment designed against\n * this belief, the (dated) Readings it produced, and the per-belief\n * bar-line verdict it settles at closure. That is literally\n * \"experiment → readings → re-score\", the round the operator asked to\n * see, and it is the only unit the data model pre-registers as a trial:\n * the bar line's `We're right if` / `We're wrong if` are written *before*\n * any Reading exists, so its verdict is a real round boundary, not one we\n * invent;\n * - readings with **no** Experiment (bare/found — a Market-rung commitment\n * or desk research dropped in directly) carry no pre-registered bar, so\n * they are not a \"round\" in that strict sense. They still move the\n * number, so they collect into one closing, kind-`\"direct\"` entry rather\n * than disappearing from the picture.\n *\n * Ordered chronologically (oldest first) — the point of this view is watching\n * the belief move round by round, which `understanding.ts`'s magnitude-first\n * ranking deliberately does not show.\n *\n * No new maths: each round's push on Confidence is read off\n * `confidenceAttribution`'s per-experiment mover — the same decomposition\n * `understanding.ts` shows, just regrouped by time instead of by size, so a\n * cycle's push and the drawer's push always agree. Computed fresh on read,\n * out of the OPS-1251 on-write recompute.\n */\nimport {\n readingBeliefInputs,\n type AnyRecord,\n type BarLine,\n type Result,\n} from \"@validation-os/core\";\nimport { confidenceAttribution } from \"@validation-os/core/derivation\";\nimport {\n isArchivedExperiment,\n liveExperiments,\n readingBeliefFor,\n readingGrades,\n str,\n testsAssumption,\n} from \"./derived-views.js\";\n\n/** The round's key: the experiment id, or `\"direct\"` for the bare-reading bucket. */\nexport const DIRECT_CYCLE_KEY = \"direct\";\n\n/** One reading's place inside a round, reduced to what the timeline draws. */\nexport interface CycleReadingView {\n id: string;\n date: string | null;\n result: Result | null;\n}\n\n/** One round of the loop. */\nexport interface CycleView {\n key: string;\n kind: \"experiment\" | \"direct\";\n /** The experiment's title; null for the direct bucket. */\n title: string | null;\n /** The experiment's lifecycle status; null for the direct bucket. */\n status: string | null;\n /** The round's anchor date: the experiment's own `Date`, or (falling back)\n * its earliest reading's date. Null only when neither is known. */\n date: string | null;\n /** This belief's bar-line verdict, once judged; null pre-closure and always\n * null for the direct bucket (it carries no bar line). */\n barVerdict: Result | null;\n /** The round's readings, oldest first. */\n readings: CycleReadingView[];\n /** Signed push on Confidence this round contributed (sums, across every\n * round, to the belief's Confidence). */\n contribution: number;\n /** |contribution| — how hard this round moved the number. */\n magnitude: number;\n}\n\nfunction readingDate(r: AnyRecord): string | null {\n return str(r.Date);\n}\n\n/** One reading reduced for the timeline — its verdict is this belief's own\n * belief-score Result (the row no longer carries a scalar Result). */\nfunction toCycleReading(r: AnyRecord, assumptionId: string): CycleReadingView {\n return {\n id: r.id,\n date: readingDate(r),\n result: readingBeliefFor(r, assumptionId)?.Result ?? null,\n };\n}\n\nfunction sortByDate(readings: CycleReadingView[]): CycleReadingView[] {\n return [...readings].sort((a, b) => {\n if (a.date === b.date) return 0;\n if (a.date === null) return 1; // undated sinks to the end of its round\n if (b.date === null) return -1;\n return a.date < b.date ? -1 : 1;\n });\n}\n\nfunction barVerdictFor(exp: AnyRecord, assumptionId: string): Result | null {\n const bars = (exp.barLines as BarLine[] | undefined) ?? [];\n const line = bars.find((b) => b.assumptionId === assumptionId);\n return (line?.barVerdict as Result | null | undefined) ?? null;\n}\n\n/**\n * Build one belief's cycles from its readings and the Experiments register.\n * Both arrays are the raw records (Title-cased fields) — the same shape\n * `understanding.ts`/`journey.ts` take — so a caller loading the registers\n * once can hand them straight through.\n */\nexport function buildCycles(\n assumptionId: string,\n readings: AnyRecord[],\n experiments: AnyRecord[],\n): CycleView[] {\n const mine = readings.filter((r) => readingGrades(r, assumptionId));\n const inputs = readings\n .flatMap(readingBeliefInputs)\n .filter((i) => i.assumptionId === assumptionId);\n const { movers } = confidenceAttribution(inputs);\n const moverByKey = new Map(movers.map((m) => [m.key, m]));\n\n const byExperiment = new Map<string, AnyRecord[]>();\n const direct: AnyRecord[] = [];\n for (const r of mine) {\n const expId = str(r.experimentId);\n if (expId) {\n const bucket = byExperiment.get(expId) ?? [];\n bucket.push(r);\n byExperiment.set(expId, bucket);\n } else {\n direct.push(r);\n }\n }\n\n const experimentsById = new Map(experiments.map((e) => [e.id, e]));\n // Every LIVE experiment testing this belief (a bar line naming it) plus any\n // experiment a reading points at that isn't linked via bar lines — the same\n // union `understanding.ts` builds, so no round is silently dropped. Archived\n // plans never form a round (OPS-1305); an absent (missing) plan still does.\n const experimentIds = new Set<string>([\n ...liveExperiments(experiments)\n .filter((e) => testsAssumption(e, assumptionId))\n .map((e) => e.id),\n ...[...byExperiment.keys()].filter((id) => {\n const e = experimentsById.get(id);\n return !e || !isArchivedExperiment(e);\n }),\n ]);\n\n const cycles: CycleView[] = [...experimentIds].map((id) => {\n const exp = experimentsById.get(id);\n const readingViews = sortByDate(\n (byExperiment.get(id) ?? []).map((r) => toCycleReading(r, assumptionId)),\n );\n const mover = moverByKey.get(id);\n const date = (exp ? str(exp.Date) : null) ?? readingViews[0]?.date ?? null;\n return {\n key: id,\n kind: \"experiment\",\n title: exp ? str(exp.Title) : null,\n status: exp ? str(exp.Status) : null,\n date,\n barVerdict: exp ? barVerdictFor(exp, assumptionId) : null,\n readings: readingViews,\n contribution: mover?.contribution ?? 0,\n magnitude: mover?.magnitude ?? 0,\n };\n });\n\n if (direct.length > 0) {\n const readingViews = sortByDate(\n direct.map((r) => toCycleReading(r, assumptionId)),\n );\n const mover = moverByKey.get(DIRECT_CYCLE_KEY);\n cycles.push({\n key: DIRECT_CYCLE_KEY,\n kind: \"direct\",\n title: null,\n status: null,\n date: readingViews[0]?.date ?? null,\n barVerdict: null,\n readings: readingViews,\n contribution: mover?.contribution ?? 0,\n magnitude: mover?.magnitude ?? 0,\n });\n }\n\n // Chronological, oldest first — undated rounds sink to the end rather than\n // jumping the queue, since their place in time is genuinely unknown.\n cycles.sort((a, b) => {\n if (a.date === b.date) return a.key.localeCompare(b.key);\n if (a.date === null) return 1;\n if (b.date === null) return -1;\n return a.date < b.date ? -1 : 1;\n });\n\n return cycles;\n}\n","import { useState } from \"react\";\nimport type { AnyRecord, Result } from \"@validation-os/core\";\nimport type { BeliefStage, NextMove, StageKey } from \"@validation-os/core/derivation\";\nimport { journeyColdState } from \"./cold-start.js\";\nimport type { CycleView } from \"./cycles.js\";\nimport {\n eventStepIn,\n eventTone,\n type JourneyEventView,\n type JourneyView,\n type StoryStepIn,\n} from \"./journey.js\";\nimport { movePresentation } from \"./next-move.js\";\nimport { formatSigned, type Tone } from \"./primitives.js\";\nimport type { Route } from \"./route.js\";\nimport { stageMeters, type StageMeterView } from \"./stage-meters.js\";\nimport {\n EditBeliefForm,\n ScoreImpactForm,\n WriteDecisionForm,\n} from \"./step-in-forms.js\";\nimport { UnderstandingPanel } from \"./understanding-panel.js\";\n\n/**\n * The per-belief journey — the drill-in altitude (design OPS-1297, build\n * OPS-1330), mounted on the record page. An A+B hybrid:\n *\n * - at rest, a compact **read-only stage rail** — the same Framed → Planned →\n * Tested → Known spine the pipeline board draws, zoomed to one belief. The\n * rail is pure status: nothing to act on there;\n * - it **expands into the chronological story** through the record page's\n * existing \"Why?\" reveal idiom — the dated event log (bet → score →\n * experiment → readings → confidence-cross → now), the same history\n * regrouped into **rounds** (OPS-1347 — one card per Experiment run, plus\n * any bare/direct evidence, oldest first), and ending in the ranked\n * next-move card (OPS-1292).\n *\n * **Step-in is story-only** (OPS-1297): the next-move card and the per-event\n * edits carry the OPS-1294 human set (edit the bet · score impact · write\n * decision), and manual override lives at the foot of the story. There is\n * deliberately no experiment-design form here.\n *\n * The narrative is the *loop* story — why the number is what it is. It is not\n * the raw record history: that audit trail belongs to the record page itself\n * (OPS-1282) and this must not retell it. Every number arrives derived through\n * `buildJourney`; nothing is computed here.\n */\nexport interface BeliefJourneyProps {\n /** This belief's journey, already derived (`buildJourney`). */\n journey: JourneyView;\n /** The belief record itself — what the step-in forms write against. */\n assumption: AnyRecord;\n basePath?: string;\n /** Navigate the shell — used by the story's manual override. */\n onNavigate: (route: Route) => void;\n /** Re-read the registers after a step-in writes. */\n onChanged: () => void;\n}\n\n/** Where the belief sits, in plain language — the rail's one-line reading. */\nconst STAGE_SENTENCE: Record<StageKey, string> = {\n framed: \"Still being framed — the bet isn't complete yet.\",\n planned: \"Framed, and waiting on a test to move it.\",\n tested: \"Under test — evidence is landing.\",\n known: \"Every pre-registered bar has settled.\",\n};\n\n/** The event dot's tone → its class. */\nconst DOT_CLASS: Record<Tone, string> = {\n good: \"vos-jny-dot-good\",\n warn: \"vos-jny-dot-warn\",\n crit: \"vos-jny-dot-crit\",\n accent: \"vos-jny-dot-accent\",\n neutral: \"vos-jny-dot-neutral\",\n};\n\nexport function BeliefJourney({\n journey,\n assumption,\n basePath,\n onNavigate,\n onChanged,\n}: BeliefJourneyProps) {\n const [open, setOpen] = useState(false);\n const [stepIn, setStepIn] = useState<StoryStepIn | null>(null);\n\n const closeForm = () => setStepIn(null);\n const afterWrite = () => {\n setStepIn(null);\n onChanged(); // the API recomputed on write — pull the new numbers back in\n };\n\n const { stage, resolved } = journey;\n const coldState = journeyColdState(journey);\n\n return (\n <section className=\"vos-jny vos-card\">\n <div className=\"vos-jny-head\">\n <div>\n <span className=\"vos-jny-eyebrow\">The journey</span>\n <p className=\"vos-jny-at\">\n {resolved\n ? resolved === \"killed\"\n ? \"Killed — the evidence went against it.\"\n : \"Moot — a decision retired the question.\"\n : STAGE_SENTENCE[stage.stage]}\n </p>\n </div>\n {resolved ? (\n <span\n className={`vos-pill ${resolved === \"killed\" ? \"vos-pill-crit\" : \"vos-pill-neutral\"}`}\n >\n {resolved === \"killed\" ? \"Killed\" : \"Moot\"}\n </span>\n ) : stage.killZone ? (\n <span className=\"vos-pill vos-pill-crit\">Kill lane</span>\n ) : null}\n </div>\n\n <StageRail stage={stage} />\n\n <button\n type=\"button\"\n className=\"vos-why vos-jny-why\"\n onClick={() => setOpen((o) => !o)}\n aria-expanded={open}\n >\n {open ? \"Hide the story ▴\" : \"How did it get here? ▾\"}\n </button>\n\n {open ? (\n <div className=\"vos-why-panel vos-jny-story\">\n <section>\n <div className=\"vos-why-section-title\">The story so far</div>\n {coldState.cold ? (\n <JourneyColdCard body={coldState.body} eyebrow={coldState.eyebrow} />\n ) : (\n <ol className=\"vos-jny-events\">\n {journey.events.map((event, i) => (\n <EventRow\n key={`${event.kind}-${event.refId ?? i}`}\n event={event}\n onStepIn={setStepIn}\n />\n ))}\n </ol>\n )}\n </section>\n\n {journey.cycles.length > 0 ? (\n <section>\n <div className=\"vos-why-section-title\">Round by round</div>\n <CycleTimeline cycles={journey.cycles} />\n </section>\n ) : null}\n\n {/* OPS-1276's attribution + trajectory, reused whole — the story says\n what happened; this says what it did to the number. */}\n <section>\n <div className=\"vos-why-section-title\">What moved the number</div>\n <UnderstandingPanel assumption={assumption} basePath={basePath} />\n </section>\n\n <NextMoveCard\n move={journey.nextMove}\n resolved={resolved}\n onAct={setStepIn}\n />\n\n <button\n type=\"button\"\n className=\"vos-override\"\n onClick={() =>\n onNavigate({ name: \"records\", register: \"assumptions\" })\n }\n >\n Act on a different belief →\n </button>\n </div>\n ) : null}\n\n {stepIn === \"edit-belief\" ? (\n <EditBeliefForm\n assumption={assumption}\n basePath={basePath}\n onDone={afterWrite}\n onCancel={closeForm}\n />\n ) : null}\n {stepIn === \"score-impact\" ? (\n <ScoreImpactForm\n assumption={assumption}\n basePath={basePath}\n onDone={afterWrite}\n onCancel={closeForm}\n />\n ) : null}\n {stepIn === \"write-decision\" ? (\n <WriteDecisionForm\n assumption={assumption}\n basePath={basePath}\n kill={stage.killZone}\n onDone={afterWrite}\n onCancel={closeForm}\n />\n ) : null}\n </section>\n );\n}\n\n/** The order the spine runs in — the rail's stops, and how far along we are. */\nconst SPINE: StageKey[] = [\"framed\", \"planned\", \"tested\", \"known\"];\n\n/**\n * The resting rail: the four-stage spine with this belief's meters. Read-only —\n * every act lives in the story (OPS-1297), so nothing here is clickable.\n */\nfunction StageRail({ stage }: { stage: BeliefStage }) {\n const meters = stageMeters(stage);\n const at = SPINE.indexOf(stage.stage);\n return (\n <div\n className=\"vos-jny-rail\"\n role=\"img\"\n aria-label={`Stage ${at + 1} of 4 — ${STAGE_SENTENCE[stage.stage]}`}\n >\n {meters.map((meter, i) => (\n <RailStop\n key={meter.key}\n meter={meter}\n at={i === at}\n done={i < at}\n last={i === meters.length - 1}\n />\n ))}\n </div>\n );\n}\n\nfunction RailStop({\n meter,\n at,\n done,\n last,\n}: {\n meter: StageMeterView;\n at: boolean;\n done: boolean;\n last: boolean;\n}) {\n return (\n <>\n <div\n className={`vos-jny-stop${at ? \" vos-jny-stop-at\" : \"\"}${done ? \" vos-jny-stop-done\" : \"\"}`}\n >\n <div className=\"vos-jny-stopname\">\n <span className=\"vos-jny-stopn\">{meter.n}</span>\n {meter.name}\n </div>\n <div\n className={`vos-jny-track${meter.kind === \"signed\" ? \" vos-jny-known\" : \"\"}`}\n >\n {meter.kind === \"signed\" ? (\n <>\n <span className=\"vos-jny-mid\" />\n {meter.sign !== \"zero\" ? (\n <i\n className={\n meter.sign === \"pos\" ? \"vos-jny-pos\" : \"vos-jny-neg\"\n }\n style={{ width: `${meter.pct}%` }}\n />\n ) : null}\n </>\n ) : (\n <i className=\"vos-jny-fill\" style={{ width: `${meter.pct}%` }} />\n )}\n </div>\n <div className=\"vos-jny-cap\">\n {meter.flag ? (\n <span className=\"vos-jny-flag\">{meter.flag}</span>\n ) : (\n <span className={meter.muted ? \"vos-muted\" : \"\"}>{meter.label}</span>\n )}\n </div>\n </div>\n {last ? null : (\n <span className=\"vos-jny-arrow\" aria-hidden=\"true\">\n →\n </span>\n )}\n </>\n );\n}\n\n/** One dated moment in the belief's life, with its step-in when it has one. */\nfunction EventRow({\n event,\n onStepIn,\n}: {\n event: JourneyEventView;\n onStepIn: (form: StoryStepIn) => void;\n}) {\n const act = eventStepIn(event.kind);\n const conf = event.confidence;\n return (\n <li className={`vos-jny-ev${event.kind === \"now\" ? \" vos-jny-ev-now\" : \"\"}`}>\n <span className={`vos-jny-dot ${DOT_CLASS[eventTone(event)]}`} />\n <span className=\"vos-jny-date\">{event.date ?? \"—\"}</span>\n <span className=\"vos-jny-label\">{event.label}</span>\n {conf !== null ? (\n <span\n className={`vos-pill ${conf < 0 ? \"vos-pill-crit\" : \"vos-pill-good\"} vos-jny-conf`}\n >\n conf {formatSigned(conf)}\n </span>\n ) : null}\n {act ? (\n <button\n type=\"button\"\n className=\"vos-linkbtn vos-jny-act\"\n onClick={() => onStepIn(act.form)}\n >\n {act.cta}\n </button>\n ) : null}\n </li>\n );\n}\n\n/** A reading dot's tone, from its result alone (the cycle cards have no\n * confidence-cross / now to fold in, unlike `eventTone`). */\nfunction readingDotTone(result: Result | null): Tone {\n if (result === \"Validated\") return \"good\";\n if (result === \"Invalidated\") return \"crit\";\n return \"neutral\"; // Inconclusive, or unresolved\n}\n\nconst BAR_VERDICT_PILL: Record<Result, string> = {\n Validated: \"vos-pill vos-pill-good\",\n Invalidated: \"vos-pill vos-pill-crit\",\n Inconclusive: \"vos-pill vos-pill-neutral\",\n};\n\n/**\n * The validation loop, round by round (OPS-1347): one card per cycle — an\n * Experiment's run against this belief, or (failing that) its bare/direct\n * evidence — each with its readings as a dot row, its bar verdict, and how\n * hard the round pushed Confidence. A horizontal strip, oldest round first,\n * so scrolling it *is* watching the belief move.\n */\nfunction CycleTimeline({ cycles }: { cycles: CycleView[] }) {\n const maxMagnitude = Math.max(...cycles.map((c) => c.magnitude), 0.01);\n return (\n <ol className=\"vos-cyc-list\">\n {cycles.map((cycle, i) => (\n <CycleCard key={cycle.key} cycle={cycle} n={i + 1} max={maxMagnitude} />\n ))}\n </ol>\n );\n}\n\nfunction CycleCard({\n cycle,\n n,\n max,\n}: {\n cycle: CycleView;\n n: number;\n max: number;\n}) {\n const up = cycle.contribution >= 0;\n const moving = cycle.magnitude > 0;\n const width = Math.round((cycle.magnitude / max) * 50);\n const fill = up\n ? { left: \"50%\", width: `${width}%`, background: \"var(--vos-good)\" }\n : { right: \"50%\", width: `${width}%`, background: \"var(--vos-crit)\" };\n return (\n <li className=\"vos-cyc-card\">\n <div className=\"vos-cyc-head\">\n <span className=\"vos-cyc-num\">Round {n}</span>\n {cycle.date ? <span className=\"vos-cyc-date\">{cycle.date}</span> : null}\n </div>\n <div className=\"vos-cyc-title\">\n {cycle.kind === \"direct\"\n ? \"Direct evidence\"\n : cycle.title ?? \"Untitled experiment\"}\n </div>\n {cycle.readings.length > 0 ? (\n <div\n className=\"vos-cyc-dots\"\n role=\"img\"\n aria-label={`${cycle.readings.length} reading${cycle.readings.length === 1 ? \"\" : \"s\"}`}\n >\n {cycle.readings.map((r) => (\n <span\n key={r.id}\n className={`vos-jny-dot ${DOT_CLASS[readingDotTone(r.result)]}`}\n />\n ))}\n </div>\n ) : (\n <span className=\"vos-hint\">No readings yet</span>\n )}\n <div className=\"vos-cyc-foot\">\n {cycle.barVerdict ? (\n <span className={BAR_VERDICT_PILL[cycle.barVerdict]}>\n {cycle.barVerdict}\n </span>\n ) : cycle.kind === \"experiment\" ? (\n <span className=\"vos-hint\">\n {cycle.status === \"Closed\" ? \"No bar line\" : \"Bar pending\"}\n </span>\n ) : null}\n {moving ? (\n <span className=\"vos-cyc-push\">\n <span className=\"vos-track vos-signed vos-cyc-track\">\n <i style={fill} />\n </span>\n <span className={up ? \"vos-text-good\" : \"vos-text-crit\"}>\n {formatSigned(cycle.contribution)}\n </span>\n </span>\n ) : null}\n </div>\n </li>\n );\n}\n\n/**\n * Where the story ends: the same ranked move the front door would offer for\n * this belief (OPS-1292), or the note that its journey is over. Step-in adapts\n * to the act (OPS-1294) — a human act opens its form here; an agent-run act\n * says so plainly rather than offering a button that does nothing.\n */\nfunction NextMoveCard({\n move,\n resolved,\n onAct,\n}: {\n move: NextMove | null;\n resolved: \"killed\" | \"moot\" | null;\n onAct: (form: StoryStepIn) => void;\n}) {\n if (resolved) {\n return (\n <div className=\"vos-jny-card vos-jny-card-done\">\n <span className=\"vos-jny-card-eyebrow\">The end of the road</span>\n <p className=\"vos-jny-card-reason\">\n {resolved === \"killed\"\n ? \"This belief is killed — the evidence went against it. It retired its risk; nothing more to test.\"\n : \"This belief is moot — a decision retired the question without a test. It carries no risk now.\"}\n </p>\n </div>\n );\n }\n if (!move) return null;\n\n const pres = movePresentation(move.move);\n return (\n <div\n className={`vos-jny-card${move.killLane ? \" vos-jny-card-kill\" : \"\"}`}\n >\n <span className=\"vos-jny-card-eyebrow\">\n {move.killLane ? \"Kill lane — the evidence has turned\" : \"The next move\"}\n </span>\n <p className=\"vos-jny-card-reason\">{move.reason}</p>\n {pres.steppable && pres.form ? (\n <button\n type=\"button\"\n className=\"vos-btn\"\n onClick={() => onAct(pres.form as StoryStepIn)}\n >\n {pres.cta}\n </button>\n ) : (\n <span className=\"vos-agent-note\">\n 🤖 Claude Code runs this off the dashboard — it'll show up here when\n it lands.\n </span>\n )}\n </div>\n );\n}\n\n/** The no-history cold-state card — replaces the sparse `bet` + `now` events\n * with one guided line that names the belief's next move. */\nfunction JourneyColdCard({\n eyebrow,\n body,\n}: {\n eyebrow: string;\n body: string;\n}) {\n return (\n <div className=\"vos-jny-cold vos-card\">\n <span className=\"vos-jny-card-eyebrow\">{eyebrow}</span>\n <p className=\"vos-jny-card-reason\">{body}</p>\n </div>\n );\n}\n","import { useState } from \"react\";\nimport type { AnyRecord } from \"@validation-os/core\";\nimport { DrawerShell } from \"./drawer-shell.js\";\nimport { buildPatch, draftFrom, type Draft } from \"./edit.js\";\nimport { EditFields } from \"./edit-fields.js\";\nimport { FIELD_CONTROL_CLASS, FIELD_LABEL_CLASS } from \"./field-styles.js\";\nimport { useCreate, useLink } from \"./use-mutations.js\";\nimport { useUpdate } from \"./use-records.js\";\n\n/**\n * The human step-in set (OPS-1294): score impact, write decision, and edit the\n * belief — the small edits a founder makes on the review surface there and then,\n * not where validating happens. The reading form lives with the evidence, and\n * there is deliberately no experiment-design form here (OPS-1297).\n *\n * All three ride the shared `DrawerShell` chrome and write through the\n * Clerk-gated API, which recomputes the derived numbers on write — so the hero's\n * risk chip, the ranking and the journey rail refresh from authoritative\n * numbers, never anything the client computed.\n */\n\nfunction belief(record: AnyRecord): string {\n const title = record[\"Title\"];\n return typeof title === \"string\" && title.trim() ? title : record.id;\n}\n\n// ── Score impact ────────────────────────────────────────────────────────────\n\nexport interface ScoreImpactFormProps {\n /** The assumption being weighted (its version guards the write). */\n assumption: AnyRecord;\n basePath?: string;\n /** Called after a successful save. */\n onDone: () => void;\n onCancel: () => void;\n}\n\n/**\n * Score a belief's Impact — a real input (a slider tied to a number), not a bare\n * cell edit (OPS-1294). Impact is the one hand-scored number Risk propagates\n * from, so scoring it is what lets an unweighted belief take its place in the\n * ranking. The optional justification records *why* that weight.\n */\nexport function ScoreImpactForm({\n assumption,\n basePath,\n onDone,\n onCancel,\n}: ScoreImpactFormProps) {\n const current = assumption[\"Impact\"];\n const [impact, setImpact] = useState<number>(\n typeof current === \"number\" ? current : 50,\n );\n const justificationCurrent = assumption[\"Scoring justification\"];\n const [justification, setJustification] = useState<string>(\n typeof justificationCurrent === \"string\" ? justificationCurrent : \"\",\n );\n const { save, saving, conflict, error } = useUpdate(\"assumptions\", basePath);\n\n const onSubmit = async (e: React.FormEvent) => {\n e.preventDefault();\n if (saving) return;\n const patch: Record<string, unknown> = {\n version: assumption.version,\n Impact: impact,\n };\n const wasJustification =\n typeof justificationCurrent === \"string\" ? justificationCurrent : \"\";\n if (justification.trim() !== wasJustification.trim()) {\n patch[\"Scoring justification\"] = justification.trim();\n }\n const result = await save(assumption.id, patch);\n if (result.ok) onDone();\n };\n\n return (\n <DrawerShell open onClose={onCancel} ariaLabel=\"Score impact\">\n <header className=\"vos-drawer-header\">\n <span className=\"vos-drawer-eyebrow\">Score impact</span>\n <h2 className=\"vos-drawer-title\">{belief(assumption)}</h2>\n </header>\n <form onSubmit={onSubmit} className=\"vos-form\">\n <div className=\"vos-form-body\">\n <div className=\"vos-field\">\n <label htmlFor=\"score-impact-range\" className={FIELD_LABEL_CLASS}>\n Impact if wrong — how much of the plan rests on this?\n </label>\n <div className=\"vos-slider-row\">\n <input\n id=\"score-impact-range\"\n type=\"range\"\n min={0}\n max={100}\n value={impact}\n onChange={(e) => setImpact(Number(e.target.value))}\n className=\"vos-slider\"\n />\n <input\n type=\"number\"\n min={0}\n max={100}\n value={impact}\n onChange={(e) => {\n const n = Number(e.target.value);\n if (!Number.isNaN(n)) setImpact(Math.max(0, Math.min(100, n)));\n }}\n className={`${FIELD_CONTROL_CLASS} vos-slider-num`}\n aria-label=\"Impact (0–100)\"\n />\n </div>\n <p className=\"vos-field-hint\">\n 0 = wouldn't matter · 100 = the plan can't survive it being wrong.\n Risk follows Impact until evidence lands.\n </p>\n </div>\n\n <div className=\"vos-field\">\n <label htmlFor=\"score-impact-why\" className={FIELD_LABEL_CLASS}>\n Why this weight? <span className=\"vos-muted\">(optional)</span>\n </label>\n <textarea\n id=\"score-impact-why\"\n rows={3}\n value={justification}\n onChange={(e) => setJustification(e.target.value)}\n className={FIELD_CONTROL_CLASS}\n placeholder=\"What makes this belief matter as much (or as little) as you scored it?\"\n />\n </div>\n\n {conflict ? <p className=\"vos-error\">{conflict}</p> : null}\n {error ? <p className=\"vos-error\">{error}</p> : null}\n </div>\n <footer className=\"vos-drawer-footer\">\n <button\n type=\"button\"\n onClick={onCancel}\n className=\"vos-btn vos-btn-ghost vos-btn-sm\"\n >\n Cancel\n </button>\n <button type=\"submit\" disabled={saving} className=\"vos-btn vos-btn-sm\">\n {saving ? \"Saving…\" : \"Save impact\"}\n </button>\n </footer>\n </form>\n </DrawerShell>\n );\n}\n\n// ── Edit the belief ──────────────────────────────────────────────────────────\n\nexport interface EditBeliefFormProps {\n /** The assumption being edited (its version guards the write). */\n assumption: AnyRecord;\n basePath?: string;\n /** Called after a successful save. */\n onDone: () => void;\n onCancel: () => void;\n}\n\n/**\n * Edit the bet itself — the assumption-edit half of the OPS-1294 step-in set,\n * reached from the journey story's `bet` event. It renders the register's\n * editable fields from the same schema the drawer uses (`EditFields`), so the\n * two never drift, and writes only the fields actually changed: the patch is\n * diffed against the record it opened on, so a teammate's concurrent edit to an\n * untouched field survives. Framing completeness (the rail's Framed meter)\n * recomputes server-side on write.\n */\nexport function EditBeliefForm({\n assumption,\n basePath,\n onDone,\n onCancel,\n}: EditBeliefFormProps) {\n const [draft, setDraft] = useState<Draft>(() =>\n draftFrom(\"assumptions\", assumption),\n );\n const { save, saving, conflict, error } = useUpdate(\"assumptions\", basePath);\n\n const onSubmit = async (e: React.FormEvent) => {\n e.preventDefault();\n if (saving) return;\n const patch = buildPatch(\"assumptions\", assumption, draft);\n patch.version = assumption.version;\n if (Object.keys(patch).length <= 1) {\n onCancel(); // only `version` present — nothing actually changed\n return;\n }\n const result = await save(assumption.id, patch);\n if (result.ok) onDone();\n };\n\n return (\n <DrawerShell open onClose={onCancel} ariaLabel=\"Edit the bet\">\n <header className=\"vos-drawer-header\">\n <span className=\"vos-drawer-eyebrow\">Edit the bet</span>\n <h2 className=\"vos-drawer-title\">{belief(assumption)}</h2>\n </header>\n <form onSubmit={onSubmit} className=\"vos-form\">\n <div className=\"vos-form-body\">\n <EditFields\n register=\"assumptions\"\n draft={draft}\n onField={(key, value) =>\n setDraft((d) => ({ ...d, [key]: value }))\n }\n />\n {conflict ? <p className=\"vos-error\">{conflict}</p> : null}\n {error ? <p className=\"vos-error\">{error}</p> : null}\n </div>\n <footer className=\"vos-drawer-footer\">\n <button\n type=\"button\"\n onClick={onCancel}\n className=\"vos-btn vos-btn-ghost vos-btn-sm\"\n >\n Cancel\n </button>\n <button type=\"submit\" disabled={saving} className=\"vos-btn vos-btn-sm\">\n {saving ? \"Saving…\" : \"Save the bet\"}\n </button>\n </footer>\n </form>\n </DrawerShell>\n );\n}\n\n// ── Write decision ────────────────────────────────────────────────────────────\n\nconst DECISION_STATUS = [\"Provisional\", \"Active\"] as const;\n\nexport interface WriteDecisionFormProps {\n /** The belief the decision rests on or resolves. */\n assumption: AnyRecord;\n basePath?: string;\n /**\n * A kill-lane decision (Confidence ≤ −50) defaults to *resolving* (retiring)\n * the belief; an ordinary decide defaults to resting *on* it.\n */\n kill?: boolean;\n onDone: () => void;\n onCancel: () => void;\n}\n\n/**\n * Write a decision against a belief (OPS-1294) — create the Decision record and\n * wire it to the belief in one step, honouring the method's `based on` vs\n * `resolves` split: a decision that *rests on* a belief keeps the question open\n * (rationale); one that *resolves* it retires the question without a test\n * (Impact → 0, it goes moot). The kill lane defaults to resolving.\n */\nexport function WriteDecisionForm({\n assumption,\n basePath,\n kill = false,\n onDone,\n onCancel,\n}: WriteDecisionFormProps) {\n const [title, setTitle] = useState(\"\");\n const [status, setStatus] =\n useState<(typeof DECISION_STATUS)[number]>(\"Provisional\");\n const [relation, setRelation] = useState<\"resolves\" | \"based-on\">(\n kill ? \"resolves\" : \"based-on\",\n );\n const { create, saving: creating, error: createError } = useCreate(\n \"decisions\",\n basePath,\n );\n const { link, linking, error: linkError } = useLink(basePath);\n const [failed, setFailed] = useState<string | null>(null);\n\n const busy = creating || linking;\n const missing = title.trim() === \"\";\n\n const onSubmit = async (e: React.FormEvent) => {\n e.preventDefault();\n if (missing || busy) return;\n setFailed(null);\n try {\n const decision = await create({ Title: title.trim(), Status: status });\n await link({\n relation: relation === \"resolves\" ? \"decision-resolves\" : \"decision-based-on\",\n from: { register: \"decisions\", id: decision.id },\n to: { register: \"assumptions\", id: assumption.id },\n });\n onDone();\n } catch {\n // The hooks surface their own message; keep the form open to retry.\n setFailed(\"Couldn't write the decision — please try again.\");\n }\n };\n\n return (\n <DrawerShell open onClose={onCancel} ariaLabel=\"Write decision\">\n <header className=\"vos-drawer-header\">\n <span className=\"vos-drawer-eyebrow\">\n {kill ? \"Kill or re-test\" : \"Write a decision\"}\n </span>\n <h2 className=\"vos-drawer-title\">{belief(assumption)}</h2>\n </header>\n <form onSubmit={onSubmit} className=\"vos-form\">\n <div className=\"vos-form-body\">\n <div className=\"vos-field\">\n <label htmlFor=\"decision-title\" className={FIELD_LABEL_CLASS}>\n The decision <span className=\"vos-req\">*</span>\n </label>\n <input\n id=\"decision-title\"\n type=\"text\"\n value={title}\n onChange={(e) => setTitle(e.target.value)}\n className={FIELD_CONTROL_CLASS}\n placeholder=\"What are you deciding?\"\n />\n </div>\n\n <div className=\"vos-field\">\n <span className={FIELD_LABEL_CLASS}>How does it relate?</span>\n <label className=\"vos-radio\">\n <input\n type=\"radio\"\n name=\"decision-relation\"\n checked={relation === \"based-on\"}\n onChange={() => setRelation(\"based-on\")}\n />\n <span>\n <b>Rests on</b> this belief — the question stays open (rationale).\n </span>\n </label>\n <label className=\"vos-radio\">\n <input\n type=\"radio\"\n name=\"decision-relation\"\n checked={relation === \"resolves\"}\n onChange={() => setRelation(\"resolves\")}\n />\n <span>\n <b>Resolves</b> this belief — retires the question without a test\n (it goes moot).\n </span>\n </label>\n </div>\n\n <div className=\"vos-field\">\n <label htmlFor=\"decision-status\" className={FIELD_LABEL_CLASS}>\n Status\n </label>\n <select\n id=\"decision-status\"\n value={status}\n onChange={(e) =>\n setStatus(e.target.value as (typeof DECISION_STATUS)[number])\n }\n className={FIELD_CONTROL_CLASS}\n >\n {DECISION_STATUS.map((s) => (\n <option key={s} value={s}>\n {s}\n </option>\n ))}\n </select>\n </div>\n\n {(failed || createError || linkError) ? (\n <p className=\"vos-error\">{failed || createError || linkError}</p>\n ) : null}\n </div>\n <footer className=\"vos-drawer-footer\">\n <button\n type=\"button\"\n onClick={onCancel}\n className=\"vos-btn vos-btn-ghost vos-btn-sm\"\n >\n Cancel\n </button>\n <button\n type=\"submit\"\n disabled={missing || busy}\n title={missing ? \"Name the decision\" : undefined}\n className=\"vos-btn vos-btn-sm\"\n >\n {busy ? \"Writing…\" : \"Write decision\"}\n </button>\n </footer>\n </form>\n </DrawerShell>\n );\n}\n","import { useEffect, useRef, type ReactNode } from \"react\";\n\nexport interface DrawerShellProps {\n /** Whether the drawer is mounted/visible. */\n open: boolean;\n onClose: () => void;\n /** Accessible name for the dialog. */\n ariaLabel: string;\n children: ReactNode;\n}\n\n/**\n * The right-hand slide-over chrome shared by the record drawer and the create\n * drawer: a click-to-dismiss scrim, an `aria-modal` panel, Escape-to-close, and\n * focus moved into the panel on open so keyboard users aren't stranded behind\n * the modal. Everything inside is the caller's content. Styled with the\n * package's own token sheet — no host Tailwind.\n */\nexport function DrawerShell({\n open,\n onClose,\n ariaLabel,\n children,\n}: DrawerShellProps) {\n const panelRef = useRef<HTMLDivElement>(null);\n\n useEffect(() => {\n if (!open) return;\n const onKey = (e: KeyboardEvent) => {\n if (e.key === \"Escape\") onClose();\n };\n document.addEventListener(\"keydown\", onKey);\n panelRef.current?.focus();\n return () => document.removeEventListener(\"keydown\", onKey);\n }, [open, onClose]);\n\n if (!open) return null;\n\n return (\n <>\n {/* Scrim — click to dismiss. */}\n <button\n type=\"button\"\n aria-label=\"Close\"\n onClick={onClose}\n className=\"vos-scrim\"\n />\n <aside\n ref={panelRef}\n role=\"dialog\"\n aria-modal=\"true\"\n aria-label={ariaLabel}\n tabIndex={-1}\n className=\"vos-drawer\"\n >\n {children}\n </aside>\n </>\n );\n}\n","/**\n * Shared class names for form controls, so the create form and the relation\n * editor render identical inputs (and any restyle happens in one place). These\n * are the package's own semantic classes, backed by the `styles.css` token\n * sheet — no host Tailwind.\n */\n\nexport const FIELD_LABEL_CLASS = \"vos-field-label\";\n\nexport const FIELD_CONTROL_CLASS = \"vos-input\";\n","import { useCallback, useState } from \"react\";\nimport type { AnyRecord, Collection, Relation } from \"@validation-os/core\";\n\n/**\n * Client write hooks — the create + link counterparts to `use-records`'\n * read hooks. Both POST through the Clerk-gated API (`POST {basePath}/{register}`\n * and `POST {basePath}/link`), so the browser never touches Firestore and the\n * server always recomputes derived fields. Each returns a `pending`/`error`\n * pair and an action that resolves to the result (or throws), so the caller can\n * refresh the list/record afterwards.\n */\n\n/** Pull the API's `{ data }` envelope, or throw its plain-language message. */\nasync function postJson<T>(url: string, body: unknown): Promise<T> {\n const res = await fetch(url, {\n method: \"POST\",\n headers: { \"content-type\": \"application/json\" },\n body: JSON.stringify(body),\n });\n const payload = (await res.json().catch(() => null)) as\n | { data?: T; message?: string; error?: string }\n | null;\n if (!res.ok) {\n const message =\n payload?.message ?? payload?.error ?? `Request failed (${res.status})`;\n throw new Error(message);\n }\n return (payload as { data: T }).data;\n}\n\nexport interface UseCreateResult {\n create: (data: Record<string, unknown>) => Promise<AnyRecord>;\n saving: boolean;\n error: string | null;\n}\n\n/** Create a record in `register`; the server stamps derived fields on write. */\nexport function useCreate(\n register: Collection,\n basePath = \"/api\",\n): UseCreateResult {\n const [saving, setSaving] = useState(false);\n const [error, setError] = useState<string | null>(null);\n\n const create = useCallback(\n async (data: Record<string, unknown>) => {\n setSaving(true);\n setError(null);\n try {\n return await postJson<AnyRecord>(`${basePath}/${register}`, data);\n } catch (e) {\n const message = e instanceof Error ? e.message : \"Failed to create\";\n setError(message);\n throw e;\n } finally {\n setSaving(false);\n }\n },\n [register, basePath],\n );\n\n return { create, saving, error };\n}\n\nexport interface LinkArgs {\n relation: Relation;\n from: { register: Collection; id: string };\n to: { register: Collection; id: string };\n}\n\nexport interface UseLinkResult {\n link: (args: LinkArgs) => Promise<void>;\n linking: boolean;\n error: string | null;\n}\n\n/** Wire a relation; the API sets both ends and recomputes derived fields. */\nexport function useLink(basePath = \"/api\"): UseLinkResult {\n const [linking, setLinking] = useState(false);\n const [error, setError] = useState<string | null>(null);\n\n const link = useCallback(\n async (args: LinkArgs) => {\n setLinking(true);\n setError(null);\n try {\n await postJson<unknown>(`${basePath}/link`, args);\n } catch (e) {\n const message = e instanceof Error ? e.message : \"Failed to link\";\n setError(message);\n throw e;\n } finally {\n setLinking(false);\n }\n },\n [basePath],\n );\n\n return { link, linking, error };\n}\n","/**\n * The dashboard's visual primitives, rendered in the package's own semantic\n * classes (backed by the `styles.css` token sheet) — never host Tailwind. Each\n * is a thin wrapper over the pure logic in `primitives.ts`, so the mapping is\n * tested there and the markup stays trivial. These are the bricks the register\n * views and the assembled app compose.\n */\nimport type { ReactNode } from \"react\";\nimport {\n confidenceTone,\n formatCount,\n formatSigned,\n riskFraction,\n riskLevel,\n sparklinePath,\n sparklineY,\n statusTone,\n type Tone,\n} from \"./primitives.js\";\n\nconst PILL_CLASS: Record<Tone, string> = {\n good: \"vos-pill vos-pill-good\",\n warn: \"vos-pill vos-pill-warn\",\n crit: \"vos-pill vos-pill-crit\",\n accent: \"vos-pill vos-pill-accent\",\n neutral: \"vos-pill vos-pill-neutral\",\n};\n\n/** A colored status pill — tone from the status, the label shown verbatim. */\nexport function StatusPill({ status }: { status: string | null | undefined }) {\n if (!status) return <span className=\"vos-muted\">—</span>;\n return <span className={PILL_CLASS[statusTone(status)]}>{status}</span>;\n}\n\nconst FILL_CLASS: Record<Tone, string> = {\n good: \"vos-fill-good\",\n warn: \"vos-fill-warn\",\n crit: \"vos-fill-crit\",\n accent: \"vos-fill-good\",\n neutral: \"vos-fill-good\",\n};\nconst TEXT_CLASS: Record<Tone, string> = {\n good: \"vos-text-good\",\n warn: \"vos-text-warn\",\n crit: \"vos-text-crit\",\n accent: \"vos-text-good\",\n neutral: \"\",\n};\n\n/**\n * A risk bar (0–100) plus its number, both toned by threshold: a longer, redder\n * bar means a riskier belief the eye should land on first (spec story 5).\n */\nexport function RiskBar({ risk }: { risk: number }) {\n const level = riskLevel(risk);\n const pct = Math.round(riskFraction(risk) * 100);\n return (\n <span className=\"vos-metric-cell\">\n <span\n className=\"vos-risk-bar\"\n role=\"img\"\n aria-label={`Risk ${Math.round(risk)} of 100`}\n >\n <i className={FILL_CLASS[level]} style={{ width: `${pct}%` }} />\n </span>\n <b className={`vos-metric-num ${TEXT_CLASS[level]}`}>{Math.round(risk)}</b>\n </span>\n );\n}\n\n/**\n * A signed confidence reading: a tiny sparkline of its trajectory when a\n * history is available, always the +/- number (negative reads crit) — so a row\n * shows both where a belief stands and, when known, which way it is trending\n * (spec story 6). With no history the number stands alone; the list endpoint\n * carries no per-row series, so the in-row sparkline appears wherever a caller\n * does have one (e.g. the drawer trajectory uses `Sparkline` directly).\n */\nexport function ConfidenceCell({\n confidence,\n history,\n}: {\n confidence: number;\n history?: number[];\n}) {\n const tone = confidenceTone(confidence);\n return (\n <span className=\"vos-metric-cell\">\n {history && history.length >= 2 ? (\n <Sparkline\n values={history}\n width={46}\n height={16}\n min={-100}\n max={100}\n tone={tone}\n />\n ) : null}\n <b className={`vos-metric-num ${TEXT_CLASS[tone]}`}>\n {formatSigned(confidence)}\n </b>\n </span>\n );\n}\n\nconst STROKE_VAR: Record<Tone, string> = {\n good: \"var(--vos-good)\",\n warn: \"var(--vos-warn)\",\n crit: \"var(--vos-crit)\",\n accent: \"var(--vos-accent)\",\n neutral: \"var(--vos-muted)\",\n};\n\n/**\n * A signed sparkline over `values`. A zero baseline is drawn whenever the domain\n * spans it, so a line dipping below zero reads as a belief losing ground. The\n * last point gets a dot. `fill` shades the area under the line. Pure geometry\n * comes from `sparklinePath`/`sparklineY`.\n */\nexport function Sparkline({\n values,\n width = 240,\n height = 44,\n min,\n max,\n tone = \"good\",\n fill = false,\n ariaLabel,\n}: {\n values: number[];\n width?: number;\n height?: number;\n min?: number;\n max?: number;\n tone?: Tone;\n fill?: boolean;\n ariaLabel?: string;\n}) {\n const d = sparklinePath(values, width, height, min, max);\n if (!d) return null;\n const lo = min ?? Math.min(...values, 0);\n const hi = max ?? Math.max(...values, 0);\n const stroke = STROKE_VAR[tone];\n const last = values[values.length - 1]!;\n const lastX = width - 2;\n const lastY = sparklineY(last, height, lo, hi);\n const zeroY = sparklineY(0, height, lo, hi);\n const showBaseline = lo < 0 && hi > 0;\n return (\n <svg\n className=\"vos-spark\"\n width={width}\n height={height}\n viewBox={`0 0 ${width} ${height}`}\n preserveAspectRatio=\"none\"\n role=\"img\"\n aria-label={ariaLabel ?? `Trend, now ${formatSigned(last)}`}\n >\n {fill ? (\n <path\n d={`${d} L ${width - 2} ${height} L 2 ${height} Z`}\n fill={stroke}\n opacity=\"0.13\"\n />\n ) : null}\n {showBaseline ? (\n <line\n x1={2}\n x2={width - 2}\n y1={zeroY}\n y2={zeroY}\n stroke=\"var(--vos-border-strong)\"\n strokeWidth={1}\n strokeDasharray=\"3 3\"\n />\n ) : null}\n <path d={d} fill=\"none\" stroke={stroke} strokeWidth={2} />\n <circle cx={lastX} cy={lastY} r={3} fill={stroke} />\n </svg>\n );\n}\n\n/**\n * A glanceable stat tile — a label, a big number, and an optional sub-caption.\n * Becomes a button when `onClick` is given (counts that double as nav). Pure\n * presentation; the caller supplies the value.\n */\nexport function StatTile({\n label,\n value,\n sub,\n onClick,\n active,\n}: {\n label: string;\n value: number;\n sub?: ReactNode;\n onClick?: () => void;\n active?: boolean;\n}) {\n const body = (\n <>\n <div className=\"vos-tile-label\">{label}</div>\n <div className=\"vos-tile-value\">{formatCount(value)}</div>\n {sub ? <div className=\"vos-tile-sub\">{sub}</div> : null}\n </>\n );\n if (onClick) {\n return (\n <button\n type=\"button\"\n className=\"vos-tile\"\n onClick={onClick}\n aria-pressed={active}\n >\n {body}\n </button>\n );\n }\n return <div className=\"vos-tile\">{body}</div>;\n}\n","/**\n * The understanding layer's data join (OPS-1276). Pure: given an assumption\n * and the readings + experiments registers, it produces everything the Reveal\n * shows — the experiments testing the belief (each with how hard it moves\n * Confidence and how close it is to concluding), the goal/direct evidence that\n * also moves the number, and the Confidence-over-time trajectory.\n *\n * The record → derivation-input mapping is `@validation-os/core`'s shared\n * `readingBeliefInputs`, which fans a reading row out into one input per belief;\n * we keep this belief's inputs, so a reading is read here exactly as it is\n * server-side. Archived experiments never surface here (OPS-1305) — the \"Why?\"\n * only ever shows a live plan or direct evidence.\n */\nimport {\n readingBeliefInputs,\n type AnyRecord,\n type BarLine,\n} from \"@validation-os/core\";\nimport {\n confidenceAttribution,\n confidenceTrajectory,\n experimentProgress,\n isConcluded,\n type MoverKind,\n type Progress,\n type TrajectoryPoint,\n} from \"@validation-os/core/derivation\";\nimport {\n isArchivedExperiment,\n liveExperiments,\n str,\n testsAssumption,\n} from \"./derived-views.js\";\n\n/** An experiment testing this assumption: how hard it moves Confidence, and\n * how close it is to concluding. `contribution` is 0 for a running experiment\n * that has not produced a concluded reading yet — it still shows, so its\n * progress-to-conclusion is visible. */\nexport interface ExperimentView {\n experimentId: string;\n title: string | null;\n status: string | null;\n /** Signed push on Confidence; 0 until a concluded reading lands. */\n contribution: number;\n magnitude: number;\n /** Concluded readings this experiment has produced for the belief. */\n readingCount: number;\n progress: Progress | null;\n /** Concluded/closed — reads as done rather than in-flight. */\n done: boolean;\n}\n\n/** Direct evidence that moves Confidence but is not tied to an experiment\n * (a bare/found reading, or a Market-rung reading with no plan). */\nexport interface OtherMover {\n key: string;\n kind: Exclude<MoverKind, \"experiment\">;\n contribution: number;\n magnitude: number;\n readingCount: number;\n}\n\nexport interface Understanding {\n /** The same Confidence the derived box shows. */\n confidence: number;\n /** Experiments testing this belief, ranked by how hard they push. */\n experiments: ExperimentView[];\n /** Goal/direct evidence that also moves the number. */\n otherMovers: OtherMover[];\n /** Confidence over time; empty when no concluded reading is dated. */\n trajectory: TrajectoryPoint[];\n /** Concluded readings feeding the number, across all sources. */\n readingCount: number;\n}\n\nexport function buildUnderstanding(\n assumption: AnyRecord,\n readings: AnyRecord[],\n experiments: AnyRecord[],\n): Understanding {\n const inputs = readings\n .flatMap(readingBeliefInputs)\n .filter((i) => i.assumptionId === assumption.id);\n const { confidence, movers } = confidenceAttribution(inputs);\n\n const experimentsById = new Map(experiments.map((e) => [e.id, e]));\n const moverByExperiment = new Map(\n movers.filter((m) => m.kind === \"experiment\").map((m) => [m.experimentId!, m]),\n );\n\n // Every live experiment testing this belief — whether or not it has moved the\n // number yet — plus any experiment a reading points at that isn't linked via\n // bar lines. So a freshly-started plan with no readings still shows. Archived\n // plans are dropped entirely (OPS-1305): never a mover, never a row. A plan a\n // reading points at but that isn't in the register is kept (absent ≠ archived).\n const experimentIds = new Set<string>([\n ...liveExperiments(experiments)\n .filter((e) => testsAssumption(e, assumption.id))\n .map((e) => e.id),\n ...[...moverByExperiment.keys()].filter((id) => {\n const e = experimentsById.get(id);\n return !e || !isArchivedExperiment(e);\n }),\n ]);\n\n const experimentViews: ExperimentView[] = [...experimentIds].map((id) => {\n const exp = experimentsById.get(id);\n const mover = moverByExperiment.get(id);\n const bars = (exp?.barLines as BarLine[] | undefined) ?? [];\n const progress = bars.length ? experimentProgress(bars) : null;\n const status = exp ? str(exp.Status) : null;\n return {\n experimentId: id,\n title: exp ? str(exp.Title) : null,\n status,\n contribution: mover?.contribution ?? 0,\n magnitude: mover?.magnitude ?? 0,\n readingCount: mover?.readingCount ?? 0,\n progress,\n done: status === \"Closed\" || progress?.concluded === true,\n };\n });\n // Strongest movers first; among non-movers, in-flight before done, then id.\n experimentViews.sort(\n (a, b) =>\n b.magnitude - a.magnitude ||\n Number(a.done) - Number(b.done) ||\n a.experimentId.localeCompare(b.experimentId),\n );\n\n const otherMovers: OtherMover[] = movers\n .filter((m) => m.kind !== \"experiment\")\n .map((m) => ({\n key: m.key,\n kind: m.kind as OtherMover[\"kind\"],\n contribution: m.contribution,\n magnitude: m.magnitude,\n readingCount: m.readingCount,\n }));\n\n return {\n confidence,\n experiments: experimentViews,\n otherMovers,\n trajectory: confidenceTrajectory(inputs),\n readingCount: inputs.filter((r) => isConcluded(r.result)).length,\n };\n}\n","import type { ReactNode } from \"react\";\nimport type { AnyRecord } from \"@validation-os/core\";\nimport type { TrajectoryPoint } from \"@validation-os/core/derivation\";\nimport { useList } from \"./use-records.js\";\nimport { Sparkline } from \"./primitives-view.js\";\nimport { confidenceTone, formatSigned } from \"./primitives.js\";\nimport {\n buildUnderstanding,\n type ExperimentView,\n type OtherMover,\n} from \"./understanding.js\";\n\n/**\n * The understanding layer behind the Confidence \"Why?\" (OPS-1276): which\n * experiments move the number (ranked by push) and how close each running\n * experiment is to concluding, the goal/direct evidence that also moves it, and\n * Confidence over time. It lazy-loads the readings + experiments registers (it\n * only mounts when the Reveal is open), then derives everything through the\n * shared derivation module. Restyled into the drawer's accent/pill language\n * (spec story 11): signed push tracks and a signed trajectory sparkline, in the\n * package's own token sheet — no host Tailwind.\n */\nexport function UnderstandingPanel({\n assumption,\n basePath,\n}: {\n assumption: AnyRecord;\n basePath?: string;\n}) {\n const readings = useList(\"readings\", basePath);\n const experiments = useList(\"experiments\", basePath);\n\n if (readings.loading || experiments.loading) {\n return <Muted>Working out what moved the number…</Muted>;\n }\n if (readings.error || experiments.error) {\n return <Muted>Couldn't load the evidence behind this number.</Muted>;\n }\n\n const u = buildUnderstanding(\n assumption,\n readings.records ?? [],\n experiments.records ?? [],\n );\n\n if (u.experiments.length === 0 && u.otherMovers.length === 0) {\n return (\n <Muted>\n No experiments or concluded readings yet — Confidence rests on the\n neutral prior alone.\n </Muted>\n );\n }\n\n // One scale for every push bar so experiments and other evidence compare.\n const maxMagnitude = Math.max(\n ...u.experiments.map((e) => e.magnitude),\n ...u.otherMovers.map((m) => m.magnitude),\n 0.01,\n );\n\n return (\n <>\n {u.experiments.length ? (\n <section>\n <div className=\"vos-why-section-title\">What's moving Confidence</div>\n {u.experiments.map((e) => (\n <PushRow\n key={e.experimentId}\n label={e.title ?? `Experiment ${e.experimentId}`}\n note={experimentDetail(e)}\n contribution={e.contribution}\n magnitude={e.magnitude}\n max={maxMagnitude}\n done={e.done}\n />\n ))}\n </section>\n ) : null}\n\n {u.otherMovers.length ? (\n <section>\n <div className=\"vos-why-section-title\">Other evidence</div>\n {u.otherMovers.map((m) => (\n <PushRow\n key={m.key}\n label={otherMoverLabel(m)}\n contribution={m.contribution}\n magnitude={m.magnitude}\n max={maxMagnitude}\n />\n ))}\n </section>\n ) : null}\n\n <Trajectory points={u.trajectory} />\n </>\n );\n}\n\n/** A labelled row with a signed contribution and a signed push bar (fill left\n * for negative, right for positive; width ∝ push). */\nfunction PushRow({\n label,\n note,\n contribution,\n magnitude,\n max,\n done,\n}: {\n label: string;\n note?: string;\n contribution: number;\n magnitude: number;\n max: number;\n done?: boolean;\n}) {\n const up = contribution >= 0;\n const moving = magnitude > 0;\n const width = Math.round((magnitude / max) * 50);\n const fill = up\n ? { left: \"50%\", width: `${width}%`, background: \"var(--vos-good)\" }\n : { right: \"50%\", width: `${width}%`, background: \"var(--vos-crit)\" };\n return (\n <div className=\"vos-mover\">\n <span className=\"vos-mover-name\">{label}</span>\n {note ? (\n <span className={`vos-mover-note ${done ? \"vos-text-good\" : \"vos-text-warn\"}`}>\n {note}\n </span>\n ) : null}\n <span className=\"vos-track vos-signed\">\n {moving ? <i style={fill} /> : null}\n </span>\n <span\n className=\"vos-mover-val\"\n style={{ color: up ? \"var(--vos-good)\" : \"var(--vos-crit)\" }}\n >\n {moving ? formatSigned(contribution) : \"—\"}\n </span>\n </div>\n );\n}\n\nfunction Trajectory({ points }: { points: TrajectoryPoint[] }) {\n if (points.length < 2) {\n return (\n <p className=\"vos-hint\">\n {points.length === 1\n ? `One dated reading so far — Confidence ${formatSigned(points[0]!.confidence)} on ${points[0]!.date}.`\n : \"No dated readings yet to chart a trajectory.\"}\n </p>\n );\n }\n const first = points[0]!;\n const last = points[points.length - 1]!;\n const values = points.map((p) => p.confidence);\n return (\n <div className=\"vos-traj\">\n <div className=\"vos-traj-head\">\n <span className=\"vos-lbl\">Confidence over time</span>\n </div>\n <Sparkline\n values={values}\n width={260}\n height={44}\n min={-100}\n max={100}\n tone={confidenceTone(last.confidence)}\n fill\n ariaLabel={`Confidence moved from ${formatSigned(first.confidence)} to ${formatSigned(last.confidence)}`}\n />\n <div className=\"vos-traj-foot\">\n <span>{first.date}</span>\n <span className=\"vos-num\">now {formatSigned(last.confidence)}</span>\n </div>\n </div>\n );\n}\n\nfunction experimentDetail(e: ExperimentView): string {\n const evidence =\n e.readingCount === 0\n ? \"No readings yet\"\n : `${e.readingCount} reading${e.readingCount === 1 ? \"\" : \"s\"}`;\n const p = e.progress;\n if (e.done) {\n return p\n ? `Concluded · ${p.total} of ${p.total} bars settled`\n : `Concluded · ${evidence}`;\n }\n if (!p || p.total === 0) return `${evidence} · no pre-registered bars`;\n return `${evidence} · ${p.settled} of ${p.total} bars settled · ${p.toGo} to go`;\n}\n\nfunction otherMoverLabel(m: OtherMover): string {\n return m.readingCount === 1 ? \"A direct reading\" : \"Direct readings\";\n}\n\nfunction Muted({ children }: { children: ReactNode }) {\n return <p className=\"vos-hint\">{children}</p>;\n}\n","/**\n * The list-surface view-model (OPS-1287) — the pure shaped-query layer above the\n * flat `RegisterTable`. Given a register's records (plus, for the cross-register\n * views, the other registers), it computes the canonical derived-view tabs, the\n * group-by boards, the filtered/sorted rows, the readings-under-plan nesting, and\n * the needs-a-human counts. DOM-free and unit-tested at this seam exactly like\n * `columns.ts`; `RegisterBrowser` renders what it returns.\n *\n * The tabs are **derived views, never stored** — each is a predicate over the\n * records (and, where the ontology's derived view needs it, the other\n * registers). Membership is recomputed on every read, so renames, new readings,\n * and status changes are always reflected. Saved views are the same shaped query\n * under a user name, kept as a separate list from these canonical tabs.\n */\nimport type { AnyRecord, Collection } from \"@validation-os/core\";\nimport { riskBand, type RiskBand } from \"./primitives.js\";\nimport {\n derivedNum,\n inKillLane,\n isTesting,\n readingBeliefFor,\n readingBeliefs,\n str,\n strList,\n} from \"./derived-views.js\";\n\n/** A reading is concluded when any of its belief-scores landed a verdict\n * (Validated/Invalidated); Inconclusive-only readings move nothing. */\nfunction hasConcludedBelief(r: AnyRecord): boolean {\n return readingBeliefs(r).some((b) => b.Result !== \"Inconclusive\");\n}\n\n// ── Shaped-query descriptor ──────────────────────────────────────────────────\n\n/** A group-by axis. Only assumptions expose the full set; see `groupByAxesFor`. */\nexport type GroupByAxis = \"Lens\" | \"Theme\" | \"Risk band\" | \"Status\" | \"Owner\";\n\nexport interface SortSpec {\n /** A record field or a `derived.*` key (risk / confidence / strength …). */\n key: string;\n dir: \"asc\" | \"desc\";\n}\n\n/** The query that shapes a register view — all optional, all recomputable. */\nexport interface ViewDescriptor {\n /** Which canonical tab; defaults to the register's default tab. */\n tabId?: string;\n /** Group rows by an axis, or null for a flat list. */\n groupBy?: GroupByAxis | null;\n /** Sort override; null falls back to the tab's default sort. */\n sort?: SortSpec | null;\n /** Free-text filter over Title + Description, case-insensitive. */\n query?: string;\n}\n\n/** A saved view is a named shaped query, kept apart from the canonical tabs. */\nexport interface SavedView extends ViewDescriptor {\n name: string;\n}\n\n/**\n * The other registers a cross-register tab reads (Testing/Proven/In-tension),\n * plus the reference date overdue is measured against. Everything optional: a\n * tab whose context is absent simply matches nothing rather than throwing.\n */\nexport interface RegisterContext {\n assumptions?: AnyRecord[];\n experiments?: AnyRecord[];\n readings?: AnyRecord[];\n decisions?: AnyRecord[];\n /** ISO date \"now\" for the Overdue view; omitted → nothing reads overdue. */\n asOf?: string;\n}\n\n// ── Tab catalogue ─────────────────────────────────────────────────────────────\n\n/** A tab as the caller sees it — id + label, and whether it flags a human. */\nexport interface TabDef {\n id: string;\n label: string;\n /** The register lands here first. */\n isDefault?: boolean;\n /** A state that needs a human — surfaced as a nav count badge too (story 20). */\n needsHuman?: boolean;\n}\n\ninterface InternalTab extends TabDef {\n /** Membership predicate — a derived view over the record (+ other registers). */\n predicate: (r: AnyRecord, ctx: RegisterContext) => boolean;\n /** The tab's default sort, applied unless the descriptor overrides it. */\n defaultSort?: SortSpec;\n /** Readings only: this tab nests rows under their evidence plan (story 21). */\n nested?: boolean;\n}\n\n/** Proven (ontology derived view): a Live belief whose strongest concluded\n * belief-score across its readings is Validated. A reading scores per belief\n * now (OPS-1305), so both the strength and the verdict are read off this\n * belief's own entry in each reading's `beliefs[]`, not the retired row scalars. */\nfunction isProven(a: AnyRecord, ctx: RegisterContext): boolean {\n if (str(a.Status) !== \"Live\") return false;\n const scores = (ctx.readings ?? [])\n .map((r) => readingBeliefFor(r, a.id))\n .filter((b): b is NonNullable<typeof b> => b != null && b.Result !== \"Inconclusive\");\n if (scores.length === 0) return false;\n const strongest = scores.reduce((best, b) =>\n Math.abs(b.derived?.strength ?? 0) > Math.abs(best.derived?.strength ?? 0)\n ? b\n : best,\n );\n return strongest.Result === \"Validated\";\n}\n\n/** An overdue running plan: a Deadline in the past relative to `asOf`. */\nfunction isOverdue(e: AnyRecord, ctx: RegisterContext): boolean {\n const deadline = str(e.Deadline);\n if (!ctx.asOf || !deadline || str(e.Status) !== \"Running\") return false;\n return deadline < ctx.asOf;\n}\n\n/** A standing decision in tension: it rests on a belief that has turned against\n * it — an Invalidated assumption, or one now in the kill lane. */\nfunction inTension(d: AnyRecord, ctx: RegisterContext): boolean {\n if (str(d.Status) !== \"Active\") return false;\n const based = strList(d.basedOnIds);\n if (based.length === 0) return false;\n const byId = new Map((ctx.assumptions ?? []).map((a) => [a.id, a]));\n return based.some((id) => {\n const a = byId.get(id);\n if (!a) return false;\n return str(a.Status) === \"Invalidated\" || inKillLane(a);\n });\n}\n\nconst ALWAYS = () => true;\nconst byStatus =\n (...values: string[]) =>\n (r: AnyRecord) =>\n values.includes(str(r.Status) ?? \"\");\n\nconst TAB_CATALOGUE: Record<Collection, InternalTab[]> = {\n assumptions: [\n {\n id: \"live\",\n label: \"Live\",\n isDefault: true,\n predicate: (r) => str(r.Status) === \"Live\" && r.moot !== true,\n defaultSort: { key: \"risk\", dir: \"desc\" },\n },\n {\n id: \"testing\",\n label: \"Testing\",\n predicate: (r, ctx) => isTesting(r, ctx.experiments ?? []),\n },\n {\n id: \"kill-lane\",\n label: \"Kill lane\",\n needsHuman: true,\n predicate: (r) => inKillLane(r),\n },\n { id: \"proven\", label: \"Proven\", predicate: isProven },\n { id: \"moot\", label: \"Moot\", predicate: (r) => r.moot === true },\n { id: \"draft\", label: \"Draft\", predicate: byStatus(\"Draft\") },\n { id: \"invalidated\", label: \"Invalidated\", predicate: byStatus(\"Invalidated\") },\n ],\n experiments: [\n {\n id: \"test-next\",\n label: \"Test-next\",\n isDefault: true,\n // Candidate/designed plans — the pool the prioritisation layer ranks.\n predicate: byStatus(\"Draft\"),\n },\n { id: \"running\", label: \"Running\", predicate: byStatus(\"Running\") },\n { id: \"closed\", label: \"Closed\", predicate: byStatus(\"Closed\") },\n {\n id: \"overdue\",\n label: \"Overdue\",\n needsHuman: true,\n predicate: isOverdue,\n },\n ],\n readings: [\n {\n id: \"recent\",\n label: \"Recent\",\n isDefault: true,\n predicate: ALWAYS,\n defaultSort: { key: \"Date\", dir: \"desc\" },\n },\n {\n id: \"by-origin\",\n label: \"By plan\",\n predicate: ALWAYS,\n nested: true,\n },\n {\n id: \"concluded\",\n label: \"± Concluded\",\n predicate: (r) => hasConcludedBelief(r),\n },\n {\n id: \"inconclusive\",\n label: \"Inconclusive\",\n predicate: (r) => !hasConcludedBelief(r),\n },\n ],\n decisions: [\n {\n id: \"standing\",\n label: \"Standing\",\n isDefault: true,\n predicate: byStatus(\"Active\"),\n },\n { id: \"provisional\", label: \"Provisional\", predicate: byStatus(\"Provisional\") },\n {\n id: \"superseded\",\n label: \"Superseded\",\n predicate: byStatus(\"Superseded\", \"Reversed\"),\n },\n {\n id: \"in-tension\",\n label: \"In tension\",\n needsHuman: true,\n predicate: inTension,\n },\n ],\n glossary: [\n // The migrated glossary carries no area/theme axis, so the prototype's\n // \"By-area\" tab folds into A–Z plus the status views (OPS-1305 schema).\n {\n id: \"a-z\",\n label: \"A–Z\",\n isDefault: true,\n predicate: ALWAYS,\n defaultSort: { key: \"Title\", dir: \"asc\" },\n },\n { id: \"provisional\", label: \"Provisional\", predicate: byStatus(\"Provisional\") },\n { id: \"superseded\", label: \"Superseded\", predicate: byStatus(\"Superseded\") },\n ],\n};\n\n/** The canonical derived-view tabs for a register, in display order. */\nexport function tabsFor(register: Collection): TabDef[] {\n return TAB_CATALOGUE[register].map(({ id, label, isDefault, needsHuman }) => ({\n id,\n label,\n isDefault,\n needsHuman,\n }));\n}\n\n/** The default tab id for a register (the curated front door, story 15). */\nexport function defaultTabId(register: Collection): string {\n const tab = TAB_CATALOGUE[register].find((t) => t.isDefault);\n return (tab ?? TAB_CATALOGUE[register][0]!).id;\n}\n\nfunction findTab(register: Collection, tabId: string | undefined): InternalTab {\n const tabs = TAB_CATALOGUE[register];\n return tabs.find((t) => t.id === tabId) ?? tabs.find((t) => t.isDefault) ?? tabs[0]!;\n}\n\n// ── Group-by ───────────────────────────────────────────────────────────────\n\n/** The group-by axes a register offers. Assumptions get the full set (story 18);\n * the others expose Status, the one axis every register shares. */\nexport function groupByAxesFor(register: Collection): GroupByAxis[] {\n if (register === \"assumptions\")\n return [\"Lens\", \"Theme\", \"Risk band\", \"Status\", \"Owner\"];\n return [\"Status\"];\n}\n\nexport interface GroupBucket {\n /** Stable bucket key. */\n key: string;\n /** Plain-language bucket heading. */\n label: string;\n records: AnyRecord[];\n}\n\nconst RISK_BAND_ORDER: RiskBand[] = [\"Critical\", \"High\", \"Watch\"];\n\n/**\n * Group records by an axis. Risk band uses the three fixed bands in\n * strongest-first order; multi-value axes (Theme, Owner) place a record in every\n * bucket it belongs to, with an explicit empty-value bucket. Single-value axes\n * (Lens, Status) bucket once, empty → an \"—\" bucket. Bucket order is stable:\n * risk band by severity, everything else first-appearance.\n */\nexport function groupRecords(\n records: AnyRecord[],\n axis: GroupByAxis,\n): GroupBucket[] {\n if (axis === \"Risk band\") {\n const buckets = new Map<RiskBand, AnyRecord[]>();\n for (const r of records) {\n const band = riskBand(derivedNum(r, \"risk\") ?? 0);\n (buckets.get(band) ?? buckets.set(band, []).get(band)!).push(r);\n }\n return RISK_BAND_ORDER.filter((b) => buckets.has(b)).map((b) => ({\n key: b,\n label: b,\n records: buckets.get(b)!,\n }));\n }\n\n const multi = axis === \"Theme\" || axis === \"Owner\";\n const order: string[] = [];\n const buckets = new Map<string, AnyRecord[]>();\n const push = (key: string, r: AnyRecord) => {\n if (!buckets.has(key)) {\n buckets.set(key, []);\n order.push(key);\n }\n buckets.get(key)!.push(r);\n };\n const emptyLabel = axis === \"Owner\" ? \"Unassigned\" : \"—\";\n for (const r of records) {\n if (multi) {\n const values = strList(r[axis]);\n if (values.length === 0) push(emptyLabel, r);\n else for (const v of values) push(v, r);\n } else {\n push(str(r[axis]) ?? emptyLabel, r);\n }\n }\n return order.map((key) => ({ key, label: key, records: buckets.get(key)! }));\n}\n\n// ── Filter & sort ─────────────────────────────────────────────────────────────\n\n/** Case-insensitive substring filter over Title + Description + Source. Source\n * (a reading's generator — person / dataset / cohort) is searchable so a\n * teammate can pull every reading from one source by typing its name. */\nexport function filterRecords(records: AnyRecord[], query: string): AnyRecord[] {\n const q = query.trim().toLowerCase();\n if (!q) return records;\n return records.filter((r) => {\n const hay =\n `${str(r.Title) ?? \"\"} ${str(r.Description) ?? \"\"} ${str(r.Source) ?? \"\"}`.toLowerCase();\n return hay.includes(q);\n });\n}\n\n/** Read a sort key off a record — a `derived.*` number or a top-level field. */\nfunction sortValue(r: AnyRecord, key: string): unknown {\n const derived = derivedNum(r, key);\n if (derived !== null) return derived;\n return r[key];\n}\n\n/** A stable sort by one key; numbers compare numerically, everything else by\n * locale string. Missing values sort last regardless of direction. */\nexport function sortRecords(records: AnyRecord[], sort: SortSpec): AnyRecord[] {\n const dir = sort.dir === \"asc\" ? 1 : -1;\n return [...records]\n .map((r, i) => ({ r, i }))\n .sort((a, b) => {\n const av = sortValue(a.r, sort.key);\n const bv = sortValue(b.r, sort.key);\n const aMissing = av === null || av === undefined || av === \"\";\n const bMissing = bv === null || bv === undefined || bv === \"\";\n if (aMissing && bMissing) return a.i - b.i;\n if (aMissing) return 1;\n if (bMissing) return -1;\n let cmp: number;\n if (typeof av === \"number\" && typeof bv === \"number\") cmp = av - bv;\n else cmp = String(av).localeCompare(String(bv));\n return cmp !== 0 ? cmp * dir : a.i - b.i; // stable tie-break\n })\n .map((x) => x.r);\n}\n\n// ── Nesting: readings under their evidence plan ───────────────────────────────\n\nexport interface NestedGroup {\n /** The experiment id, or null for bare/found readings. */\n experimentId: string | null;\n /** The plan's title, or a plain label for the bare bucket. */\n label: string;\n readings: AnyRecord[];\n}\n\n/** Nest readings under their originating evidence plan (story 21). Bare/found\n * readings (no `experimentId`) collect in a trailing \"No plan\" group. Plans keep\n * the order they first appear in `experiments`. */\nexport function nestReadingsByPlan(\n readings: AnyRecord[],\n experiments: AnyRecord[],\n): NestedGroup[] {\n const titleById = new Map(experiments.map((e) => [e.id, str(e.Title)]));\n const order: (string | null)[] = [];\n const groups = new Map<string | null, AnyRecord[]>();\n for (const r of readings) {\n const key = str(r.experimentId);\n if (!groups.has(key)) {\n groups.set(key, []);\n order.push(key);\n }\n groups.get(key)!.push(r);\n }\n // Bare readings last, plans in first-seen order otherwise.\n order.sort((a, b) => Number(a === null) - Number(b === null));\n return order.map((experimentId) => ({\n experimentId,\n label:\n experimentId === null\n ? \"No plan (bare readings)\"\n : titleById.get(experimentId) ?? `Experiment ${experimentId}`,\n readings: groups.get(experimentId)!,\n }));\n}\n\n// ── The shaped view ───────────────────────────────────────────────────────────\n\nexport interface ShapedRegister {\n tabs: TabDef[];\n activeTabId: string;\n groupByAxes: GroupByAxis[];\n activeGroupBy: GroupByAxis | null;\n sort: SortSpec | null;\n query: string;\n /** Rows after tab predicate + filter + sort (the flat list). */\n rows: AnyRecord[];\n /** Group buckets when an axis is active, else null. */\n groups: GroupBucket[] | null;\n /** Readings-under-plan nesting when the active tab nests, else null. */\n nested: NestedGroup[] | null;\n}\n\n/**\n * Shape a register into its tabs, active rows, groups and nesting from a view\n * descriptor. Pure: the same records + descriptor always give the same view. The\n * descriptor round-trips — a saved view's tab/group/sort/query reproduce here.\n */\nexport function shapeRegister(\n register: Collection,\n records: AnyRecord[],\n descriptor: ViewDescriptor = {},\n ctx: RegisterContext = {},\n): ShapedRegister {\n const tab = findTab(register, descriptor.tabId);\n const inTab = records.filter((r) => tab.predicate(r, ctx));\n const filtered = filterRecords(inTab, descriptor.query ?? \"\");\n const sort = descriptor.sort ?? tab.defaultSort ?? null;\n const rows = sort ? sortRecords(filtered, sort) : filtered;\n\n const axes = groupByAxesFor(register);\n const activeGroupBy =\n descriptor.groupBy && axes.includes(descriptor.groupBy)\n ? descriptor.groupBy\n : null;\n const groups = activeGroupBy ? groupRecords(rows, activeGroupBy) : null;\n\n const nested =\n tab.nested && register === \"readings\"\n ? nestReadingsByPlan(rows, ctx.experiments ?? [])\n : null;\n\n return {\n tabs: tabsFor(register),\n activeTabId: tab.id,\n groupByAxes: axes,\n activeGroupBy,\n sort,\n query: descriptor.query ?? \"\",\n rows,\n groups,\n nested,\n };\n}\n\n// ── Needs-a-human counts (the nav badges) ─────────────────────────────────────\n\n/** The needs-a-human counts that surface as nav badges (story 20). */\nexport interface NeedsHumanCounts {\n /** Live beliefs in the kill zone awaiting a human verdict. */\n killLane: number;\n /** Running plans past their deadline. */\n overdue: number;\n /** Standing decisions resting on a belief that turned against them. */\n inTension: number;\n}\n\n/** Count the needs-a-human states across the registers, reusing the same tab\n * predicates so a badge and its tab never disagree. */\nexport function needsHumanCounts(ctx: RegisterContext): NeedsHumanCounts {\n return {\n killLane: (ctx.assumptions ?? []).filter((a) => inKillLane(a)).length,\n overdue: (ctx.experiments ?? []).filter((e) => isOverdue(e, ctx)).length,\n inTension: (ctx.decisions ?? []).filter((d) => inTension(d, ctx)).length,\n };\n}\n","/**\n * The reading detail's per-belief verdict list (OPS-1305) — one artifact row\n * scores several beliefs, so this renders each belief's own take: the\n * assumption (title + link), its Result, derived Strength and the grading\n * justification. Rung AND magnitude band are NOT per belief — they are\n * row-level attributes of the reading now (0.10), shown once as a paired header\n * badge, so neither appears on these cards. This list is the reading detail's\n * centrepiece:\n * a one-line verdict tally leads, then a stack of result-toned cards — a\n * coloured rail and a bold Result pill carry the verdict at a glance, the\n * assumption title anchors each card, and the justification reads as its own\n * quote-set-off prose. Shared by the record page and the drawer so the two\n * never drift.\n */\nimport type { AnyRecord } from \"@validation-os/core\";\nimport { formatSigned } from \"./primitives.js\";\nimport {\n readingBeliefSummary,\n readingBeliefVerdicts,\n type BeliefSummary,\n} from \"./record-view.js\";\n\n/** Verdict pill tone: Validated reads good, Invalidated crit, else neutral. */\nfunction resultClass(result: string | null): string {\n if (result === \"Validated\") return \"vos-pill vos-pill-good\";\n if (result === \"Invalidated\") return \"vos-pill vos-pill-crit\";\n return \"vos-pill vos-pill-neutral\";\n}\n\n/** The card's left-rail tone class, matching the verdict's meaning. */\nfunction verdictTone(result: string | null): string {\n if (result === \"Validated\") return \"is-good\";\n if (result === \"Invalidated\") return \"is-crit\";\n return \"is-neutral\";\n}\n\n/** The one-line tally above the cards — only the non-zero outcomes, each toned,\n * so the headline reads \"3 beliefs · 2 validated · 1 inconclusive\" at a glance. */\nfunction VerdictTally({ summary }: { summary: BeliefSummary }) {\n const parts: { n: number; label: string; cls: string }[] = [\n { n: summary.validated, label: \"validated\", cls: \"vos-tally-good\" },\n { n: summary.inconclusive, label: \"inconclusive\", cls: \"vos-tally-neutral\" },\n { n: summary.invalidated, label: \"invalidated\", cls: \"vos-tally-crit\" },\n ].filter((p) => p.n > 0);\n return (\n <p className=\"vos-verdict-tally\">\n <span className=\"vos-tally-total\">\n {summary.total} belief{summary.total === 1 ? \"\" : \"s\"}\n </span>\n {parts.map((p) => (\n <span key={p.label} className={`vos-tally-part ${p.cls}`}>\n {p.n} {p.label}\n </span>\n ))}\n </p>\n );\n}\n\nexport function BeliefVerdicts({\n reading,\n assumptions,\n onOpenRecord,\n}: {\n reading: AnyRecord;\n assumptions: AnyRecord[];\n onOpenRecord?: (id: string) => void;\n}) {\n const verdicts = readingBeliefVerdicts(reading, assumptions);\n if (verdicts.length === 0) {\n return <p className=\"vos-hint\">This reading grades no beliefs yet.</p>;\n }\n const summary = readingBeliefSummary(reading, assumptions);\n return (\n <div className=\"vos-verdicts-wrap\">\n <VerdictTally summary={summary} />\n <ul className=\"vos-verdicts\">\n {verdicts.map((v) => (\n <li\n key={v.assumptionId}\n className={`vos-verdict ${verdictTone(v.result)}`}\n >\n <div className=\"vos-verdict-head\">\n {v.linked && onOpenRecord ? (\n <button\n type=\"button\"\n className=\"vos-inline-link vos-verdict-title\"\n onClick={() => onOpenRecord(v.assumptionId)}\n >\n {v.title}\n </button>\n ) : (\n <span className=\"vos-verdict-title\">{v.title}</span>\n )}\n <span className={resultClass(v.result)}>{v.result ?? \"Ungraded\"}</span>\n </div>\n {v.strength !== null ? (\n <div className=\"vos-verdict-meta\">\n <span className=\"vos-verdict-strength\">\n Strength {formatSigned(v.strength)}\n </span>\n </div>\n ) : null}\n {v.excerpt ? (\n <p className=\"vos-verdict-quote\">“{v.excerpt}”</p>\n ) : null}\n {v.justification ? (\n <p className=\"vos-verdict-why\">{v.justification}</p>\n ) : null}\n </li>\n ))}\n </ul>\n </div>\n );\n}\n","import { useMemo, useState } from \"react\";\nimport type { AnyRecord, Collection } from \"@validation-os/core\";\nimport { columnsFor, primaryLabel } from \"./columns.js\";\nimport { DrawerShell } from \"./drawer-shell.js\";\nimport { REGISTER_LABEL, REGISTER_SINGULAR } from \"./labels.js\";\nimport {\n needsHumanCounts,\n shapeRegister,\n type GroupByAxis,\n type RegisterContext,\n type SavedView,\n type SortSpec,\n type TabDef,\n type ViewDescriptor,\n} from \"./list-surface.js\";\nimport { RegisterTable } from \"./register-table.js\";\nimport { RecordDrawer } from \"./record-drawer.js\";\nimport { RecordForm } from \"./record-form.js\";\nimport type { RelatedSet } from \"./record-view.js\";\nimport { RelationEditor } from \"./relation-editor.js\";\nimport { useList, useRecord } from \"./use-records.js\";\nimport { useSavedViews } from \"./use-saved-views.js\";\n\nexport interface RegisterBrowserProps {\n register: Collection;\n /** API base path (default `/api`). */\n basePath?: string;\n /** A one-line description under the register title (spec story 7/9). */\n subtitle?: string;\n /** Open a record's canonical full page (story 12). When set, the drawer\n * offers a \"Full page\" link; reads/edits still happen in the peek drawer. */\n onOpenRecord?: (id: string) => void;\n /** Pre-filter applied before tab/free-text — Lens × Stage from the grid. */\n lens?: string;\n stage?: string;\n}\n\n/**\n * Which context registers a register's derived-view tabs — and the record\n * drawer's relation-field/bar-line links (OPS-1345) — read. `assumptions` is\n * also needed on `experiments` (a bar line's `assumptionId`) and `readings`\n * (its own `assumptionId`), not just `decisions` (`Based on`/`Resolves`).\n */\nfunction contextNeeds(register: Collection): {\n experiments: boolean;\n readings: boolean;\n assumptions: boolean;\n} {\n return {\n experiments: register === \"assumptions\" || register === \"readings\",\n readings: register === \"assumptions\",\n assumptions:\n register === \"decisions\" ||\n register === \"experiments\" ||\n register === \"readings\",\n };\n}\n\n/**\n * The browse-create-edit surface for one register. Above the flat table sits the\n * list-surface (OPS-1287): canonical derived-view tabs (a curated default first),\n * a group-by board (assumptions by Lens / Theme / Risk band / Status / Owner),\n * free-text search and sort, readings nested under their evidence plan, and a\n * count badge on the states that need a human. Everything visible is computed by\n * the pure `shapeRegister` view-model; this component just renders it and owns\n * the descriptor state.\n *\n * The write surface is unchanged: a row opens the read/edit/relations drawer, a\n * \"New\" button opens the create form, and all reads/writes go over the Clerk-\n * gated API (which recomputes derived fields on write). The canonical full record\n * page is reachable via the drawer's \"Full page\" link when `onOpenRecord` is set.\n */\nexport function RegisterBrowser({\n register,\n basePath,\n subtitle,\n onOpenRecord,\n lens,\n stage,\n}: RegisterBrowserProps) {\n const { records, loading, error, refresh: refreshList } = useList(\n register,\n basePath,\n );\n\n // Context registers — loaded only when this register's tabs read them.\n const needs = contextNeeds(register);\n const experiments = useList(\"experiments\", basePath, needs.experiments);\n const readings = useList(\"readings\", basePath, needs.readings);\n const assumptions = useList(\"assumptions\", basePath, needs.assumptions);\n\n const [descriptor, setDescriptor] = useState<ViewDescriptor>({});\n const savedViews = useSavedViews(register);\n const [openId, setOpenId] = useState<string | null>(null);\n const [creating, setCreating] = useState(false);\n const {\n record,\n loading: recordLoading,\n error: recordError,\n refresh: refreshRecord,\n } = useRecord(register, openId, basePath);\n\n // \"Today\" for the Overdue view — a stable per-mount value.\n const [asOf] = useState(() => new Date().toISOString().slice(0, 10));\n\n const rows = records ?? [];\n const prefiltered = useMemo(() => {\n return rows.filter((r) => {\n if (lens !== undefined && (r.Lens ?? \"\") !== lens) return false;\n if (stage !== undefined && (r.Stage ?? \"\") !== stage) return false;\n return true;\n });\n }, [rows, lens, stage]);\n const ctx: RegisterContext = {\n asOf,\n assumptions: register === \"assumptions\" ? prefiltered : assumptions.records ?? [],\n experiments: register === \"experiments\" ? prefiltered : experiments.records ?? [],\n readings: register === \"readings\" ? prefiltered : readings.records ?? [],\n decisions: register === \"decisions\" ? prefiltered : [],\n };\n\n const shaped = useMemo(\n () => shapeRegister(register, prefiltered, descriptor, ctx),\n // ctx is derived from the same inputs; listing them keeps the memo honest.\n // eslint-disable-next-line react-hooks/exhaustive-deps\n [register, prefiltered, descriptor, ctx.assumptions, ctx.experiments, ctx.readings, asOf],\n );\n\n // The needs-a-human badge counts, keyed by the tab they belong to — the tab\n // itself carries the `needsHuman` flag (single source in the catalogue), so\n // a badge and its tab can never disagree.\n const counts = needsHumanCounts(ctx);\n const humanCount: Record<string, number> = {\n \"kill-lane\": counts.killLane,\n overdue: counts.overdue,\n \"in-tension\": counts.inTension,\n };\n const badgeFor = (tab: TabDef): number | null => {\n if (!tab.needsHuman) return null;\n const n = humanCount[tab.id] ?? 0;\n return n > 0 ? n : null;\n };\n\n // The drawer's relation/bar-line links (OPS-1345) read the same context\n // registers the derived-view tabs already loaded above — one fetch, two\n // consumers, never the other end of a link is left unresolved.\n const related: RelatedSet = {\n assumptions: ctx.assumptions,\n experiments: ctx.experiments,\n readings: ctx.readings,\n decisions: ctx.decisions,\n };\n\n // Assumption id → title, so a reading row's belief chips (OPS-1305) read as\n // titles. Loaded already for the readings register (see `contextNeeds`).\n const assumptionTitles = new Map(\n (ctx.assumptions ?? []).map((a) => [a.id, primaryLabel(a)]),\n );\n\n const patch = (p: Partial<ViewDescriptor>) =>\n setDescriptor((d) => ({ ...d, ...p }));\n\n const saveCurrentView = () => {\n if (typeof window === \"undefined\") return;\n const name = window.prompt(\"Name this view\");\n if (name) savedViews.save(name, descriptor);\n };\n const applySavedView = (view: SavedView) => {\n const { name: _name, ...rest } = view;\n void _name;\n setDescriptor(rest);\n };\n\n return (\n <div>\n <div className=\"vos-head\">\n <div>\n <h1>{REGISTER_LABEL[register]}</h1>\n {subtitle ? <p>{subtitle}</p> : null}\n </div>\n <div className=\"vos-spacer\" />\n <button\n type=\"button\"\n onClick={() => refreshList()}\n className=\"vos-btn vos-btn-ghost\"\n >\n ↻ Refresh\n </button>\n <button\n type=\"button\"\n onClick={() => setCreating(true)}\n className=\"vos-btn\"\n >\n + New {REGISTER_SINGULAR[register]}\n </button>\n </div>\n\n {/* Canonical derived-view tabs (story 15/16). */}\n <div className=\"vos-tabs\" role=\"tablist\" aria-label=\"Views\">\n {shaped.tabs.map((tab) => {\n const active = tab.id === shaped.activeTabId;\n const badge = badgeFor(tab);\n return (\n <button\n key={tab.id}\n type=\"button\"\n role=\"tab\"\n aria-selected={active}\n className={`vos-tab ${active ? \"is-active\" : \"\"} ${\n tab.needsHuman ? \"vos-tab-human\" : \"\"\n }`}\n onClick={() => patch({ tabId: tab.id })}\n >\n {tab.label}\n {badge !== null ? <span className=\"vos-tab-badge\">{badge}</span> : null}\n </button>\n );\n })}\n </div>\n\n {/* Group-by · sort · search (stories 18/19/23). */}\n <ViewControls\n register={register}\n descriptor={descriptor}\n axes={shaped.groupByAxes}\n onGroupBy={(groupBy) => patch({ groupBy })}\n onSort={(sort) => patch({ sort })}\n onQuery={(query) => patch({ query })}\n />\n\n {/* User saved views — a separate list from the canonical tabs (story 17). */}\n <div className=\"vos-saved-views\">\n <span className=\"vos-saved-label\">Saved views</span>\n {savedViews.views.length === 0 ? (\n <span className=\"vos-hint\">none yet</span>\n ) : (\n savedViews.views.map((v) => (\n <span key={v.name} className=\"vos-saved-view\">\n <button\n type=\"button\"\n className=\"vos-saved-apply\"\n onClick={() => applySavedView(v)}\n >\n {v.name}\n </button>\n <button\n type=\"button\"\n className=\"vos-saved-x\"\n aria-label={`Delete saved view ${v.name}`}\n onClick={() => savedViews.remove(v.name)}\n >\n ×\n </button>\n </span>\n ))\n )}\n <button\n type=\"button\"\n className=\"vos-btn vos-btn-ghost vos-btn-sm\"\n onClick={saveCurrentView}\n >\n + Save this view\n </button>\n </div>\n\n {loading && !records ? (\n <p className=\"vos-muted\">\n Loading {REGISTER_LABEL[register].toLowerCase()}…\n </p>\n ) : error ? (\n <p className=\"vos-error\">{error}</p>\n ) : (\n <ShapedBody\n register={register}\n shaped={shaped}\n onRowClick={setOpenId}\n selectedId={openId}\n assumptionTitles={assumptionTitles}\n />\n )}\n\n <RecordDrawer\n register={register}\n record={record}\n loading={recordLoading}\n error={recordError}\n open={openId !== null}\n onClose={() => setOpenId(null)}\n basePath={basePath}\n onOpenFull={\n onOpenRecord && openId ? () => onOpenRecord(openId) : undefined\n }\n onOpenRecord={onOpenRecord}\n related={related}\n onChanged={() => {\n refreshRecord();\n refreshList();\n }}\n >\n {openId ? (\n <RelationEditor\n register={register}\n recordId={openId}\n basePath={basePath}\n onLinked={() => {\n refreshRecord();\n refreshList();\n }}\n />\n ) : null}\n </RecordDrawer>\n\n <DrawerShell\n open={creating}\n onClose={() => setCreating(false)}\n ariaLabel={`New ${REGISTER_SINGULAR[register]} record`}\n >\n <header className=\"vos-drawer-header\">\n <div>\n <p className=\"vos-drawer-eyebrow\">New</p>\n <h2 className=\"vos-drawer-title\">{REGISTER_SINGULAR[register]}</h2>\n </div>\n </header>\n <RecordForm\n register={register}\n basePath={basePath}\n onCreated={(id) => {\n setCreating(false);\n refreshList();\n setOpenId(id);\n }}\n onCancel={() => setCreating(false)}\n />\n </DrawerShell>\n </div>\n );\n}\n\n/** The group-by / sort / search control row. Sort options come from the\n * register's columns, so grouping never costs the derived-score columns. */\nfunction ViewControls({\n register,\n descriptor,\n axes,\n onGroupBy,\n onSort,\n onQuery,\n}: {\n register: Collection;\n descriptor: ViewDescriptor;\n axes: GroupByAxis[];\n onGroupBy: (axis: GroupByAxis | null) => void;\n onSort: (sort: SortSpec | null) => void;\n onQuery: (query: string) => void;\n}) {\n const sortable = columnsFor(register);\n const sort = descriptor.sort ?? null;\n\n return (\n <div className=\"vos-view-controls\">\n <input\n type=\"search\"\n className=\"vos-input vos-search\"\n placeholder=\"Filter…\"\n value={descriptor.query ?? \"\"}\n onChange={(e) => onQuery(e.target.value)}\n aria-label=\"Filter records\"\n />\n\n {axes.length ? (\n <label className=\"vos-control\">\n <span>Group</span>\n <select\n className=\"vos-input\"\n value={descriptor.groupBy ?? \"\"}\n onChange={(e) =>\n onGroupBy((e.target.value || null) as GroupByAxis | null)\n }\n >\n <option value=\"\">None</option>\n {axes.map((axis) => (\n <option key={axis} value={axis}>\n {axis}\n </option>\n ))}\n </select>\n </label>\n ) : null}\n\n <label className=\"vos-control\">\n <span>Sort</span>\n <select\n className=\"vos-input\"\n value={sort?.key ?? \"\"}\n onChange={(e) =>\n onSort(\n e.target.value\n ? { key: e.target.value, dir: sort?.dir ?? \"desc\" }\n : null,\n )\n }\n >\n <option value=\"\">Default</option>\n {sortable.map((c) => (\n <option key={c.key} value={c.key}>\n {c.header}\n </option>\n ))}\n </select>\n </label>\n\n {sort ? (\n <button\n type=\"button\"\n className=\"vos-btn vos-btn-ghost vos-btn-sm\"\n onClick={() =>\n onSort({ key: sort.key, dir: sort.dir === \"asc\" ? \"desc\" : \"asc\" })\n }\n aria-label={`Sort ${sort.dir === \"asc\" ? \"ascending\" : \"descending\"}`}\n >\n {sort.dir === \"asc\" ? \"↑\" : \"↓\"}\n </button>\n ) : null}\n </div>\n );\n}\n\n/** Renders the shaped view: nested (readings under plan), grouped (a heading +\n * table per bucket), or a single flat table. Every branch reuses `RegisterTable`\n * as the leaf renderer, so the derived-score columns are identical throughout. */\nfunction ShapedBody({\n register,\n shaped,\n onRowClick,\n selectedId,\n assumptionTitles,\n}: {\n register: Collection;\n shaped: ReturnType<typeof shapeRegister>;\n onRowClick: (id: string) => void;\n selectedId: string | null;\n assumptionTitles?: Map<string, string>;\n}) {\n if (shaped.nested) {\n if (shaped.nested.length === 0)\n return <p className=\"vos-empty\">No readings in this view.</p>;\n return (\n <div className=\"vos-groups\">\n {shaped.nested.map((group) => (\n <section key={group.experimentId ?? \"__none__\"} className=\"vos-group\">\n <h3 className=\"vos-group-head\">\n {group.label}\n <span className=\"vos-group-n\">{group.readings.length}</span>\n </h3>\n <RegisterTable\n register={register}\n records={group.readings}\n onRowClick={onRowClick}\n selectedId={selectedId}\n assumptionTitles={assumptionTitles}\n />\n </section>\n ))}\n </div>\n );\n }\n\n if (shaped.groups) {\n if (shaped.groups.length === 0)\n return <p className=\"vos-empty\">No records in this view.</p>;\n return (\n <div className=\"vos-groups\">\n {shaped.groups.map((group) => (\n <section key={group.key} className=\"vos-group\">\n <h3 className=\"vos-group-head\">\n {group.label}\n <span className=\"vos-group-n\">{group.records.length}</span>\n </h3>\n <RegisterTable\n register={register}\n records={group.records}\n onRowClick={onRowClick}\n selectedId={selectedId}\n assumptionTitles={assumptionTitles}\n />\n </section>\n ))}\n </div>\n );\n }\n\n return (\n <RegisterTable\n register={register}\n records={shaped.rows}\n onRowClick={onRowClick}\n selectedId={selectedId}\n assumptionTitles={assumptionTitles}\n />\n );\n}\n","import type { AnyRecord, Collection } from \"@validation-os/core\";\nimport {\n cellValue,\n columnsFor,\n formatValue,\n primaryLabel,\n readingAssumptionChips,\n type ColumnDef,\n} from \"./columns.js\";\nimport { ConfidenceCell, RiskBar, StatusPill } from \"./primitives-view.js\";\n\nexport interface RegisterTableProps {\n register: Collection;\n records: AnyRecord[];\n /** Called with the clicked record's id — opens the read-only drawer. */\n onRowClick?: (id: string) => void;\n /** The id of the currently-open record, highlighted in the list. */\n selectedId?: string | null;\n /** Assumption id → title, so a reading row's belief chips read as titles\n * rather than ids (OPS-1305). Omitted → chips fall back to the bare ids. */\n assumptionTitles?: Map<string, string>;\n}\n\n/**\n * A list table for one register — a row per record, the register's key fields\n * as columns. Assumptions read their state at a glance: a colored Status pill, a\n * signed Confidence, and a threshold-toned Risk bar (spec stories 4–6). Which\n * cells render as pills/bars/sparklines is declared on the column (`kind`), so\n * the treatment stays testable at the columns seam and this component stays a\n * dumb renderer. Presentational: the caller supplies the rows.\n */\nexport function RegisterTable({\n register,\n records,\n onRowClick,\n selectedId,\n assumptionTitles,\n}: RegisterTableProps) {\n const columns = columnsFor(register);\n\n if (records.length === 0) {\n return <p className=\"vos-empty\">No records yet.</p>;\n }\n\n return (\n <div className=\"vos-card vos-table-scroll\">\n <table className=\"vos-table\">\n <thead>\n <tr>\n {columns.map((c) => (\n <th\n key={c.key}\n scope=\"col\"\n className={c.align === \"right\" ? \"vos-r\" : undefined}\n >\n {c.header}\n </th>\n ))}\n </tr>\n </thead>\n <tbody>\n {records.map((record) => {\n const isSelected = record.id === selectedId;\n return (\n <tr\n key={record.id}\n onClick={() => onRowClick?.(record.id)}\n onKeyDown={\n onRowClick\n ? (e) => {\n if (e.key === \"Enter\" || e.key === \" \") {\n e.preventDefault();\n onRowClick(record.id);\n }\n }\n : undefined\n }\n tabIndex={onRowClick ? 0 : undefined}\n aria-selected={isSelected}\n className={isSelected ? \"is-selected\" : undefined}\n >\n {columns.map((c, i) => (\n <td\n key={c.key}\n className={c.align === \"right\" ? \"vos-r\" : undefined}\n >\n <Cell\n column={c}\n record={record}\n headline={i === 0}\n chips={\n i === 0 && register === \"readings\"\n ? readingAssumptionChips(record, assumptionTitles)\n : undefined\n }\n />\n </td>\n ))}\n </tr>\n );\n })}\n </tbody>\n </table>\n </div>\n );\n}\n\n/** One cell, rendered per its column's `kind`. The headline column falls back\n * to the record's id so a row is never blank. */\nfunction Cell({\n column,\n record,\n headline,\n chips,\n}: {\n column: ColumnDef;\n record: AnyRecord;\n headline: boolean;\n /** Belief chips shown under the headline (readings only) to disambiguate\n * same-titled readings by the belief(s) each one grades. */\n chips?: string[];\n}) {\n const raw = cellValue(column, record);\n\n if (column.kind === \"status\") {\n return <StatusPill status={raw == null ? null : String(raw)} />;\n }\n if (column.kind === \"risk\") {\n return typeof raw === \"number\" ? (\n <RiskBar risk={raw} />\n ) : (\n <span className=\"vos-muted\">—</span>\n );\n }\n if (column.kind === \"confidence\") {\n return typeof raw === \"number\" ? (\n <ConfidenceCell confidence={raw} />\n ) : (\n <span className=\"vos-muted\">—</span>\n );\n }\n\n const text =\n headline && (raw === null || raw === undefined || raw === \"\")\n ? primaryLabel(record)\n : formatValue(raw);\n if (headline && chips && chips.length > 0) {\n return (\n <span className=\"vos-ttl-wrap\">\n <span className=\"vos-ttl\">{text}</span>\n <span className=\"vos-reading-chips\">\n {chips.map((chip, n) => (\n <span key={n} className=\"vos-chip vos-pill vos-pill-neutral\">\n {chip}\n </span>\n ))}\n </span>\n </span>\n );\n }\n return <span className={headline ? \"vos-ttl\" : undefined}>{text}</span>;\n}\n","import { useEffect, useState, type ReactNode } from \"react\";\nimport type { AnyRecord, Collection } from \"@validation-os/core\";\nimport { DrawerShell } from \"./drawer-shell.js\";\nimport { REGISTER_LABEL } from \"./labels.js\";\nimport { derivedLabel, formatValue, primaryLabel } from \"./columns.js\";\nimport { detailRows, type DetailRow } from \"./detail-fields.js\";\nimport { derivedTone, formatSigned, heroToneClass } from \"./primitives.js\";\nimport { buildPatch, draftErrors, draftFrom, type Draft } from \"./edit.js\";\nimport { EditFields } from \"./edit-fields.js\";\nimport type { RelatedSet } from \"./record-view.js\";\nimport { useUpdate } from \"./use-records.js\";\nimport { UnderstandingPanel } from \"./understanding-panel.js\";\nimport { EvidenceBody } from \"./markdown.js\";\nimport { BeliefVerdicts } from \"./belief-verdicts.js\";\n\nexport interface RecordDrawerProps {\n register: Collection;\n /** The open record, or null while loading / when nothing is selected. */\n record: AnyRecord | null;\n /** True while the record is being fetched. */\n loading?: boolean;\n error?: string | null;\n /** Whether the drawer is open (a row is selected). */\n open: boolean;\n onClose: () => void;\n /** API base path (default `/api`). */\n basePath?: string;\n /** Re-fetch the record + its list — called after a save, and the re-fetch\n * path offered when a concurrent edit is detected. */\n onChanged?: () => void;\n /** Open this record's canonical full page (story 12). When set, the header\n * shows a \"Full page\" link; the drawer stays the quick read/edit peek. */\n onOpenFull?: () => void;\n /**\n * Open *any* linked record's full page (OPS-1345) — the same navigation the\n * canonical record page's Connections tab uses, reused here so a relation\n * field or a bar line's assumption is a click, not inert text. Falls back\n * to plain (unclickable) titles when omitted.\n */\n onOpenRecord?: (id: string) => void;\n /** The other registers' rows, loaded so a relation field / bar line can\n * resolve to a title instead of a raw id (OPS-1345). Omitted relations\n * simply fall back to showing the id. */\n related?: RelatedSet;\n /** Extra content below the fields in read mode — e.g. the relation editor. */\n children?: ReactNode;\n}\n\n/** Sub-captions under the derived numbers — the formula, in plain language. */\nconst DERIVED_SUB: Record<string, string> = {\n confidence: \"Signed average of concluded readings\",\n risk: \"Impact × (1 − Confidence⁺/100)\",\n derivedImpact: \"Impact re-weighted by links\",\n impact: \"Impact re-weighted by links\",\n strength: \"of the evidence base\",\n sourceQuality: \"of the source\",\n};\n\n/**\n * A record drawer that reads and edits, and wires relations. The derived\n * numbers lead as a visually distinct \"computed — not editable\" hero (spec\n * stories 4/10): a bordered box, each number big and mono, Confidence toned by\n * sign and Risk by threshold, with a \"Why?\" reveal opening the understanding\n * layer in the same accent/pill language (story 11). Editing recomputes those\n * numbers server-side on save; a concurrent edit surfaces as a gentle, jargon-\n * free prompt with a re-fetch path (story 12). In read mode the drawer hosts\n * the relation editor (`children`). Chrome is shared via `DrawerShell`; styled\n * with the package's own token sheet, no host Tailwind.\n */\nexport function RecordDrawer({\n register,\n record,\n loading,\n error,\n open,\n onClose,\n basePath,\n onChanged,\n onOpenFull,\n onOpenRecord,\n related,\n children,\n}: RecordDrawerProps) {\n const [editing, setEditing] = useState(false);\n const [draft, setDraft] = useState<Draft>({});\n // The record as it was when editing began. Diffing the draft against this\n // (not the live `record`) is what makes a conflict re-fetch safe: only the\n // fields the editor actually changed are written, on top of the latest\n // version — so a teammate's concurrent change to an untouched field survives.\n const [baseline, setBaseline] = useState<AnyRecord | null>(null);\n const [why, setWhy] = useState(false);\n const { save, saving, conflict, error: saveError, reset } = useUpdate(\n register,\n basePath,\n );\n\n // Opening a different record drops any in-progress edit and clears banners.\n const recordId = record?.id ?? null;\n useEffect(() => {\n setEditing(false);\n setBaseline(null);\n setWhy(false);\n reset();\n }, [recordId, reset]);\n\n const derived =\n record && record.derived && typeof record.derived === \"object\"\n ? (record.derived as Record<string, unknown>)\n : null;\n\n const rows = record ? detailRows(register, record, related ?? {}) : [];\n\n function startEditing() {\n if (!record) return;\n setBaseline(record);\n setDraft(draftFrom(register, record));\n reset();\n setEditing(true);\n }\n\n function cancelEditing() {\n setEditing(false);\n reset();\n }\n\n async function onSave() {\n if (!record || !baseline) return;\n // A field that fails validation (e.g. Impact outside 0–100) blocks the\n // write entirely — never sent, so the server's own range check is a\n // backstop, not the first line of defence.\n if (Object.keys(draftErrors(register, draft)).length > 0) return;\n // Diff against the baseline (the fields the editor changed), but write\n // against the freshest known version so a reloaded record rebases cleanly.\n const patch = buildPatch(register, baseline, draft);\n patch.version = record.version;\n if (Object.keys(patch).length <= 1) {\n setEditing(false); // only `version` present — nothing actually changed\n return;\n }\n const result = await save(record.id, patch);\n if (result.ok) {\n setEditing(false);\n onChanged?.(); // pull the recomputed record + refreshed list back in\n }\n // On conflict/error the hook holds the message; we stay in edit mode with\n // the draft intact so nothing the editor typed is lost.\n }\n\n function reloadLatest() {\n reset();\n // Re-fetch the latest record; the baseline is kept, so the next save still\n // writes only the fields this editor changed — never the teammate's edits.\n onChanged?.();\n }\n\n const setField = (key: string, value: string) =>\n setDraft((d) => ({ ...d, [key]: value }));\n\n const errors = editing ? draftErrors(register, draft) : {};\n const hasErrors = Object.keys(errors).length > 0;\n\n return (\n <DrawerShell\n open={open}\n onClose={onClose}\n ariaLabel={`${REGISTER_LABEL[register]} record`}\n >\n <header className=\"vos-drawer-header\">\n <div style={{ flex: 1, minWidth: 0 }}>\n <p className=\"vos-drawer-eyebrow\">{REGISTER_LABEL[register]}</p>\n <h2 className=\"vos-drawer-title\">\n {record ? primaryLabel(record) : loading ? \"Loading…\" : \"—\"}\n </h2>\n </div>\n {record ? (\n <span className=\"vos-verbadge\">v{formatValue(record.version)}</span>\n ) : null}\n {record && !editing && onOpenFull ? (\n <button\n type=\"button\"\n onClick={onOpenFull}\n className=\"vos-btn vos-btn-ghost vos-btn-sm\"\n >\n Full page ↗\n </button>\n ) : null}\n {record && !editing ? (\n <button\n type=\"button\"\n onClick={startEditing}\n className=\"vos-btn vos-btn-ghost vos-btn-sm\"\n >\n Edit\n </button>\n ) : null}\n <button\n type=\"button\"\n onClick={onClose}\n className=\"vos-iconbtn\"\n aria-label=\"Close\"\n >\n ✕\n </button>\n </header>\n\n <div className=\"vos-drawer-body\">\n {loading ? (\n <p className=\"vos-muted\">Loading record…</p>\n ) : error ? (\n <p className=\"vos-error\">{error}</p>\n ) : !record ? (\n <p className=\"vos-muted\">No record.</p>\n ) : (\n <>\n {derived ? (\n <div>\n <div className=\"vos-derived\">\n <div className=\"vos-derived-head\">\n Derived\n <span className=\"vos-lock\">🔒 computed on write — not editable</span>\n </div>\n <div className=\"vos-dgrid\">\n {Object.entries(derived).map(([key, value]) => (\n <DerivedCell\n key={key}\n field={key}\n value={value}\n showWhy={key === \"confidence\"}\n whyOpen={why}\n onWhy={() => setWhy((w) => !w)}\n />\n ))}\n </div>\n </div>\n {\"confidence\" in derived && why ? (\n <div className=\"vos-why-panel\">\n <UnderstandingPanel assumption={record} basePath={basePath} />\n </div>\n ) : null}\n </div>\n ) : null}\n\n {conflict ? (\n <ConflictBanner message={conflict} onReload={reloadLatest} />\n ) : null}\n {saveError ? (\n <p role=\"alert\" className=\"vos-banner vos-banner-crit\">\n {saveError}\n </p>\n ) : null}\n\n {editing ? (\n <EditFields\n register={register}\n draft={draft}\n errors={errors}\n onField={setField}\n />\n ) : (\n <>\n <div className=\"vos-detail-list\">\n {rows.map((row) => (\n <DetailRowView\n key={row.key}\n row={row}\n onOpenRecord={onOpenRecord}\n />\n ))}\n </div>\n {typeof record.body === \"string\" && record.body.trim() ? (\n <section className=\"vos-record-prose\">\n <div className=\"vos-detail-k\">\n {register === \"readings\" ? \"Quote\" : \"Narrative\"}\n </div>\n <EvidenceBody\n text={record.body}\n partLabel={register === \"readings\" ? \"Finding\" : \"Part\"}\n />\n </section>\n ) : null}\n {register === \"readings\" ? (\n <section className=\"vos-record-prose\">\n <div className=\"vos-detail-k\">Per-belief verdicts</div>\n <BeliefVerdicts\n reading={record}\n assumptions={related?.assumptions ?? []}\n onOpenRecord={onOpenRecord}\n />\n </section>\n ) : null}\n </>\n )}\n </>\n )}\n </div>\n\n {/* Relation editor (read mode only) — editing keeps the drawer focused. */}\n {record && !loading && !error && !editing ? children : null}\n\n {record && editing ? (\n <footer className=\"vos-drawer-footer\">\n <button\n type=\"button\"\n onClick={cancelEditing}\n disabled={saving}\n className=\"vos-btn vos-btn-ghost vos-btn-sm\"\n >\n Cancel\n </button>\n <button\n type=\"button\"\n onClick={onSave}\n disabled={saving || hasErrors}\n title={hasErrors ? \"Fix the highlighted field before saving\" : undefined}\n className=\"vos-btn vos-btn-sm\"\n >\n {saving ? \"Saving…\" : \"Save\"}\n </button>\n </footer>\n ) : record ? (\n <footer className=\"vos-drawer-footer\">\n {record.id} · updated {formatValue(record.updatedAt)}\n </footer>\n ) : null}\n </DrawerShell>\n );\n}\n\n/** One row in the generic field list (OPS-1345) — a relation field renders\n * as linked title(s), `Owner`/`Agreed by` as plain name(s), `barLines` as\n * structured rows with a linked assumption; everything else is `row.text`\n * from `formatValue`. Never the stored id or raw JSON. */\nfunction DetailRowView({\n row,\n onOpenRecord,\n}: {\n row: DetailRow;\n onOpenRecord?: (id: string) => void;\n}) {\n return (\n <div className=\"vos-detail-row\">\n <span className=\"vos-detail-k\">{row.label}</span>\n <span className=\"vos-detail-v\">\n {row.kind === \"relation\" ? (\n row.items && row.items.length ? (\n <RelationLinks items={row.items} onOpenRecord={onOpenRecord} />\n ) : (\n \"—\"\n )\n ) : row.kind === \"owner\" ? (\n row.names && row.names.length ? row.names.join(\", \") : \"—\"\n ) : row.kind === \"bar-lines\" ? (\n row.bars && row.bars.length ? (\n <ul className=\"vos-bars\">\n {row.bars.map((b, i) => (\n <li key={i} className=\"vos-bar-line\">\n <span className=\"vos-bar-if\">{b.rightIf || \"—\"}</span>\n {b.assumption ? (\n <InlineLink\n id={b.assumption.id}\n title={b.assumption.title}\n onOpenRecord={onOpenRecord}\n />\n ) : null}\n <span\n className={\n b.barVerdict\n ? \"vos-pill vos-pill-good\"\n : \"vos-pill vos-pill-neutral\"\n }\n >\n {b.barVerdict ?? \"open\"}\n </span>\n </li>\n ))}\n </ul>\n ) : (\n \"—\"\n )\n ) : (\n row.text\n )}\n </span>\n </div>\n );\n}\n\n/** A comma-separated list of clickable relation links — falls back to plain\n * (unclickable) titles when no navigate handler is wired. */\nfunction RelationLinks({\n items,\n onOpenRecord,\n}: {\n items: { id: string; title: string }[];\n onOpenRecord?: (id: string) => void;\n}) {\n return (\n <span className=\"vos-detail-links\">\n {items.map((item, i) => (\n <span key={item.id}>\n {i > 0 ? \", \" : null}\n <InlineLink id={item.id} title={item.title} onOpenRecord={onOpenRecord} />\n </span>\n ))}\n </span>\n );\n}\n\n/** One navigable title — a button when a navigate handler is wired, else\n * plain text (still a title, never a raw id). */\nfunction InlineLink({\n id,\n title,\n onOpenRecord,\n}: {\n id: string;\n title: string;\n onOpenRecord?: (id: string) => void;\n}) {\n return onOpenRecord ? (\n <button\n type=\"button\"\n className=\"vos-inline-link\"\n onClick={() => onOpenRecord(id)}\n >\n {title}\n </button>\n ) : (\n <span>{title}</span>\n );\n}\n\n/** One number in the derived hero: label (+ \"Why?\" on Confidence), the big\n * mono value toned by meaning, and the formula sub-caption. */\nfunction DerivedCell({\n field,\n value,\n showWhy,\n whyOpen,\n onWhy,\n}: {\n field: string;\n value: unknown;\n showWhy: boolean;\n whyOpen: boolean;\n onWhy: () => void;\n}) {\n const num = typeof value === \"number\" ? value : null;\n let toneClass = \"\";\n let display = formatValue(value);\n if (num !== null) {\n toneClass = heroToneClass(derivedTone(field, num));\n // Confidence is signed; the other numbers read as whole counts.\n display = field === \"confidence\" ? formatSigned(num) : String(Math.round(num));\n }\n return (\n <div className=\"vos-dcell\">\n <div className=\"vos-dcell-k\">\n {derivedLabel(field)}\n {showWhy ? (\n <button\n type=\"button\"\n className=\"vos-why\"\n onClick={onWhy}\n aria-expanded={whyOpen}\n >\n Why? {whyOpen ? \"▴\" : \"▾\"}\n </button>\n ) : null}\n </div>\n <div className={`vos-dcell-v ${toneClass}`}>{display}</div>\n {DERIVED_SUB[field] ? (\n <div className=\"vos-dcell-sub\">{DERIVED_SUB[field]}</div>\n ) : null}\n </div>\n );\n}\n\nfunction ConflictBanner({\n message,\n onReload,\n}: {\n message: string;\n onReload: () => void;\n}) {\n return (\n <div role=\"alert\" className=\"vos-banner vos-banner-warn\">\n <div className=\"vos-banner-body\">\n <span>{message}</span>\n </div>\n <button type=\"button\" onClick={onReload}>\n Review the latest\n </button>\n </div>\n );\n}\n\n","import { useMemo, useState } from \"react\";\nimport type { Collection } from \"@validation-os/core\";\nimport { REGISTER_LABEL } from \"./labels.js\";\nimport {\n emptyDraft,\n formFieldsFor,\n missingRequired,\n toCreatePayload,\n type FormField,\n} from \"./form-fields.js\";\nimport { FIELD_CONTROL_CLASS, FIELD_LABEL_CLASS } from \"./field-styles.js\";\nimport { useCreate } from \"./use-mutations.js\";\n\nexport interface RecordFormProps {\n register: Collection;\n basePath?: string;\n /** Called with the new record's id after a successful create. */\n onCreated: (id: string) => void;\n onCancel: () => void;\n}\n\n/**\n * The \"new record\" form for one register (spec user story 13). Editable own-\n * fields only — derived numbers are computed server-side and marked\n * computed-not-editable elsewhere; relations are wired by linking after the\n * record exists. Presence-gap fields (5 Whys, etc.) appear as first-class\n * textareas. On submit it POSTs through the API, which recomputes on write.\n */\nexport function RecordForm({\n register,\n basePath,\n onCreated,\n onCancel,\n}: RecordFormProps) {\n const fields = useMemo(() => formFieldsFor(register), [register]);\n const [draft, setDraft] = useState<Record<string, string>>(() =>\n emptyDraft(register),\n );\n const { create, saving, error } = useCreate(register, basePath);\n\n const missing = missingRequired(register, draft);\n const set = (key: string, value: string) =>\n setDraft((d) => ({ ...d, [key]: value }));\n\n const onSubmit = async (e: React.FormEvent) => {\n e.preventDefault();\n if (missing.length > 0 || saving) return;\n try {\n const created = await create(toCreatePayload(register, draft));\n onCreated(created.id);\n } catch {\n // The hook surfaces the message in `error`; keep the form open to retry.\n }\n };\n\n return (\n <form onSubmit={onSubmit} className=\"vos-form\">\n <div className=\"vos-form-body\">\n {fields.map((field) => (\n <Field\n key={field.key}\n field={field}\n value={draft[field.key] ?? \"\"}\n onChange={(v) => set(field.key, v)}\n />\n ))}\n {error ? <p className=\"vos-error\">{error}</p> : null}\n </div>\n\n <footer className=\"vos-drawer-footer\">\n <button type=\"button\" onClick={onCancel} className=\"vos-btn vos-btn-ghost vos-btn-sm\">\n Cancel\n </button>\n <button\n type=\"submit\"\n disabled={missing.length > 0 || saving}\n title={\n missing.length > 0 ? `Fill in: ${missing.join(\", \")}` : undefined\n }\n className=\"vos-btn vos-btn-sm\"\n >\n {saving ? \"Creating…\" : `Create ${REGISTER_LABEL[register]}`}\n </button>\n </footer>\n </form>\n );\n}\n\nfunction Field({\n field,\n value,\n onChange,\n}: {\n field: FormField;\n value: string;\n onChange: (value: string) => void;\n}) {\n const id = `field-${field.key}`;\n return (\n <div className=\"vos-field\">\n <label htmlFor={id} className={FIELD_LABEL_CLASS}>\n {field.label}\n {field.required ? <span className=\"vos-req\"> *</span> : null}\n </label>\n {field.kind === \"textarea\" ? (\n <textarea\n id={id}\n value={value}\n rows={3}\n placeholder={field.placeholder}\n onChange={(e) => onChange(e.target.value)}\n className={FIELD_CONTROL_CLASS}\n />\n ) : field.kind === \"select\" ? (\n <select\n id={id}\n value={value}\n onChange={(e) => onChange(e.target.value)}\n className={FIELD_CONTROL_CLASS}\n >\n <option value=\"\">—</option>\n {field.options?.map((opt) => (\n <option key={opt} value={opt}>\n {opt}\n </option>\n ))}\n </select>\n ) : (\n <input\n id={id}\n type={field.kind === \"number\" ? \"number\" : \"text\"}\n value={value}\n placeholder={field.placeholder}\n onChange={(e) => onChange(e.target.value)}\n className={FIELD_CONTROL_CLASS}\n />\n )}\n </div>\n );\n}\n","/**\n * The editable-field spec for the \"new record\" form, per register — kept as\n * pure data + functions (like `columns.ts`) so the create form is unit-testable\n * without a DOM. Only a record's own scalar fields appear here: derived numbers\n * are computed server-side (never typed), and relations are wired separately by\n * linking (see `relations.ts` / the relation editor), so id/relation fields are\n * deliberately absent. Vocabularies mirror `core`'s type unions.\n */\nimport type { Collection } from \"@validation-os/core\";\nimport type { FieldKind } from \"./edit.js\";\n\n// The create form and the edit form speak the same field-kind vocabulary\n// (`FieldKind` lives in `edit.js`); the create-side spec adds `required` (a\n// blank blocks submit) and numeric `coerce` (a labelled numeric select → a\n// number), which the edit side doesn't need.\n\nexport interface FormField {\n /** Record field key (what the create payload uses). */\n key: string;\n /** Plain-language label a non-technical teammate reads. */\n label: string;\n kind: FieldKind;\n /** Options for a `select`. */\n options?: readonly string[];\n /** A `select`/`text` value that should be stored as a number. */\n coerce?: \"number\";\n required?: boolean;\n placeholder?: string;\n}\n\nconst ASSUMPTION_STATUS = [\"Draft\", \"Live\", \"Invalidated\"] as const;\nconst EXPERIMENT_STATUS = [\"Draft\", \"Running\", \"Closed\"] as const;\nconst CLOSURE_REASON = [\"Completed\", \"Early-stop\", \"Kill\"] as const;\nconst EXPERIMENT_OUTCOME = [\"Achieved\", \"Missed\", \"Dropped\"] as const;\nconst DECISION_STATUS = [\"Active\", \"Provisional\", \"Superseded\", \"Reversed\"] as const;\nconst GLOSSARY_STATUS = [\"Active\", \"Provisional\", \"Superseded\"] as const;\nconst FEASIBILITY = [\"High\", \"Medium\", \"Low\"] as const;\n/** Representativeness / Credibility picks, as labelled numeric options. */\nconst QUALITY = [\"1\", \"0.7\", \"0.5\"] as const;\n\nconst FIELDS: Record<Collection, FormField[]> = {\n assumptions: [\n { key: \"Title\", label: \"Assumption\", kind: \"text\", required: true },\n { key: \"Description\", label: \"Description\", kind: \"textarea\" },\n { key: \"Lens\", label: \"Lens\", kind: \"text\" },\n { key: \"Impact\", label: \"Impact (0–100)\", kind: \"number\" },\n { key: \"Status\", label: \"Status\", kind: \"select\", options: ASSUMPTION_STATUS },\n {\n key: \"Scoring justification\",\n label: \"Scoring justification\",\n kind: \"textarea\",\n },\n ],\n experiments: [\n { key: \"Title\", label: \"Experiment\", kind: \"text\", required: true },\n { key: \"Instrument\", label: \"Instrument\", kind: \"text\" },\n { key: \"Feasibility\", label: \"Feasibility\", kind: \"select\", options: FEASIBILITY },\n { key: \"Status\", label: \"Status\", kind: \"select\", options: EXPERIMENT_STATUS },\n {\n key: \"closureReason\",\n label: \"Closure reason\",\n kind: \"select\",\n options: CLOSURE_REASON,\n },\n { key: \"Deadline\", label: \"Deadline\", kind: \"text\", placeholder: \"YYYY-MM-DD\" },\n { key: \"Outcome\", label: \"Outcome\", kind: \"select\", options: EXPERIMENT_OUTCOME },\n { key: \"Date\", label: \"Date\", kind: \"text\", placeholder: \"YYYY-MM-DD\" },\n ],\n readings: [\n { key: \"Title\", label: \"Reading\", kind: \"text\", required: true },\n { key: \"Source\", label: \"Source\", kind: \"text\" },\n // Rung / Result / Magnitude band / Grading justification are PER BELIEF now\n // (OPS-1305) — carried in `beliefs[]`, not on the row. They are omitted here\n // so the create form can never write a dead row-level field; grading a\n // reading's beliefs is a deferred follow-up (a `beliefs[]` editor).\n {\n key: \"Representativeness\",\n label: \"Representativeness\",\n kind: \"select\",\n options: QUALITY,\n coerce: \"number\",\n },\n {\n key: \"Credibility\",\n label: \"Credibility\",\n kind: \"select\",\n options: QUALITY,\n coerce: \"number\",\n },\n { key: \"body\", label: \"Quote\", kind: \"textarea\" },\n { key: \"Date\", label: \"Date\", kind: \"text\", placeholder: \"YYYY-MM-DD\" },\n ],\n decisions: [\n { key: \"Title\", label: \"Decision\", kind: \"text\", required: true },\n { key: \"Statement\", label: \"Statement\", kind: \"textarea\" },\n { key: \"Status\", label: \"Status\", kind: \"select\", options: DECISION_STATUS },\n ],\n glossary: [\n { key: \"Title\", label: \"Term\", kind: \"text\", required: true },\n { key: \"Status\", label: \"Status\", kind: \"select\", options: GLOSSARY_STATUS },\n { key: \"Definition\", label: \"Definition\", kind: \"textarea\" },\n { key: \"How it differs\", label: \"How it differs\", kind: \"textarea\" },\n ],\n};\n\n/** The editable fields for a register's create form, in display order. */\nexport function formFieldsFor(register: Collection): FormField[] {\n return FIELDS[register];\n}\n\n/** A blank draft: every field keyed to an empty string (form-friendly). */\nexport function emptyDraft(register: Collection): Record<string, string> {\n const draft: Record<string, string> = {};\n for (const f of formFieldsFor(register)) draft[f.key] = \"\";\n return draft;\n}\n\n/** Labels of required fields the draft has left blank (submit-gating). */\nexport function missingRequired(\n register: Collection,\n draft: Record<string, string>,\n): string[] {\n return formFieldsFor(register)\n .filter((f) => f.required && !String(draft[f.key] ?? \"\").trim())\n .map((f) => f.label);\n}\n\n/**\n * Turn a string-keyed form draft into a create payload: numbers coerced, blank\n * optional values dropped so the record stores only what was filled. Derived\n * and relation fields are never here — the server computes the former and\n * linking wires the latter.\n */\nexport function toCreatePayload(\n register: Collection,\n draft: Record<string, string>,\n): Record<string, unknown> {\n const out: Record<string, unknown> = {};\n for (const f of formFieldsFor(register)) {\n const raw = String(draft[f.key] ?? \"\").trim();\n if (raw === \"\") continue; // leave unfilled fields unset\n if (f.kind === \"number\" || f.coerce === \"number\") {\n const n = Number(raw);\n if (!Number.isNaN(n)) out[f.key] = n;\n } else {\n out[f.key] = raw;\n }\n }\n return out;\n}\n","import { useMemo, useState } from \"react\";\nimport type { Collection } from \"@validation-os/core\";\nimport { primaryLabel } from \"./columns.js\";\nimport { FIELD_CONTROL_CLASS } from \"./field-styles.js\";\nimport { linkChoicesFrom } from \"./link-choices.js\";\nimport { useList } from \"./use-records.js\";\nimport { useLink } from \"./use-mutations.js\";\n\nexport interface RelationEditorProps {\n /** The register of the open record initiating the link. */\n register: Collection;\n /** The open record's id (the `from` end). */\n recordId: string;\n basePath?: string;\n /** Called after a relation is wired, so the drawer can re-fetch. */\n onLinked: () => void;\n}\n\n/**\n * Wire a relation from the open record (spec user story 14). Pick an edge, then\n * a target record from the register that edge points at; linking sets both ends\n * server-side and recomputes derived fields. Registers with no outbound edges\n * (glossary, people) render nothing.\n */\nexport function RelationEditor({\n register,\n recordId,\n basePath,\n onLinked,\n}: RelationEditorProps) {\n const choices = useMemo(() => linkChoicesFrom(register), [register]);\n const [relation, setRelation] = useState(\"\");\n const [targetId, setTargetId] = useState(\"\");\n const { link, linking, error } = useLink(basePath);\n\n const active = choices.find((c) => c.relation === relation) ?? null;\n const { records } = useList(\n (active?.targetRegister ?? register) as Collection,\n basePath,\n );\n // Never offer to link a record to itself (self-referential registers).\n const targets = (records ?? []).filter(\n (r) => !(active?.targetRegister === register && r.id === recordId),\n );\n\n if (choices.length === 0) return null;\n\n const onLink = async () => {\n if (!active || !targetId || linking) return;\n try {\n await link({\n relation: active.relation,\n from: { register, id: recordId },\n to: { register: active.targetRegister, id: targetId },\n });\n setTargetId(\"\");\n setRelation(\"\");\n onLinked();\n } catch {\n // `error` carries the message; leave the picks in place to retry.\n }\n };\n\n return (\n <section className=\"vos-relation\">\n <h3 className=\"vos-sectitle\">Link a record</h3>\n <div className=\"vos-field-stack\">\n <select\n aria-label=\"Relation\"\n value={relation}\n onChange={(e) => {\n setRelation(e.target.value);\n setTargetId(\"\");\n }}\n className={FIELD_CONTROL_CLASS}\n >\n <option value=\"\">Choose a relation…</option>\n {choices.map((c) => (\n <option key={c.relation} value={c.relation}>\n {c.label}\n </option>\n ))}\n </select>\n\n {active ? (\n <select\n aria-label=\"Target record\"\n value={targetId}\n onChange={(e) => setTargetId(e.target.value)}\n className={FIELD_CONTROL_CLASS}\n >\n <option value=\"\">Choose a record…</option>\n {targets.map((r) => (\n <option key={r.id} value={r.id}>\n {primaryLabel(r)}\n </option>\n ))}\n </select>\n ) : null}\n\n {error ? <p className=\"vos-error\">{error}</p> : null}\n\n <button\n type=\"button\"\n onClick={onLink}\n disabled={!active || !targetId || linking}\n className=\"vos-btn vos-btn-sm\"\n style={{ alignSelf: \"flex-start\" }}\n >\n {linking ? \"Linking…\" : \"Link\"}\n </button>\n </div>\n </section>\n );\n}\n","/**\n * Which relations a record of a given register can initiate — the menu the\n * relation editor offers. Derived from `core`'s single `RELATIONS` table (so\n * the two never drift) and turned into plain-language choices, each naming the\n * register whose records are valid link targets.\n */\nimport { RELATIONS, type Collection, type Relation } from \"@validation-os/core\";\n\nexport interface LinkChoice {\n relation: Relation;\n /** Plain-language name of the edge, from the initiating record's side. */\n label: string;\n /** The register to pick a target record from. */\n targetRegister: Collection;\n}\n\n/** Plain-language label for each relation, read from the `from` side. */\nconst RELATION_LABEL: Record<Relation, string> = {\n \"assumption-reading\": \"Add reading\",\n \"assumption-depends-on\": \"Depends on\",\n \"assumption-contradicts\": \"Contradicts\",\n \"reading-experiment\": \"From experiment\",\n \"decision-based-on\": \"Based on assumption\",\n \"decision-resolves\": \"Resolves assumption\",\n};\n\n/** The relations a record of `register` can initiate, in table order. */\nexport function linkChoicesFrom(register: Collection): LinkChoice[] {\n return (Object.keys(RELATIONS) as Relation[])\n .filter((r) => RELATIONS[r].from.register === register)\n .map((relation) => ({\n relation,\n label: RELATION_LABEL[relation],\n targetRegister: RELATIONS[relation].targetRegister,\n }));\n}\n","import { useCallback, useEffect, useState } from \"react\";\nimport type { Collection } from \"@validation-os/core\";\nimport type { SavedView, ViewDescriptor } from \"./list-surface.js\";\n\n/**\n * Client hook for a register's user saved views (OPS-1287 story 17) — the same\n * shaped query (tab · group · filter · sort) under a user-chosen name, kept as a\n * **separate list** from the shipped canonical tabs so a working view never\n * clobbers them. Persisted per-register in `localStorage` (no backend, no schema\n * change); a save under an existing name overwrites it. SSR-safe: with no\n * `window` the list is simply empty.\n */\nconst storageKey = (register: Collection) => `vos:saved-views:${register}`;\n\nfunction read(register: Collection): SavedView[] {\n if (typeof window === \"undefined\") return [];\n try {\n const raw = window.localStorage.getItem(storageKey(register));\n const parsed = raw ? (JSON.parse(raw) as unknown) : [];\n return Array.isArray(parsed) ? (parsed as SavedView[]) : [];\n } catch {\n return [];\n }\n}\n\nfunction write(register: Collection, views: SavedView[]): void {\n if (typeof window === \"undefined\") return;\n try {\n window.localStorage.setItem(storageKey(register), JSON.stringify(views));\n } catch {\n // A full or unavailable store is non-fatal — the views just don't persist.\n }\n}\n\nexport interface UseSavedViewsResult {\n views: SavedView[];\n /** Save (or overwrite by name) the current shaped query under a name. */\n save: (name: string, descriptor: ViewDescriptor) => void;\n /** Drop a saved view by name. */\n remove: (name: string) => void;\n}\n\nexport function useSavedViews(register: Collection): UseSavedViewsResult {\n const [views, setViews] = useState<SavedView[]>(() => read(register));\n\n // Re-read when the register changes (the browser remounts per register, but\n // this keeps the hook correct if reused without a key).\n useEffect(() => setViews(read(register)), [register]);\n\n const save = useCallback(\n (name: string, descriptor: ViewDescriptor) => {\n const trimmed = name.trim();\n if (!trimmed) return;\n setViews((prev) => {\n const next = [\n ...prev.filter((v) => v.name !== trimmed),\n { name: trimmed, ...descriptor },\n ];\n write(register, next);\n return next;\n });\n },\n [register],\n );\n\n const remove = useCallback(\n (name: string) => {\n setViews((prev) => {\n const next = prev.filter((v) => v.name !== name);\n write(register, next);\n return next;\n });\n },\n [register],\n );\n\n return { views, save, remove };\n}\n","import type { Collection } from \"@validation-os/core\";\n\n/**\n * The dashboard's client-owned navigation state (OPS-1298 / DEV-5879 redesign).\n * One `<ValidationOSDashboard/>` mounts at a single host route and drives\n * everything off the URL hash — there is no second entry point (OPS-1280).\n *\n * - `assumptions` — the Assumptions nav item. The grid (Lens × Stage) is the\n * default landing; `view: \"all\"` switches to the pipeline board; `lens` +\n * `stage` drill into a single cell's assumptions (pipeline view filtered).\n * - `experiments` — the Experiments nav item (the live evidence plans list).\n * - `readings` — the Readings nav item (the evidence log list).\n * - `assumption` — the assumption detail (next-move, relations, glossary,\n * evidence-first readings). The id is the assumption id.\n * - `experiment` — the evidence-first experiment detail (readings lead, bar\n * lines as context, unstarted bars separate). The id is the experiment id.\n * - `reading` — the per-belief reading detail (Context + per-belief verdicts\n * with excerpts). The id is the reading id.\n * - `records` — one register's browse table (the manual-override surface,\n * kept from the original scheme). Backward-compatible with `#<register>`.\n * - `record` — the legacy unified record page (still mounted for decisions +\n * glossary, which keep the tabbed layout). The id is the record id.\n *\n * The legacy `next`, `pipeline`, and `stage-grid` routes still parse (they\n * map onto the new nav: `next`→`assumptions`, `pipeline`→`assumptions` with\n * `view: \"all\"`, `stage-grid`→`assumptions`) so old deep links keep working.\n */\nexport type Route =\n | { name: \"assumptions\"; lens?: string; stage?: string; view?: \"all\" }\n | { name: \"experiments\" }\n | { name: \"readings\" }\n | { name: \"assumption\"; id: string }\n | { name: \"experiment\"; id: string }\n | { name: \"reading\"; id: string }\n | { name: \"records\"; register: Collection; lens?: string; stage?: string; view?: \"all\" }\n | { name: \"record\"; id: string };\n\nconst DEFAULT_ROUTE: Route = { name: \"assumptions\" };\n\n/**\n * Parse a URL hash into a Route. The empty hash and anything unrecognised fall\n * back to the Assumptions grid (the default landing). A bare register name\n * (`#assumptions`) stays backward-compatible with the original `#<register>`\n * scheme, so it resolves to that register's Records table; `registers` is the\n * set the instance allows, so an unknown or disallowed register name falls\n * through to the default.\n *\n * Legacy routes `#next`, `#pipeline`, and `#stage-grid` still parse — they map\n * onto the new nav so old deep links keep working.\n */\nexport function parseRoute(hash: string, registers: Collection[]): Route {\n const h = hash.replace(/^#\\/?/, \"\");\n if (!h) return DEFAULT_ROUTE;\n const [pathPart = \"\", queryPart = \"\"] = h.split(\"?\");\n const parts = pathPart.split(\"/\");\n const head = parts[0] ?? \"\";\n const query = new URLSearchParams(queryPart ?? \"\");\n const lens = query.get(\"lens\") ?? undefined;\n const stage = query.get(\"stage\") ?? undefined;\n const view = (query.get(\"view\") as \"all\" | null) ?? undefined;\n\n // Legacy routes → new nav.\n if (head === \"next\") return { name: \"assumptions\" };\n if (head === \"pipeline\") return { name: \"assumptions\", view: \"all\" };\n if (head === \"stage-grid\") return { name: \"assumptions\" };\n\n // New detail routes.\n if (head === \"assumption\") {\n const id = parts.slice(1).join(\"/\");\n return id ? { name: \"assumption\", id } : DEFAULT_ROUTE;\n }\n if (head === \"experiment\") {\n const id = parts.slice(1).join(\"/\");\n return id ? { name: \"experiment\", id } : DEFAULT_ROUTE;\n }\n if (head === \"reading\") {\n const id = parts.slice(1).join(\"/\");\n return id ? { name: \"reading\", id } : DEFAULT_ROUTE;\n }\n\n // New top-level nav routes.\n if (head === \"assumptions\") {\n const r: Route = { name: \"assumptions\" };\n if (lens) r.lens = lens;\n if (stage) r.stage = stage;\n if (view) r.view = view;\n return r;\n }\n if (head === \"experiments\") return { name: \"experiments\" };\n if (head === \"readings\") return { name: \"readings\" };\n\n // Legacy record drill-in + records table.\n if (head === \"record\") {\n const id = parts.slice(1).join(\"/\");\n return id ? { name: \"record\", id } : DEFAULT_ROUTE;\n }\n if ((registers as string[]).includes(head)) {\n return { name: \"records\", register: head as Collection, lens, stage, view };\n }\n return DEFAULT_ROUTE;\n}\n\n/**\n * The hash fragment (no leading `#`) for a Route — the inverse of `parseRoute`.\n * `records` serialises to the bare register name to keep deep links stable with\n * the original scheme.\n */\nexport function formatRoute(route: Route): string {\n switch (route.name) {\n case \"assumptions\": {\n const q = new URLSearchParams();\n if (route.lens) q.set(\"lens\", route.lens);\n if (route.stage) q.set(\"stage\", route.stage);\n if (route.view) q.set(\"view\", route.view);\n const qs = q.toString();\n return qs ? `assumptions?${qs}` : \"assumptions\";\n }\n case \"assumption\":\n return `assumption/${route.id}`;\n case \"experiment\":\n return `experiment/${route.id}`;\n case \"reading\":\n return `reading/${route.id}`;\n case \"records\": {\n const q = new URLSearchParams();\n if (route.lens) q.set(\"lens\", route.lens);\n if (route.stage) q.set(\"stage\", route.stage);\n if (route.view) q.set(\"view\", route.view);\n const qs = q.toString();\n return qs ? `${route.register}?${qs}` : route.register;\n }\n case \"record\":\n return `record/${route.id}`;\n default:\n return route.name;\n }\n}\n","import type { Collection } from \"@validation-os/core\";\nimport { REGISTER_ICON, REGISTER_LABEL, WORKFLOW_NAV } from \"./labels.js\";\nimport { formatCount } from \"./primitives.js\";\nimport type { Route } from \"./route.js\";\nimport type { Counts } from \"./use-counts.js\";\n\nexport interface SidebarNavProps {\n /** The active route — drives which item is highlighted. A detail route\n * (`assumption` / `experiment` / `reading` / `record`) highlights its\n * parent nav item. */\n route: Route;\n /** Called when a nav item is chosen, with the route it selects. */\n onNavigate: (route: Route) => void;\n /** Live per-register counts; a middle dot shows until they load. */\n counts?: Counts | null;\n /** Per-register needs-a-human counts — a persistent alert badge on the\n * register that needs attention (kill lane, overdue plans, tensions; story 20). */\n needsHuman?: Partial<Record<Collection, number>>;\n /** The registers shown under a \"Registers\" group (decisions + glossary keep\n * the legacy records-table surface). The three nav-owned registers\n * (assumptions / experiments / readings) are not duplicated here. */\n registers: Collection[];\n}\n\n/**\n * The sidebar nav (DEV-5879 redesign): three top-level items — Assumptions\n * (the default landing, Lens × Stage grid with a \"View all\" toggle to the\n * pipeline board), Experiments (the live evidence plans), Readings (the\n * evidence log) — above a small \"Registers\" group for decisions + glossary,\n * which keep the legacy records-table surface. A presentational brick: the\n * caller owns the active route and supplies the counts. The assembled\n * `<ValidationOSDashboard/>` composes this; it's also exported for anyone\n * building their own surface. Styled with the package's own token sheet.\n */\nexport function SidebarNav({\n route,\n onNavigate,\n counts,\n needsHuman,\n registers,\n}: SidebarNavProps) {\n // The three nav items own assumptions / experiments / readings; the records\n // group holds the rest (decisions, glossary).\n const recordsRegisters = registers.filter(\n (r) => r !== \"assumptions\" && r !== \"experiments\" && r !== \"readings\",\n );\n const activeRegister =\n route.name === \"records\" ? route.register : null;\n\n // Which nav item is active for a given route — detail routes highlight\n // their parent (assumption → assumptions, experiment → experiments, etc).\n function activeNav(): string | null {\n switch (route.name) {\n case \"assumptions\":\n case \"assumption\":\n return \"assumptions\";\n case \"experiments\":\n case \"experiment\":\n return \"experiments\";\n case \"readings\":\n case \"reading\":\n return \"readings\";\n default:\n return null;\n }\n }\n const active = activeNav();\n\n return (\n <nav className=\"vos-nav\" aria-label=\"Navigation\">\n <div>\n <div className=\"vos-nav-group\">Workflow</div>\n {WORKFLOW_NAV.map((item) => {\n const isActive = active === item.route;\n const count =\n counts?.[item.route as Collection] ??\n (item.route === \"assumptions\"\n ? counts?.assumptions\n : item.route === \"experiments\"\n ? counts?.experiments\n : counts?.readings);\n return (\n <button\n key={item.route}\n type=\"button\"\n className={`vos-nav-item ${isActive ? \"is-active\" : \"\"}`}\n aria-current={isActive ? \"page\" : undefined}\n onClick={() => onNavigate({ name: item.route })}\n >\n <span className=\"vos-nav-ic\" aria-hidden=\"true\">\n {item.icon}\n </span>\n {item.label}\n {item.isDefault ? (\n <span className=\"vos-nav-default\">home</span>\n ) : null}\n <span className=\"vos-nav-count vos-num\">\n {count !== undefined ? formatCount(count) : \"·\"}\n </span>\n </button>\n );\n })}\n </div>\n\n {recordsRegisters.length > 0 ? (\n <div>\n <div className=\"vos-nav-group\">Registers</div>\n {recordsRegisters.map((register) => {\n const isActive = register === activeRegister;\n return (\n <button\n key={register}\n type=\"button\"\n className={`vos-nav-item ${isActive ? \"is-active\" : \"\"}`}\n aria-current={isActive ? \"page\" : undefined}\n onClick={() => onNavigate({ name: \"records\", register })}\n >\n <span className=\"vos-nav-ic\" aria-hidden=\"true\">\n {REGISTER_ICON[register]}\n </span>\n {REGISTER_LABEL[register]}\n {needsHuman?.[register] ? (\n <span\n className=\"vos-nav-alert\"\n title={`${needsHuman[register]} need a human`}\n >\n {formatCount(needsHuman[register] ?? 0)}\n </span>\n ) : null}\n <span className=\"vos-nav-count vos-num\">\n {counts?.[register] !== undefined\n ? formatCount(counts[register] ?? 0)\n : \"·\"}\n </span>\n </button>\n );\n })}\n </div>\n ) : null}\n </nav>\n );\n}\n","import { useCallback, useEffect, useMemo, useState } from \"react\";\nimport type { Collection } from \"@validation-os/core\";\nimport { liveExperiments } from \"./derived-views.js\";\nimport { needsHumanCounts, type NeedsHumanCounts } from \"./list-surface.js\";\nimport { useList } from \"./use-records.js\";\n\nexport type Counts = Partial<Record<Collection, number>>;\n\nexport interface UseCountsResult {\n counts: Counts | null;\n loading: boolean;\n error: string | null;\n refresh: () => void;\n}\n\n/**\n * Client hook: fetch per-register counts from the API (`GET {basePath}/counts`).\n * The API reads Firestore server-side through the adapter; this only speaks\n * HTTP, so no backend credentials ever reach the browser.\n */\nexport function useCounts(basePath = \"/api\"): UseCountsResult {\n const [counts, setCounts] = useState<Counts | null>(null);\n const [loading, setLoading] = useState(true);\n const [error, setError] = useState<string | null>(null);\n const [tick, setTick] = useState(0);\n\n useEffect(() => {\n let live = true;\n setLoading(true);\n fetch(`${basePath}/counts`)\n .then(async (res) => {\n if (!res.ok) throw new Error(`Counts request failed (${res.status})`);\n return (await res.json()) as { counts: Counts };\n })\n .then((body) => {\n if (!live) return;\n setCounts(body.counts);\n setError(null);\n })\n .catch((e: unknown) => {\n if (!live) return;\n setError(e instanceof Error ? e.message : \"Failed to load counts\");\n })\n .finally(() => {\n if (live) setLoading(false);\n });\n return () => {\n live = false;\n };\n }, [basePath, tick]);\n\n const refresh = useCallback(() => setTick((t) => t + 1), []);\n return { counts, loading, error, refresh };\n}\n\n/** The needs-a-human counts mapped to the register that owns each badge — kill\n * lane → assumptions, overdue → experiments, in-tension → decisions. */\nexport type NeedsHumanByRegister = Partial<Record<Collection, number>>;\n\nexport interface UseNeedsHumanResult {\n counts: NeedsHumanCounts;\n byRegister: NeedsHumanByRegister;\n /**\n * Live-only experiment count — archived plans excluded (OPS-1305). The API's\n * `/counts` tallies every stored row, but an archived plan never surfaces\n * anywhere in the UI, so the nav badge would overcount (66 vs the live few).\n * `null` until the experiments list loads, so the caller falls back to the\n * API count rather than flashing a wrong number.\n */\n liveExperimentCount: number | null;\n}\n\n/**\n * Client hook: load the assumptions / experiments / decisions registers and\n * derive the needs-a-human counts (kill lane, overdue, in tension) so the nav\n * can carry a persistent badge on the register that needs a human (story 20).\n * Reuses the same `needsHumanCounts` view-model the tabs and their badges use, so\n * a nav badge and its tab never disagree.\n */\nexport function useNeedsHuman(basePath = \"/api\"): UseNeedsHumanResult {\n const assumptions = useList(\"assumptions\", basePath);\n const experiments = useList(\"experiments\", basePath);\n const decisions = useList(\"decisions\", basePath);\n const [asOf] = useState(() => new Date().toISOString().slice(0, 10));\n\n return useMemo(() => {\n const counts = needsHumanCounts({\n asOf,\n assumptions: assumptions.records ?? [],\n experiments: experiments.records ?? [],\n decisions: decisions.records ?? [],\n });\n const byRegister: NeedsHumanByRegister = {};\n if (counts.killLane > 0) byRegister.assumptions = counts.killLane;\n if (counts.overdue > 0) byRegister.experiments = counts.overdue;\n if (counts.inTension > 0) byRegister.decisions = counts.inTension;\n const liveExperimentCount = experiments.records\n ? liveExperiments(experiments.records).length\n : null;\n return { counts, byRegister, liveExperimentCount };\n }, [asOf, assumptions.records, experiments.records, decisions.records]);\n}\n","/**\n * The \"Connect Claude Code\" command composer (OPS-1349). A person signed into\n * the dashboard mints a personal token and gets back ONE ready-to-paste command\n * that points their own Claude Code at this hosted register through the\n * `remote-api` connector. Everything environmental — the API URL, the env-var\n * name — is baked in here; the person supplies only their minted token.\n *\n * Pure and deterministic so it can be unit-tested exactly (prior art:\n * `route.ts`). The config keys it writes (`api_base_url`, `token_env`) are the\n * `remote-api` connector's contract, fixed by the spec — so this does not\n * depend on the connector doc or the setup wizard shipping first.\n */\n\n/** The env var the `remote-api` connector reads the bearer token from. */\nexport const DEFAULT_TOKEN_ENV = \"VALIDATION_OS_TOKEN\";\n\nexport interface ConnectCommandInput {\n /** The personal bearer token the deployment minted for the signed-in user. */\n token: string;\n /** The hosted API root, baked in by the deployment. */\n apiBaseUrl: string;\n /** Override the token env-var name; defaults to {@link DEFAULT_TOKEN_ENV}. */\n tokenEnv?: string;\n}\n\n// A single quote, backslash, or any whitespace would break the single-quoted\n// shell literal (or let a crafted value inject shell) — reject rather than\n// silently emit a broken/unsafe command. Minted tokens and real URLs never\n// contain these.\nconst SHELL_UNSAFE = /['\"\\\\\\s]/;\n\n/**\n * Build the paste command: export the token into its env var, then write a\n * `remote-api` `validation-os.config.yaml` at the workspace root. Running it\n * leaves the workspace ready for `/setup-validation-os` to confirm, or for the\n * skills to use directly.\n */\nexport function composeConnectCommand(input: ConnectCommandInput): string {\n const tokenEnv = input.tokenEnv ?? DEFAULT_TOKEN_ENV;\n const guarded: [string, string][] = [\n [\"Token\", input.token],\n [\"API base URL\", input.apiBaseUrl],\n ];\n for (const [label, value] of guarded) {\n if (SHELL_UNSAFE.test(value)) {\n throw new Error(`${label} contains characters that can't be safely pasted.`);\n }\n }\n return [\n `export ${tokenEnv}='${input.token}'`,\n `cat > validation-os.config.yaml <<'EOF'`,\n `connector: remote-api`,\n `remote_api:`,\n ` api_base_url: ${input.apiBaseUrl}`,\n ` token_env: ${tokenEnv}`,\n `EOF`,\n ].join(\"\\n\");\n}\n","import { useState } from \"react\";\nimport { composeConnectCommand } from \"./connect.js\";\n\n/**\n * The \"Connect Claude Code\" page (OPS-1349). A person already signed into the\n * dashboard mints a personal token and gets one ready-to-paste command that\n * points their own Claude Code at this hosted register.\n *\n * Auth-vendor-free by construction: token minting is INJECTED (`mintToken`), so\n * this package never imports Clerk — the deployment wires a mint function that\n * creates the signed-in user's personal API key and hands back the token\n * (mirrors how the API's `authenticate` is injected). The command itself is the\n * pure `composeConnectCommand`; this component is only the chrome around it.\n */\nexport interface ConnectClaudeCodeProps {\n /** The hosted API root, baked into the emitted command. */\n apiBaseUrl: string;\n /** Override the token env-var name written into the config. */\n tokenEnv?: string;\n /**\n * Mint a personal bearer token for the signed-in user. Injected by the\n * deployment (e.g. create a Clerk API key whose subject is the user's ID).\n */\n mintToken: () => Promise<string>;\n}\n\ntype State =\n | { phase: \"idle\" }\n | { phase: \"minting\" }\n | { phase: \"ready\"; command: string }\n | { phase: \"error\"; message: string };\n\nexport function ConnectClaudeCode({\n apiBaseUrl,\n tokenEnv,\n mintToken,\n}: ConnectClaudeCodeProps) {\n const [state, setState] = useState<State>({ phase: \"idle\" });\n const [copied, setCopied] = useState(false);\n\n async function generate() {\n setState({ phase: \"minting\" });\n setCopied(false);\n try {\n const token = await mintToken();\n const command = composeConnectCommand({ token, apiBaseUrl, tokenEnv });\n setState({ phase: \"ready\", command });\n } catch (e) {\n setState({\n phase: \"error\",\n message:\n e instanceof Error\n ? e.message\n : \"Couldn't generate your connection command.\",\n });\n }\n }\n\n async function copy(command: string) {\n try {\n await navigator.clipboard.writeText(command);\n setCopied(true);\n } catch {\n // Clipboard blocked — the person can still select the text manually.\n }\n }\n\n return (\n <div>\n <div className=\"vos-head\">\n <div>\n <h1>Connect Claude Code</h1>\n <p>\n Run the validation skills against this register from your own Claude\n Code — no repo, no keys to hunt down.\n </p>\n </div>\n </div>\n\n <ol className=\"vos-hint\" style={{ lineHeight: 1.8 }}>\n <li>Generate your personal connection command below.</li>\n <li>Paste it into a terminal in the workspace you'll run the skills in.</li>\n <li>\n The command carries a token tied to <strong>you</strong> — anything you\n write lands under your name. Don't share it.\n </li>\n </ol>\n\n {state.phase !== \"ready\" ? (\n <button\n type=\"button\"\n className=\"vos-btn\"\n onClick={generate}\n disabled={state.phase === \"minting\"}\n >\n {state.phase === \"minting\"\n ? \"Generating…\"\n : \"Generate connection command\"}\n </button>\n ) : null}\n\n {state.phase === \"error\" ? (\n <p className=\"vos-hint\" role=\"alert\">\n {state.message}\n </p>\n ) : null}\n\n {state.phase === \"ready\" ? (\n <div>\n <pre className=\"vos-code\" aria-label=\"Connection command\">\n {state.command}\n </pre>\n <div style={{ display: \"flex\", gap: 8 }}>\n <button\n type=\"button\"\n className=\"vos-btn\"\n onClick={() => copy(state.command)}\n >\n {copied ? \"Copied\" : \"Copy command\"}\n </button>\n <button type=\"button\" className=\"vos-btn-ghost\" onClick={generate}>\n Regenerate\n </button>\n </div>\n <p className=\"vos-hint\" style={{ marginTop: 12 }}>\n Generating again revokes nothing on its own — remove old keys from\n your account settings when you rotate.\n </p>\n </div>\n ) : null}\n </div>\n );\n}\n","import type { ReactNode } from \"react\";\n\nexport interface SurfacePlaceholderProps {\n /** The surface's title, shown as the pane heading. */\n title: string;\n /** A one-line description under the title. */\n subtitle: string;\n /** What fills this pane, and which build ships it. */\n detail: ReactNode;\n}\n\n/**\n * A pane the navigation shell reserves for a surface built in its own step\n * (OPS-1298: \"the shell can land first; each surface fills its pane as it\n * ships\"). It renders the surface's heading and a labelled placeholder so the\n * route, nav slot, and title are real and reachable while the surface itself is\n * still to come. Each later build swaps this out for the real component.\n */\nexport function SurfacePlaceholder({\n title,\n subtitle,\n detail,\n}: SurfacePlaceholderProps) {\n return (\n <div>\n <div className=\"vos-head\">\n <div>\n <h1>{title}</h1>\n <p>{subtitle}</p>\n </div>\n </div>\n <div className=\"vos-empty\">{detail}</div>\n </div>\n );\n}\n","import type { ReactNode } from \"react\";\nimport type { AnyRecord } from \"@validation-os/core\";\nimport { coldStartFor, FIRST_RUN_LINE } from \"./cold-start.js\";\nimport { formatSigned } from \"./primitives.js\";\nimport { buildPipeline, weekOverWeekDelta, type PipelineRow } from \"./pipeline.js\";\nimport type { Route } from \"./route.js\";\nimport { stageMeters } from \"./stage-meters.js\";\nimport { useList } from \"./use-records.js\";\n\n/**\n * The step-back portfolio pipeline (OPS-1300) — the middle altitude of the\n * workflow dashboard. One row per live belief, sorted riskiest first, each\n * carrying the four loop meters (Framed → Planned → Tested → Known) as a\n * connected track, with a stage-aware next move on hover. Above them, the\n * single burn-up headline: \"% of risk bought down\". Resolved beliefs are set\n * apart behind a disclosure; the raw Impact shows only as a faint bar.\n *\n * It lazy-loads the assumption, experiment and reading registers and derives\n * everything through the pure `pipeline` view-model — no number is computed\n * here (spec: explain from inputs). Clicking a belief, its next move, or its\n * Journey link routes to that belief's record page (OPS-1298), the review\n * surface where step-in happens.\n */\nexport function PipelineSurface({\n basePath,\n onNavigate,\n}: {\n basePath?: string;\n onNavigate: (route: Route) => void;\n}) {\n const assumptions = useList(\"assumptions\", basePath);\n const experiments = useList(\"experiments\", basePath);\n const readings = useList(\"readings\", basePath);\n\n const loading =\n assumptions.loading || experiments.loading || readings.loading;\n const error = assumptions.error || experiments.error || readings.error;\n\n return (\n <div>\n <div className=\"vos-head\">\n <div>\n <h1>Portfolio — where everything stands</h1>\n <p>\n Every belief the business depends on, and how far each has travelled\n from bet to known.\n </p>\n </div>\n <div className=\"vos-spacer\" />\n <button\n type=\"button\"\n className=\"vos-btn vos-btn-ghost\"\n onClick={() => {\n assumptions.refresh();\n experiments.refresh();\n readings.refresh();\n }}\n >\n ↻ Refresh\n </button>\n </div>\n\n {loading && !assumptions.records ? (\n <p className=\"vos-muted\">Reading where every belief stands…</p>\n ) : error ? (\n <p className=\"vos-error\">{error}</p>\n ) : (\n <PipelineBoard\n assumptions={assumptions.records ?? []}\n experiments={experiments.records ?? []}\n readings={readings.records ?? []}\n onNavigate={onNavigate}\n />\n )}\n </div>\n );\n}\n\nfunction PipelineBoard({\n assumptions,\n experiments,\n readings,\n onNavigate,\n}: {\n assumptions: AnyRecord[];\n experiments: AnyRecord[];\n readings: AnyRecord[];\n onNavigate: (route: Route) => void;\n}) {\n const view = buildPipeline(assumptions, experiments);\n const delta = weekOverWeekDelta(assumptions, readings, new Date());\n const { progress, rows, resolved, resolvedRetired } = view;\n\n const cold = coldStartFor({\n assumptions,\n experiments,\n readings,\n // The pipeline surface doesn't load decisions (the burn-up reads only\n // assumptions + experiments + readings); coldStartFor only reads\n // assumptions.length, so an empty decisions array is honest here.\n decisions: [],\n });\n if (cold.cold) {\n return (\n <>\n <div className=\"vos-firstrun\">{FIRST_RUN_LINE}</div>\n <section className=\"vos-pipe-hero vos-cold vos-cold-pipe-hero\">\n <div className=\"vos-pipe-read\">\n <div className=\"vos-pipe-eyebrow\">Risk bought down</div>\n <div className=\"vos-pipe-big vos-num\">\n {cold.pipeline.headline}\n </div>\n <div className=\"vos-pipe-sub\">{cold.pipeline.invitation}</div>\n </div>\n </section>\n\n <StageSpine />\n\n <div className=\"vos-card vos-pipe-board vos-cold vos-cold-pipe-board\">\n <div className=\"vos-pipe-boardhead\">\n <div className=\"vos-pipe-bt\">\n Pipeline <span>· 0 live beliefs</span>\n </div>\n </div>\n <div className=\"vos-cold-pipe-body\">\n <p>{cold.pipeline.boardBody}</p>\n <button\n type=\"button\"\n className=\"vos-btn\"\n onClick={() => onNavigate({ name: \"records\", register: \"assumptions\" })}\n >\n {cold.pipeline.boardCta}\n </button>\n </div>\n </div>\n </>\n );\n }\n\n const openRecord = (id: string) => onNavigate({ name: \"record\", id });\n\n return (\n <>\n {/* Headline: the one burn-up reading, a single meter (not a chart). */}\n <section className=\"vos-pipe-hero\">\n <div className=\"vos-pipe-read\">\n <div className=\"vos-pipe-eyebrow\">Risk bought down</div>\n <div className=\"vos-pipe-big vos-num\">\n {Math.round(progress.percent)}\n <span>%</span>\n </div>\n <div className=\"vos-pipe-sub\">\n of all risk you've ever identified\n {delta !== null ? (\n <>\n {\" · \"}\n <span className={delta >= 0 ? \"vos-text-good\" : \"vos-text-crit\"}>\n {formatSigned(delta)} pts this week\n </span>\n </>\n ) : null}\n </div>\n </div>\n <div className=\"vos-pipe-figs\">\n <Fig value={progress.retired} label=\"risk retired\" good />\n <Fig value={progress.identified} label=\"risk identified\" />\n <Fig value={progress.live} label=\"still live\" />\n </div>\n </section>\n\n {/* The four meters every belief carries, in order. */}\n <StageSpine />\n\n <div className=\"vos-card vos-pipe-board\">\n <div className=\"vos-pipe-boardhead\">\n <div className=\"vos-pipe-bt\">\n Pipeline <span>· {rows.length} live {rows.length === 1 ? \"belief\" : \"beliefs\"}</span>\n </div>\n <div className=\"vos-pipe-sortnote\">sorted by live risk — riskiest first</div>\n </div>\n {rows.length === 0 ? (\n <div className=\"vos-empty\" style={{ margin: 16 }}>\n Every belief is resolved — nothing live to test right now.\n </div>\n ) : (\n rows.map((row) => (\n <RowView key={row.id} row={row} onOpen={() => openRecord(row.id)} />\n ))\n )}\n </div>\n\n {resolved.length > 0 ? (\n <details className=\"vos-pipe-resolved\">\n <summary className=\"vos-pipe-disclosure\">\n Resolved &amp; set apart — <b>{resolved.length}</b>{\" \"}\n {resolved.length === 1 ? \"belief\" : \"beliefs\"} (killed or made moot) ·\n retired {resolvedRetired} risk\n </summary>\n <div className=\"vos-pipe-resolved-body\">\n {resolved.map((r) => (\n <button\n type=\"button\"\n key={r.id}\n className=\"vos-pipe-rrow\"\n onClick={() => openRecord(r.id)}\n >\n <span className=\"vos-pipe-rstmt\">{r.statement || r.id}</span>\n <span\n className={`vos-pill ${\n r.kind === \"killed\" ? \"vos-pill-crit\" : \"vos-pill-neutral\"\n }`}\n >\n {r.kind === \"killed\" ? \"Killed\" : \"Moot\"}\n </span>\n <span className=\"vos-pipe-retired\">retired {r.retired} risk</span>\n </button>\n ))}\n </div>\n </details>\n ) : null}\n\n <p className=\"vos-hint vos-pipe-foot\">\n <b>Hidden by default:</b> resolved beliefs (above), the raw Impact score\n (shown only as a faint bar — the machinery, not the move), and the\n confidence derivation (it lives on the belief's journey page). The\n headline is a <b>burn-up</b>: writing a new bet grows \"risk identified\",\n so fresh risk never reads as backsliding.\n </p>\n </>\n );\n}\n\nfunction Fig({\n value,\n label,\n good,\n}: {\n value: number;\n label: string;\n good?: boolean;\n}) {\n return (\n <div className=\"vos-pipe-fig\">\n <div className={`vos-pipe-fv vos-num ${good ? \"vos-text-good\" : \"\"}`}>\n {Math.round(value)}\n </div>\n <div className=\"vos-pipe-fl\">{label}</div>\n </div>\n );\n}\n\nfunction StageKey({\n idx,\n name,\n desc,\n open,\n}: {\n idx: string;\n name: string;\n desc: string;\n open?: boolean;\n}) {\n return (\n <div className=\"vos-pipe-stage\">\n <span className={`vos-pipe-idx ${open ? \"vos-pipe-idx-open\" : \"\"}`}>{idx}</span>\n <div>\n <div className=\"vos-pipe-skname\">{name}</div>\n <div className=\"vos-pipe-skdesc\">{desc}</div>\n </div>\n </div>\n );\n}\n\n/** The four-stage spine — Framed → Planned → Tested → Known — shared by the\n * cold and warm paths so the legend never drifts between them. */\nfunction StageSpine() {\n return (\n <div className=\"vos-pipe-stages\">\n <StageKey idx=\"1\" name=\"Framed\" desc=\"The bet is written & complete\" />\n <span className=\"vos-pipe-arrow\" aria-hidden=\"true\">→</span>\n <StageKey idx=\"2\" name=\"Planned\" desc=\"A test is designed to move it\" />\n <span className=\"vos-pipe-arrow\" aria-hidden=\"true\">→</span>\n <StageKey idx=\"3\" name=\"Tested\" desc=\"Evidence landing, bars settling\" />\n <span className=\"vos-pipe-arrow\" aria-hidden=\"true\">→</span>\n <StageKey idx=\"4\" open name=\"Known\" desc={'Signed confidence — never \"done\"'} />\n </div>\n );\n}\n\nfunction RowView({ row, onOpen }: { row: PipelineRow; onOpen: () => void }) {\n const confClass =\n row.confSign === \"pos\"\n ? \"vos-pill-good\"\n : row.confSign === \"neg\"\n ? \"vos-pill-crit\"\n : \"vos-pill-neutral\";\n const impactPct = Math.max(0, Math.min(100, Math.round(row.impact)));\n return (\n <div className=\"vos-pipe-row\">\n <div className={`vos-pipe-stripe vos-fill-${row.riskTone}`} />\n\n <button type=\"button\" className=\"vos-pipe-belief\" onClick={onOpen}>\n <span className=\"vos-pipe-stmt\">{row.statement || row.id}</span>\n <span className=\"vos-pipe-bmeta\">\n <span className=\"vos-pipe-impact-track\" title={`Derived Impact ${row.impact}`}>\n <i style={{ width: `${impactPct}%` }} />\n </span>\n <span className=\"vos-num\">impact {Math.round(row.impact)}</span>\n </span>\n </button>\n\n {/* The four meters, captioned by the shared mapping the journey rail also\n reads (`stageMeters`) — a row and a belief's rail can't disagree. */}\n <div className=\"vos-pipe-prog\" aria-label=\"Loop progress\">\n {stageMeters(row).map((m) => (\n <Meter\n key={m.key}\n n={m.n}\n label={m.flag ? undefined : m.label}\n flag={m.flag}\n muted={m.muted}\n >\n {m.kind === \"signed\" ? (\n <div className=\"vos-pipe-track vos-pipe-known\">\n <span className=\"vos-pipe-known-mid\" />\n {m.sign !== \"zero\" ? (\n <i\n className={\n m.sign === \"pos\" ? \"vos-pipe-known-pos\" : \"vos-pipe-known-neg\"\n }\n style={{ width: `${m.pct}%` }}\n />\n ) : null}\n </div>\n ) : (\n <div className=\"vos-pipe-track\">\n <i className=\"vos-pipe-fill-accent\" style={{ width: `${m.pct}%` }} />\n </div>\n )}\n </Meter>\n ))}\n </div>\n\n <div className=\"vos-pipe-risk\">\n <div className={`vos-pipe-rv vos-text-${row.riskTone} vos-num`}>\n {Math.round(row.risk)}\n </div>\n <div className=\"vos-pipe-rl\">risk</div>\n <span className={`vos-pill ${confClass} vos-pipe-conf`}>\n conf {formatSigned(row.confidence)}\n </span>\n </div>\n\n <div className=\"vos-pipe-actions\">\n <button type=\"button\" className=\"vos-btn vos-btn-sm\" onClick={onOpen}>\n {row.nextMove}\n </button>\n <button\n type=\"button\"\n className=\"vos-btn vos-btn-ghost vos-btn-sm\"\n onClick={onOpen}\n >\n Journey →\n </button>\n </div>\n </div>\n );\n}\n\nfunction Meter({\n n,\n label,\n flag,\n muted,\n children,\n}: {\n n: string;\n label?: string;\n flag?: string;\n muted?: boolean;\n children: ReactNode;\n}) {\n return (\n <div className=\"vos-pipe-seg\">\n {children}\n <div className=\"vos-pipe-cap\">\n <span className=\"vos-pipe-capn\">{n}</span>\n {flag ? (\n <span className=\"vos-pipe-flag\">{flag}</span>\n ) : (\n <span className={`vos-pipe-capv ${muted ? \"vos-muted\" : \"\"}`}>{label}</span>\n )}\n </div>\n </div>\n );\n}\n","import type { Collection } from \"@validation-os/core\";\nimport { REGISTER_LABEL, REGISTER_ORDER } from \"./labels.js\";\nimport { StatTile } from \"./primitives-view.js\";\nimport type { Counts } from \"./use-counts.js\";\n\nexport interface RegisterCountsProps {\n counts: Counts;\n /** Optional caption under the tiles (e.g. the backend the numbers came from). */\n caption?: string;\n /** Optional click handler per register — makes each tile a nav button. */\n onSelect?: (register: Collection) => void;\n /** The active register, highlighted when tiles are nav. */\n active?: Collection | null;\n}\n\n/**\n * A glanceable grid of stat tiles — one per register, the register's row count\n * as the hero number. A brick kept for a counts landing; the assembled app\n * surfaces the same counts in the sidebar nav. Presentational: the caller reads\n * the counts (server-side, through the adapter) and hands them in. Rendered in\n * the package's own token sheet — no host Tailwind.\n */\nexport function RegisterCounts({\n counts,\n caption,\n onSelect,\n active,\n}: RegisterCountsProps) {\n const registers = REGISTER_ORDER.filter(\n (r): r is Collection => counts[r] !== undefined,\n );\n return (\n <section aria-label=\"Register counts\">\n <div className=\"vos-tile-grid\">\n {registers.map((register) => (\n <StatTile\n key={register}\n label={REGISTER_LABEL[register]}\n value={counts[register] ?? 0}\n onClick={onSelect ? () => onSelect(register) : undefined}\n active={active === register}\n />\n ))}\n </div>\n {caption ? <p className=\"vos-hint\" style={{ marginTop: 16 }}>{caption}</p> : null}\n </section>\n );\n}\n","import { useMemo, useState } from \"react\";\nimport type { AnyRecord } from \"@validation-os/core\";\nimport { rankNextMoves, type MoveKind, type NextMove } from \"@validation-os/core/derivation\";\nimport { coldStartFor, FIRST_RUN_LINE } from \"./cold-start.js\";\nimport { movePresentation, toNextMoveInput } from \"./next-move.js\";\nimport { riskFraction, riskLevel, type Tone } from \"./primitives.js\";\nimport type { Route } from \"./route.js\";\nimport { ScoreImpactForm, WriteDecisionForm } from \"./step-in-forms.js\";\nimport { useList } from \"./use-records.js\";\n\n/**\n * The front door — \"what's my next move\" (design OPS-1295, build OPS-1304): the\n * map's headline surface. One belief, one act, all machinery behind one \"Why\n * this?\" (progressive disclosure — the hero stays clean). The single riskiest\n * unresolved belief leads (Model A, OPS-1291); a kill-lane belief (Confidence ≤\n * −50) raises a crit banner above the hero; three runners-up sit \"On deck\"; and\n * a quiet pick-list lets you act on any belief the ranking wouldn't pick (manual\n * override). Step-in adapts to the act (OPS-1294): human acts open a form here,\n * agent-run acts point at the record for review.\n *\n * The ranking itself lives once in `packages/core` (OPS-1292); this surface only\n * fetches the registers, folds them into that function, and renders the result.\n */\nexport interface NextMoveSurfaceProps {\n basePath?: string;\n /** Navigate across the shell (belief → record, override → records). */\n onNavigate: (route: Route) => void;\n}\n\n/** The four registers the ranking reads. */\nconst REGISTERS = [\"assumptions\", \"experiments\", \"readings\", \"decisions\"] as const;\n\n/** Which Framed→Planned→Tested→Known stage an act sits at (behind \"Why this?\"). */\nconst STAGES = [\"Framed\", \"Planned\", \"Tested\", \"Known\"] as const;\nconst MOVE_STAGE: Record<MoveKind, number> = {\n \"score-impact\": 0,\n \"design-experiment\": 1,\n \"record-reading\": 2,\n decide: 3,\n retest: 3,\n};\n\nconst RISK_PHRASE: Record<Tone, string> = {\n crit: \"Your riskiest belief\",\n warn: \"Worth a look\",\n good: \"Low risk\",\n accent: \"\",\n neutral: \"\",\n};\n\nexport function NextMoveSurface({ basePath, onNavigate }: NextMoveSurfaceProps) {\n const assumptions = useList(\"assumptions\", basePath);\n const experiments = useList(\"experiments\", basePath);\n const readings = useList(\"readings\", basePath);\n const decisions = useList(\"decisions\", basePath);\n\n const [why, setWhy] = useState(false);\n /** An open step-in form, keyed by the belief record it acts on. */\n const [stepIn, setStepIn] = useState<{\n form: \"score-impact\" | \"write-decision\";\n assumption: AnyRecord;\n kill: boolean;\n } | null>(null);\n\n const lists = [assumptions, experiments, readings, decisions];\n const loading = lists.some((l) => l.loading);\n const error = lists.map((l) => l.error).find(Boolean) ?? null;\n\n const moves = useMemo(() => {\n if (!assumptions.records) return [];\n return rankNextMoves(\n toNextMoveInput({\n assumptions: assumptions.records ?? [],\n experiments: experiments.records ?? [],\n readings: readings.records ?? [],\n decisions: decisions.records ?? [],\n }),\n );\n }, [assumptions.records, experiments.records, readings.records, decisions.records]);\n\n const byId = useMemo(() => {\n const m = new Map<string, AnyRecord>();\n for (const a of assumptions.records ?? []) m.set(a.id, a);\n return m;\n }, [assumptions.records]);\n\n const refreshAll = () => lists.forEach((l) => l.refresh());\n const openRecord = (id: string) => onNavigate({ name: \"record\", id });\n\n const startStepIn = (move: NextMove) => {\n const assumption = byId.get(move.assumptionId);\n const pres = movePresentation(move.move);\n if (!assumption || !pres.form) {\n openRecord(move.assumptionId); // agent-run act → review on the record\n return;\n }\n setStepIn({\n form: pres.form,\n assumption,\n kill: move.killLane,\n });\n };\n\n if (loading) {\n return (\n <NextMoveFrame>\n <div className=\"vos-empty\">Reading your beliefs…</div>\n </NextMoveFrame>\n );\n }\n if (error) {\n return (\n <NextMoveFrame>\n <div className=\"vos-banner vos-banner-crit\">\n <div className=\"vos-banner-body\">\n <b>Couldn't load the workflow.</b>\n <span>{error}</span>\n </div>\n </div>\n </NextMoveFrame>\n );\n }\n if (moves.length === 0) {\n const records = {\n assumptions: assumptions.records ?? [],\n experiments: experiments.records ?? [],\n readings: readings.records ?? [],\n decisions: decisions.records ?? [],\n };\n const cold = coldStartFor(records);\n if (cold.cold) {\n return (\n <NextMoveFrame>\n <div className=\"vos-firstrun\">{FIRST_RUN_LINE}</div>\n <div className=\"vos-card vos-cold vos-cold-next\">\n <span className=\"vos-cold-eyebrow\">{cold.next.eyebrow}</span>\n <h2 className=\"vos-cold-headline\">{cold.next.headline}</h2>\n <p className=\"vos-cold-body\">{cold.next.body}</p>\n <button\n type=\"button\"\n className=\"vos-btn vos-hero-act\"\n onClick={() => onNavigate({ name: \"records\", register: \"assumptions\" })}\n >\n {cold.next.cta}\n </button>\n </div>\n </NextMoveFrame>\n );\n }\n return (\n <NextMoveFrame>\n <div className=\"vos-empty\">\n Nothing needs your attention right now — every belief is either resting\n on a decision or waiting on a test. Add a new belief from{\" \"}\n <button\n type=\"button\"\n className=\"vos-linkbtn\"\n onClick={() => onNavigate({ name: \"records\", register: \"assumptions\" })}\n >\n Assumptions\n </button>\n .\n </div>\n </NextMoveFrame>\n );\n }\n\n const top = moves[0]!; // moves.length === 0 handled above\n const rest = moves.slice(1);\n const killMoves = moves.filter((m) => m.killLane);\n // The kill lane owns the top slot when present; the crit banner names the\n // dying belief and the hero shows it, so don't double-count it in On deck.\n const onDeck = rest.filter((m) => m.assumptionId !== top.assumptionId).slice(0, 3);\n const topPres = movePresentation(top.move);\n const topTone = riskLevel(top.risk);\n\n return (\n <NextMoveFrame>\n {killMoves.length > 0 && !top.killLane ? (\n <KillBanner count={killMoves.length} onReview={() => startStepIn(killMoves[0]!)} />\n ) : null}\n\n <div className={`vos-hero vos-card${top.killLane ? \" vos-hero-kill\" : \"\"}`}>\n <span className=\"vos-hero-eyebrow\">\n {top.killLane ? \"Kill lane — turning against you\" : \"Your next move\"}\n </span>\n\n <button\n type=\"button\"\n className=\"vos-hero-belief\"\n onClick={() => openRecord(top.assumptionId)}\n title=\"Open the full record\"\n >\n {top.title}\n </button>\n\n {/* Risk chip — seen, not read (a bar + a plain label, no number). */}\n <div className=\"vos-riskchip\" aria-label={`Risk: ${RISK_PHRASE[topTone]}`}>\n <span className=\"vos-risk-bar\" aria-hidden=\"true\">\n <i\n className={`vos-fill-${topTone}`}\n style={{ width: `${riskFraction(top.risk) * 100}%` }}\n />\n </span>\n <span className={`vos-riskchip-label vos-text-${topTone}`}>\n {top.killLane ? \"Confidence has turned negative\" : RISK_PHRASE[topTone]}\n </span>\n </div>\n\n <ActButton move={top} onStepIn={() => startStepIn(top)} onReview={() => openRecord(top.assumptionId)} />\n\n <button type=\"button\" className=\"vos-why\" onClick={() => setWhy((w) => !w)}>\n {why ? \"Hide details\" : \"Why this?\"}\n </button>\n </div>\n\n {why ? <WhyPanel top={top} ranked={moves} /> : null}\n\n {onDeck.length > 0 ? (\n <section className=\"vos-ondeck\">\n <h3 className=\"vos-sectitle\">On deck</h3>\n {onDeck.map((m) => (\n <OnDeckRow\n key={m.assumptionId}\n move={m}\n onOpen={() => openRecord(m.assumptionId)}\n onAct={() => startStepIn(m)}\n />\n ))}\n </section>\n ) : null}\n\n <button\n type=\"button\"\n className=\"vos-override\"\n onClick={() => onNavigate({ name: \"records\", register: \"assumptions\" })}\n >\n Act on a different belief →\n </button>\n\n {stepIn?.form === \"score-impact\" ? (\n <ScoreImpactForm\n assumption={stepIn.assumption}\n basePath={basePath}\n onDone={() => {\n setStepIn(null);\n refreshAll();\n }}\n onCancel={() => setStepIn(null)}\n />\n ) : null}\n {stepIn?.form === \"write-decision\" ? (\n <WriteDecisionForm\n assumption={stepIn.assumption}\n basePath={basePath}\n kill={stepIn.kill}\n onDone={() => {\n setStepIn(null);\n refreshAll();\n }}\n onCancel={() => setStepIn(null)}\n />\n ) : null}\n </NextMoveFrame>\n );\n}\n\nfunction NextMoveFrame({ children }: { children: React.ReactNode }) {\n return (\n <div>\n <div className=\"vos-head\">\n <div>\n <h1>Next move</h1>\n <p>The single next move to make — and what's on deck.</p>\n </div>\n </div>\n <div className=\"vos-next\">{children}</div>\n </div>\n );\n}\n\n/** The hero's act control — a form CTA for human acts, a review link for\n * agent-run acts (OPS-1294 step-in adaptation). */\nfunction ActButton({\n move,\n onStepIn,\n onReview,\n}: {\n move: NextMove;\n onStepIn: () => void;\n onReview: () => void;\n}) {\n const pres = movePresentation(move.move);\n if (pres.steppable) {\n return (\n <button type=\"button\" className=\"vos-btn vos-hero-act\" onClick={onStepIn}>\n {pres.cta}\n </button>\n );\n }\n return (\n <div className=\"vos-hero-agent\">\n <span className=\"vos-agent-note\">🤖 Claude Code runs this off the dashboard</span>\n <button type=\"button\" className=\"vos-btn vos-btn-ghost vos-hero-act\" onClick={onReview}>\n Review on the record →\n </button>\n </div>\n );\n}\n\nfunction KillBanner({ count, onReview }: { count: number; onReview: () => void }) {\n return (\n <div className=\"vos-banner vos-banner-crit\">\n <div className=\"vos-banner-body\">\n <b>\n {count === 1\n ? \"A belief has fallen into the kill lane\"\n : `${count} beliefs have fallen into the kill lane`}\n </b>\n <span>Confidence ≤ −50 — the evidence is against it. Kill it or test it again.</span>\n </div>\n <button type=\"button\" onClick={onReview}>\n Review\n </button>\n </div>\n );\n}\n\nfunction OnDeckRow({\n move,\n onOpen,\n onAct,\n}: {\n move: NextMove;\n onOpen: () => void;\n onAct: () => void;\n}) {\n const pres = movePresentation(move.move);\n const tone = riskLevel(move.risk);\n return (\n <div className=\"vos-ondeck-row\">\n <span className=\"vos-risk-bar\" aria-hidden=\"true\">\n <i className={`vos-fill-${tone}`} style={{ width: `${riskFraction(move.risk) * 100}%` }} />\n </span>\n <button type=\"button\" className=\"vos-ondeck-title\" onClick={onOpen}>\n {move.title}\n </button>\n <button type=\"button\" className=\"vos-pill vos-pill-accent vos-ondeck-act\" onClick={onAct}>\n {pres.pill}\n </button>\n </div>\n );\n}\n\n/** All the machinery, revealed on demand: the numeric risk, the Feasibility ×\n * Risk formula, the stage stepper, and the full ranked list (OPS-1295). */\nfunction WhyPanel({ top, ranked }: { top: NextMove; ranked: NextMove[] }) {\n return (\n <div className=\"vos-why-panel vos-next-why\">\n <p className=\"vos-why-reason\">{top.reason}</p>\n\n <div>\n <div className=\"vos-why-section-title\">Where it sits</div>\n <StageStepper move={top.move} />\n </div>\n\n <div>\n <div className=\"vos-why-section-title\">Why it's on top</div>\n <p className=\"vos-why-formula\">\n Ranked by <b>Feasibility × Risk</b> — Risk <b>{Math.round(top.risk)}</b>\n {top.feasibility ? (\n <>\n {\" \"}\n × Feasibility <b>{top.feasibility}</b>\n </>\n ) : (\n <> (no test planned yet — neutral feasibility)</>\n )}\n {top.killLane ? \" · in the kill lane, so it jumps the queue\" : null}.\n </p>\n </div>\n\n <div>\n <div className=\"vos-why-section-title\">The ranking</div>\n <ol className=\"vos-why-rank\">\n {ranked.slice(0, 6).map((m) => (\n <li key={m.assumptionId} className={m.assumptionId === top.assumptionId ? \"vos-why-rank-top\" : \"\"}>\n <span className=\"vos-why-rank-title\">{m.title}</span>\n <span className=\"vos-why-rank-score\">{Math.round(m.score)}</span>\n </li>\n ))}\n </ol>\n </div>\n </div>\n );\n}\n\nfunction StageStepper({ move }: { move: MoveKind }) {\n const at = MOVE_STAGE[move];\n return (\n <div className=\"vos-stepper\" aria-label={`Stage: ${STAGES[at]}`}>\n {STAGES.map((label, i) => (\n <span\n key={label}\n className={`vos-step${i === at ? \" vos-step-at\" : \"\"}${i < at ? \" vos-step-done\" : \"\"}`}\n >\n {label}\n </span>\n ))}\n </div>\n );\n}\n","import { useMemo, useState, type ReactNode } from \"react\";\nimport type { AnyRecord } from \"@validation-os/core\";\nimport { coldStartFor, FIRST_RUN_LINE } from \"./cold-start.js\";\nimport { DrawerShell } from \"./drawer-shell.js\";\nimport { RegisterTable } from \"./register-table.js\";\nimport type { Route } from \"./route.js\";\nimport {\n buildStageGrid,\n cellAt,\n NO_LENS,\n NO_STAGE,\n rankByRisk,\n STAGE_GLOSS,\n STAGE_ORDER,\n type StageGridCell,\n type StageGridView,\n type StageValue,\n} from \"./stage-grid-model.js\";\nimport { useList } from \"./use-records.js\";\n\n/**\n * The Lens × Stage heatmap surface (docs/stage-policy.md §The dashboard\n * surface) — the workflow dashboard's portfolio lens, mounted alongside\n * `NextMoveSurface` and `PipelineSurface`. One row per Lens (the actor — who\n * the belief is about), one column per Stage (the kind of response — engage\n * / pay / scale / defend), each cell carrying its assumption count and a\n * heatmap colour by density. Click a cell → a drill-through drawer with the\n * assumptions in that cell, ranked by Risk (the grid is the filter, Risk is\n * the rank).\n *\n * No stage-flag selector, no \"what stage am I\" prompt, no per-stage\n * confidence model — the grid reads the business state off where the bets\n * cluster, and lets you drill into any cell ranked by Risk. The densest cell\n * per row is where that part of the business is; thin/empty cells are gaps\n * (Consumer × Maturity is honestly 0 — consumers don't drive defense bets).\n *\n * Lazy-loads the assumption register and derives everything through the pure\n * `buildStageGrid` view-model — no number is computed here (spec: explain\n * from inputs). Clicking a belief in the drill-through routes to that\n * belief's record page (OPS-1298), the review surface where step-in happens.\n */\nexport interface StageGridSurfaceProps {\n basePath?: string;\n /** Navigate across the shell (belief → record). */\n onNavigate: (route: Route) => void;\n}\n\nexport function StageGridSurface({ basePath, onNavigate }: StageGridSurfaceProps) {\n const assumptions = useList(\"assumptions\", basePath);\n\n const loading = assumptions.loading;\n const error = assumptions.error;\n\n const [open, setOpen] = useState<StageGridCell | null>(null);\n\n const view = useMemo(\n () => buildStageGrid(assumptions.records ?? []),\n [assumptions.records],\n );\n\n const refresh = () => assumptions.refresh();\n const openRecord = (id: string) => onNavigate({ name: \"record\", id });\n\n if (loading && !assumptions.records) {\n return (\n <StageGridFrame>\n <div className=\"vos-empty\">Reading where your bets cluster…</div>\n </StageGridFrame>\n );\n }\n if (error) {\n return (\n <StageGridFrame>\n <div className=\"vos-banner vos-banner-crit\">\n <div className=\"vos-banner-body\">\n <b>Couldn't load the grid.</b>\n <span>{error}</span>\n </div>\n </div>\n </StageGridFrame>\n );\n }\n\n const cold = coldStartFor({\n assumptions: assumptions.records ?? [],\n experiments: [],\n readings: [],\n decisions: [],\n });\n if (cold.cold) {\n return (\n <StageGridFrame>\n <div className=\"vos-firstrun\">{FIRST_RUN_LINE}</div>\n <div className=\"vos-card vos-cold vos-cold-stage-grid\">\n <span className=\"vos-cold-eyebrow\">No bets yet</span>\n <p className=\"vos-cold-body\">\n The Lens × Stage grid reads your business state off where your\n bets cluster. Write your first belief and the grid fills in —\n the densest cell per row is where that part of the business is.\n </p>\n <button\n type=\"button\"\n className=\"vos-btn\"\n onClick={() => onNavigate({ name: \"records\", register: \"assumptions\", view: \"all\" })}\n >\n Write your first bet\n </button>\n </div>\n </StageGridFrame>\n );\n }\n\n return (\n <StageGridFrame total={view.total} onRefresh={refresh} onNavigate={onNavigate}>\n <div className=\"vos-card vos-stage-grid-card\">\n <div className=\"vos-stage-grid-scroll\">\n <table className=\"vos-stage-grid\" role=\"grid\" aria-label=\"Lens × Stage heatmap\">\n <thead>\n <tr>\n <th scope=\"col\" className=\"vos-stage-grid-corner\">Lens ↓ / Stage →</th>\n {view.stages.map((stage) => (\n <th key={stage} scope=\"col\" className=\"vos-stage-grid-col\">\n <span className=\"vos-stage-grid-stagename\">{stage}</span>\n <span className=\"vos-stage-grid-stagegloss\">{STAGE_GLOSS[stage]}</span>\n </th>\n ))}\n </tr>\n </thead>\n <tbody>\n {view.lenses.map((lens) => (\n <tr key={lens}>\n <th scope=\"row\" className=\"vos-stage-grid-rowhead\">\n {lens}\n </th>\n {view.stages.map((stage) => {\n const cell = cellAt(view, lens, stage)!;\n return (\n <StageCell\n key={stage}\n cell={cell}\n onClick={() => setOpen(cell)}\n />\n );\n })}\n </tr>\n ))}\n </tbody>\n </table>\n </div>\n <p className=\"vos-hint vos-stage-grid-foot\">\n The densest cell per row is where that part of the business is — no\n flag, no declaration, the density tells you. Click a cell to drill\n into its assumptions, ranked by Risk. Thin/empty cells are gaps:\n Consumer × Maturity is honestly 0 (consumers don't drive defense\n bets); a thin Commercial × Scale row is under-tracking scale.\n </p>\n </div>\n\n <CellDrawer\n cell={open}\n onClose={() => setOpen(null)}\n onOpenRecord={openRecord}\n onNavigate={onNavigate}\n />\n </StageGridFrame>\n );\n}\n\n/** The frame — title, subtitle, optional total + refresh. */\nfunction StageGridFrame({\n total,\n onRefresh,\n onNavigate,\n children,\n}: {\n total?: number;\n onRefresh?: () => void;\n onNavigate?: (route: Route) => void;\n children: ReactNode;\n}) {\n return (\n <div>\n <div className=\"vos-head\">\n <div>\n <h1>Lens × Stage — where your bets cluster</h1>\n <p>\n Every belief cross-tabbed by the actor it's about (Lens) and the\n kind of response it tests (Stage). The grid is the filter; Risk\n is the rank.\n </p>\n </div>\n <div className=\"vos-spacer\" />\n {total !== undefined ? (\n <span className=\"vos-hint vos-stage-grid-total\">\n {total} {total === 1 ? \"belief\" : \"beliefs\"}\n </span>\n ) : null}\n {onRefresh ? (\n <button\n type=\"button\"\n className=\"vos-btn vos-btn-ghost\"\n onClick={onRefresh}\n >\n ↻ Refresh\n </button>\n ) : null}\n {onNavigate ? (\n <button\n type=\"button\"\n className=\"vos-btn vos-btn-ghost\"\n onClick={() =>\n onNavigate({ name: \"records\", register: \"assumptions\", view: \"all\" })\n }\n >\n View all →\n </button>\n ) : null}\n </div>\n <div className=\"vos-stage-grid-host\">{children}</div>\n </div>\n );\n}\n\n/** One heatmap cell — a button (drill-through) when populated, a muted span\n * when empty (still clickable so a 0 cell is addressable, but reads as\n * quiet). The fill opacity tracks the cell's density. */\nfunction StageCell({\n cell,\n onClick,\n}: {\n cell: StageGridCell;\n onClick: () => void;\n}) {\n const empty = cell.count === 0;\n const style = empty\n ? undefined\n : {\n // Heatmap fill: opacity 0.08 → 0.92 across the density range, on the\n // accent token. Keeps the grid readable in both themes.\n \"--vos-cell-alpha\": (0.08 + cell.density * 0.84).toFixed(3),\n } as React.CSSProperties;\n return (\n <td\n className={`vos-stage-grid-cell${empty ? \" vos-stage-grid-cell-empty\" : \"\"}`}\n style={style}\n >\n <button\n type=\"button\"\n className=\"vos-stage-grid-btn\"\n onClick={onClick}\n aria-label={`${cell.lens} × ${cell.stage}: ${cell.count} ${cell.count === 1 ? \"belief\" : \"beliefs\"}`}\n title={empty ? \"No beliefs in this cell\" : `Riskiest: ${cell.assumptions[0]?.Title ?? \"—\"}`}\n >\n <span className=\"vos-stage-grid-count vos-num\">{cell.count}</span>\n </button>\n </td>\n );\n}\n\n/** The drill-through drawer — a cell's assumptions, ranked by Risk. Reuses\n * `RegisterTable` as the leaf renderer so the columns stay identical to the\n * assumptions browse table (Title, Status, Impact, Confidence, Risk). */\nfunction CellDrawer({\n cell,\n onClose,\n onOpenRecord,\n onNavigate,\n}: {\n cell: StageGridCell | null;\n onClose: () => void;\n onOpenRecord: (id: string) => void;\n onNavigate?: (route: Route) => void;\n}) {\n return (\n <DrawerShell\n open={cell !== null}\n onClose={onClose}\n ariaLabel={\n cell\n ? `${cell.lens} × ${cell.stage} — ${cell.count} ${cell.count === 1 ? \"belief\" : \"beliefs\"}`\n : \"Cell drill-through\"\n }\n >\n <header className=\"vos-drawer-header\">\n <div>\n <p className=\"vos-drawer-eyebrow\">Lens × Stage</p>\n <h2 className=\"vos-drawer-title\">\n {cell?.lens} × {cell?.stage}\n </h2>\n <p className=\"vos-hint\">\n {cell && cell.count > 0\n ? `${cell.count} ${cell.count === 1 ? \"belief\" : \"beliefs\"}, ranked by Risk — riskiest first.`\n : \"No beliefs in this cell.\"}\n </p>\n </div>\n {cell && cell.stage !== \"—\" && onNavigate && (\n <button\n type=\"button\"\n className=\"vos-btn vos-btn-secondary\"\n onClick={() =>\n onNavigate({\n name: \"records\",\n register: \"assumptions\",\n lens: cell.lens === \"—\" ? undefined : cell.lens,\n stage: cell.stage,\n })\n }\n >\n Open in table →\n </button>\n )}\n </header>\n {cell && cell.count > 0 ? (\n <div className=\"vos-stage-grid-drawer-body\">\n <RegisterTable\n register=\"assumptions\"\n records={cell.assumptions}\n onRowClick={onOpenRecord}\n />\n </div>\n ) : cell ? (\n <p className=\"vos-empty\" style={{ margin: 16 }}>\n No beliefs in this cell — a gap, not a bug.\n </p>\n ) : null}\n </DrawerShell>\n );\n}\n\n// Re-export the pure view-model exports for callers building their own surface\n// (matches the pattern `pipeline-surface.tsx` sets for `buildPipeline`).\nexport {\n buildStageGrid,\n cellAt,\n NO_LENS,\n NO_STAGE,\n rankByRisk,\n STAGE_GLOSS,\n STAGE_ORDER,\n};\nexport type { StageGridCell, StageGridView, StageValue };"],"mappings":"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","names":["useCallback","useEffect","useState","t","belief","confidence","jsx","jsxs","rule","m","confidence","t","Fragment","jsx","jsxs","useState","str","useState","t","Fragment","jsx","jsxs","confidence","nextMove","belief","snippetFromBody","pct","useMemo","useState","str","num","str","t","pct","confidence","norm","Fragment","jsx","jsxs","useMemo","Breadcrumb","useState","Breadcrumb","jsx","t","jsxs","useMemo","jsx","jsxs","pct","jsx","jsxs","useMemo","verdictTone","jsx","jsxs","useMemo","jsx","jsxs","useMemo","verdictTone","jsx","jsxs","useMemo","useState","jsx","jsxs","assumptionCompleteness","readingBeliefInputs","beliefTestMeters","deriveBeliefStage","readingBeliefInputs","readingBeliefInputs","str","belief","confidence","beliefTestMeters","assumptionCompleteness","deriveBeliefStage","readingBeliefInputs","nextMove","useState","useState","useEffect","Fragment","jsx","jsxs","useCallback","useState","jsx","jsxs","useState","Fragment","jsx","jsxs","PILL_CLASS","pct","confidence","readingBeliefInputs","confidenceAttribution","experimentProgress","isConcluded","readingBeliefInputs","confidence","confidenceAttribution","experimentProgress","isConcluded","Fragment","jsx","jsxs","Fragment","jsx","jsxs","useState","t","buckets","jsx","jsxs","verdictTone","Fragment","jsx","jsxs","PILL_CLASS","useState","useMemo","t","useMemo","useState","jsx","jsxs","useEffect","useState","Fragment","jsx","jsxs","useState","useEffect","ConflictBanner","num","useMemo","useState","DECISION_STATUS","jsx","jsxs","useMemo","useState","useMemo","useState","jsx","jsxs","useMemo","useState","useCallback","useEffect","useState","jsx","jsxs","useState","useMemo","groupBy","jsx","jsxs","useCallback","useEffect","useMemo","useState","useState","useEffect","useCallback","t","useMemo","jsx","jsxs","useState","useEffect","useCallback","useState","jsx","jsxs","useState","jsx","jsxs","Fragment","jsx","jsxs","PipelineBoard","jsx","jsxs","useMemo","useState","rankNextMoves","Fragment","jsx","jsxs","useState","useMemo","rankNextMoves","jsx","jsxs","Fragment","useMemo","useState","jsx","jsxs","useState","useMemo"]}
1
+ {"version":3,"sources":["../src/dashboard-app.tsx","../src/labels.ts","../src/assumption-detail.tsx","../src/breadcrumb.tsx","../src/evidence-composition.ts","../src/derived-views.ts","../src/confidence-explainer.ts","../src/markdown.tsx","../src/glossary-text.tsx","../src/primitives.ts","../src/glossary.ts","../src/record-view.ts","../src/columns.ts","../src/use-records.ts","../src/edit.ts","../src/assumptions-surface.tsx","../src/next-move.ts","../src/cold-start.ts","../src/pipeline.ts","../src/stage-grid-model.ts","../src/recommended-experiments.ts","../src/stage-meters.ts","../src/experiment-detail.tsx","../src/confidence-donut.tsx","../src/experiments-surface.tsx","../src/reading-detail.tsx","../src/readings-surface.tsx","../src/record-page.tsx","../src/detail-fields.ts","../src/edit-fields.tsx","../src/journey.ts","../src/cycles.ts","../src/journey-surface.tsx","../src/step-in-forms.tsx","../src/drawer-shell.tsx","../src/field-styles.ts","../src/use-mutations.ts","../src/primitives-view.tsx","../src/understanding.ts","../src/understanding-panel.tsx","../src/list-surface.ts","../src/belief-verdicts.tsx","../src/register-browser.tsx","../src/register-table.tsx","../src/record-drawer.tsx","../src/record-form.tsx","../src/form-fields.ts","../src/relation-editor.tsx","../src/link-choices.ts","../src/use-saved-views.ts","../src/route.ts","../src/sidebar-nav.tsx","../src/use-counts.ts","../src/connect.ts","../src/connect-claude-code.tsx","../src/surface-placeholder.tsx","../src/pipeline-surface.tsx","../src/register-counts.tsx","../src/next-move-surface.tsx","../src/stage-grid-surface.tsx"],"sourcesContent":["import { useCallback, useEffect, useState } from \"react\";\nimport type { Collection } from \"@validation-os/core\";\nimport { REGISTER_ORDER, REGISTER_SUBTITLE } from \"./labels.js\";\nimport { AssumptionDetail } from \"./assumption-detail.js\";\nimport { AssumptionsSurface } from \"./assumptions-surface.js\";\nimport { ExperimentDetail } from \"./experiment-detail.js\";\nimport { ExperimentsSurface } from \"./experiments-surface.js\";\nimport { ReadingDetail } from \"./reading-detail.js\";\nimport { ReadingsSurface } from \"./readings-surface.js\";\nimport { RecordPage } from \"./record-page.js\";\nimport { RegisterBrowser } from \"./register-browser.js\";\nimport { formatRoute, parseRoute, type Route } from \"./route.js\";\nimport { SidebarNav } from \"./sidebar-nav.js\";\nimport { useCounts, useNeedsHuman } from \"./use-counts.js\";\n\n/**\n * Everything the instance passes — config only, never secrets. The API base\n * path points at where the Clerk-gated `@validation-os/api` routes are mounted;\n * the backend label (from the connector config) shows in the topbar; branding\n * and the signed-in user are optional cosmetics. Auth is the instance's Clerk\n * provider that this renders within — no credential reaches the package.\n */\nexport interface DashboardConfig {\n /** Where the API is mounted (default `/api`). */\n basePath?: string;\n /** Topbar backend indicator, e.g. \"Firestore · my-register\". */\n backendLabel?: string;\n /** Optional product branding for the sidebar. */\n branding?: {\n /** Product name shown next to the mark (default \"Validation-OS\"). */\n name?: string;\n /** One or two letters for the square mark (default \"V\"). */\n initials?: string;\n /** A logo image for the square mark; overrides `initials` when set. */\n logoUrl?: string;\n };\n /** Optional agent label shown in the topbar, e.g. \"Claude Code\". */\n agentLabel?: string;\n /** The signed-in user, for the topbar avatar + name. */\n user?: { name?: string; caption?: string };\n /** Restrict/reorder the registers shown; defaults to all, in order. */\n registers?: Collection[];\n}\n\nexport interface ValidationOSDashboardProps {\n config?: DashboardConfig;\n}\n\n/** Two letters from a name for the avatar, e.g. \"Benji Fisher\" → \"BF\". */\nfunction initialsOf(name: string): string {\n const parts = name.trim().split(/\\s+/);\n const first = parts[0]?.[0] ?? \"\";\n const last = parts.length > 1 ? (parts[parts.length - 1]?.[0] ?? \"\") : \"\";\n return (first + last).toUpperCase() || \"?\";\n}\n\n/**\n * The entire styled dashboard as one mountable app (spec OPS-1280 / DEV-5879\n * redesign): the frame — a 3-item sidebar (Assumptions / Experiments /\n * Readings) plus a small Registers group for decisions + glossary, topbar with\n * the backend indicator and user — and the surfaces it routes between. The\n * Assumptions nav lands on the Lens × Stage grid; a \"Grid / View all\" toggle\n * switches to the pipeline board. Both drill into the same AssumptionDetail.\n * Experiments shows the live evidence plans; Readings shows the evidence log.\n * Each detail view is evidence-first: readings lead, bar lines are context.\n *\n * Navigation is owned here, not the host router: the active route lives in\n * client state, synced to the URL hash (OPS-1298), so the instance mounts this\n * at one route and wires no routing. Styled by the package's own token sheet —\n * the instance imports `styles.css` once and builds no UI.\n */\nexport function ValidationOSDashboard({ config = {} }: ValidationOSDashboardProps) {\n const {\n basePath = \"/api\",\n backendLabel,\n branding,\n agentLabel,\n user,\n registers = REGISTER_ORDER,\n } = config;\n\n const [route, setRoute] = useState<Route>(() =>\n typeof window === \"undefined\"\n ? { name: \"assumptions\" }\n : parseRoute(window.location.hash, registers),\n );\n const { counts } = useCounts(basePath);\n const { byRegister: needsHuman, liveExperimentCount } = useNeedsHuman(basePath);\n\n // The nav count must match what actually renders. `/counts` tallies every\n // stored row, but archived evidence plans never surface (OPS-1305), so the\n // experiments badge is corrected to the live-only count once it's known —\n // otherwise it reads e.g. 66 while the register shows a handful.\n const navCounts =\n counts && liveExperimentCount !== null\n ? { ...counts, experiments: liveExperimentCount }\n : counts;\n\n // Keep the route and the URL hash in step, so a deep link opens the right\n // surface and the browser back/forward buttons move between them. The hash is\n // the single source of truth: `navigate` only writes it, and this listener\n // reads it back into state.\n useEffect(() => {\n if (typeof window === \"undefined\") return;\n const onHash = () => setRoute(parseRoute(window.location.hash, registers));\n onHash();\n window.addEventListener(\"hashchange\", onHash);\n return () => window.removeEventListener(\"hashchange\", onHash);\n }, [registers]);\n\n const navigate = useCallback((next: Route) => {\n if (typeof window === \"undefined\") {\n setRoute(next);\n return;\n }\n window.location.hash = formatRoute(next);\n }, []);\n\n const toggleTheme = useCallback(() => {\n const root = document.documentElement;\n const current =\n root.getAttribute(\"data-theme\") ??\n (window.matchMedia(\"(prefers-color-scheme: dark)\").matches\n ? \"dark\"\n : \"light\");\n root.setAttribute(\"data-theme\", current === \"dark\" ? \"light\" : \"dark\");\n }, []);\n\n const brandName = branding?.name ?? \"Validation-OS\";\n const brandMark = branding?.initials ?? \"V\";\n\n return (\n <div className=\"vos-app\">\n <div className=\"vos-brand\">\n <span className=\"vos-brand-dot\">\n {branding?.logoUrl ? (\n <img src={branding.logoUrl} alt=\"\" />\n ) : (\n brandMark\n )}\n </span>{\" \"}\n {brandName}\n </div>\n\n <div className=\"vos-topbar\">\n <div className=\"vos-spacer\" />\n <button type=\"button\" className=\"vos-iconbtn\" onClick={toggleTheme}>\n ◐ Theme\n </button>\n {user?.name ? (\n <div className=\"vos-user\">\n <span className=\"vos-avatar\">{initialsOf(user.name)}</span>\n <div>\n <span className=\"vos-user-name\">{user.name}</span>\n {user.caption ? <small>{user.caption}</small> : null}\n </div>\n </div>\n ) : null}\n </div>\n\n <SidebarNav\n route={route}\n onNavigate={navigate}\n counts={navCounts}\n needsHuman={needsHuman}\n registers={registers}\n />\n\n <main className=\"vos-main\">\n {route.name === \"assumptions\" ? (\n <AssumptionsSurface\n key={`assumptions-${route.view ?? \"\"}-${route.lens ?? \"\"}-${route.stage ?? \"\"}`}\n basePath={basePath}\n onNavigate={navigate}\n view={route.view}\n lens={route.lens}\n stage={route.stage}\n />\n ) : route.name === \"experiments\" ? (\n <ExperimentsSurface\n key=\"experiments\"\n basePath={basePath}\n onNavigate={navigate}\n />\n ) : route.name === \"readings\" ? (\n <ReadingsSurface\n key=\"readings\"\n basePath={basePath}\n onNavigate={navigate}\n />\n ) : route.name === \"assumption\" ? (\n <AssumptionDetail\n key={`assumption-${route.id}`}\n assumptionId={route.id}\n basePath={basePath}\n onNavigate={navigate}\n />\n ) : route.name === \"experiment\" ? (\n <ExperimentDetail\n key={`experiment-${route.id}`}\n experimentId={route.id}\n basePath={basePath}\n onNavigate={navigate}\n />\n ) : route.name === \"reading\" ? (\n <ReadingDetail\n key={`reading-${route.id}`}\n readingId={route.id}\n basePath={basePath}\n onNavigate={navigate}\n />\n ) : route.name === \"records\" ? (\n <RegisterBrowser\n key={route.register + (route.lens ?? \"\") + (route.stage ?? \"\") + (route.view ?? \"\")}\n register={route.register}\n basePath={basePath}\n subtitle={REGISTER_SUBTITLE[route.register]}\n onOpenRecord={(id) => navigate({ name: \"record\", id })}\n lens={route.lens}\n stage={route.stage}\n />\n ) : route.name === \"record\" ? (\n <RecordPage\n key={route.id}\n recordId={route.id}\n onNavigate={navigate}\n backRegister={registers[0] ?? \"assumptions\"}\n basePath={basePath}\n />\n ) : (\n <AssumptionsSurface\n key=\"assumptions-fallback\"\n basePath={basePath}\n onNavigate={navigate}\n />\n )}\n </main>\n </div>\n );\n}\n","import type { Collection } from \"@validation-os/core\";\n\n/** Plain-language labels — the register is a surface a non-technical\n * teammate meets, so no jargon and no code-y plurals. */\nexport const REGISTER_LABEL: Record<Collection, string> = {\n assumptions: \"Assumptions\",\n // One container-agnostic lens now Goal is unified into Experiment (OPS-1299 /\n // OPS-1287 story 22): all plans browse in one place under this label.\n experiments: \"Evidence plans\",\n readings: \"Evidence\",\n decisions: \"Decisions\",\n glossary: \"Glossary\",\n};\n\n/** Singular labels — for \"New {thing}\" affordances (never a naive de-pluralise\n * that would read \"New Glossary\"). */\nexport const REGISTER_SINGULAR: Record<Collection, string> = {\n assumptions: \"Assumption\",\n experiments: \"Evidence plan\",\n readings: \"Evidence\",\n decisions: \"Decision\",\n glossary: \"Glossary term\",\n};\n\n/** The order tiles read left-to-right, top-to-bottom. */\nexport const REGISTER_ORDER: Collection[] = [\n \"assumptions\",\n \"experiments\",\n \"readings\",\n \"decisions\",\n \"glossary\",\n];\n\n/** A one-line description shown under each register's title (spec story 9). */\nexport const REGISTER_SUBTITLE: Record<Collection, string> = {\n assumptions:\n \"Falsifiable beliefs the plan rests on. Risk = Impact × (1 − max(0, Confidence)/100).\",\n experiments: \"The evidence plans that move Confidence in the beliefs.\",\n readings: \"The evidence logged against experiments and beliefs.\",\n decisions: \"The choices made, and what they rest on.\",\n glossary: \"The shared vocabulary for this venture.\",\n};\n\n/** A single-glyph icon per register for the sidebar nav (matches the prototype\n * feel; a glyph, not an icon font, so nothing external is pulled in). */\nexport const REGISTER_ICON: Record<Collection, string> = {\n assumptions: \"◎\",\n experiments: \"⚗\",\n readings: \"✦\",\n decisions: \"§\",\n glossary: \"A\",\n};\n\n/** The sidebar groups — all five registers now sit in one set (the retired\n * `people` reference collection was the only \"Reference\" member). */\nexport const REGISTER_GROUPS: { label: string; registers: Collection[] }[] = [\n {\n label: \"Registers\",\n registers: [\"assumptions\", \"experiments\", \"readings\", \"decisions\", \"glossary\"],\n },\n];\n\n/** The workflow surfaces the sidebar lists above the register tables\n * (OPS-1298 / DEV-5879 redesign): three top-level nav items — Assumptions\n * (the default landing, the Lens × Stage grid with a \"View all\" toggle to\n * the pipeline board), Experiments (the live evidence plans), and Evidence\n * (the evidence log). Kept beside the register presentation data so all\n * sidebar labels/icons live in one place. */\nexport interface WorkflowNavItem {\n /** The route this item selects. */\n route: \"assumptions\" | \"experiments\" | \"readings\";\n label: string;\n icon: string;\n /** The default landing — carries a \"home\" badge in the nav. */\n isDefault?: boolean;\n}\n\nexport const WORKFLOW_NAV: WorkflowNavItem[] = [\n { route: \"assumptions\", label: \"Assumptions\", icon: \"◎\", isDefault: true },\n { route: \"experiments\", label: \"Experiments\", icon: \"⚗\" },\n { route: \"readings\", label: \"Evidence\", icon: \"✦\" },\n];\n","import { useMemo } from \"react\";\nimport {\n QUESTION_TYPES,\n STAGES,\n type AnyRecord,\n type QuestionType,\n type Rung,\n} from \"@validation-os/core\";\nimport { isNonEvidence, riskThresholdForStage } from \"@validation-os/core/derivation\";\nimport { Breadcrumb } from \"./breadcrumb.js\";\nimport { buildEvidenceComposition, readingContributions, type ReadingContribution } from \"./evidence-composition.js\";\nimport { buildConfidenceExplainer } from \"./confidence-explainer.js\";\nimport { readingBeliefs, readingBeliefFor, liveExperiments } from \"./derived-views.js\";\nimport { EvidenceBody } from \"./markdown.js\";\nimport { GlossaryText } from \"./glossary-text.js\";\nimport { toGlossaryTerms } from \"./glossary.js\";\nimport { formatSigned, type Tone } from \"./primitives.js\";\nimport type { Route } from \"./route.js\";\nimport {\n buildRecordPage,\n type BacklinkItem,\n type Meter,\n type Pill,\n type RelatedSet,\n} from \"./record-view.js\";\nimport { useList } from \"./use-records.js\";\n\n/**\n * The assumption detail (DEV-5883): next-move panel at the top, score cards,\n * evidence composition (per-rung bars, lens-aware), body (Markdown with\n * glossary auto-linking), graph relations grouped by kind, linked experiments\n * with bar-line preview, evidence-first linked readings (each with its own\n * excerpt for this assumption).\n */\nexport interface AssumptionDetailProps {\n assumptionId: string;\n basePath?: string;\n onNavigate: (route: Route) => void;\n}\n\nexport function AssumptionDetail({\n assumptionId,\n basePath,\n onNavigate,\n}: AssumptionDetailProps) {\n const assumptions = useList(\"assumptions\", basePath);\n const experiments = useList(\"experiments\", basePath);\n const readings = useList(\"readings\", basePath);\n const decisions = useList(\"decisions\", basePath);\n const glossary = useList(\"glossary\", basePath);\n\n const loading =\n assumptions.loading && !assumptions.records;\n\n const related: RelatedSet = {\n assumptions: assumptions.records ?? [],\n experiments: experiments.records ?? [],\n readings: readings.records ?? [],\n decisions: decisions.records ?? [],\n glossary: glossary.records ?? [],\n };\n\n const record = useMemo(\n () => (assumptions.records ?? []).find((a) => String(a.id) === assumptionId) ?? null,\n [assumptions.records, assumptionId],\n );\n\n if (loading) {\n return (\n <div>\n <Breadcrumb trail={[{ label: \"Assumptions\", route: { name: \"assumptions\" } }]} onNavigate={onNavigate} />\n <p className=\"vos-muted\">Loading belief…</p>\n </div>\n );\n }\n if (!record) {\n return (\n <div>\n <Breadcrumb trail={[{ label: \"Assumptions\", route: { name: \"assumptions\" } }]} onNavigate={onNavigate} />\n <p className=\"vos-error\">Belief not found: {assumptionId}</p>\n </div>\n );\n }\n\n const page = buildRecordPage(\"assumptions\", record, related);\n const lens = String(record.Lens ?? \"—\");\n const stage = String(record.Stage ?? \"—\");\n const questionType = String(record[\"Question Type\"] ?? \"—\");\n const derived = (record.derived ?? {}) as {\n derivedImpact?: number;\n risk?: number;\n confidence?: number;\n completeness?: number;\n };\n const confidence = derived.confidence ?? 0;\n const risk = derived.risk ?? 0;\n const impact = derived.derivedImpact ?? 0;\n const framed = derived.completeness ?? 0;\n\n // DEV-5890: stage-keyed Risk threshold — the stopping bar for this stage.\n const stageKey = STAGES.find((s) => s === stage);\n const riskThreshold = stageKey ? riskThresholdForStage(stageKey) : null;\n const clearedThreshold = riskThreshold != null ? risk <= riskThreshold : null;\n\n // Next move — derive a one-line next move from the page's meters, or fall\n // back to a stage-aware verb. (The existing nextMove lives in pipeline.ts;\n // for the detail we read the first meter that needs attention.)\n const nextMove = nextMoveFor(record, experiments.records ?? []);\n\n // Linked experiments testing this assumption — live only (exclude Archived).\n const linkedExperiments = liveExperiments(experiments.records ?? []).filter((e) => {\n const ids = Array.isArray(e.barLineAssumptionIds)\n ? (e.barLineAssumptionIds as string[])\n : [];\n return ids.includes(assumptionId);\n });\n\n // Linked readings — evidence-first: each reading that scores this assumption,\n // with the per-belief excerpt.\n const linkedReadings = (readings.records ?? [])\n .filter((r) => {\n const beliefs = readingBeliefs(r);\n return beliefs.some((b) => b.assumptionId === assumptionId);\n })\n .sort((a, b) => String(b.Date ?? \"\").localeCompare(String(a.Date ?? \"\")));\n\n // Graph relations — grouped by kind, then by entity type.\n const relations = relationsFor(record, related);\n\n // Glossary terms for auto-linking the body.\n const glossaryTerms = toGlossaryTerms(glossary.records ?? []);\n\n const title = String(record.Title ?? assumptionId);\n const statement = String(record.Description ?? title);\n\n return (\n <div>\n <Breadcrumb\n trail={[\n { label: \"Assumptions\", route: { name: \"assumptions\" } },\n { label: assumptionId, route: { name: \"assumption\", id: assumptionId } },\n ]}\n onNavigate={onNavigate}\n />\n\n <div className=\"vos-detail-head\">\n <span className=\"vos-detail-id vos-num\">{assumptionId}</span>\n <span className=\"vos-detail-tag\">{lens}</span>\n <span className=\"vos-detail-tag\">{stage}</span>\n <span className=\"vos-detail-tag vos-detail-tag-qt\">{questionType}</span>\n </div>\n <div className=\"vos-detail-title\">{statement}</div>\n\n {/* Next move panel — accent-bordered, prominent */}\n <div className=\"vos-card vos-next-move\">\n <div className=\"vos-next-move-label\">Recommended next move</div>\n <div className=\"vos-next-move-text\">{nextMove}</div>\n </div>\n\n {/* Score cards */}\n <div className=\"vos-score-cards\">\n <ScoreCard label=\"Impact\" value={Math.round(impact)} />\n <ScoreCard label=\"Risk\" value={Math.round(risk)} tone={riskTone(risk)} />\n <ScoreCard label=\"Confidence\" value={formatSigned(confidence)} />\n <ScoreCard label=\"Framed\" value={`${Math.round(framed)}%`} />\n </div>\n\n {/* DEV-5890: stage-keyed Risk threshold indicator. */}\n {riskThreshold != null ? (\n <div className=\"vos-card vos-threshold-indicator\">\n <div className=\"vos-threshold-label\">Stage threshold</div>\n <div className=\"vos-threshold-row\">\n <span className=\"vos-num\">Risk {Math.round(risk)}</span>\n <span className=\"vos-threshold-bar vos-num\">{riskThreshold}</span>\n <span\n className={`vos-threshold-status ${\n clearedThreshold ? \"vos-threshold-cleared\" : \"vos-threshold-needs\"\n }`}\n >\n {clearedThreshold ? \"Cleared for this stage\" : \"Needs evidence\"}\n </span>\n </div>\n <div className=\"vos-threshold-hint\">\n {clearedThreshold\n ? `Risk at or below the ${stage} threshold — de-prioritized.`\n : `Risk above the ${stage} threshold — testing-priority.`}\n </div>\n </div>\n ) : null}\n\n {/* Evidence composition — per-rung bars, lens-aware (uses the real\n confidence attribution math, so contributions add up to Confidence) */}\n <EvidenceCompositionView assumption={record} readings={readings.records ?? []} />\n\n {/* Confidence explainer — the formula, per-rung W0s, anchors, and what\n each piece of evidence contributes. Demystifies how the number is\n calculated. */}\n <ConfidenceExplainerView assumption={record} readings={readings.records ?? []} />\n\n {/* Body — Markdown with glossary auto-linking */}\n {statement ? (\n <div className=\"vos-card vos-detail-section\">\n <div className=\"vos-detail-section-label\">Body</div>\n <GlossaryText text={statement} terms={glossaryTerms} selfId={assumptionId} />\n </div>\n ) : null}\n\n {/* Relations — grouped by kind, then by entity type */}\n {relations.length > 0 ? (\n <div className=\"vos-card vos-detail-section\">\n <div className=\"vos-detail-section-label\">Relations · {relations.length}</div>\n {([\"Depends on\", \"Enables\", \"Contradicts\"] as const).map((kind) => {\n const rels = relations.filter((r) => r.kind === kind);\n if (rels.length === 0) return null;\n const byType = groupBy(rels, (r) => r.targetType);\n return (\n <div key={kind} className=\"vos-rel-group\">\n <div className={`vos-rel-kind vos-rel-kind-${kindToClass(kind)}`}>{kind.toUpperCase()}</div>\n {Object.entries(byType).map(([type, items]) => (\n <div key={type} className=\"vos-rel-type\">\n <div className=\"vos-rel-type-label\">{type}s ({items.length})</div>\n {items.map((r) => (\n <RelationRow key={r.targetId} rel={r} onNavigate={onNavigate} />\n ))}\n </div>\n ))}\n </div>\n );\n })}\n </div>\n ) : null}\n\n {/* Linked experiments — with bar-line preview for this assumption */}\n {linkedExperiments.length > 0 ? (\n <div className=\"vos-card vos-detail-section\">\n <div className=\"vos-detail-section-label\">\n Experiments testing this · {linkedExperiments.length}\n </div>\n {linkedExperiments.map((e) => {\n const id = String(e.id ?? \"\");\n const bars = Array.isArray(e.barLines) ? e.barLines : [];\n const myBar = bars.find((b: any) => b?.assumptionId === assumptionId);\n const expConf = (e.derived as any)?.experimentConfidence ?? 50;\n return (\n <button\n key={id}\n type=\"button\"\n className=\"vos-linked-row\"\n onClick={() => onNavigate({ name: \"experiment\", id })}\n >\n <span className=\"vos-linked-gauge vos-num\">{Math.round(expConf)}</span>\n <span className=\"vos-linked-title\">{String(e.Title ?? id)}</span>\n {myBar ? (\n <span className=\"vos-linked-bar\">\n <strong>Right if:</strong> {String(myBar.rightIf ?? \"\")}\n {myBar.barVerdict ? (\n <span className={`vos-pill vos-pill-${verdictTone(myBar.barVerdict)}`}>\n {String(myBar.barVerdict)}\n </span>\n ) : null}\n </span>\n ) : null}\n </button>\n );\n })}\n </div>\n ) : null}\n\n {/* Evidence list — one row per piece of evidence, with per-belief\n excerpt, verdict, rung, anchor score and its contribution to Confidence.\n DEV-5890: readings are grouped into probative evidence vs flagged as\n non-evidence for this assumption's question type. */}\n <EvidenceList\n assumptionId={assumptionId}\n questionType={questionType}\n readings={readings.records ?? []}\n onNavigate={onNavigate}\n />\n </div>\n );\n}\n\nfunction EvidenceList({\n assumptionId,\n questionType,\n readings,\n onNavigate,\n}: {\n assumptionId: string;\n questionType: string;\n readings: AnyRecord[];\n onNavigate: (route: Route) => void;\n}) {\n const linkedReadings = readings\n .filter((r) => readingBeliefs(r).some((b) => b.assumptionId === assumptionId))\n .sort((a, b) => String(b.Date ?? \"\").localeCompare(String(a.Date ?? \"\")));\n\n const contribById = useMemo(() => {\n const rec = readings.find((a) => String(a.id) === assumptionId);\n if (!rec) return new Map<string, ReadingContribution>();\n const rows = readingContributions(rec, readings);\n return new Map(rows.map((r) => [r.id, r]));\n }, [readings, assumptionId]);\n\n // DEV-5890: group linked readings into probative vs flagged-as-non-evidence\n // for this assumption's question type.\n const qt = QUESTION_TYPES.find((q) => q === questionType);\n const { probative, flagged } = useMemo(() => {\n const prob: AnyRecord[] = [];\n const flag: AnyRecord[] = [];\n for (const r of linkedReadings) {\n const rung = String(r.Rung ?? \"\") as Rung;\n if (qt && (RUNGS as readonly string[]).includes(rung) && isNonEvidence(qt, rung)) {\n flag.push(r);\n } else {\n prob.push(r);\n }\n }\n return { probative: prob, flagged: flag };\n }, [linkedReadings, qt]);\n\n if (linkedReadings.length === 0) return null;\n\n const renderRow = (r: AnyRecord, flagged: boolean) => {\n const id = String(r.id ?? \"\");\n const belief = readingBeliefFor(r, assumptionId);\n if (!belief) return null;\n const result = String(belief.Result ?? \"Inconclusive\");\n const justification = String(belief[\"Grading justification\"] ?? \"\");\n const excerpt =\n typeof belief.excerpt === \"string\" && belief.excerpt !== \"\"\n ? belief.excerpt\n : snippetFromBody(String(r.body ?? \"\"), assumptionId);\n const rung = String(r.Rung ?? \"\");\n const source = String(r.Source ?? \"\");\n const expId = r.experimentId ? String(r.experimentId) : null;\n const c = contribById.get(id);\n return (\n <button\n key={id}\n type=\"button\"\n className={`vos-evidence-row vos-verdict-${verdictTone(result)}${\n flagged ? \" vos-evidence-row-flagged\" : \"\"\n }`}\n onClick={() => onNavigate({ name: \"reading\", id })}\n >\n <div className=\"vos-evidence-row-head\">\n <span className=\"vos-evidence-date vos-num\">{String(r.Date ?? \"\")}</span>\n <span className=\"vos-evidence-title\">{String(r.Title ?? id)}</span>\n <span className={`vos-pill vos-pill-${verdictTone(result)}`}>{result}</span>\n <span className=\"vos-rung-tag\">{rung}</span>\n {flagged ? (\n <span className=\"vos-evidence-flag\" title=\"This rung is non-evidence for this assumption's question type — reclassify the assumption or drop the reading.\">\n non-evidence\n </span>\n ) : null}\n {c && c.used ? (\n <span className={`vos-evidence-score vos-num vos-text-${contributionTone(c.contribution)}`}>\n {formatSigned(c.contribution)} confidence\n </span>\n ) : null}\n </div>\n {excerpt ? (\n <div className=\"vos-evidence-excerpt\">&ldquo;{excerpt}&rdquo;</div>\n ) : null}\n {justification ? (\n <div className={`vos-belief-rationale vos-verdict-border-${verdictTone(result)}`}>\n <span className=\"vos-belief-rationale-label\">grading rationale:</span>\n {justification}\n </div>\n ) : null}\n <div className=\"vos-evidence-source\">\n <span className=\"vos-evidence-source-link\" title={source}>{source}</span>\n {expId ? (\n <>\n {\" · from experiment \"}\n <span\n className=\"vos-link\"\n onClick={(ev) => {\n ev.stopPropagation();\n onNavigate({ name: \"experiment\", id: expId });\n }}\n >\n {expId}\n </span>\n </>\n ) : null}\n </div>\n </button>\n );\n };\n\n return (\n <div className=\"vos-card vos-detail-section\">\n <div className=\"vos-detail-section-label\">\n Evidence · {linkedReadings.length} piece{linkedReadings.length === 1 ? \"\" : \"s\"} of evidence\n </div>\n {probative.length > 0 ? (\n <div className=\"vos-evidence-group vos-evidence-group-probative\">\n <div className=\"vos-evidence-group-label\">\n Probative evidence · {probative.length}\n </div>\n {probative.map((r) => renderRow(r, false))}\n </div>\n ) : null}\n {flagged.length > 0 ? (\n <div className=\"vos-evidence-group vos-evidence-group-flagged\">\n <div className=\"vos-evidence-group-label\">\n Flagged as non-evidence for this question type · {flagged.length}\n </div>\n {flagged.map((r) => renderRow(r, true))}\n </div>\n ) : null}\n </div>\n );\n}\n\nfunction contributionTone(v: number): Tone {\n if (v > 0) return \"good\";\n if (v < 0) return \"crit\";\n return \"neutral\";\n}\n\n/** The 6 fixed rung values, for the non-evidence grouping check. */\nconst RUNGS = [\n \"Talk\",\n \"Desk research\",\n \"Signed up\",\n \"Observed usage\",\n \"Signed intent\",\n \"Paying users\",\n] as const;\n\nfunction snippetFromBody(body: string, cue: string): string {\n if (!body) return \"\";\n const quoteMatch = body.match(/## Quote\\n+([\\s\\S]*?)(?=\\n## |\\n##$|$)/i);\n if (quoteMatch) {\n const q = quoteMatch[1]!.trim();\n return q.length > 220 ? q.slice(0, 217).trim() + \"…\" : q;\n }\n const sentences = body.split(/(?<=[.!?])\\s+/);\n const cueLower = cue.toLowerCase();\n for (const s of sentences) {\n if (s.toLowerCase().includes(cueLower)) return s.trim();\n }\n const first = sentences[0]?.trim() ?? \"\";\n return first.length > 220 ? first.slice(0, 217).trim() + \"…\" : first;\n}\n\n/* ── helpers ───────────────────────────────────────────────────────────── */\n\nfunction ScoreCard({\n label,\n value,\n tone,\n}: {\n label: string;\n value: number | string;\n tone?: \"good\" | \"warn\" | \"crit\";\n}) {\n const cls = tone ? `vos-score-value vos-text-${tone}` : \"vos-score-value\";\n return (\n <div className=\"vos-score-card\">\n <div className={cls}>{value}</div>\n <div className=\"vos-score-label\">{label}</div>\n </div>\n );\n}\n\nfunction riskTone(risk: number): \"good\" | \"warn\" | \"crit\" {\n if (risk >= 70) return \"crit\";\n if (risk >= 40) return \"warn\";\n return \"good\";\n}\n\nfunction verdictTone(verdict: string): \"good\" | \"crit\" | \"neutral\" {\n if (verdict === \"Validated\") return \"good\";\n if (verdict === \"Invalidated\") return \"crit\";\n return \"neutral\";\n}\n\nfunction kindToClass(kind: string): string {\n if (kind === \"Depends on\") return \"depends\";\n if (kind === \"Enables\") return \"enables\";\n return \"contradicts\";\n}\n\nfunction groupBy<T>(arr: T[], fn: (t: T) => string): Record<string, T[]> {\n const out: Record<string, T[]> = {};\n for (const x of arr) {\n const k = fn(x);\n if (!out[k]) out[k] = [];\n out[k].push(x);\n }\n return out;\n}\n\ninterface Relation {\n kind: \"Depends on\" | \"Enables\" | \"Contradicts\";\n targetId: string;\n targetType: \"assumption\" | \"decision\";\n targetTitle: string;\n}\n\nfunction relationsFor(record: AnyRecord, related: RelatedSet): Relation[] {\n const out: Relation[] = [];\n const push = (ids: unknown, kind: Relation[\"kind\"], type: Relation[\"targetType\"]) => {\n if (!Array.isArray(ids)) return;\n for (const id of ids) {\n const idStr = String(id);\n const target =\n type === \"assumption\"\n ? (related.assumptions ?? []).find((a) => String(a.id) === idStr)\n : (related.decisions ?? []).find((d) => String(d.id) === idStr);\n out.push({\n kind,\n targetId: idStr,\n targetType: type,\n targetTitle: target ? String(target.Title ?? idStr) : idStr,\n });\n }\n };\n push(record.dependsOnIds, \"Depends on\", \"assumption\");\n push(record.enablesIds, \"Enables\", \"assumption\");\n push(record.contradictsIds, \"Contradicts\", \"assumption\");\n // Decisions that resolve / are based-on this assumption aren't on the\n // assumption record's relation fields — skip for now.\n return out;\n}\n\nfunction RelationRow({\n rel,\n onNavigate,\n}: {\n rel: Relation;\n onNavigate: (route: Route) => void;\n}) {\n const isAssumption = rel.targetType === \"assumption\";\n return (\n <button\n type=\"button\"\n className=\"vos-rel-row\"\n disabled={!isAssumption}\n onClick={() => isAssumption && onNavigate({ name: \"assumption\", id: rel.targetId })}\n >\n <span className=\"vos-rel-id vos-num\">{rel.targetId}</span>\n <span className=\"vos-rel-title\">{rel.targetTitle}</span>\n {!isAssumption ? <span className=\"vos-rel-tag\">decision</span> : null}\n </button>\n );\n}\n\nfunction nextMoveFor(assumption: AnyRecord, experiments: AnyRecord[]): string {\n // A simple stage-aware next-move verb: if there's a live experiment testing\n // this assumption → \"Record a reading\"; if framed but no test → \"Design an\n // experiment\"; if not framed → \"Frame the belief\". (The full OPS-1292\n // ranking lives in core's rankNextMoves; this is the detail's one-liner.)\n const id = String(assumption.id ?? \"\");\n const framed = ((assumption.derived as any)?.completeness ?? 0) >= 100;\n const hasLiveTest = experiments.some((e) => {\n const status = String(e.Status ?? \"\");\n if (status === \"Archived\") return false;\n const ids = Array.isArray(e.barLineAssumptionIds)\n ? (e.barLineAssumptionIds as string[])\n : [];\n return ids.includes(id);\n });\n if (hasLiveTest) return \"Record a reading\";\n if (framed) return \"Design an experiment\";\n return \"Frame the belief\";\n}\n\n/* ── Confidence explainer — the formula + per-rung breakdown ───────────── */\n\nfunction ConfidenceExplainerView({\n assumption,\n readings,\n}: {\n assumption: AnyRecord;\n readings: AnyRecord[];\n}) {\n const view = useMemo(\n () => buildConfidenceExplainer(assumption, readings),\n [assumption, readings],\n );\n return (\n <details className=\"vos-card vos-detail-section vos-explainer\">\n <summary className=\"vos-explainer-summary\">\n <span className=\"vos-detail-section-label\">How Confidence is calculated</span>\n <span className=\"vos-explainer-conf vos-num\">{formatSigned(view.confidence)}</span>\n </summary>\n <div className=\"vos-explainer-body\">\n <p className=\"vos-explainer-formula\">{view.formula}</p>\n <p className=\"vos-explainer-summary-text\">{view.summary}</p>\n <div className=\"vos-explainer-rungs\">\n <div className=\"vos-explainer-rungs-head\">\n <span>Rung</span>\n <span>W0 (prior)</span>\n <span>Anchors (L/T/H)</span>\n <span>Evidence</span>\n <span>Contribution</span>\n </div>\n {view.rungs.map((r) => (\n <div\n key={r.rung}\n className={`vos-explainer-rung ${!r.inLens ? \"is-not-lens\" : \"\"} ${r.count > 0 ? \"has-evidence\" : \"\"}`}\n >\n <span className=\"vos-explainer-rung-name\" title={r.description}>\n {r.label}\n </span>\n <span className=\"vos-explainer-rung-w0 vos-num\">{r.w0}</span>\n <span className=\"vos-explainer-rung-anchors vos-num\">\n {r.anchors.Low}/{r.anchors.Typical}/{r.anchors.High}\n </span>\n <span className=\"vos-explainer-rung-count vos-num\">\n {r.count > 0 ? `${r.count} source${r.count === 1 ? \"\" : \"s\"}` : \"—\"}\n </span>\n <span className={`vos-explainer-rung-contrib vos-num ${r.contribution > 0 ? \"vos-text-good\" : r.contribution < 0 ? \"vos-text-crit\" : \"\"}`}>\n {r.count > 0 ? formatSigned(r.contribution) : \"—\"}\n </span>\n </div>\n ))}\n </div>\n <div className=\"vos-explainer-foot\">\n <p>\n <strong>W0</strong> = the prior weight for each rung — how many distinct\n sources it takes to approach that rung's cap. Desk research has a low W0\n (2 — one authoritative source nearly saturates it); Talk has a higher W0\n (6.5 — needs ~10 sources); do-rungs have high W0s (327 — needs ~20\n sources to reach 75% of the cap).\n </p>\n <p>\n <strong>Strength</strong> = the rung's anchor × the sign of the result\n (Validated = +, Invalidated = −, Inconclusive = 0). The anchor is the\n band (Low/Typical/High) the evidence lands at.\n </p>\n <p>\n <strong>Weight</strong> = |Strength| × source quality × commitment factor\n (1.0 for evidence linked to an experiment, 0.85 for found evidence).\n </p>\n <p>\n <strong>Contribution</strong> = (Weight × Strength) / denominator. The\n sum of all contributions equals Confidence. Evidence at a higher rung\n always outweighs evidence at a lower rung — the rung ladder dominates.\n </p>\n </div>\n </div>\n </details>\n );\n}\n\nfunction EvidenceCompositionView({\n assumption,\n readings,\n}: {\n assumption: AnyRecord;\n readings: AnyRecord[];\n}) {\n const comp = useMemo(\n () => buildEvidenceComposition(assumption, readings),\n [assumption, readings],\n );\n return (\n <div className=\"vos-card vos-detail-section\">\n <div className=\"vos-detail-section-label\">\n Evidence composition · Σ = {formatSigned(comp.totalContribution)} (adds to Confidence)\n </div>\n {comp.rungs.length === 0 ? (\n <div className=\"vos-muted\">No lens set — evidence composition needs a lens.</div>\n ) : (\n comp.rungs.map((r) => {\n const abs = Math.abs(r.contribution);\n const pct = r.cap > 0 ? Math.min(100, (abs / r.cap) * 100) : 0;\n const isEmpty = r.count === 0;\n const tone = r.contribution > 0 ? \"good\" : r.contribution < 0 ? \"crit\" : \"accent\";\n return (\n <div key={r.rung} className=\"vos-comp-row\">\n <span className={`vos-comp-rung ${isEmpty ? \"is-empty\" : \"\"}`}>{r.rung}</span>\n <div className=\"vos-comp-bar\">\n <i className={`vos-comp-fill vos-fill-${tone}`} style={{ width: `${isEmpty ? 0 : Math.max(4, pct)}%` }} />\n </div>\n <span className=\"vos-comp-val vos-num\">\n {isEmpty ? \"—\" : (\n <>\n <span className={`vos-text-${tone}`}>{formatSigned(r.contribution)}</span>\n <span style={{ color: \"var(--vos-faint)\" }}> · cap {r.cap}</span>\n </>\n )}\n </span>\n <span className=\"vos-comp-count vos-num\">\n {r.count} {r.count === 1 ? \"source\" : \"sources\"}\n </span>\n </div>\n );\n })\n )}\n </div>\n );\n}","import type { Route } from \"./route.js\";\n\n/**\n * A breadcrumb trail (DEV-5881). Each segment is a button that navigates to\n * its route; the last segment is rendered as plain text (the current page).\n */\nexport interface BreadcrumbProps {\n trail: { label: string; route: Route }[];\n onNavigate?: (route: Route) => void;\n}\n\nexport function Breadcrumb({ trail, onNavigate }: BreadcrumbProps) {\n return (\n <nav className=\"vos-crumb\" aria-label=\"Breadcrumb\">\n {trail.map((t, i) => {\n const isLast = i === trail.length - 1;\n return (\n <span key={i} className=\"vos-crumb-item\">\n {i > 0 ? <span className=\"vos-crumb-sep\" aria-hidden=\"true\">/</span> : null}\n {isLast || !onNavigate ? (\n <span className=\"vos-crumb-current\">{t.label}</span>\n ) : (\n <button\n type=\"button\"\n className=\"vos-crumb-link\"\n onClick={() => onNavigate(t.route)}\n >\n {t.label}\n </button>\n )}\n </span>\n );\n })}\n </nav>\n );\n}","/**\n * Evidence composition (DEV-5883) — the per-rung breakdown of what's moving an\n * assumption's Confidence. Uses the same `confidenceAttribution` math the\n * hero number uses (so the composition literally adds up to Confidence), not\n * raw strength sums. Each rung's `contribution` is its signed share of the\n * average; `cap` is the rung's Typical anchor (the practical ceiling for one\n * reading at that rung). Empty rungs (no evidence) are kept in the lens-aware\n * ladder order so the composition shows the gaps honestly.\n */\nimport type { AnyRecord } from \"@validation-os/core\";\nimport { RUNG_ANCHOR, scoreAndDedupe, w0ForRung, type AttributionReadingInput } from \"@validation-os/core/derivation\";\nimport { readingBeliefFor } from \"./derived-views.js\";\nimport { str } from \"./derived-views.js\";\n\nexport interface RungContribution {\n /** The rung name (e.g. \"Talk\", \"Desk research\", \"Signed up\"). */\n rung: string;\n /** The signed push on Confidence from this rung's readings. Sums to\n * totalContribution across all rungs. */\n contribution: number;\n /** The rung's Typical anchor — the practical ceiling for one reading. */\n cap: number;\n /** How many distinct readings at this rung scored this assumption. */\n count: number;\n}\n\nexport interface EvidenceCompositionView {\n /** One entry per rung in the question-type-aware ladder (lens → its 4 rungs), in\n * ladder order, whether or not there's evidence. */\n rungs: RungContribution[];\n /** Σ contributions — equals the assumption's Confidence (the attribution\n * invariant). */\n totalContribution: number;\n}\n\nexport interface ReadingContribution {\n /** Reading id. */\n id: string;\n /** Signed contribution to the assumption's Confidence. */\n contribution: number;\n /** The absolute weight this reading received after deduplication. */\n weight: number;\n /** The signed strength used (rung anchor × result sign). */\n strength: number;\n /** Whether this reading was kept after deduplication. */\n used: boolean;\n}\n\nconst LENS_RUNGS: Record<string, string[]> = {\n Consumer: [\"Talk\", \"Desk research\", \"Signed up\", \"Observed usage\"],\n Commercial: [\"Talk\", \"Desk research\", \"Signed intent\", \"Paying users\"],\n};\nconst ALL_RUNGS = [\n \"Talk\",\n \"Desk research\",\n \"Signed up\",\n \"Observed usage\",\n \"Signed intent\",\n \"Paying users\",\n];\nfunction rungsForLens(lens: string): string[] {\n return LENS_RUNGS[lens] ?? ALL_RUNGS;\n}\n\nexport function buildEvidenceComposition(\n assumption: AnyRecord,\n readings: AnyRecord[],\n): EvidenceCompositionView {\n const id = str(assumption.id) ?? \"\";\n const lens = str(assumption.Lens) ?? \"\";\n // DEV-5890: read the assumption's Question Type so the cap and the\n // attribution math use the right sub-ladder. Default to Existence.\n const questionType =\n (str(assumption[\"Question Type\"]) as AttributionReadingInput[\"questionType\"]) ??\n \"Existence\";\n const ladder = rungsForLens(lens);\n\n // Build the attribution inputs for THIS assumption only — fan each linked\n // reading's beliefs out, keep only the one that scores this assumption, and\n // feed those into the same scoreAndDedupe + per-rung contribution math the\n // confidence formula uses.\n const inputs: AttributionReadingInput[] = [];\n for (const r of readings) {\n const belief = readingBeliefFor(r, id);\n if (!belief) continue;\n const result = str(belief.Result) ?? \"Inconclusive\";\n if (result === \"Inconclusive\") continue;\n const rung = str(r.Rung) ?? \"Talk\";\n inputs.push({\n id: str(r.id) ?? \"\",\n source: str(r.Source) ?? null,\n rung: rung as AttributionReadingInput[\"rung\"],\n result: result as AttributionReadingInput[\"result\"],\n questionType,\n representativeness: Number(r.Representativeness) || 1.0,\n credibility: Number(r.Credibility) || 1.0,\n date: str(r.Date),\n magnitudeBand: r.magnitudeBand as AttributionReadingInput[\"magnitudeBand\"],\n experimentId: str(r.experimentId),\n });\n }\n\n // Dedupe to the winners (same math as confidence()) and compute the\n // per-rung contribution shares: cᵢ = (wᵢ·sᵢ) / den.\n const winners = scoreAndDedupe(inputs);\n const rungsPresent = new Set(winners.map((x) => x.input.rung));\n let den = 0;\n for (const rung of rungsPresent) den += w0ForRung(rung as any);\n for (const x of winners) den += x.weight;\n\n const perRung = new Map<string, { contribution: number; count: number }>();\n for (const x of winners) {\n const rung = x.input.rung as string;\n const cur = perRung.get(rung) ?? { contribution: 0, count: 0 };\n cur.contribution += (x.weight * x.strength) / den;\n cur.count += 1;\n perRung.set(rung, cur);\n }\n\n const rungs: RungContribution[] = ladder.map((rung) => {\n const e = perRung.get(rung);\n return {\n rung,\n contribution: e ? Math.round((e.contribution + Number.EPSILON) * 100) / 100 : 0,\n // DEV-5890: cap is the rung's High anchor in the assumption's\n // question-type sub-ladder — the ceiling (0 for non-evidence rungs).\n cap:\n RUNG_ANCHOR[questionType]?.[rung as AttributionReadingInput[\"rung\"]]?.High ??\n 0,\n count: e?.count ?? 0,\n };\n });\n\n const total = rungs.reduce((s, r) => s + r.contribution, 0);\n return {\n rungs,\n totalContribution: Math.round((total + Number.EPSILON) * 100) / 100,\n };\n}\n\n/** Per-reading contribution breakdown for an assumption — used by the evidence\n * list to show how much each piece of evidence moved Confidence. Mirrors the\n * math in buildEvidenceComposition but returns one row per reading, including\n * readings that were deduped out (used=false). */\nexport function readingContributions(\n assumption: AnyRecord,\n readings: AnyRecord[],\n): ReadingContribution[] {\n const id = str(assumption.id) ?? \"\";\n // DEV-5890: read the assumption's Question Type for the sub-ladder lookup.\n const questionType =\n (str(assumption[\"Question Type\"]) as AttributionReadingInput[\"questionType\"]) ??\n \"Existence\";\n const inputs: AttributionReadingInput[] = [];\n for (const r of readings) {\n const belief = readingBeliefFor(r, id);\n if (!belief) continue;\n const result = str(belief.Result) ?? \"Inconclusive\";\n if (result === \"Inconclusive\") continue;\n const rung = str(r.Rung) ?? \"Talk\";\n inputs.push({\n id: str(r.id) ?? \"\",\n source: str(r.Source) ?? null,\n rung: rung as AttributionReadingInput[\"rung\"],\n result: result as AttributionReadingInput[\"result\"],\n questionType,\n representativeness: Number(r.Representativeness) || 1.0,\n credibility: Number(r.Credibility) || 1.0,\n date: str(r.Date),\n magnitudeBand: r.magnitudeBand as AttributionReadingInput[\"magnitudeBand\"],\n experimentId: str(r.experimentId),\n });\n }\n\n const winners = scoreAndDedupe(inputs);\n const winnerIds = new Set(winners.map((w) => w.input.id));\n const rungsPresent = new Set(winners.map((x) => x.input.rung));\n let den = 0;\n for (const rung of rungsPresent) den += w0ForRung(rung as any);\n for (const x of winners) den += x.weight;\n\n return inputs.map((input) => {\n const w = winners.find((x) => x.input.id === input.id);\n const used = winnerIds.has(input.id);\n const strength = w\n ? w.strength\n : (input.result === \"Validated\" ? 1 : input.result === \"Invalidated\" ? -1 : 0) *\n (RUNG_ANCHOR[questionType]?.[input.rung]?.Typical ?? 0);\n const weight = w ? w.weight : 0;\n return {\n id: input.id,\n contribution: w && den > 0 ? Math.round(((w.weight * w.strength) / den) * 100) / 100 : 0,\n weight,\n strength,\n used,\n };\n });\n}","/**\n * Shared derived-view predicates — the small, pure \"is this record in this\n * state?\" helpers the ontology's derived views (`skills/_shared/ontology.yaml`\n * → `derived_views`) describe. Kept in one module so the list surface, the\n * record page, and the understanding layer read a state (kill lane, Testing, a\n * belief an experiment tests) the same way — a single definition to change, not\n * three. DOM-free and unit-tested through its callers' seams.\n */\nimport type { AnyRecord, BarLine, BeliefScore } from \"@validation-os/core\";\n\n/** The kill-zone Confidence threshold (ontology `kill_lane`): a Live belief at\n * or below this awaits a human kill verdict. */\nexport const KILL_ZONE = -50;\n\n// ── Reading beliefs (OPS-1305) ───────────────────────────────────────────────\n// A reading is one artifact ROW carrying a `beliefs[]` array — each entry scores\n// one assumption (its own Rung / Result / strength / justification). The scalar\n// r.assumptionId / r.Rung / r.Result are gone from the row; these helpers read a\n// belief off the array so every consumer resolves \"this reading's take on this\n// belief\" one way.\n\n/** The per-belief scores a reading row carries (one per assumption it grades). */\nexport function readingBeliefs(r: AnyRecord): BeliefScore[] {\n return Array.isArray(r.beliefs) ? (r.beliefs as BeliefScore[]) : [];\n}\n\n/** This reading's score for one belief, or undefined if it doesn't grade it. */\nexport function readingBeliefFor(\n r: AnyRecord,\n assumptionId: string,\n): BeliefScore | undefined {\n return readingBeliefs(r).find((b) => b.assumptionId === assumptionId);\n}\n\n/** Does this reading carry a score for this belief? */\nexport function readingGrades(r: AnyRecord, assumptionId: string): boolean {\n return readingBeliefFor(r, assumptionId) !== undefined;\n}\n\n// ── Archived experiments (OPS-1305) ──────────────────────────────────────────\n// Archived plans are a final product decision: they NEVER render — not in a\n// register table, not as a relation on any record, not as a mover behind a\n// belief. There is no \"show archived\" control anywhere. A future Running plan\n// appears; today, with every plan Archived, nothing experiment-shaped shows.\n\n/** An experiment retired from the frontend — never surfaced. */\nexport function isArchivedExperiment(e: AnyRecord): boolean {\n return str(e.Status) === \"Archived\";\n}\n\n/** The experiments the frontend may surface — everything but Archived. */\nexport function liveExperiments(experiments: AnyRecord[]): AnyRecord[] {\n return experiments.filter((e) => !isArchivedExperiment(e));\n}\n\n/**\n * A reading's evidence-ladder Rung — transitional across the 0.10 row-level\n * move. Rung describes the artifact/source (the same across all the beliefs one\n * reading grades), so it is becoming a row-level `Rung` on the reading. This\n * prefers that row value (the final shape) and falls back to the first belief\n * that still carries one, so the badge/column render correct Rung whether the\n * data is pre- or post-migration. The belief read is a defensive cast, never a\n * hard dependency on `BeliefScore.Rung`, so it survives that field's removal\n * from core.\n */\nexport function readingRung(r: AnyRecord): string | null {\n const row = str(r.Rung);\n if (row) return row;\n for (const b of readingBeliefs(r)) {\n const v = (b as { Rung?: unknown }).Rung;\n if (typeof v === \"string\" && v !== \"\") return v;\n }\n return null;\n}\n\n/**\n * A reading's magnitude band — the intensity paired with its Rung (0.10,\n * row-level). Same transitional shape as {@link readingRung}: prefers the\n * row-level `magnitudeBand`, falls back to the first belief that still carries\n * one, and reads the belief field through a defensive cast so it survives\n * `BeliefScore.magnitudeBand`'s removal from core.\n */\nexport function readingMagnitudeBand(r: AnyRecord): string | null {\n const row = str(r.magnitudeBand);\n if (row) return row;\n for (const b of readingBeliefs(r)) {\n const v = (b as { magnitudeBand?: unknown }).magnitudeBand;\n if (typeof v === \"string\" && v !== \"\") return v;\n }\n return null;\n}\n\n/** A non-empty string, else null — the guard every field read shares. */\nexport function str(v: unknown): string | null {\n return typeof v === \"string\" && v !== \"\" ? v : null;\n}\n/** A finite number off the record's `derived` tuple, else null. */\nexport function derivedNum(r: AnyRecord, key: string): number | null {\n const v = (r.derived as Record<string, unknown> | undefined)?.[key];\n return typeof v === \"number\" ? v : null;\n}\n/** The string members of an array field (id/relation lists, Theme, Owner). */\nexport function strList(v: unknown): string[] {\n return Array.isArray(v) ? v.filter((x): x is string => typeof x === \"string\") : [];\n}\n\n/** Does this experiment pre-register a bar line against the belief? Reads the\n * composed bar lines, falling back to the projected id list. */\nexport function testsAssumption(exp: AnyRecord, assumptionId: string): boolean {\n const bars = exp.barLines as BarLine[] | undefined;\n if (bars?.some((b) => b.assumptionId === assumptionId)) return true;\n return strList(exp.barLineAssumptionIds).includes(assumptionId);\n}\n\n/** Does this experiment hold a still-open bar line on the belief (no verdict)? */\nexport function hasOpenBarOn(exp: AnyRecord, assumptionId: string): boolean {\n const bars = exp.barLines as BarLine[] | undefined;\n return (\n bars?.some((b) => b.assumptionId === assumptionId && b.barVerdict == null) ??\n false\n );\n}\n\n/** Kill lane (ontology `kill_lane`): Live AND Confidence in the kill zone. */\nexport function inKillLane(a: AnyRecord): boolean {\n return str(a.Status) === \"Live\" && (derivedNum(a, \"confidence\") ?? 0) <= KILL_ZONE;\n}\n\n/** Testing (ontology `testing`): a Live belief with a Running plan holding an\n * open bar line on it. */\nexport function isTesting(a: AnyRecord, experiments: AnyRecord[]): boolean {\n if (str(a.Status) !== \"Live\") return false;\n return experiments.some(\n (e) => str(e.Status) === \"Running\" && hasOpenBarOn(e, a.id),\n );\n}\n","/**\n * Confidence explainer (DEV-5879) — a user-facing breakdown of how an\n * assumption's Confidence is calculated, showing the formula, the per-rung\n * W0 priors, the question-type-aware rung ladder with anchors, and what each piece of\n * evidence contributes. The numbers come from the same `scoreAndDedupe` +\n * per-rung W0 math the hero number uses (via `buildEvidenceComposition`), so\n * the explainer literally adds up to Confidence.\n */\nimport type { AnyRecord } from \"@validation-os/core\";\nimport { RUNG_ANCHOR, W0_BY_RUNG } from \"@validation-os/core/derivation\";\nimport { buildEvidenceComposition, type RungContribution } from \"./evidence-composition.js\";\nimport { readingBeliefFor, str } from \"./derived-views.js\";\n\nexport interface RungExplainer {\n /** The rung name. */\n rung: string;\n /** The W0 prior weight for this rung (how many sources approach the cap). */\n w0: number;\n /** The anchor bands: Low / Typical / High. */\n anchors: { Low: number; Typical: number; High: number };\n /** The contribution this rung's evidence makes to Confidence. */\n contribution: number;\n /** How many distinct sources at this rung scored this assumption. */\n count: number;\n /** Whether this rung is in the assumption's lens ladder. */\n inLens: boolean;\n /** Plain-language label for the rung. */\n label: string;\n /** Plain-language description of what evidence at this rung means. */\n description: string;\n}\n\nexport interface ConfidenceExplainerView {\n /** The assumption's Confidence (the hero number). */\n confidence: number;\n /** The formula as a plain-language string. */\n formula: string;\n /** The per-rung breakdown (all 6 rungs, lens-aware order). */\n rungs: RungExplainer[];\n /** The total contribution (Σ = Confidence). */\n totalContribution: number;\n /** The denominator (Σ W0[rungs with evidence] + Σ weights). */\n denominator: number;\n /** Plain-language summary of what's moving the number. */\n summary: string;\n}\n\nconst RUNG_INFO: Record<string, { label: string; description: string }> = {\n Talk: {\n label: \"Talk\",\n description: \"Opinions, pitch reactions, anecdotes. Quick to get but slow to move the needle — needs ~10 distinct sources to approach the cap.\",\n },\n \"Desk research\": {\n label: \"Desk research\",\n description: \"Published sources, competitor analysis, market reports. Authoritative — 2 strong sources nearly saturate this rung.\",\n },\n \"Signed up\": {\n label: \"Signed up (Consumer)\",\n description: \"Consumers signing up for the product. A do-rung — 20 signups bring this to ~75% of its cap.\",\n },\n \"Observed usage\": {\n label: \"Observed usage (Consumer)\",\n description: \"Usage sessions, analytics, telemetry, A/B tests. A do-rung — 20 observed users bring this to ~75% of its cap.\",\n },\n \"Signed intent\": {\n label: \"Signed intent (Commercial)\",\n description: \"LOIs, signed letters of intent from businesses. A do-rung — 20 signed intents bring this to ~75% of its cap.\",\n },\n \"Paying users\": {\n label: \"Paying users (Commercial)\",\n description: \"Closed commitments — revenue. The strongest do-rung — 20 paying users bring this to ~75% of its cap.\",\n },\n};\n\nexport function buildConfidenceExplainer(\n assumption: AnyRecord,\n readings: AnyRecord[],\n): ConfidenceExplainerView {\n const comp = buildEvidenceComposition(assumption, readings);\n const lens = str(assumption.Lens) ?? \"\";\n const lensRungs = new Set(comp.rungs.map((r) => r.rung));\n // DEV-5890: read the assumption's Question Type so anchors come from the\n // right sub-ladder.\n const questionType =\n (str(assumption[\"Question Type\"]) as keyof typeof RUNG_ANCHOR) ?? \"Existence\";\n\n // All 6 rungs in the canonical order, lens-aware.\n const allRungs = [\n \"Talk\",\n \"Desk research\",\n \"Signed up\",\n \"Observed usage\",\n \"Signed intent\",\n \"Paying users\",\n ];\n\n const rungs: RungExplainer[] = allRungs.map((rung) => {\n const e = comp.rungs.find((r) => r.rung === rung);\n const info = RUNG_INFO[rung] ?? { label: rung, description: \"\" };\n return {\n rung,\n w0: W0_BY_RUNG[rung as keyof typeof W0_BY_RUNG] ?? 100,\n anchors:\n RUNG_ANCHOR[questionType]?.[rung as keyof (typeof RUNG_ANCHOR)[typeof questionType]] ??\n { Low: 0, Typical: 0, High: 0 },\n contribution: e?.contribution ?? 0,\n count: e?.count ?? 0,\n inLens: lensRungs.has(rung),\n label: info.label,\n description: info.description,\n };\n });\n\n const confidence = ((assumption.derived as any)?.confidence) ?? 0;\n const totalContribution = comp.totalContribution;\n\n // The denominator: Σ W0[rungs with evidence] + Σ weights. We approximate\n // from the composition (the contribution = (w×s)/den, so den = (w×s)/c).\n // For the explainer, we show the rungs-with-evidence W0 sum + the total\n // weight as the denominator components.\n const rungsWithEvidence = rungs.filter((r) => r.count > 0);\n const w0Sum = rungsWithEvidence.reduce((s, r) => s + r.w0, 0);\n\n const summary =\n rungsWithEvidence.length === 0\n ? \"No concluded evidence yet. Confidence is 0 — the bet is open. Any Validated or Invalidated evidence at any rung will start moving this number.\"\n : rungsWithEvidence.length === 1\n ? `All evidence is at the ${rungsWithEvidence[0]!.rung} rung (${rungsWithEvidence[0]!.count} source${rungsWithEvidence[0]!.count === 1 ? \"\" : \"s\"}). ${rungsWithEvidence[0]!.description}`\n : `Evidence spans ${rungsWithEvidence.length} rungs. The strongest push comes from ${rungs.reduce((a, b) => (Math.abs(b.contribution) > Math.abs(a.contribution) ? b : a)).rung}.`;\n\n return {\n confidence,\n formula: \"Confidence = Σ(weight × strength) / (Σ W0[rungs with evidence] + Σ weights)\",\n rungs,\n totalContribution,\n denominator: w0Sum,\n summary,\n };\n}","/**\n * A tiny, dependency-free Markdown renderer (OPS-1305) — enough to render a\n * reading's quote (`body`) and an experiment's narrative (`body`) as formatted\n * prose without pulling a runtime dependency into a package that ships with\n * near-zero deps (only `@validation-os/core`). react-markdown + remark would add\n * a sizeable tree for a feature this small, so we hand-roll the common subset:\n * headings, bold / italic / inline code, links, ordered & unordered lists,\n * blockquotes, fenced code blocks and paragraphs.\n *\n * It is safe by construction: the output is React elements, never\n * `dangerouslySetInnerHTML`, and link hrefs are restricted to http(s)/mailto and\n * in-app (#, /) targets — a `javascript:` or other scheme renders as plain text.\n * Anything it doesn't recognise falls through as text, so no input is ever lost.\n */\nimport { useState, type ReactNode } from \"react\";\n\n/** A Markdown thematic break: `---`, `***` or `___` (3+), optionally spaced. */\nconst HR_RE = /^ {0,3}([-*_])(?: *\\1){2,} *$/;\n\n/** Render Markdown `text` into the package's prose styling. Empty → nothing. */\nexport function Markdown({ text }: { text: string }) {\n const trimmed = (text ?? \"\").trim();\n if (!trimmed) return null;\n return <div className=\"vos-md\">{renderBlocks(trimmed)}</div>;\n}\n\n/**\n * A reading/experiment body presented for scanning (OPS-1305 design pass). A\n * merged reading concatenates several per-finding write-ups joined by `---`\n * rules; rendered as one blob it reads as a wall. This splits on those rules\n * into distinct \"finding\" cards and, past the first, tucks the rest behind a\n * \"show full evidence\" toggle so the detail leads with a scannable summary, not\n * everything at once. A single-segment body (the common experiment narrative)\n * renders as plain prose with no chrome — no behaviour change there.\n */\nexport function EvidenceBody({\n text,\n partLabel = \"Part\",\n}: {\n text: string;\n /** Noun for each split segment, e.g. \"Finding\" on a reading. */\n partLabel?: string;\n}) {\n const [expanded, setExpanded] = useState(false);\n const trimmed = (text ?? \"\").trim();\n const parts = trimmed ? splitOnRules(trimmed) : [];\n if (parts.length === 0) return null;\n if (parts.length === 1) return <Markdown text={parts[0]!} />;\n\n const hidden = parts.length - 1;\n const visible = expanded ? parts : parts.slice(0, 1);\n return (\n <div className=\"vos-evidence\">\n <ol className=\"vos-evidence-parts\">\n {visible.map((p, n) => (\n <li key={n} className=\"vos-evidence-part\">\n <span className=\"vos-evidence-n\">\n {partLabel} {n + 1}\n <span className=\"vos-evidence-of\"> of {parts.length}</span>\n </span>\n <Markdown text={p} />\n </li>\n ))}\n </ol>\n <button\n type=\"button\"\n className=\"vos-btn vos-btn-ghost vos-btn-sm vos-evidence-more\"\n onClick={() => setExpanded((e) => !e)}\n aria-expanded={expanded}\n >\n {expanded\n ? \"Show less\"\n : `Show full evidence — ${hidden} more ${partLabel.toLowerCase()}${hidden === 1 ? \"\" : \"s\"}`}\n </button>\n </div>\n );\n}\n\n/** Split a body on thematic-break lines into trimmed, non-empty segments. */\nfunction splitOnRules(text: string): string[] {\n const lines = text.replace(/\\r\\n?/g, \"\\n\").split(\"\\n\");\n const parts: string[][] = [[]];\n for (const line of lines) {\n if (HR_RE.test(line)) parts.push([]);\n else parts[parts.length - 1]!.push(line);\n }\n return parts.map((p) => p.join(\"\\n\").trim()).filter((p) => p !== \"\");\n}\n\n// ── Blocks ────────────────────────────────────────────────────────────────────\n\nfunction renderBlocks(text: string): ReactNode[] {\n const lines = text.replace(/\\r\\n?/g, \"\\n\").split(\"\\n\");\n const out: ReactNode[] = [];\n let i = 0;\n let key = 0;\n\n while (i < lines.length) {\n const line = lines[i]!;\n\n // Blank line — skip.\n if (line.trim() === \"\") {\n i += 1;\n continue;\n }\n\n // Fenced code block: ``` … ```\n const fence = line.match(/^```/);\n if (fence) {\n const body: string[] = [];\n i += 1;\n while (i < lines.length && !/^```/.test(lines[i]!)) {\n body.push(lines[i]!);\n i += 1;\n }\n i += 1; // consume the closing fence (if present)\n out.push(\n <pre key={key++} className=\"vos-md-pre\">\n <code>{body.join(\"\\n\")}</code>\n </pre>,\n );\n continue;\n }\n\n // Thematic break: --- / *** / ___ (a stray one left in a single segment).\n if (HR_RE.test(line)) {\n out.push(<hr key={key++} className=\"vos-md-hr\" />);\n i += 1;\n continue;\n }\n\n // Heading: #… up to ######\n const heading = line.match(/^(#{1,6})\\s+(.*)$/);\n if (heading) {\n const level = heading[1]!.length;\n const Tag = `h${Math.min(level + 2, 6)}` as \"h3\" | \"h4\" | \"h5\" | \"h6\";\n out.push(<Tag key={key++}>{renderInline(heading[2]!)}</Tag>);\n i += 1;\n continue;\n }\n\n // Blockquote: consecutive `>` lines.\n if (/^>\\s?/.test(line)) {\n const quote: string[] = [];\n while (i < lines.length && /^>\\s?/.test(lines[i]!)) {\n quote.push(lines[i]!.replace(/^>\\s?/, \"\"));\n i += 1;\n }\n out.push(\n <blockquote key={key++} className=\"vos-md-quote\">\n {renderBlocks(quote.join(\"\\n\"))}\n </blockquote>,\n );\n continue;\n }\n\n // Unordered list: consecutive `- ` / `* ` / `+ ` lines.\n if (/^[-*+]\\s+/.test(line)) {\n const items: string[] = [];\n while (i < lines.length && /^[-*+]\\s+/.test(lines[i]!)) {\n items.push(lines[i]!.replace(/^[-*+]\\s+/, \"\"));\n i += 1;\n }\n out.push(\n <ul key={key++} className=\"vos-md-ul\">\n {items.map((it, n) => (\n <li key={n}>{renderInline(it)}</li>\n ))}\n </ul>,\n );\n continue;\n }\n\n // Ordered list: consecutive `1. ` lines.\n if (/^\\d+\\.\\s+/.test(line)) {\n const items: string[] = [];\n while (i < lines.length && /^\\d+\\.\\s+/.test(lines[i]!)) {\n items.push(lines[i]!.replace(/^\\d+\\.\\s+/, \"\"));\n i += 1;\n }\n out.push(\n <ol key={key++} className=\"vos-md-ol\">\n {items.map((it, n) => (\n <li key={n}>{renderInline(it)}</li>\n ))}\n </ol>,\n );\n continue;\n }\n\n // Paragraph: gather consecutive non-blank, non-structural lines.\n const para: string[] = [];\n while (\n i < lines.length &&\n lines[i]!.trim() !== \"\" &&\n !HR_RE.test(lines[i]!) &&\n !/^```|^#{1,6}\\s|^>\\s?|^[-*+]\\s+|^\\d+\\.\\s+/.test(lines[i]!)\n ) {\n para.push(lines[i]!);\n i += 1;\n }\n out.push(<p key={key++}>{renderInline(para.join(\" \"))}</p>);\n }\n\n return out;\n}\n\n// ── Inline ──────────────────────────────────────────────────────────────────\n\n/** Only these href shapes are allowed to become links; everything else stays\n * plain text so a `javascript:`/`data:` scheme can never be clicked. */\nfunction safeHref(href: string): string | null {\n if (/^(https?:\\/\\/|mailto:)/i.test(href)) return href;\n if (/^[#/]/.test(href)) return href; // in-app / anchor targets\n return null;\n}\n\ninterface InlineRule {\n re: RegExp;\n render: (m: RegExpExecArray, key: number) => ReactNode;\n /** Whether the captured inner text is itself parsed for inline markup. */\n recurse: boolean;\n inner?: (m: RegExpExecArray) => string;\n}\n\nconst INLINE_RULES: InlineRule[] = [\n // Inline code first — its contents are literal.\n {\n re: /`([^`]+)`/,\n render: (m, key) => (\n <code key={key} className=\"vos-md-code\">\n {m[1]}\n </code>\n ),\n recurse: false,\n },\n // Links: [text](href)\n {\n re: /\\[([^\\]]+)\\]\\(([^)\\s]+)\\)/,\n render: (m, key) => {\n const href = safeHref(m[2]!);\n if (!href) return <span key={key}>{m[1]}</span>;\n return (\n <a key={key} href={href} target=\"_blank\" rel=\"noopener noreferrer\">\n {m[1]}\n </a>\n );\n },\n recurse: false,\n },\n // Bold: **text** or __text__\n {\n re: /\\*\\*([^*]+)\\*\\*|__([^_]+)__/,\n render: (m, key) => <strong key={key}>{renderInline(m[1] ?? m[2] ?? \"\")}</strong>,\n recurse: true,\n inner: (m) => m[1] ?? m[2] ?? \"\",\n },\n // Italic: *text* or _text_\n {\n re: /\\*([^*]+)\\*|_([^_]+)_/,\n render: (m, key) => <em key={key}>{renderInline(m[1] ?? m[2] ?? \"\")}</em>,\n recurse: true,\n inner: (m) => m[1] ?? m[2] ?? \"\",\n },\n];\n\nfunction renderInline(text: string): ReactNode[] {\n const nodes: ReactNode[] = [];\n let rest = text;\n let key = 0;\n\n while (rest.length > 0) {\n // Find the earliest-starting match across every rule.\n let best: { rule: InlineRule; m: RegExpExecArray } | null = null;\n for (const rule of INLINE_RULES) {\n const m = new RegExp(rule.re).exec(rest);\n if (m && (best === null || m.index < best.m.index)) {\n best = { rule, m };\n }\n }\n\n if (!best) {\n nodes.push(rest);\n break;\n }\n\n const { rule, m } = best;\n if (m.index > 0) nodes.push(rest.slice(0, m.index));\n nodes.push(rule.render(m, key++));\n rest = rest.slice(m.index + m[0].length);\n }\n\n return nodes;\n}\n","/**\n * Renders prose with glossary terms auto-linked (OPS-1285). A thin wrapper over\n * the pure `linkify` view-model: it turns the node list into text runs and\n * dotted inline links, each with a hover/focus definition-preview popover\n * (definition + status pill + \"don't confuse with\" neighbour chips, the chips\n * themselves links). Nothing is stored — every render re-derives from the live\n * glossary. Styled with the package's own token sheet, no host Tailwind.\n */\nimport { Fragment } from \"react\";\nimport { statusTone } from \"./primitives.js\";\nimport { linkify, type GlossaryTerm, type TermPreview } from \"./glossary.js\";\n\nexport interface GlossaryTextProps {\n /** The prose to linkify — body text or a short-text field (story 27). */\n text: string;\n /** The live glossary, already normalised (see `toGlossaryTerms`). */\n terms: GlossaryTerm[];\n /** The record this prose belongs to — its own term never self-links. */\n selfId?: string;\n /** Open a term's record (from a link or a neighbour chip; story 30). */\n onOpenTerm?: (id: string) => void;\n}\n\nconst PILL_CLASS = {\n good: \"vos-pill vos-pill-good\",\n warn: \"vos-pill vos-pill-warn\",\n crit: \"vos-pill vos-pill-crit\",\n accent: \"vos-pill vos-pill-accent\",\n neutral: \"vos-pill vos-pill-neutral\",\n} as const;\n\nexport function GlossaryText({\n text,\n terms,\n selfId,\n onOpenTerm,\n}: GlossaryTextProps) {\n const nodes = linkify(text, terms, { selfId });\n return (\n <>\n {nodes.map((node, i) =>\n node.kind === \"text\" ? (\n <Fragment key={i}>{node.text}</Fragment>\n ) : (\n <TermLink\n key={i}\n text={node.text}\n term={node.term}\n onOpenTerm={onOpenTerm}\n />\n ),\n )}\n </>\n );\n}\n\n/** One dotted inline link with its hover/focus definition-preview popover. */\nfunction TermLink({\n text,\n term,\n onOpenTerm,\n}: {\n text: string;\n term: TermPreview;\n onOpenTerm?: (id: string) => void;\n}) {\n return (\n <span className=\"vos-gloss\">\n <button\n type=\"button\"\n className=\"vos-gloss-term\"\n onClick={onOpenTerm ? () => onOpenTerm(term.id) : undefined}\n >\n {text}\n </button>\n <span className=\"vos-gloss-pop\" role=\"tooltip\">\n <span className=\"vos-gloss-pop-head\">\n <b>{term.title}</b>\n <span className={PILL_CLASS[statusTone(term.status)]}>\n {term.status}\n </span>\n </span>\n <span className=\"vos-gloss-pop-def\">{term.definition || \"—\"}</span>\n {term.dontConfuseWith.length ? (\n <span className=\"vos-gloss-pop-neighbours\">\n <span className=\"vos-gloss-pop-label\">Don't confuse with</span>\n {term.dontConfuseWith.map((n) => (\n <button\n key={n.id}\n type=\"button\"\n className=\"vos-gloss-chip\"\n onClick={onOpenTerm ? () => onOpenTerm(n.id) : undefined}\n >\n {n.title}\n </button>\n ))}\n </span>\n ) : null}\n </span>\n </span>\n );\n}\n","/**\n * Pure presentation logic for the dashboard's visual primitives — status→tone,\n * risk→fraction/level, the sparkline path, and count/number formatting. Kept\n * free of React and the DOM so the mapping that drives every pill, bar and\n * sparkline is unit-tested at this seam (spec story 13), and the components stay\n * thin wrappers over it.\n */\n\n/** A pill/fill tone — maps onto the `--vos-good/warn/crit/accent` tokens. */\nexport type Tone = \"good\" | \"warn\" | \"crit\" | \"accent\" | \"neutral\";\n\n/** Statuses that read as settled/positive, whatever the register. */\nconst GOOD_STATUS = new Set([\n \"live\",\n \"concluded\",\n \"closed\",\n \"done\",\n \"resolved\",\n \"accepted\",\n \"adopted\",\n \"shipped\",\n]);\n/** Statuses that read as in-flight / not yet settled. */\nconst WARN_STATUS = new Set([\n \"testing\",\n \"running\",\n \"in progress\",\n \"in-progress\",\n \"draft\",\n]);\n/** Statuses that read as a problem. */\nconst CRIT_STATUS = new Set([\n \"invalidated\",\n \"rejected\",\n \"blocked\",\n \"failed\",\n \"at risk\",\n]);\n\n/**\n * A record's Status → a pill tone. Live/concluded read good, testing/running\n * read warn, invalidated/rejected read crit; everything else (Proposed, and any\n * status we don't recognise) stays neutral rather than guessing a colour. Case-\n * and whitespace-insensitive.\n */\nexport function statusTone(status: string | null | undefined): Tone {\n if (!status) return \"neutral\";\n const s = status.trim().toLowerCase();\n if (GOOD_STATUS.has(s)) return \"good\";\n if (WARN_STATUS.has(s)) return \"warn\";\n if (CRIT_STATUS.has(s)) return \"crit\";\n return \"neutral\";\n}\n\n/**\n * Risk band thresholds — Critical ≥ 70, High 40–69, Watch < 40 (OPS-1287). A\n * belief is critical at ≥ `RISK_CRIT`, watch/high at ≥ `RISK_WARN`. These are a\n * prioritisation setting (a config knob), not a record property; overriding them\n * is `configureRiskBands`. Kept dashboard-wide so the flat-table risk cell, the\n * group-by risk-band axis, and the hero meter all band a number the same way.\n */\nexport let RISK_CRIT = 70;\nexport let RISK_WARN = 40;\n\n/** The three fixed risk bands, strongest first (OPS-1287 story 19). */\nexport type RiskBand = \"Critical\" | \"High\" | \"Watch\";\n\n/**\n * Override the two risk-band thresholds (the config knob). Left as a setter over\n * module state rather than threaded through every call, so an instance can retune\n * the bands once at startup and every risk rendering follows.\n */\nexport function configureRiskBands(crit: number, warn: number): void {\n RISK_CRIT = crit;\n RISK_WARN = warn;\n}\n\n/** Risk (0–100) → its band label. Grouping uses this; sort stays continuous. */\nexport function riskBand(risk: number): RiskBand {\n if (risk >= RISK_CRIT) return \"Critical\";\n if (risk >= RISK_WARN) return \"High\";\n return \"Watch\";\n}\n\n/** Risk (0–100) → a tone for the bar fill and the number. */\nexport function riskLevel(risk: number): Tone {\n if (risk >= RISK_CRIT) return \"crit\";\n if (risk >= RISK_WARN) return \"warn\";\n return \"good\";\n}\n\n/** Risk (0–100) → the bar's fill fraction (0–1), clamped. */\nexport function riskFraction(risk: number): number {\n if (!Number.isFinite(risk)) return 0;\n return Math.max(0, Math.min(100, risk)) / 100;\n}\n\n/** Confidence (signed) → the tone for its number: negative reads crit. */\nexport function confidenceTone(confidence: number): Tone {\n return confidence < 0 ? \"crit\" : \"good\";\n}\n\n/**\n * The tone for a derived-hero number. Confidence reads crit when negative; Risk\n * reads by threshold; Derived Impact, Strength and anything else read neutral.\n * Pure, so the drawer's hero doesn't hand-roll this branching.\n */\nexport function derivedTone(field: string, value: number): Tone {\n if (field === \"confidence\") return confidenceTone(value);\n if (field === \"risk\") return riskLevel(value);\n return \"neutral\";\n}\n\n/**\n * Tone → the text-colour class for a derived-hero number. Only warn/crit are\n * tinted; a good or neutral number stays the default text colour (the hero\n * doesn't paint every number green the way the in-row cells do).\n */\nexport function heroToneClass(tone: Tone): string {\n if (tone === \"crit\") return \"vos-text-crit\";\n if (tone === \"warn\") return \"vos-text-warn\";\n return \"\";\n}\n\n/** A signed number rendered with an explicit sign: `+6`, `-3`, `0`. */\nexport function formatSigned(n: number): string {\n const r = Math.round(n);\n return r > 0 ? `+${r}` : String(r);\n}\n\n/** A count for the nav/tiles, thousands-separated. */\nexport function formatCount(n: number): string {\n return n.toLocaleString();\n}\n\n/**\n * An SVG polyline `d` for a sparkline over `values`, fit to a `width`×`height`\n * box with a 2px inset. The vertical domain defaults to the data's own range\n * (with 0 always included, so a signed series keeps its baseline meaningful);\n * pass `min`/`max` to pin it — e.g. −100…100 for Confidence. Returns \"\" for\n * fewer than two points (nothing to draw).\n */\nexport function sparklinePath(\n values: number[],\n width: number,\n height: number,\n min?: number,\n max?: number,\n): string {\n if (values.length < 2) return \"\";\n const lo = min ?? Math.min(...values, 0);\n const hi = max ?? Math.max(...values, 0);\n const span = hi - lo || 1;\n const inset = 2;\n return values\n .map((v, i) => {\n const x = (i / (values.length - 1)) * (width - inset * 2) + inset;\n const y = height - inset - ((v - lo) / span) * (height - inset * 2);\n return `${i ? \"L\" : \"M\"}${x.toFixed(1)} ${y.toFixed(1)}`;\n })\n .join(\" \");\n}\n\n/** The y for a value in the same box `sparklinePath` uses — for endpoint dots\n * and the zero baseline. */\nexport function sparklineY(\n value: number,\n height: number,\n lo: number,\n hi: number,\n): number {\n const span = hi - lo || 1;\n const inset = 2;\n return height - inset - ((value - lo) / span) * (height - inset * 2);\n}\n","/**\n * Glossary auto-linking (OPS-1285) — the pure render-time pass that turns\n * glossary Titles appearing in prose into links, computed fresh on every render\n * so renames / retirements / status changes are always reflected with nothing\n * stored. Kept DOM-free at this seam and unit-tested exactly like\n * `link-choices.ts`; the `GlossaryText` component renders what it returns.\n *\n * The four forks the OPS-1285 prototype resolved are the rules here:\n * - match on **Title only** (no alias list), case-insensitive, word-boundary,\n * **longest title wins** (Derived Impact over Impact), **every** occurrence;\n * - **Active + Provisional** terms link, **Superseded never**, and never a\n * term inside its own record;\n * - **no false-positive machinery** — a generic word that is a term links\n * harmlessly; the simplicity is the decision.\n */\nimport type { AnyRecord } from \"@validation-os/core\";\n\n/** A glossary term reduced to what linking needs — the normalised input. */\nexport interface GlossaryTerm {\n id: string;\n title: string;\n /** \"Active\" | \"Provisional\" | \"Superseded\". */\n status: string;\n definition: string;\n howItDiffers: string;\n}\n\n/** A \"don't confuse with\" neighbour — a chip that is itself a link. */\nexport interface NeighbourChip {\n id: string;\n title: string;\n}\n\n/** The definition-preview payload a link node carries (the hover popover). */\nexport interface TermPreview {\n id: string;\n title: string;\n status: string;\n definition: string;\n /** Neighbours named in this term's \"How it differs\" (story 29/30). */\n dontConfuseWith: NeighbourChip[];\n}\n\n/** One piece of linkified prose: literal text, or a link to a term. */\nexport type LinkifyNode =\n | { kind: \"text\"; text: string }\n | { kind: \"link\"; text: string; term: TermPreview };\n\nexport interface LinkifyOptions {\n /** The id of the record the prose belongs to — its own term never links. */\n selfId?: string;\n}\n\n/** Only Active and Provisional terms link (Superseded never; story 28). */\nfunction linkable(term: GlossaryTerm): boolean {\n return term.status === \"Active\" || term.status === \"Provisional\";\n}\n\n/** Escape a title for use inside a `RegExp`. */\nfunction escapeRegExp(s: string): string {\n return s.replace(/[.*+?^${}()|[\\]\\\\]/g, \"\\\\$&\");\n}\n\n/**\n * A matcher for a set of titles: longest-first alternation on word boundaries,\n * case-insensitive and global, so `exec` walks every occurrence and the longest\n * title wins at each position. Returns null when there is nothing to match.\n */\nfunction buildMatcher(titles: string[]): RegExp | null {\n const usable = titles.filter((t) => t.trim() !== \"\");\n if (usable.length === 0) return null;\n // Longest first: JS alternation takes the first matching branch at a\n // position, so ordering by length makes \"Derived Impact\" win over \"Impact\".\n const ordered = [...usable].sort((a, b) => b.length - a.length);\n const alt = ordered.map(escapeRegExp).join(\"|\");\n return new RegExp(`\\\\b(?:${alt})\\\\b`, \"gi\");\n}\n\n/**\n * The terms named in a term's \"How it differs\" prose — the neighbour chips.\n * Excludes the term itself and any non-linkable (Superseded) neighbour, and is\n * de-duplicated in first-appearance order.\n */\nexport function dontConfuseWith(\n term: GlossaryTerm,\n terms: GlossaryTerm[],\n): NeighbourChip[] {\n const others = terms.filter((t) => t.id !== term.id && linkable(t));\n const byLowerTitle = new Map(others.map((t) => [t.title.toLowerCase(), t]));\n const matcher = buildMatcher(others.map((t) => t.title));\n if (!matcher || !term.howItDiffers) return [];\n const seen = new Set<string>();\n const chips: NeighbourChip[] = [];\n for (const m of term.howItDiffers.matchAll(matcher)) {\n const hit = byLowerTitle.get(m[0].toLowerCase());\n if (hit && !seen.has(hit.id)) {\n seen.add(hit.id);\n chips.push({ id: hit.id, title: hit.title });\n }\n }\n return chips;\n}\n\n/**\n * Linkify `text` against the glossary. Returns an ordered list of text and link\n * nodes; a link node carries the term's definition-preview payload. Pure and\n * render-time — nothing is stored.\n */\nexport function linkify(\n text: string,\n terms: GlossaryTerm[],\n options: LinkifyOptions = {},\n): LinkifyNode[] {\n if (!text) return [];\n\n const candidates = terms.filter(\n (t) => linkable(t) && t.id !== options.selfId && t.title.trim() !== \"\",\n );\n const matcher = buildMatcher(candidates.map((t) => t.title));\n if (!matcher) return [{ kind: \"text\", text }];\n\n const byLowerTitle = new Map(candidates.map((t) => [t.title.toLowerCase(), t]));\n // Previews are the same for every occurrence of a term — compute once.\n const previewCache = new Map<string, TermPreview>();\n const previewFor = (term: GlossaryTerm): TermPreview => {\n let p = previewCache.get(term.id);\n if (!p) {\n p = {\n id: term.id,\n title: term.title,\n status: term.status,\n definition: term.definition,\n dontConfuseWith: dontConfuseWith(term, terms),\n };\n previewCache.set(term.id, p);\n }\n return p;\n };\n\n const nodes: LinkifyNode[] = [];\n let last = 0;\n for (const m of text.matchAll(matcher)) {\n const term = byLowerTitle.get(m[0].toLowerCase());\n if (!term) continue; // matched a non-candidate casing — leave as text\n const start = m.index;\n if (start > last) nodes.push({ kind: \"text\", text: text.slice(last, start) });\n nodes.push({ kind: \"link\", text: m[0], term: previewFor(term) });\n last = start + m[0].length;\n }\n if (last < text.length) nodes.push({ kind: \"text\", text: text.slice(last) });\n return nodes;\n}\n\n/** Normalise glossary records into the linking input, dropping blank-title\n * rows (they can never match). Tolerates missing optional fields. */\nexport function toGlossaryTerms(records: AnyRecord[]): GlossaryTerm[] {\n return records\n .map((r) => ({\n id: r.id,\n title: typeof r.Title === \"string\" ? r.Title : \"\",\n status: typeof r.Status === \"string\" ? r.Status : \"\",\n definition: typeof r.Definition === \"string\" ? r.Definition : \"\",\n howItDiffers:\n typeof r[\"How it differs\"] === \"string\"\n ? (r[\"How it differs\"] as string)\n : \"\",\n }))\n .filter((t) => t.title.trim() !== \"\");\n}\n","/**\n * The record-page view-model (OPS-1286) — the pure join behind the canonical\n * full record page. Given a record and the related registers, it computes the\n * header lane/queue pills (all derived), the leading-score meters per register,\n * the genuine human-input free-text remainder, and the backlink panels grouped\n * by relation (each row carrying a glance-readable score chip, an empty relation\n * kept as a \"none yet\" panel rather than dropped). DOM-free and unit-tested at\n * this seam; `RecordPage` renders what it returns and the understanding layer\n * supplies the \"Why?\" attribution unchanged.\n */\nimport type {\n AnyRecord,\n BarLine,\n Collection,\n Result,\n} from \"@validation-os/core\";\nimport { experimentProgress } from \"@validation-os/core/derivation\";\nimport {\n confidenceTone,\n formatSigned,\n riskLevel,\n statusTone,\n type Tone,\n} from \"./primitives.js\";\nimport { primaryLabel } from \"./columns.js\";\nimport {\n derivedNum,\n inKillLane,\n isArchivedExperiment,\n isTesting,\n liveExperiments,\n readingBeliefs,\n readingGrades,\n readingMagnitudeBand,\n readingRung,\n str,\n strList,\n testsAssumption,\n} from \"./derived-views.js\";\n\n// ── Related set ───────────────────────────────────────────────────────────────\n\n/** The registers a record page reads to resolve its relations. All optional —\n * a panel whose register is absent simply resolves to \"none yet\". */\nexport interface RelatedSet {\n assumptions?: AnyRecord[];\n experiments?: AnyRecord[];\n readings?: AnyRecord[];\n decisions?: AnyRecord[];\n glossary?: AnyRecord[];\n}\n\nexport interface RecordPageOptions {\n /** ISO date \"now\" for the Overdue pill; omitted → nothing reads overdue. */\n asOf?: string;\n}\n\n/** Records for a list of ids, in id order, skipping ids with no record. */\nfunction byIds(records: AnyRecord[] | undefined, ids: string[]): AnyRecord[] {\n const map = new Map((records ?? []).map((r) => [r.id, r]));\n return ids.map((id) => map.get(id)).filter((r): r is AnyRecord => r != null);\n}\n\n// ── Header pills ──────────────────────────────────────────────────────────────\n\n/** A header pill: a short derived label toned by meaning. */\nexport interface Pill {\n label: string;\n tone: Tone;\n}\n\n/**\n * The derived lane/queue pills for a record header (story 2). Every register\n * leads with its Status pill; assumptions add Moot / Kill lane / Testing,\n * experiments add Concluded / Overdue, decisions mark Standing. All derived —\n * none is a stored field.\n */\nexport function headerPills(\n register: Collection,\n record: AnyRecord,\n related: RelatedSet = {},\n options: RecordPageOptions = {},\n): Pill[] {\n const pills: Pill[] = [];\n const status = str(record.Status);\n if (status) pills.push({ label: status, tone: statusTone(status) });\n\n if (register === \"assumptions\") {\n if (record.moot === true) pills.push({ label: \"Moot\", tone: \"neutral\" });\n if (inKillLane(record)) pills.push({ label: \"Kill lane\", tone: \"crit\" });\n else if (isTesting(record, related.experiments ?? []))\n pills.push({ label: \"Testing\", tone: \"warn\" });\n } else if (register === \"experiments\") {\n // A candidate/designed plan sits in the test-next pool (ontology\n // `test_next_surface`); the prioritisation layer owns its exact rank.\n if (status === \"Draft\") pills.push({ label: \"Test-next\", tone: \"accent\" });\n if (status === \"Closed\") pills.push({ label: \"Concluded\", tone: \"good\" });\n const deadline = str(record.Deadline);\n if (\n options.asOf &&\n deadline &&\n status === \"Running\" &&\n deadline < options.asOf\n )\n pills.push({ label: \"Overdue\", tone: \"crit\" });\n } else if (register === \"decisions\") {\n if (status === \"Active\") pills.push({ label: \"Standing\", tone: \"good\" });\n } else if (register === \"readings\") {\n // Rung + magnitude band are the reading's own evidence tier + intensity\n // (0.10, row-level) — one per artifact, so they lead the header as a single\n // paired badge (\"Talk · High\"), not the per-belief cards. Both fall\n // back to a belief's value on pre-migration data.\n const rung = readingRung(record);\n const band = readingMagnitudeBand(record);\n const label = [rung, band].filter(Boolean).join(\" · \");\n if (label) pills.push({ label, tone: \"accent\" });\n }\n return pills;\n}\n\n// ── Leading-score meters ──────────────────────────────────────────────────────\n\n/** A leading-score meter. `bar`/`signed` carry a number in a min…max domain;\n * `pill` carries a categorical value shown as a toned pill. */\nexport interface Meter {\n key: string;\n label: string;\n kind: \"bar\" | \"signed\" | \"pill\";\n /** Number (bar/signed) or category (pill); null when the record has no value. */\n value: number | string | null;\n tone: Tone;\n /** For bar/signed: the domain the fill maps onto. */\n min?: number;\n max?: number;\n /** True when a \"Why?\" attribution is available (Confidence only). */\n hasWhy?: boolean;\n}\n\n/**\n * The register's leading scores as meters (story 4). Reads only what the\n * migrated schema actually stores — a derived number becomes a bar/signed meter,\n * a categorical leading field becomes a pill; nothing is invented where the\n * schema carries no number. Confidence is flagged `hasWhy` — the understanding\n * layer decomposes it.\n */\nexport function leadingMeters(register: Collection, record: AnyRecord): Meter[] {\n switch (register) {\n case \"assumptions\":\n return [\n {\n key: \"confidence\",\n label: \"Confidence\",\n kind: \"signed\",\n value: derivedNum(record, \"confidence\"),\n tone: confidenceTone(derivedNum(record, \"confidence\") ?? 0),\n min: -100,\n max: 100,\n hasWhy: true,\n },\n {\n key: \"risk\",\n label: \"Risk\",\n kind: \"bar\",\n value: derivedNum(record, \"risk\"),\n tone: riskLevel(derivedNum(record, \"risk\") ?? 0),\n max: 100,\n },\n {\n key: \"derivedImpact\",\n label: \"Derived Impact\",\n kind: \"bar\",\n value: derivedNum(record, \"derivedImpact\"),\n tone: \"neutral\",\n max: 100,\n },\n ];\n case \"readings\":\n // Strength and Result are per belief now (OPS-1305) — they live in the\n // per-belief verdict list (`readingBeliefVerdicts`), not as row meters.\n // Source quality is the only row-level score left.\n return [\n {\n key: \"sourceQuality\",\n label: \"Source quality\",\n kind: \"bar\",\n // Stored 0–1; show as a 0–100 fill.\n value:\n derivedNum(record, \"sourceQuality\") === null\n ? null\n : Math.round((derivedNum(record, \"sourceQuality\") ?? 0) * 100),\n tone: \"neutral\",\n max: 100,\n },\n ];\n case \"experiments\": {\n const bars = (record.barLines as BarLine[] | undefined) ?? [];\n const progress = experimentProgress(bars);\n return [\n {\n key: \"maturity\",\n label: \"Maturity\",\n kind: \"bar\",\n value: progress.total ? Math.round((progress.settled / progress.total) * 100) : null,\n tone: progress.concluded ? \"good\" : \"warn\",\n max: 100,\n },\n {\n key: \"Feasibility\",\n label: \"Feasibility\",\n kind: \"pill\",\n value: str(record.Feasibility),\n tone: \"neutral\",\n },\n ];\n }\n case \"decisions\":\n return [\n {\n key: \"Status\",\n label: \"Status\",\n kind: \"pill\",\n value: str(record.Status),\n tone: statusTone(str(record.Status) ?? \"\"),\n },\n ];\n case \"glossary\":\n return [\n {\n key: \"Status\",\n label: \"Status\",\n kind: \"pill\",\n value: str(record.Status),\n tone: statusTone(str(record.Status) ?? \"\"),\n },\n ];\n }\n}\n\n// ── Human-input free text (story 7) ──────────────────────────────────────────\n\n/** The genuine human-input free-text remainder — clearly separated from what\n * the system computed. Auto-linked against the glossary at render time. */\nexport interface HumanText {\n key: string;\n label: string;\n text: string;\n}\n\nconst HUMAN_FIELDS: Record<Collection, { key: string; label: string }[]> = {\n assumptions: [{ key: \"Scoring justification\", label: \"Scoring justification\" }],\n // A reading's grading justification is per belief now (OPS-1305) — it renders\n // in the verdict cards (`BeliefVerdicts`), so surfacing a stale row-level copy\n // here too would double up. The row carries no other genuine human free-text.\n readings: [],\n decisions: [\n { key: \"Statement\", label: \"Statement\" },\n { key: \"Unanimity justification\", label: \"Unanimity justification\" },\n ],\n experiments: [{ key: \"Instrument\", label: \"Instrument\" }],\n glossary: [\n { key: \"Definition\", label: \"Definition\" },\n { key: \"How it differs\", label: \"How it differs\" },\n ],\n};\n\n/** The human-input fields a register carries text for (empty ones dropped). */\nexport function humanInputFields(\n register: Collection,\n record: AnyRecord,\n): HumanText[] {\n return HUMAN_FIELDS[register]\n .map((f) => ({ key: f.key, label: f.label, text: str(record[f.key]) ?? \"\" }))\n .filter((f) => f.text !== \"\");\n}\n\n// ── Per-belief verdict list (reading detail) ─────────────────────────────────\n\n/** One belief a reading grades, prepared for the reading detail's verdict list\n * (OPS-1305). Modelled on the experiment bar-line view: the assumption resolved\n * to a title + navigable id, plus this belief's own Result / derived Strength\n * and the grading justification. Rung AND magnitude band are NOT here — they are\n * row-level attributes of the artifact now (0.10), the same for every belief the\n * reading grades, so they show once at the reading level, not per card. */\nexport interface BeliefVerdict {\n assumptionId: string;\n /** The belief's title if it's in the loaded set, else its bare id. */\n title: string;\n /** True when the assumption resolved — drives whether the title links. */\n linked: boolean;\n result: Result | null;\n /** Derived per-belief strength (signed −100…100). */\n strength: number | null;\n justification: string;\n /** Verbatim quote/excerpt for this belief, if recorded. */\n excerpt: string;\n}\n\n/** The per-belief verdicts a reading carries, in stored order — the reading\n * detail's answer to \"what did this artifact say about each belief?\". Pure:\n * resolves each belief-score against the loaded assumptions for its title. */\nexport function readingBeliefVerdicts(\n reading: AnyRecord,\n assumptions: AnyRecord[] = [],\n): BeliefVerdict[] {\n const byId = new Map(assumptions.map((a) => [a.id, a]));\n return readingBeliefs(reading).map((b) => {\n const hit = byId.get(b.assumptionId);\n const strength =\n b.derived && typeof b.derived.strength === \"number\"\n ? b.derived.strength\n : null;\n return {\n assumptionId: b.assumptionId,\n title: hit ? primaryLabel(hit) : b.assumptionId,\n linked: hit != null,\n result: (b.Result as Result | undefined) ?? null,\n strength,\n justification:\n typeof b[\"Grading justification\"] === \"string\"\n ? b[\"Grading justification\"]\n : \"\",\n excerpt:\n typeof b.excerpt === \"string\" && b.excerpt !== \"\"\n ? b.excerpt\n : snippetFromBody(String(reading.body ?? \"\"), b.assumptionId),\n };\n });\n}\n\n/** Pull a short quote-like snippet from a reading body as a fallback excerpt.\n * Prefers text inside a `## Quote` block, then a sentence mentioning the\n * assumption title or id, then the first sentence. */\nfunction snippetFromBody(body: string, cue: string): string {\n if (!body) return \"\";\n const quoteMatch = body.match(/## Quote\\n+([\\s\\S]*?)(?=\\n## |\\n##$|$)/i);\n if (quoteMatch) {\n const q = quoteMatch[1]!.trim();\n return q.length > 220 ? q.slice(0, 217).trim() + \"…\" : q;\n }\n const sentences = body.split(/(?<=[.!?])\\s+/);\n const cueLower = cue.toLowerCase();\n for (const s of sentences) {\n if (s.toLowerCase().includes(cueLower)) return s.trim();\n }\n const first = sentences[0]?.trim() ?? \"\";\n return first.length > 220 ? first.slice(0, 217).trim() + \"…\" : first;\n}\n\n/** A reading's verdicts tallied by result — the one-line \"what did this say?\"\n * summary above the per-belief list (OPS-1305 design pass). `inconclusive`\n * folds every non-Validated/Invalidated verdict (Inconclusive or ungraded) so\n * the three counts always sum to `total`. */\nexport interface BeliefSummary {\n total: number;\n validated: number;\n invalidated: number;\n inconclusive: number;\n}\n\n/** Tally a reading's per-belief verdicts by result. Pure over the same input\n * the verdict list reads, so the headline and the cards never disagree. */\nexport function readingBeliefSummary(\n reading: AnyRecord,\n assumptions: AnyRecord[] = [],\n): BeliefSummary {\n const verdicts = readingBeliefVerdicts(reading, assumptions);\n let validated = 0;\n let invalidated = 0;\n for (const v of verdicts) {\n if (v.result === \"Validated\") validated += 1;\n else if (v.result === \"Invalidated\") invalidated += 1;\n }\n return {\n total: verdicts.length,\n validated,\n invalidated,\n inconclusive: verdicts.length - validated - invalidated,\n };\n}\n\n// ── Backlink panels ───────────────────────────────────────────────────────────\n\n/** A glance-readable score chip for a linked record (story 9). */\nexport interface ScoreChip {\n label: string;\n value: string;\n tone: Tone;\n}\n\nexport interface BacklinkItem {\n id: string;\n register: Collection;\n title: string;\n chip: ScoreChip;\n}\n\n/** A relation panel — the inbound/outbound edges of one relation, grouped and\n * labelled. Kept even when empty (story 10). */\nexport interface RelationPanel {\n id: string;\n label: string;\n register: Collection;\n items: BacklinkItem[];\n}\n\n/** The linked record's headline score, glance-readable (story 9). */\nexport function scoreChip(register: Collection, record: AnyRecord): ScoreChip {\n if (register === \"assumptions\") {\n const c = derivedNum(record, \"confidence\") ?? 0;\n return { label: \"Confidence\", value: formatSigned(c), tone: confidenceTone(c) };\n }\n if (register === \"readings\") {\n // Strength is per belief now (OPS-1305); the row's glance score is its\n // Source quality (0–1 → 0–100), a property of the artifact, not a belief.\n const sq = derivedNum(record, \"sourceQuality\");\n return {\n label: \"Source quality\",\n value: sq === null ? \"—\" : String(Math.round(sq * 100)),\n tone: \"neutral\",\n };\n }\n const status = str(record.Status) ?? \"—\";\n return { label: \"Status\", value: status, tone: statusTone(status) };\n}\n\ninterface PanelDef {\n id: string;\n label: string;\n register: Collection;\n resolve: (record: AnyRecord, related: RelatedSet) => AnyRecord[];\n}\n\nconst PANELS: Record<Collection, PanelDef[]> = {\n assumptions: [\n {\n id: \"readings\",\n label: \"Readings\",\n register: \"readings\",\n resolve: (r, rel) =>\n (rel.readings ?? []).filter((x) => readingGrades(x, r.id)),\n },\n {\n id: \"depends-on\",\n label: \"Depends on\",\n register: \"assumptions\",\n resolve: (r, rel) => byIds(rel.assumptions, strList(r.dependsOnIds)),\n },\n {\n id: \"enables\",\n label: \"Enables\",\n register: \"assumptions\",\n resolve: (r, rel) => byIds(rel.assumptions, strList(r.enablesIds)),\n },\n {\n id: \"contradicts\",\n label: \"Contradicts\",\n register: \"assumptions\",\n resolve: (r, rel) => byIds(rel.assumptions, strList(r.contradictsIds)),\n },\n {\n id: \"tested-by\",\n label: \"Tested by\",\n register: \"experiments\",\n // Archived plans never surface as a relation (OPS-1305) — live plans only.\n resolve: (r, rel) =>\n liveExperiments(rel.experiments ?? []).filter((e) =>\n testsAssumption(e, r.id),\n ),\n },\n {\n id: \"decisions-based\",\n label: \"Decisions based on this\",\n register: \"decisions\",\n resolve: (r, rel) =>\n (rel.decisions ?? []).filter((d) => strList(d.basedOnIds).includes(r.id)),\n },\n {\n id: \"resolved-by\",\n label: \"Resolved by\",\n register: \"decisions\",\n resolve: (r, rel) =>\n (rel.decisions ?? []).filter((d) => strList(d.resolvesIds).includes(r.id)),\n },\n ],\n readings: [\n {\n id: \"assumption\",\n label: \"Beliefs\",\n register: \"assumptions\",\n // A reading grades several beliefs now (OPS-1305) — resolve them all.\n resolve: (r, rel) => byIds(rel.assumptions, strList(r.assumptionIds)),\n },\n {\n id: \"experiment\",\n label: \"Evidence plan\",\n register: \"experiments\",\n // Only ever surface a NON-archived plan (OPS-1305): an archived origin\n // reads as no plan at all, never a leaked backlink.\n resolve: (r, rel) =>\n byIds(rel.experiments, [str(r.experimentId) ?? \"\"].filter(Boolean)).filter(\n (e) => !isArchivedExperiment(e),\n ),\n },\n ],\n experiments: [\n {\n id: \"readings\",\n label: \"Readings\",\n register: \"readings\",\n resolve: (r, rel) => (rel.readings ?? []).filter((x) => x.experimentId === r.id),\n },\n {\n id: \"assumptions-tested\",\n label: \"Beliefs tested\",\n register: \"assumptions\",\n resolve: (r, rel) => {\n const bars = (r.barLines as BarLine[] | undefined) ?? [];\n const ids = bars.length\n ? bars.map((b) => b.assumptionId)\n : strList(r.barLineAssumptionIds);\n return byIds(rel.assumptions, ids);\n },\n },\n ],\n decisions: [\n {\n id: \"based-on\",\n label: \"Based on\",\n register: \"assumptions\",\n resolve: (r, rel) => byIds(rel.assumptions, strList(r.basedOnIds)),\n },\n {\n id: \"resolves\",\n label: \"Resolves\",\n register: \"assumptions\",\n resolve: (r, rel) => byIds(rel.assumptions, strList(r.resolvesIds)),\n },\n ],\n glossary: [],\n};\n\n/** The backlink panels for a record, grouped by relation, each row carrying a\n * score chip. Empty relations are kept (items: []) so a missing connection reads\n * as \"none yet\", not an absent section (story 8/10). */\nexport function backlinkPanels(\n register: Collection,\n record: AnyRecord,\n related: RelatedSet = {},\n): RelationPanel[] {\n return PANELS[register].map((def) => ({\n id: def.id,\n label: def.label,\n register: def.register,\n items: def.resolve(record, related).map((rec) => ({\n id: rec.id,\n register: def.register,\n title: primaryLabel(rec),\n chip: scoreChip(def.register, rec),\n })),\n }));\n}\n\n// ── The assembled page model ──────────────────────────────────────────────────\n\nexport type RecordTabId = \"overview\" | \"evidence\" | \"connections\" | \"history\";\n\nexport interface RecordPageModel {\n register: Collection;\n title: string;\n pills: Pill[];\n meters: Meter[];\n humanText: HumanText[];\n panels: RelationPanel[];\n /** The tabs this record shows, in order (story 3 + 11). */\n tabs: RecordTabId[];\n /** True when the belief journey drill-in can mount here (story 13). */\n hasJourney: boolean;\n}\n\n/** The registers whose record page carries an Evidence tab (story 3/14). */\nfunction hasEvidenceTab(register: Collection): boolean {\n return register === \"assumptions\" || register === \"experiments\";\n}\n\n/** Assemble the whole record-page model. Pure: same record + related always\n * gives the same page. */\nexport function buildRecordPage(\n register: Collection,\n record: AnyRecord,\n related: RelatedSet = {},\n options: RecordPageOptions = {},\n): RecordPageModel {\n const tabs: RecordTabId[] = [\"overview\"];\n if (hasEvidenceTab(register)) tabs.push(\"evidence\");\n tabs.push(\"connections\", \"history\");\n return {\n register,\n title: primaryLabel(record),\n pills: headerPills(register, record, related, options),\n meters: leadingMeters(register, record),\n humanText: humanInputFields(register, record),\n panels: backlinkPanels(register, record, related),\n tabs,\n hasJourney: register === \"assumptions\",\n };\n}\n","/**\n * Per-register table columns and value formatting — the presentational shape\n * of the browse tables, kept as pure data/functions so it is unit-testable\n * without a DOM. The register is a surface a non-technical teammate meets, so\n * headers are plain language and derived numbers are shown, never hidden.\n */\nimport type { AnyRecord, Collection } from \"@validation-os/core\";\nimport { readingMagnitudeBand, readingRung } from \"./derived-views.js\";\n\n/**\n * How a cell renders. `text` is plain formatted text; `status` is a colored\n * pill; `risk` is a threshold-toned bar + number; `confidence` is a signed\n * number (with a sparkline when a trajectory is available). Keeping this on the\n * column — not branching by key in the table — is what makes the visual\n * treatment declarative and testable at this seam (spec story 13).\n */\nexport type CellKind = \"text\" | \"status\" | \"risk\" | \"confidence\";\n\nexport interface ColumnDef {\n /** Stable key; also the default field read from the record. */\n key: string;\n /** Plain-language column header. */\n header: string;\n /** Pull the display value from a record (defaults to `record[key]`). */\n accessor?: (record: AnyRecord) => unknown;\n /** Numeric columns right-align for a clean column of figures. */\n align?: \"left\" | \"right\";\n /** Marks a column whose value is computed, never hand-typed (spec story 4). */\n derived?: boolean;\n /** How the cell renders; defaults to `text`. */\n kind?: CellKind;\n}\n\n/** Read a nested `derived` number off a record, tolerating a missing tuple. */\nfunction derivedField(field: string): (r: AnyRecord) => unknown {\n return (r) => (r.derived as Record<string, unknown> | undefined)?.[field];\n}\n\n/**\n * The columns each register shows, left-to-right. The first column is always\n * the record's headline (Title, or Name for people); assumptions additionally\n * surface Impact, Confidence and Risk at a glance (spec user story 2).\n */\nconst COLUMNS: Record<Collection, ColumnDef[]> = {\n assumptions: [\n { key: \"Title\", header: \"Belief\" },\n {\n key: \"Status\",\n header: \"Status\",\n kind: \"status\",\n },\n { key: \"Impact\", header: \"Impact\", align: \"right\" },\n {\n key: \"confidence\",\n header: \"Confidence\",\n align: \"right\",\n derived: true,\n kind: \"confidence\",\n accessor: derivedField(\"confidence\"),\n },\n {\n key: \"risk\",\n header: \"Risk\",\n align: \"right\",\n derived: true,\n kind: \"risk\",\n accessor: derivedField(\"risk\"),\n },\n ],\n experiments: [\n { key: \"Title\", header: \"Evidence plan\" },\n { key: \"Status\", header: \"Status\", kind: \"status\" },\n { key: \"Feasibility\", header: \"Feasibility\" },\n ],\n readings: [\n { key: \"Title\", header: \"Reading\" },\n { key: \"Source\", header: \"Source\" },\n { key: \"Date\", header: \"Date\" },\n // Rung + magnitude band are row-level attributes of the artifact (0.10): the\n // evidence tier and its intensity, one per reading, not per belief. They lead\n // the row's evidential weight, so each earns a column. Both helpers fall back\n // to a belief's value on pre-migration data so the columns are never blank\n // during the rollout.\n { key: \"Rung\", header: \"Rung\", accessor: (r) => readingRung(r) },\n { key: \"magnitudeBand\", header: \"Band\", accessor: (r) => readingMagnitudeBand(r) },\n // The row's per-belief Result / Strength stay in the reading detail's\n // verdict list (OPS-1305). The table previews the quote (`body`) so a row is\n // legible at a glance; assumption chips (see `readingAssumptionChips`)\n // disambiguate same-titled readings.\n {\n key: \"body\",\n header: \"Quote\",\n accessor: (r) => bodyPreview(r.body),\n },\n ],\n decisions: [\n { key: \"Title\", header: \"Decision\" },\n { key: \"Status\", header: \"Status\", kind: \"status\" },\n ],\n glossary: [\n { key: \"Title\", header: \"Term\" },\n { key: \"Status\", header: \"Status\", kind: \"status\" },\n ],\n};\n\n/** The columns to render for a register. */\nexport function columnsFor(register: Collection): ColumnDef[] {\n return COLUMNS[register];\n}\n\n/** A one-line, length-capped preview of a reading's free-text `body` (its\n * quote), for the readings table. Collapses whitespace and ellipsises; a\n * missing/empty body reads as the empty string (formatted to an em dash). */\nexport function bodyPreview(value: unknown, max = 80): string {\n if (typeof value !== \"string\") return \"\";\n const oneLine = value.replace(/\\s+/g, \" \").trim();\n if (oneLine.length <= max) return oneLine;\n return `${oneLine.slice(0, max - 1).trimEnd()}…`;\n}\n\n/** The belief chips for a reading row — the assumptions it grades, resolved to\n * titles when a lookup is given, else their bare ids. Disambiguates readings\n * that share a Title by showing which belief(s) each one actually scored. */\nexport function readingAssumptionChips(\n record: AnyRecord,\n titleById: Map<string, string> = new Map(),\n): string[] {\n const ids = Array.isArray(record.assumptionIds)\n ? record.assumptionIds.filter((x): x is string => typeof x === \"string\")\n : [];\n return ids.map((id) => titleById.get(id) ?? id);\n}\n\n/** Read a column's raw value from a record (accessor, else `record[key]`). */\nexport function cellValue(column: ColumnDef, record: AnyRecord): unknown {\n return column.accessor ? column.accessor(record) : record[column.key];\n}\n\n/** Format any stored value for display; empty/missing reads as an em dash. */\nexport function formatValue(value: unknown): string {\n if (value === null || value === undefined || value === \"\") return \"—\";\n if (typeof value === \"boolean\") return value ? \"Yes\" : \"No\";\n if (Array.isArray(value)) {\n return value.length ? value.map(formatScalar).join(\", \") : \"—\";\n }\n return formatScalar(value);\n}\n\nfunction formatScalar(value: unknown): string {\n if (value === null || value === undefined) return \"—\";\n if (typeof value === \"number\") return String(value);\n if (typeof value === \"object\") return JSON.stringify(value);\n return String(value);\n}\n\n/** The record's headline for a row/drawer: Title, else Name, else its id. */\nexport function primaryLabel(record: AnyRecord): string {\n const title = record.Title ?? record.Name;\n return typeof title === \"string\" && title.trim() ? title : record.id;\n}\n\n// ── Field labels ────────────────────────────────────────────────────────────\n// The register is a surface a non-technical teammate meets, so field names are\n// shown in plain language, never as raw camelCase keys. This is the single\n// source for both the drawer's field list and its computed-numbers block.\n\n/** Labels for the computed `derived` tuple. Both `derivedImpact` (the\n * derivation module's name) and `impact` (the migrated data's name, pending the\n * OPS-1273 schema ripple) map to one label so the drawer reads cleanly either\n * way. */\nconst DERIVED_LABEL: Record<string, string> = {\n confidence: \"Confidence\",\n risk: \"Risk\",\n derivedImpact: \"Derived Impact\",\n impact: \"Derived Impact\",\n completeness: \"Completeness %\",\n sourceQuality: \"Source quality\",\n strength: \"Strength\",\n};\n\n/** Plain-language names for the camelCase id/relation fields; Title-cased\n * fields (Title, Status, Impact, Owner…) already read cleanly and pass through. */\nconst FIELD_LABEL: Record<string, string> = {\n dependsOnIds: \"Depends on\",\n enablesIds: \"Enables\",\n contradictsIds: \"Contradicts\",\n readingIds: \"Readings\",\n assumptionId: \"Assumption\",\n assumptionIds: \"Beliefs\",\n experimentId: \"Evidence plan\",\n body: \"Quote\",\n contextLinks: \"Context links\",\n basedOnIds: \"Based on\",\n resolvesIds: \"Resolves\",\n barLineAssumptionIds: \"Assumptions tested\",\n closureReason: \"Closure reason\",\n magnitudeBand: \"Magnitude band\",\n moot: \"Moot\",\n};\n\n/** A record field's display label — an override, else a humanised key. */\nexport function fieldLabel(key: string): string {\n const override = FIELD_LABEL[key];\n if (override) return override;\n if (/^[A-Z]/.test(key)) return key; // already Title-cased, reads fine\n const spaced = key.replace(/([a-z0-9])([A-Z])/g, \"$1 $2\").toLowerCase();\n return spaced.charAt(0).toUpperCase() + spaced.slice(1);\n}\n\n/** A computed (`derived`) field's display label. */\nexport function derivedLabel(key: string): string {\n return DERIVED_LABEL[key] ?? fieldLabel(key);\n}\n","import { useCallback, useEffect, useState } from \"react\";\nimport type { AnyRecord, Collection } from \"@validation-os/core\";\nimport { CONFLICT_MESSAGE } from \"./edit.js\";\n\n/**\n * Client hooks that read the register over HTTP through the API read routes\n * (`GET {basePath}/{register}` and `GET {basePath}/{register}/{id}`). The API\n * reaches Firestore server-side through the adapter, so no backend credentials\n * ever reach the browser — the browser only ever speaks to the Clerk-gated API.\n */\n\ninterface AsyncState<T> {\n data: T | null;\n loading: boolean;\n error: string | null;\n}\n\n/** Both read routes wrap their payload in a `{ data }` envelope. */\nfunction pickData<T>(body: unknown): T {\n return (body as { data: T }).data;\n}\n\n/**\n * Fetch one JSON resource, tracking loading/error. A null `url` means \"idle\"\n * (nothing to load yet) — the drawer's get hook uses this until a row is\n * clicked. Returns a `refresh` that re-runs the fetch. This is the shared\n * engine behind both `useList` and `useRecord`.\n */\nfunction useJsonResource<T>(url: string | null): AsyncState<T> & {\n refresh: () => void;\n} {\n const [state, setState] = useState<AsyncState<T>>({\n data: null,\n loading: url !== null,\n error: null,\n });\n const [tick, setTick] = useState(0);\n\n useEffect(() => {\n if (url === null) {\n setState({ data: null, loading: false, error: null });\n return;\n }\n let live = true;\n setState((s) => ({ ...s, loading: true }));\n fetch(url)\n .then(async (res) => {\n if (!res.ok) throw new Error(`Request to ${url} failed (${res.status})`);\n return pickData<T>(await res.json());\n })\n .then((data) => live && setState({ data, loading: false, error: null }))\n .catch(\n (e: unknown) =>\n live &&\n setState({\n data: null,\n loading: false,\n error: e instanceof Error ? e.message : \"Failed to load\",\n }),\n );\n return () => {\n live = false;\n };\n }, [url, tick]);\n\n const refresh = useCallback(() => setTick((t) => t + 1), []);\n return { ...state, refresh };\n}\n\nexport interface UseListResult {\n records: AnyRecord[] | null;\n loading: boolean;\n error: string | null;\n refresh: () => void;\n}\n\n/**\n * Fetch every row of a register. `enabled` (default true) gates the fetch: pass\n * false to keep the hook idle — the list-surface loads a *context* register\n * (e.g. experiments, for the assumptions \"Testing\" view) only when the current\n * register's tabs actually need it, without breaking the rules-of-hooks.\n */\nexport function useList(\n register: Collection,\n basePath = \"/api\",\n enabled = true,\n): UseListResult {\n const { data, loading, error, refresh } = useJsonResource<AnyRecord[]>(\n enabled ? `${basePath}/${register}` : null,\n );\n return { records: data, loading, error, refresh };\n}\n\nexport interface UseRecordResult {\n record: AnyRecord | null;\n loading: boolean;\n error: string | null;\n /** Re-fetch the record — the re-fetch path after a save or edit conflict. */\n refresh: () => void;\n}\n\n/**\n * Fetch one record by id. `id` may be null (nothing open) — the hook stays\n * idle until an id is supplied, so it drives a drawer that opens on row click.\n * `refresh` re-fetches: the edit flow calls it after a save, and it's the\n * re-fetch path offered when a write hits a concurrent-edit conflict.\n */\nexport function useRecord(\n register: Collection,\n id: string | null,\n basePath = \"/api\",\n): UseRecordResult {\n const url = id\n ? `${basePath}/${register}/${encodeURIComponent(id)}`\n : null;\n const { data, loading, error, refresh } = useJsonResource<AnyRecord>(url);\n return { record: data, loading, error, refresh };\n}\n\n/** The outcome of a save: the recomputed record, or a rejection with a\n * plain-language message (a concurrent-edit conflict, or another failure). */\nexport type SaveResult =\n | { ok: true; record: AnyRecord }\n | { ok: false; conflict: boolean; message: string };\n\nconst SAVE_FAILED = \"Couldn't save your changes — please try again.\";\n\n/**\n * Map an update response (status + parsed body) to a `SaveResult`. Pure, so\n * the 409/error/ok branching is unit-testable without a DOM. A 409 is a\n * concurrent-edit conflict, surfaced in the API's plain-language copy (or the\n * `CONFLICT_MESSAGE` fallback) — never version jargon (spec user story 12).\n */\nexport function interpretSave(status: number, body: unknown): SaveResult {\n if (status >= 200 && status < 300) {\n return { ok: true, record: pickData<AnyRecord>(body) };\n }\n const message = (body as { message?: unknown } | null)?.message;\n const text = typeof message === \"string\" ? message : null;\n if (status === 409) {\n return { ok: false, conflict: true, message: text ?? CONFLICT_MESSAGE };\n }\n return { ok: false, conflict: false, message: text ?? SAVE_FAILED };\n}\n\nexport interface UseUpdateResult {\n /** PATCH `{ version, ...patch }`; resolves to the recomputed record or a\n * rejection. Never throws — callers branch on `result.ok`. */\n save: (id: string, patch: Record<string, unknown>) => Promise<SaveResult>;\n saving: boolean;\n /** Plain-language conflict prompt when a concurrent edit was detected. */\n conflict: string | null;\n /** Plain-language message for any other save failure. */\n error: string | null;\n /** Clear conflict/error state (e.g. when re-entering edit mode). */\n reset: () => void;\n}\n\n/**\n * Version-guarded update over the API write route. A stale version comes back\n * as a 409, which we surface as a gentle, jargon-free `conflict` message (spec\n * user story 12) — the API sends the copy, and `CONFLICT_MESSAGE` is the\n * fallback. Derived values are recomputed server-side, so the returned record\n * carries the authoritative numbers, never anything the client computed.\n */\nexport function useUpdate(\n register: Collection,\n basePath = \"/api\",\n): UseUpdateResult {\n const [saving, setSaving] = useState(false);\n const [conflict, setConflict] = useState<string | null>(null);\n const [error, setError] = useState<string | null>(null);\n\n const save = useCallback(\n async (id: string, patch: Record<string, unknown>): Promise<SaveResult> => {\n setSaving(true);\n setConflict(null);\n setError(null);\n try {\n const res = await fetch(\n `${basePath}/${register}/${encodeURIComponent(id)}`,\n {\n method: \"PATCH\",\n headers: { \"content-type\": \"application/json\" },\n body: JSON.stringify(patch),\n },\n );\n const body = await res.json().catch(() => null);\n const result = interpretSave(res.status, body);\n if (!result.ok && result.conflict) setConflict(result.message);\n else if (!result.ok) setError(result.message);\n return result;\n } catch (e) {\n const message =\n e instanceof Error ? e.message : \"Couldn't save your changes.\";\n setError(message);\n return { ok: false, conflict: false, message };\n } finally {\n setSaving(false);\n }\n },\n [register, basePath],\n );\n\n const reset = useCallback(() => {\n setConflict(null);\n setError(null);\n }, []);\n\n return { save, saving, conflict, error, reset };\n}\n","/**\n * The pure edit-logic seam — which fields a register lets you edit, how a\n * form draft maps back to a version-guarded patch, and the plain-language\n * conflict copy. Kept as pure data/functions (no DOM) so the edit behaviour\n * is unit-testable exactly like `columns.ts`; the drawer component consumes it.\n *\n * Derived numbers (Confidence, Risk, Derived Impact, Strength) are never\n * editable — they are computed server-side on write (spec user story 4/11),\n * so they never appear here. Relation links are set through `link`, a separate\n * story, so relation-id fields aren't editable inputs either.\n */\nimport type { AnyRecord, Collection } from \"@validation-os/core\";\n\n/** The plain-language conflict prompt — never version jargon (user story 12).\n * The API returns its own copy on a 409; this is the client-side fallback. */\nexport const CONFLICT_MESSAGE =\n \"Someone edited this while you had it open — your changes are safe, \" +\n \"take a look before saving again.\";\n\nexport type FieldKind = \"text\" | \"textarea\" | \"number\" | \"select\";\n\nexport interface FieldEditor {\n /** The record key this editor writes. */\n key: string;\n /** Plain-language label shown beside the input. */\n label: string;\n kind: FieldKind;\n /** For `select`: the allowed options (a leading blank = \"unset\"). */\n options?: readonly string[];\n /** An empty input clears the field to `null` rather than \"\". */\n nullable?: boolean;\n /** For `number`: the inclusive range a hand-scored value must sit in\n * (e.g. Impact 0–100, `registry-schema.md`). Omitted = unbounded. */\n min?: number;\n max?: number;\n}\n\nconst t = (key: string, label: string): FieldEditor => ({ key, label, kind: \"text\" });\nconst area = (key: string, label: string): FieldEditor => ({\n key,\n label,\n kind: \"textarea\",\n});\nconst num = (\n key: string,\n label: string,\n range: { min?: number; max?: number } = {},\n): FieldEditor => ({\n key,\n label,\n kind: \"number\",\n nullable: true,\n ...range,\n});\nconst sel = (\n key: string,\n label: string,\n options: readonly string[],\n nullable = false,\n): FieldEditor => ({ key, label, kind: \"select\", options, nullable });\n\nconst SOURCE_QUALITY = [\"1\", \"0.7\", \"0.5\"] as const;\n\n/**\n * The editable fields per register, in the order they render. Hand-scored and\n * descriptive fields only — derived numbers, ids/timestamps, and relation\n * links are deliberately excluded.\n */\nconst EDITORS: Record<Collection, FieldEditor[]> = {\n assumptions: [\n t(\"Title\", \"Assumption\"),\n area(\"Description\", \"Description\"),\n // The only hand-scored number in the registry (`registry-schema.md`) — a\n // 0–100 severity-if-false seed. Every other number (Confidence, Derived\n // Impact, Risk, Strength, Source quality, Completeness %) is computed on\n // write and deliberately absent from this list.\n num(\"Impact\", \"Impact\", { min: 0, max: 100 }),\n sel(\"Status\", \"Status\", [\"Draft\", \"Live\", \"Invalidated\"]),\n t(\"Lens\", \"Lens\"),\n area(\"Scoring justification\", \"Scoring justification\"),\n // `moot` is deliberately not editable here — mooting an assumption is a\n // gated business action (see core `relations.ts`), not a free-form toggle.\n // 5 Whys / Metric for truth / Gaps are gone (OPS-1305); readiness is the\n // derived Completeness %, and the why-trace lives in Depends on / Enables.\n ],\n experiments: [\n t(\"Title\", \"Experiment\"),\n t(\"Instrument\", \"Instrument\"),\n sel(\"Feasibility\", \"Feasibility\", [\"High\", \"Medium\", \"Low\"], true),\n sel(\"Status\", \"Status\", [\"Draft\", \"Running\", \"Closed\"]),\n sel(\n \"closureReason\",\n \"Closure reason\",\n [\"Completed\", \"Early-stop\", \"Kill\"],\n true,\n ),\n // Deadline + Outcome: the commitment-grade fields folded in from the\n // retired Goal record (OPS-1305). Outcome is null until Closed.\n t(\"Deadline\", \"Deadline\"),\n sel(\"Outcome\", \"Outcome\", [\"Achieved\", \"Missed\", \"Dropped\"], true),\n t(\"Date\", \"Date\"),\n ],\n readings: [\n t(\"Title\", \"Reading\"),\n t(\"Source\", \"Source\"),\n // Rung / Result / Magnitude band / Grading justification are PER BELIEF now\n // (OPS-1305) — they live in each entry of `beliefs[]`, not on the row, so\n // they are deliberately absent here rather than writing dead row-level\n // fields. Editing a reading's per-belief scores is a deferred follow-up (a\n // `beliefs[]` editor); this form edits only the row-level fields that remain.\n sel(\"Representativeness\", \"Representativeness\", SOURCE_QUALITY),\n sel(\"Credibility\", \"Credibility\", SOURCE_QUALITY),\n area(\"body\", \"Quote\"),\n t(\"Date\", \"Date\"),\n ],\n decisions: [\n t(\"Title\", \"Decision\"),\n area(\"Statement\", \"Statement\"),\n sel(\"Status\", \"Status\", [\"Active\", \"Provisional\", \"Superseded\", \"Reversed\"]),\n ],\n glossary: [\n t(\"Title\", \"Term\"),\n sel(\"Status\", \"Status\", [\"Active\", \"Provisional\", \"Superseded\"]),\n area(\"Definition\", \"Definition\"),\n area(\"How it differs\", \"How it differs\"),\n ],\n};\n\n/** The fields a register lets you edit, in render order. */\nexport function editableFields(register: Collection): FieldEditor[] {\n return EDITORS[register];\n}\n\n/** A form draft is a plain string map keyed by field — what the inputs hold. */\nexport type Draft = Record<string, string>;\n\n/** Build the initial form draft from a record: every editable field becomes a\n * string input value, and missing values become empty inputs. */\nexport function draftFrom(register: Collection, record: AnyRecord): Draft {\n const draft: Draft = {};\n for (const f of editableFields(register)) {\n const value = record[f.key];\n draft[f.key] = value === null || value === undefined ? \"\" : String(value);\n }\n return draft;\n}\n\n/** Coerce one draft value back to its stored shape, honouring kind/nullable. */\nfunction coerce(field: FieldEditor, raw: string): unknown {\n const str = String(raw);\n if (field.kind === \"number\") {\n if (str.trim() === \"\") return null;\n const n = Number(str);\n return Number.isNaN(n) ? null : n;\n }\n // An empty select is \"unset\" → null; an empty nullable text field clears too.\n if (str === \"\" && (field.kind === \"select\" || field.nullable)) return null;\n return str;\n}\n\n/** Absent and empty values compare equal, so an untouched field isn't a change. */\nfunction norm(value: unknown): unknown {\n return value === undefined || value === \"\" ? null : value;\n}\n\n/**\n * The plain-language validation error for one field's draft value, or `null`\n * when it's fine. Only `number` fields with a `min`/`max` are checked — an\n * empty input always clears to `null` (allowed; there's no \"required\" seed).\n * Kept pure so the Save button can gate on it without touching the DOM.\n */\nexport function fieldError(field: FieldEditor, raw: string): string | null {\n if (field.kind !== \"number\") return null;\n const str = String(raw ?? \"\").trim();\n if (str === \"\") return null;\n const n = Number(str);\n if (Number.isNaN(n)) return `${field.label} must be a number.`;\n if (field.min !== undefined && n < field.min) {\n return `${field.label} must be at least ${field.min}.`;\n }\n if (field.max !== undefined && n > field.max) {\n return `${field.label} must be at most ${field.max}.`;\n }\n return null;\n}\n\n/**\n * Every field in a draft that currently fails validation, keyed by field —\n * what the record page/drawer show inline and gate Save on (spec: seed\n * Impact is the only hand-scored number, and it must stay in 0–100).\n */\nexport function draftErrors(\n register: Collection,\n draft: Draft,\n): Record<string, string> {\n const errors: Record<string, string> = {};\n for (const field of editableFields(register)) {\n const message = fieldError(field, draft[field.key] ?? \"\");\n if (message) errors[field.key] = message;\n }\n return errors;\n}\n\n/**\n * A version-guarded patch from a draft: the loaded `version` plus only the\n * fields whose value actually changed (so an untouched save doesn't churn\n * unrelated fields). The API rejects a stale version with a 409.\n */\nexport function buildPatch(\n register: Collection,\n original: AnyRecord,\n draft: Draft,\n): Record<string, unknown> {\n const patch: Record<string, unknown> = { version: original.version };\n for (const field of editableFields(register)) {\n const next = coerce(field, draft[field.key] ?? \"\");\n if (norm(next) !== norm(original[field.key])) patch[field.key] = next;\n }\n return patch;\n}\n\n/** Whether a draft differs from the record it was loaded from. */\nexport function hasEdits(\n register: Collection,\n original: AnyRecord,\n draft: Draft,\n): boolean {\n return Object.keys(buildPatch(register, original, draft)).length > 1;\n}\n","import { useMemo, useState, type ReactNode } from \"react\";\nimport type { AnyRecord } from \"@validation-os/core\";\nimport { coldStartFor, FIRST_RUN_LINE } from \"./cold-start.js\";\nimport { EvidenceBody } from \"./markdown.js\";\nimport { buildPipeline, type PipelineRow } from \"./pipeline.js\";\nimport { buildRecommendedExperiments, buildNeedsFraming, type RecommendedExperiment, type NeedsFramingItem } from \"./recommended-experiments.js\";\nimport { stageMeters } from \"./stage-meters.js\";\nimport {\n buildStageGrid,\n cellAt,\n NO_LENS,\n NO_STAGE,\n rankByRisk,\n STAGE_GLOSS,\n STAGE_ORDER,\n type StageGridCell,\n} from \"./stage-grid-model.js\";\nimport type { Route } from \"./route.js\";\nimport { useList } from \"./use-records.js\";\nimport { formatSigned, type Tone } from \"./primitives.js\";\n\n/**\n * The Assumptions nav surface (DEV-5881 + DEV-5882): the Lens × Stage grid as\n * the default landing, with a \"Grid / View all\" toggle. \"View all\" switches to\n * the pipeline board (hero burn-up + pipeline rows + recommended experiments).\n * A single-cell click (one assumption) opens the AssumptionDetail directly; a\n * multi-assumption cell opens the pipeline view filtered to that cell.\n *\n * Lazy-loads the assumption + experiment registers and derives everything\n * through the pure `buildStageGrid` + `buildPipeline` +\n * `buildRecommendedExperiments` view-models.\n */\nexport interface AssumptionsSurfaceProps {\n basePath?: string;\n onNavigate: (route: Route) => void;\n /** `\"all\"` shows the pipeline board; undefined shows the grid. */\n view?: \"all\";\n /** When set, the pipeline board filters to this lens × stage. */\n lens?: string;\n stage?: string;\n}\n\nexport function AssumptionsSurface({\n basePath,\n onNavigate,\n view,\n lens,\n stage,\n}: AssumptionsSurfaceProps) {\n const assumptions = useList(\"assumptions\", basePath);\n const experiments = useList(\"experiments\", basePath);\n const readings = useList(\"readings\", basePath);\n\n const loading =\n assumptions.loading || experiments.loading || readings.loading;\n const error = assumptions.error || experiments.error || readings.error;\n\n const showPipeline = view === \"all\" || (lens !== undefined && stage !== undefined);\n\n return (\n <div>\n <div className=\"vos-head\">\n <div>\n <h1>Assumptions — where your bets cluster</h1>\n <p>\n Every falsifiable belief the business depends on, cross-tabbed by\n the actor it's about (Lens) and the kind of response it tests\n (Stage). The grid is the filter; Risk is the rank.\n </p>\n </div>\n <div className=\"vos-spacer\" />\n <div className=\"vos-seg\" role=\"tablist\" aria-label=\"Assumptions view\">\n <button\n type=\"button\"\n className={`vos-seg-btn ${!showPipeline ? \"is-active\" : \"\"}`}\n role=\"tab\"\n aria-selected={!showPipeline}\n onClick={() => onNavigate({ name: \"assumptions\" })}\n >\n Grid\n </button>\n <button\n type=\"button\"\n className={`vos-seg-btn ${showPipeline ? \"is-active\" : \"\"}`}\n role=\"tab\"\n aria-selected={showPipeline}\n onClick={() => onNavigate({ name: \"assumptions\", view: \"all\" })}\n >\n View all\n </button>\n </div>\n </div>\n\n {loading && !assumptions.records ? (\n <p className=\"vos-muted\">Reading where your bets cluster…</p>\n ) : error ? (\n <p className=\"vos-error\">{error}</p>\n ) : showPipeline ? (\n <PipelineBoard\n assumptions={assumptions.records ?? []}\n experiments={experiments.records ?? []}\n readings={readings.records ?? []}\n onNavigate={onNavigate}\n filterLens={lens}\n filterStage={stage}\n />\n ) : (\n <GridPane\n assumptions={assumptions.records ?? []}\n experiments={experiments.records ?? []}\n readings={readings.records ?? []}\n onNavigate={onNavigate}\n />\n )}\n </div>\n );\n}\n\n/* ── Grid pane ─────────────────────────────────────────────────────────── */\n\nfunction GridPane({\n assumptions,\n experiments,\n readings,\n onNavigate,\n}: {\n assumptions: AnyRecord[];\n experiments: AnyRecord[];\n readings: AnyRecord[];\n onNavigate: (route: Route) => void;\n}) {\n const view = useMemo(() => buildStageGrid(assumptions), [assumptions]);\n const recs = useMemo(\n () => buildRecommendedExperiments(assumptions, experiments),\n [assumptions, experiments],\n );\n const needsFraming = useMemo(\n () => buildNeedsFraming(assumptions),\n [assumptions],\n );\n\n const cold = coldStartFor({\n assumptions,\n experiments,\n readings,\n decisions: [],\n });\n if (cold.cold) {\n return (\n <>\n <div className=\"vos-firstrun\">{FIRST_RUN_LINE}</div>\n <div className=\"vos-card vos-cold vos-cold-stage-grid\">\n <span className=\"vos-cold-eyebrow\">No bets yet</span>\n <p className=\"vos-cold-body\">\n The Lens × Stage grid reads your business state off where your bets\n cluster. Write your first belief and the grid fills in — the\n densest cell per row is where that part of the business is.\n </p>\n <button\n type=\"button\"\n className=\"vos-btn\"\n onClick={() => onNavigate({ name: \"records\", register: \"assumptions\", view: \"all\" })}\n >\n Write your first bet\n </button>\n </div>\n </>\n );\n }\n\n function cellClick(cell: StageGridCell) {\n if (cell.count === 0) return;\n if (cell.count === 1) {\n const id = String(cell.assumptions[0]?.id ?? \"\");\n if (id) onNavigate({ name: \"assumption\", id });\n } else {\n onNavigate({\n name: \"assumptions\",\n lens: cell.lens === NO_LENS ? undefined : cell.lens,\n stage: cell.stage === NO_STAGE ? undefined : cell.stage,\n });\n }\n }\n\n return (\n <>\n <div className=\"vos-card vos-stage-grid-card\">\n <div className=\"vos-stage-grid-scroll\">\n <table className=\"vos-stage-grid\" role=\"grid\" aria-label=\"Lens × Stage heatmap\">\n <thead>\n <tr>\n <th scope=\"col\" className=\"vos-stage-grid-corner\">Lens ↓ / Stage →</th>\n {view.stages.map((s) => (\n <th key={s} scope=\"col\" className=\"vos-stage-grid-col\">\n <span className=\"vos-stage-grid-stagename\">{s}</span>\n <span className=\"vos-stage-grid-stagegloss\">{STAGE_GLOSS[s]}</span>\n </th>\n ))}\n </tr>\n </thead>\n <tbody>\n {view.lenses.map((lens) => (\n <tr key={lens}>\n <th scope=\"row\" className=\"vos-stage-grid-rowhead\">{lens}</th>\n {view.stages.map((s) => {\n const cell = cellAt(view, lens, s)!;\n return (\n <td key={s} className=\"vos-stage-grid-cell\">\n <button\n type=\"button\"\n className={`vos-stage-grid-btn vos-heat-${heatLevel(cell.density)}`}\n disabled={cell.count === 0}\n onClick={() => cellClick(cell)}\n aria-label={`${cell.count} assumptions in ${lens} × ${s}`}\n >\n {cell.count === 0 ? \"·\" : cell.count === 1 ? \"1\" : String(cell.count)}\n </button>\n </td>\n );\n })}\n </tr>\n ))}\n </tbody>\n </table>\n </div>\n <p className=\"vos-hint vos-stage-grid-foot\">\n The densest cell per row is where that part of the business is. Click a\n cell to drill into its assumptions, ranked by Risk; a single-assumption\n cell opens the detail directly.\n </p>\n </div>\n\n {/* Next moves — two columns: top 2 assumptions needing framing + top 2\n proposed experiments. This is where the action is on the grid home. */}\n {(needsFraming.length > 0 || recs.length > 0) ? (\n <NextMovesSection\n needsFraming={needsFraming}\n recs={recs}\n onOpenAssumption={(id) => onNavigate({ name: \"assumption\", id })}\n />\n ) : null}\n </>\n );\n}\n\nfunction heatLevel(density: number): 0 | 1 | 2 | 3 | 4 {\n if (density <= 0) return 0;\n if (density < 0.25) return 1;\n if (density < 0.5) return 2;\n if (density < 0.75) return 3;\n return 4;\n}\n\n/* ── Pipeline board ────────────────────────────────────────────────────── */\n\nfunction PipelineBoard({\n assumptions,\n experiments,\n readings,\n onNavigate,\n filterLens,\n filterStage,\n}: {\n assumptions: AnyRecord[];\n experiments: AnyRecord[];\n readings: AnyRecord[];\n onNavigate: (route: Route) => void;\n filterLens?: string;\n filterStage?: string;\n}) {\n const filtered = useMemo(() => {\n if (filterLens === undefined && filterStage === undefined) return assumptions;\n return assumptions.filter((a) => {\n const l = String(a.Lens ?? NO_LENS);\n const s = String(a.Stage ?? NO_STAGE);\n return (\n (filterLens === undefined || l === filterLens) &&\n (filterStage === undefined || s === filterStage)\n );\n });\n }, [assumptions, filterLens, filterStage]);\n\n const view = useMemo(\n () => buildPipeline(filtered, experiments),\n [filtered, experiments],\n );\n const { progress, rows } = view;\n\n const crumb =\n filterLens !== undefined || filterStage !== undefined ? (\n <Breadcrumb\n trail={[\n { label: \"Assumptions\", route: { name: \"assumptions\" } },\n {\n label: `${filterLens ?? \"—\"} × ${filterStage ?? \"—\"}`,\n route: { name: \"assumptions\" },\n },\n ]}\n />\n ) : null;\n\n return (\n <>\n {crumb}\n <section className=\"vos-card vos-pipe-hero vos-pipe-hero-board\">\n <div className=\"vos-pipe-read\">\n <div className=\"vos-pipe-eyebrow\">Risk bought down</div>\n <div className=\"vos-pipe-big vos-num\">\n {Math.round(progress.percent)}<span>%</span>\n </div>\n <div className=\"vos-pipe-sub\">\n {Math.round(progress.retired)} retired · {Math.round(progress.identified - progress.retired)} at risk · {rows.length} beliefs\n </div>\n </div>\n </section>\n\n <div className=\"vos-card vos-pipe-board\">\n <div className=\"vos-pipe-boardhead\">\n <div className=\"vos-pipe-bt\">\n Pipeline <span>· {rows.length} live {rows.length === 1 ? \"belief\" : \"beliefs\"}</span>\n </div>\n <div className=\"vos-pipe-sortnote\">sorted by live risk — riskiest first</div>\n </div>\n {rows.length === 0 ? (\n <div className=\"vos-empty\" style={{ margin: 16 }}>\n No live beliefs {filterLens || filterStage ? \"in this cell\" : \"\"} — nothing to test right now.\n </div>\n ) : (\n rows.map((row) => (\n <PipelineRowView\n key={row.id}\n row={row}\n onOpen={() => onNavigate({ name: \"assumption\", id: row.id })}\n />\n ))\n )}\n </div>\n </>\n );\n}\n\n/* The pipeline row — 4px risk stripe + belief + 2-segment meter + next-move.\n * The meter is 2 segments only (Framed + Known) — Planned and Tested are\n * dropped per the collapsed pipeline model (DEV-5879). */\nfunction PipelineRowView({ row, onOpen }: { row: PipelineRow; onOpen: () => void }) {\n const stripeTone: Tone = row.riskTone;\n const knownPct = Math.max(0, Math.min(100, Math.abs(row.confidence)));\n const knownSign = row.confSign;\n return (\n <div className=\"vos-pipe-row vos-pipe-row-2seg\">\n <div className={`vos-pipe-stripe vos-fill-${stripeTone}`} />\n <button type=\"button\" className=\"vos-pipe-belief\" onClick={onOpen}>\n <span className=\"vos-pipe-id vos-num\">{row.id}</span>\n <span className=\"vos-pipe-stmt\">{row.statement || row.id}</span>\n <span className=\"vos-pipe-bmeta\">\n <span className=\"vos-num\">impact {Math.round(row.impact)}</span>\n <span className={`vos-num vos-text-${row.riskTone}`}>risk {Math.round(row.risk)}</span>\n <span className=\"vos-num\">conf {formatSigned(row.confidence)}</span>\n {row.questionType ? (\n <span className=\"vos-pipe-tag vos-pipe-tag-qt\">{row.questionType}</span>\n ) : null}\n {row.stage ? (\n <span className=\"vos-pipe-tag vos-pipe-tag-stage\">{row.stage}</span>\n ) : null}\n {row.riskThreshold != null ? (\n <span\n className={`vos-pipe-tag vos-pipe-tag-thresh ${\n row.clearedThreshold ? \"vos-pipe-tag-cleared\" : \"vos-pipe-tag-needs\"\n }`}\n title={`Stage threshold ${row.riskThreshold} — ${\n row.clearedThreshold ? \"cleared for this stage\" : \"needs evidence\"\n }`}\n >\n {row.clearedThreshold ? \"cleared\" : `bar ${row.riskThreshold}`}\n </span>\n ) : null}\n </span>\n </button>\n <div className=\"vos-pipe-prog-2seg\" aria-label=\"Evidence progress (Framed + Known)\">\n <Meter2Seg framed={row.framed} knownPct={knownPct} knownSign={knownSign} />\n </div>\n <div className=\"vos-pipe-actions\">\n <button type=\"button\" className=\"vos-btn vos-btn-sm vos-btn-accent\" onClick={onOpen}>\n {row.nextMove}\n </button>\n </div>\n </div>\n );\n}\n\nfunction Meter2Seg({\n framed,\n knownPct,\n knownSign,\n}: {\n framed: number;\n knownPct: number;\n knownSign: \"pos\" | \"neg\" | \"zero\";\n}) {\n const knownTone = knownSign === \"neg\" ? \"crit\" : knownPct > 30 ? \"good\" : \"warn\";\n return (\n <div className=\"vos-meter2\">\n <div className=\"vos-meter2-track\">\n <div className=\"vos-meter2-seg vos-meter2-framed\">\n <i className=\"vos-meter2-fill-accent\" style={{ width: `${Math.min(100, framed)}%` }} />\n </div>\n <div className=\"vos-meter2-seg vos-meter2-known\">\n {knownSign !== \"zero\" ? (\n <i className={`vos-meter2-fill-${knownTone}`} style={{ width: `${knownPct}%` }} />\n ) : null}\n </div>\n </div>\n <div className=\"vos-meter2-caps\">\n <span className=\"vos-meter2-cap\">Framed</span>\n <span className=\"vos-meter2-cap\">Known</span>\n </div>\n </div>\n );\n}\n\n/* ── Next moves section — two columns: needs framing + proposed experiments ── */\n\nfunction NextMovesSection({\n needsFraming,\n recs,\n onOpenAssumption,\n}: {\n needsFraming: NeedsFramingItem[];\n recs: RecommendedExperiment[];\n onOpenAssumption: (id: string) => void;\n}) {\n const [openRec, setOpenRec] = useState<RecommendedExperiment | null>(null);\n return (\n <div className=\"vos-next-moves\">\n <div className=\"vos-next-moves-head\">Next moves</div>\n <div className=\"vos-next-moves-cols\">\n {/* Left column — top 1 assumption needing framing per lens */}\n <div className=\"vos-card vos-next-moves-col\">\n <div className=\"vos-next-moves-col-label\">Needs framing · one per lens</div>\n {needsFraming.length === 0 ? (\n <div className=\"vos-muted vos-next-moves-empty\">Every belief is fully framed.</div>\n ) : (\n needsFraming.map((a) => (\n <button\n key={a.id}\n type=\"button\"\n className=\"vos-next-moves-item\"\n onClick={() => onOpenAssumption(a.id)}\n >\n <div className=\"vos-next-moves-item-head\">\n <span\n className=\"vos-next-moves-lens\"\n style={{ background: `${a.lensColour}20`, color: a.lensColour, borderColor: `${a.lensColour}40` }}\n >\n {a.lens}\n </span>\n <span className={`vos-next-moves-item-risk vos-num vos-text-${riskToneClass(a.risk)}`}>\n {Math.round(a.risk)} risk\n </span>\n </div>\n <div className=\"vos-next-moves-item-title\">\n <span className=\"vos-next-moves-item-id vos-num\">{a.id}</span> · {a.title}\n </div>\n <div className=\"vos-next-moves-item-hint\">{a.hint}</div>\n </button>\n ))\n )}\n </div>\n\n {/* Right column — compact proposed-experiment cards; click opens a drawer */}\n <div className=\"vos-card vos-next-moves-col\">\n <div className=\"vos-next-moves-col-label\">Proposed experiments · one per lens</div>\n {recs.length === 0 ? (\n <div className=\"vos-muted vos-next-moves-empty\">Every risk has a live test.</div>\n ) : (\n recs.map((rec) => (\n <button\n key={rec.id}\n type=\"button\"\n className=\"vos-next-moves-rec vos-next-moves-rec-compact\"\n onClick={() => setOpenRec(rec)}\n >\n <div className=\"vos-next-moves-rec-head\">\n <span\n className=\"vos-next-moves-lens\"\n style={{ background: `${rec.lensColour}20`, color: rec.lensColour, borderColor: `${rec.lensColour}40` }}\n >\n {rec.lens}\n </span>\n <span className=\"vos-next-moves-rec-type\">{rec.type}</span>\n <span className=\"vos-next-moves-rec-risk vos-num\">{Math.round(rec.maxRisk)} risk</span>\n </div>\n <div className=\"vos-next-moves-rec-title\">{rec.title}</div>\n <span className=\"vos-next-moves-rec-open\" aria-hidden=\"true\">→</span>\n </button>\n ))\n )}\n </div>\n </div>\n\n {openRec ? (\n <RecommendedExperimentDrawer\n rec={openRec}\n onOpenAssumption={onOpenAssumption}\n onClose={() => setOpenRec(null)}\n />\n ) : null}\n </div>\n );\n}\n\n/* Side drawer for a recommended experiment — slides in from the right using the\n * existing .vos-drawer / .vos-scrim classes. Shows the full experiment detail\n * (rationale, bar preview, assumption chips, generated body) and the accept\n * action, instead of expanding the card inline. */\nfunction RecommendedExperimentDrawer({\n rec,\n onOpenAssumption,\n onClose,\n}: {\n rec: RecommendedExperiment;\n onOpenAssumption: (id: string) => void;\n onClose: () => void;\n}) {\n return (\n <>\n <div className=\"vos-scrim\" onClick={onClose} aria-hidden=\"true\" />\n <aside\n className=\"vos-drawer vos-rec-drawer\"\n role=\"dialog\"\n aria-modal=\"true\"\n aria-label={`Proposed experiment: ${rec.title}`}\n >\n <div className=\"vos-drawer-header\">\n <div>\n <div className=\"vos-drawer-eyebrow\">Proposed experiment</div>\n <h2 className=\"vos-drawer-title\">{rec.title}</h2>\n </div>\n <div style={{ marginLeft: \"auto\", display: \"flex\", gap: 8, alignItems: \"center\" }}>\n <span\n className=\"vos-next-moves-lens\"\n style={{ background: `${rec.lensColour}20`, color: rec.lensColour, borderColor: `${rec.lensColour}40` }}\n >\n {rec.lens}\n </span>\n <span className=\"vos-next-moves-rec-type\">{rec.type}</span>\n <span className=\"vos-next-moves-rec-risk vos-num\">{Math.round(rec.maxRisk)} risk</span>\n <button type=\"button\" className=\"vos-btn vos-btn-sm\" onClick={onClose} aria-label=\"Close\">✕</button>\n </div>\n </div>\n\n <div className=\"vos-drawer-body\">\n <div className=\"vos-rec-drawer-section\">\n <div className=\"vos-drawer-eyebrow\">Why this test</div>\n <p className=\"vos-rec-drawer-rationale\">{rec.rationale}</p>\n </div>\n\n <div className=\"vos-rec-drawer-section\">\n <div className=\"vos-drawer-eyebrow\">Bar</div>\n <div className=\"vos-rec-drawer-bar\">\n <strong>Right if:</strong> {rec.barPreview}\n </div>\n </div>\n\n <div className=\"vos-rec-drawer-section\">\n <div className=\"vos-drawer-eyebrow\">Assumptions</div>\n <div className=\"vos-next-moves-rec-chips\">\n {rec.assumptionIds.map((id) => (\n <button\n key={id}\n type=\"button\"\n className=\"vos-next-moves-rec-chip\"\n onClick={() => onOpenAssumption(id)}\n >\n {id}\n </button>\n ))}\n </div>\n </div>\n\n <div className=\"vos-rec-drawer-section\">\n <div className=\"vos-drawer-eyebrow\">Protocol</div>\n <div className=\"vos-rec-drawer-body\">\n <EvidenceBody text={rec.body} />\n </div>\n </div>\n </div>\n\n <div className=\"vos-drawer-footer\">\n <button type=\"button\" className=\"vos-btn vos-btn-sm vos-btn-accent\">\n Accept & create experiment\n </button>\n </div>\n </aside>\n </>\n );\n}\n\nfunction riskToneClass(risk: number): string {\n if (risk >= 70) return \"crit\";\n if (risk >= 40) return \"warn\";\n return \"good\";\n}\n\n/* ── Recommended experiments section (standalone — used on the pipeline board) ── */\n\nfunction RecommendedExperimentsSection({\n recs,\n onOpenAssumption,\n}: {\n recs: RecommendedExperiment[];\n onOpenAssumption: (id: string) => void;\n}) {\n return (\n <div className=\"vos-card vos-pipe-recs\">\n <div className=\"vos-pipe-recs-head\">\n Next moves · recommended experiments · one per lens (top {recs.length})\n </div>\n <div className=\"vos-pipe-recs-list\">\n {recs.map((rec) => (\n <div key={rec.id} className=\"vos-pipe-rec vos-pipe-rec-flat\">\n <div className=\"vos-pipe-rec-head\">\n <span\n className=\"vos-next-moves-lens\"\n style={{ background: `${rec.lensColour}20`, color: rec.lensColour, borderColor: `${rec.lensColour}40` }}\n >\n {rec.lens}\n </span>\n <span className=\"vos-pipe-rec-type\">{rec.type}</span>\n <span className=\"vos-pipe-rec-title\">{rec.title}</span>\n <span className=\"vos-pipe-rec-risk vos-num\">{Math.round(rec.maxRisk)} risk</span>\n </div>\n <div className=\"vos-pipe-rec-body-inner\">\n <div className=\"vos-pipe-rec-rationale\">{rec.rationale}</div>\n <div className=\"vos-pipe-rec-chips\">\n {rec.assumptionIds.map((id) => (\n <button\n key={id}\n type=\"button\"\n className=\"vos-pipe-rec-chip\"\n onClick={() => onOpenAssumption(id)}\n >\n {id}\n </button>\n ))}\n </div>\n <div className=\"vos-pipe-rec-bar\">\n <strong>Right if:</strong> {rec.barPreview}\n </div>\n {/* The generated experiment body — protocol, questions, how to run */}\n <div className=\"vos-pipe-rec-body\">\n <EvidenceBody text={rec.body} />\n </div>\n {/* Accept action visible without expanding */}\n <div className=\"vos-pipe-rec-actions\">\n <button type=\"button\" className=\"vos-btn vos-btn-sm\">Accept & create experiment</button>\n </div>\n </div>\n </div>\n ))}\n </div>\n </div>\n );\n}\n\n/* ── Breadcrumb ────────────────────────────────────────────────────────── */\n\nfunction Breadcrumb({\n trail,\n}: {\n trail: { label: string; route: Route }[];\n}) {\n return (\n <nav className=\"vos-crumb\" aria-label=\"Breadcrumb\">\n {trail.map((t, i) => (\n <span key={i} className=\"vos-crumb-item\">\n {i > 0 ? <span className=\"vos-crumb-sep\">/</span> : null}\n <span className={i === trail.length - 1 ? \"vos-crumb-current\" : \"vos-crumb-link\"}>\n {t.label}\n </span>\n </span>\n ))}\n </nav>\n );\n}","/**\n * Front-door presentation logic for the next-move ranking (build OPS-1304).\n * Two pure seams, kept free of React/DOM so they're unit-tested like\n * `columns.ts` / `primitives.ts`:\n *\n * - `toNextMoveInput` maps the fetched register records onto the shape\n * `packages/core`'s `rankNextMoves` consumes (the ranking rule itself lives\n * once in core — `ontology.yaml → derived_views.next_move`, OPS-1292);\n * - `movePresentation` maps each act to its front-door copy and whether it's a\n * human step-in form or an agent-run act shown for review (OPS-1291/1294).\n */\nimport type { AnyRecord, Feasibility } from \"@validation-os/core\";\nimport {\n isConcluded,\n type MoveKind,\n type NextMoveInput,\n} from \"@validation-os/core/derivation\";\nimport { readingBeliefs } from \"./derived-views.js\";\n\nfunction str(record: AnyRecord, key: string): string | null {\n const v = record[key];\n return typeof v === \"string\" ? v : null;\n}\nfunction numOrNull(record: AnyRecord, key: string): number | null {\n const v = record[key];\n return typeof v === \"number\" ? v : null;\n}\nfunction idList(record: AnyRecord, key: string): string[] {\n const v = record[key];\n return Array.isArray(v) ? v.filter((x): x is string => typeof x === \"string\") : [];\n}\n\n/** The four registers the ranking reads, as fetched from the API. */\nexport interface NextMoveRecords {\n assumptions: AnyRecord[];\n experiments: AnyRecord[];\n readings: AnyRecord[];\n decisions: AnyRecord[];\n}\n\n/**\n * Fold the fetched records into `rankNextMoves`' input: the derived Risk /\n * Confidence come straight off each assumption (the server keeps them current,\n * OPS-1251 — never recomputed here), and concluded readings are counted per\n * belief so the stage logic can tell \"no evidence yet\" from \"evidence in\".\n */\nexport function toNextMoveInput(records: NextMoveRecords): NextMoveInput {\n const concludedByAssumption = new Map<string, number>();\n for (const r of records.readings) {\n // A reading row scores several beliefs at once (OPS-1305); each concluded\n // belief-score counts toward its own assumption's \"evidence is in\" tally.\n for (const b of readingBeliefs(r)) {\n if (!b.assumptionId || !isConcluded(b.Result)) continue;\n concludedByAssumption.set(\n b.assumptionId,\n (concludedByAssumption.get(b.assumptionId) ?? 0) + 1,\n );\n }\n }\n\n return {\n assumptions: records.assumptions.map((a) => {\n const derived =\n a.derived && typeof a.derived === \"object\"\n ? (a.derived as Record<string, unknown>)\n : {};\n return {\n id: a.id,\n title: str(a, \"Title\") ?? a.id,\n status: str(a, \"Status\") ?? \"\",\n impact: numOrNull(a, \"Impact\"),\n moot: a.moot === true,\n risk: typeof derived.risk === \"number\" ? derived.risk : 0,\n confidence: typeof derived.confidence === \"number\" ? derived.confidence : 0,\n concludedReadings: concludedByAssumption.get(a.id) ?? 0,\n };\n }),\n experiments: records.experiments.map((e) => ({\n status: str(e, \"Status\") ?? \"\",\n feasibility: (str(e, \"Feasibility\") as Feasibility | null) ?? null,\n assumptionIds: idList(e, \"barLineAssumptionIds\"),\n })),\n decisions: records.decisions.map((d) => ({\n status: str(d, \"Status\") ?? \"\",\n assumptionIds: [...idList(d, \"basedOnIds\"), ...idList(d, \"resolvesIds\")],\n })),\n };\n}\n\n/** Which step-in form an act opens, or null for an agent-run act. */\nexport type StepInForm = \"score-impact\" | \"write-decision\";\n\nexport interface MovePresentation {\n /** Imperative CTA on the hero's act button. */\n cta: string;\n /** Short label for the \"On deck\" act pill. */\n pill: string;\n /**\n * A human step-in form (the dashboard is a review surface, OPS-1294) vs an\n * agent-run act the front door only visualises for review.\n */\n steppable: boolean;\n /** The form the act opens when steppable; null for agent-run acts. */\n form: StepInForm | null;\n}\n\nconst PRESENTATION: Record<MoveKind, MovePresentation> = {\n \"score-impact\": {\n cta: \"Score its impact\",\n pill: \"Score impact\",\n steppable: true,\n form: \"score-impact\",\n },\n \"design-experiment\": {\n cta: \"Design the test\",\n pill: \"Design test\",\n steppable: false,\n form: null,\n },\n \"record-reading\": {\n cta: \"See the test\",\n pill: \"Testing\",\n steppable: false,\n form: null,\n },\n decide: {\n cta: \"Make the call\",\n pill: \"Decide\",\n steppable: true,\n form: \"write-decision\",\n },\n retest: {\n cta: \"Kill or re-test\",\n pill: \"Re-test\",\n steppable: true,\n form: \"write-decision\",\n },\n};\n\n/** The front-door copy + step-in modality for one act. */\nexport function movePresentation(kind: MoveKind): MovePresentation {\n return PRESENTATION[kind];\n}\n","/**\n * The cross-surface cold-start view-model (OPS-1331) — pure, no React, no I/O,\n * so the \"what does the dashboard show before any beliefs exist?\" mapping is\n * unit-tested at this seam (like `next-move.ts` / `pipeline.ts` / `journey.ts`).\n *\n * The dashboard has three workflow surfaces, and each one had a basic one-line\n * empty state from its own build (OPS-1304 front door, OPS-1300 pipeline). Now\n * that all three surfaces exist (OPS-1330 journey landed), this replaces them\n * with one designed pass: a founder who opens the dashboard before any beliefs\n * exist is *guided in* rather than shown blank meters.\n *\n * Two cold states, one module:\n *\n * - **Cross-surface cold start** — zero beliefs exist. The front door and the\n * pipeline each get a designed empty state (a hero with a first-bet CTA, an\n * honest 0% burn-up with an invitation), and a shared first-run onboarding\n * line ties the three surfaces together. Trigger: `records.assumptions`\n * is empty.\n * - **Journey no-history cold state** — a belief exists but has no evidence\n * yet (no score, no test, no reading). The rail renders honestly (framed at\n * its completeness %, 0/0 bars); the story's cold-state copy names the\n * belief's first move in plain language, rather than showing two sparse\n * events with nothing between. Trigger: the story has only the structural\n * `bet` + `now` events.\n *\n * No number is invented: the pipeline's cold burn-up reads 0% because there is\n * no risk to retire; the journey's cold rail reads the belief's real framing %\n * and 0/0 tests. The copy is plain and consistent across both themes (it\n * carries no tone — these are invitations, not status).\n */\nimport type { JourneyView } from \"./journey.js\";\nimport { movePresentation, type NextMoveRecords } from \"./next-move.js\";\n\n/** The cross-surface cold start — zero beliefs exist. */\nexport interface ColdStart {\n /** True when no assumptions exist in the register. */\n cold: boolean;\n /** The first-run onboarding line — shared across every cold surface. */\n onboarding: string;\n /** The front-door hero copy. */\n next: NextColdStart;\n /** The pipeline cold-board copy. */\n pipeline: PipelineColdStart;\n}\n\n/** The front-door cold-start hero copy. */\nexport interface NextColdStart {\n /** The hero's eyebrow — a small label above the headline. */\n eyebrow: string;\n /** The hero's headline — the one line a founder reads. */\n headline: string;\n /** The hero's supporting line, under the headline. */\n body: string;\n /** The primary CTA on the cold hero. */\n cta: string;\n}\n\n/** The pipeline cold-start copy. */\nexport interface PipelineColdStart {\n /** The burn-up's headline reading (honest: 0%, no risk to retire). */\n headline: string;\n /** The line under the 0% — what the founder does next. */\n invitation: string;\n /** The empty board's body copy. */\n boardBody: string;\n /** The empty board's CTA. */\n boardCta: string;\n}\n\n/** The journey's no-history cold-state copy. */\nexport interface JourneyColdState {\n /** True when the belief has no evidence yet (only the structural events). */\n cold: boolean;\n /** The eyebrow on the cold-state card. */\n eyebrow: string;\n /** The cold-state body — names the belief's first move in plain language. */\n body: string;\n}\n\n/** The shared first-run onboarding line — one tone across all three surfaces. */\nexport const FIRST_RUN_LINE =\n \"This is your validation dashboard — three views over one loop. \" +\n \"Write your first bet to bring it to life.\";\n\n/** The front-door cold-start hero copy. */\nconst NEXT_COLD: NextColdStart = {\n eyebrow: \"Before there's evidence\",\n headline: \"No beliefs yet — write your first bet.\",\n body: \"Every belief the plan rests on starts here. Name one falsifiable assumption, score its impact, and the dashboard takes it from there: the pipeline shows where it stands, and its journey tells the story as evidence lands.\",\n cta: \"Write your first bet\",\n};\n\n/** The pipeline cold-start copy. */\nconst PIPELINE_COLD: PipelineColdStart = {\n headline: \"0%\",\n invitation: \"No risk to retire yet — write your first bet and it shows here.\",\n boardBody:\n \"Every belief you write lands here with its risk, its four loop meters, and its next move. Nothing to show until then.\",\n boardCta: \"Write your first bet\",\n};\n\n/** A cold start with every surface's copy filled in. */\nconst COLD_START: ColdStart = {\n cold: true,\n onboarding: FIRST_RUN_LINE,\n next: NEXT_COLD,\n pipeline: PIPELINE_COLD,\n};\n\n/** A warm start (beliefs exist) — every surface renders its real content. */\nconst WARM_START: ColdStart = {\n cold: false,\n onboarding: \"\",\n next: {\n eyebrow: \"\",\n headline: \"\",\n body: \"\",\n cta: \"\",\n },\n pipeline: {\n headline: \"\",\n invitation: \"\",\n boardBody: \"\",\n boardCta: \"\",\n },\n};\n\n/**\n * The cross-surface cold start, derived from the fetched registers. Cold when\n * no assumptions exist; warm otherwise. Pure — the surfaces branch on `cold`\n * and read the copy off the result.\n */\nexport function coldStartFor(records: NextMoveRecords): ColdStart {\n return records.assumptions.length === 0 ? COLD_START : WARM_START;\n}\n\n/**\n * The journey's no-history cold state. Cold when the belief's story has only\n * the two structural events (the `bet` it opened with and the `now` that\n * anchors today) — no score, no test, no reading, no confidence-cross. The\n * rail still renders honestly (its real framing % and 0/0 tests); this only\n * shapes the story's copy so a founder with one fresh belief isn't shown two\n * sparse events with nothing between.\n *\n * The body names the belief's own next move in plain language when one exists,\n * so the cold state still points forward.\n */\nexport function journeyColdState(\n journey: JourneyView,\n): JourneyColdState {\n const evidenceEvents = journey.events.filter(\n (e) => e.kind !== \"bet\" && e.kind !== \"now\",\n );\n const cold = evidenceEvents.length === 0;\n if (!cold) {\n return { cold: false, eyebrow: \"\", body: \"\" };\n }\n const move = journey.nextMove;\n const body = move\n ? `${move.reason} Your next move: ${movePresentation(move.move).cta.toLowerCase()} — the dashboard takes it from there.`\n : \"No evidence has landed yet. Score its impact, then design a test to start moving it.\";\n return {\n cold: true,\n eyebrow: \"No evidence yet\",\n body,\n };\n}\n","/**\n * The portfolio pipeline's view-model (OPS-1300) — pure, no React, no I/O, so\n * the whole \"where does everything stand\" mapping is unit-tested at this seam\n * (like `understanding.ts` for the drawer). It joins the assumption, reading\n * and experiment registers into: one row per live belief carrying the four\n * loop meters (Framed → Planned → Tested → Known) and its stage-aware next\n * move, the resolved beliefs set apart, and the portfolio burn-up headline.\n *\n * Every number is derived through `@validation-os/core` — the stored per-belief\n * derived numbers, `assumptionCompleteness` for Framed, and `portfolioProgress`\n * for the cross-belief roll-up — so the pipeline reconciles with the drawer and\n * the agent, and computes fresh on read.\n */\nimport {\n assumptionCompleteness,\n readingBeliefInputs,\n type AnyRecord,\n type BarLine,\n type BeliefReadingInput,\n} from \"@validation-os/core\";\nimport { riskThresholdForStage } from \"@validation-os/core/derivation\";\nimport { STAGE_ORDER } from \"./stage-grid-model.js\";\nimport {\n beliefRisk,\n beliefTestMeters,\n confidence,\n deriveBeliefStage,\n portfolioProgress,\n risk as riskOf,\n type PortfolioBeliefInput,\n type PortfolioProgress,\n type StageExperimentInput,\n type StageKey,\n type TestMeter,\n} from \"@validation-os/core/derivation\";\nimport { liveExperiments } from \"./derived-views.js\";\nimport { riskLevel, type Tone } from \"./primitives.js\";\n\n/** The four loop stages a belief travels, in order (OPS-1293). */\nexport type { StageKey };\n\n/** One live belief's row on the board. */\nexport interface PipelineRow {\n id: string;\n statement: string;\n /** Derived Impact — shown only as a faint bar (machinery, not the move). */\n impact: number;\n risk: number;\n /** crit / warn / good — the severity stripe, risk number and bar tone. */\n riskTone: Extract<Tone, \"crit\" | \"warn\" | \"good\">;\n confidence: number;\n /** Sign bucket for the confidence chip / Known gauge direction. */\n confSign: \"pos\" | \"neg\" | \"zero\";\n /** Conf ≤ −50 — the Known meter flips to a red re-test flag. */\n killZone: boolean;\n /** Meter 1 — framing completeness, 0–100. */\n framed: number;\n /** Meter 2 — a test with a bar line naming this belief has been designed. */\n planned: boolean;\n /** Meter 3 — pre-registered bars settled / total, across all experiments. */\n tested: { settled: number; total: number };\n /** The stage-aware verb the front door offers (navigates to the record). */\n nextMove: string;\n /** The assumption's Question Type (DEV-5890) — kind of claim. */\n questionType: string | null;\n /** The assumption's Stage (DEV-5890) — kind of response / threshold. */\n stage: string | null;\n /** The stage's Risk threshold (DEV-5890) — the stopping bar. */\n riskThreshold: number | null;\n /** Whether the assumption has cleared its stage's threshold (Risk ≤ bar). */\n clearedThreshold: boolean | null;\n}\n\n/** A belief taken off the board — killed (Invalidated) or made moot. */\nexport interface ResolvedRow {\n id: string;\n statement: string;\n kind: \"killed\" | \"moot\";\n /** Risk retired by resolving it. */\n retired: number;\n}\n\nexport interface PipelineView {\n /** Live beliefs, riskiest first. */\n rows: PipelineRow[];\n /** Resolved beliefs, set apart. */\n resolved: ResolvedRow[];\n /** The burn-up headline: identified / retired / live / percent. */\n progress: PortfolioProgress;\n /** Σ risk retired across the resolved set — the disclosure's summary. */\n resolvedRetired: number;\n}\n\nfunction num(v: unknown): number {\n const n = Number(v);\n return Number.isFinite(n) ? n : 0;\n}\n\nfunction str(v: unknown): string {\n return typeof v === \"string\" ? v : \"\";\n}\n\n/** The three stored derived numbers off an assumption record. */\nfunction derivedOf(rec: AnyRecord): {\n derivedImpact: number;\n risk: number;\n confidence: number;\n} {\n const d = (rec.derived ?? {}) as Record<string, unknown>;\n return {\n derivedImpact: num(d.derivedImpact),\n risk: num(d.risk),\n confidence: num(d.confidence),\n };\n}\n\n/** killed = Invalidated, moot = the moot flag; moot wins if somehow both. */\nexport function resolvedKind(rec: AnyRecord): \"killed\" | \"moot\" | null {\n if (rec.moot === true) return \"moot\";\n if (rec.Status === \"Invalidated\") return \"killed\";\n return null;\n}\n\n/**\n * Reduce an experiment record to the shape the shared meter logic reads: each\n * bar line naming a belief (with whether it has settled) plus the convenience\n * projection. Shared with the journey view-model so the board and a belief's\n * rail derive test state one way.\n */\nexport function toStageExperimentInput(exp: AnyRecord): StageExperimentInput {\n const bars = (exp.barLines as BarLine[] | undefined) ?? [];\n return {\n bars: bars.map((b) => ({\n assumptionId: b.assumptionId,\n settled: typeof b.barVerdict === \"string\" && b.barVerdict.trim() !== \"\",\n })),\n plannedAssumptionIds:\n (exp.barLineAssumptionIds as string[] | undefined) ?? [],\n };\n}\n\n/**\n * The stage-aware next move — the same ladder the prototype walks, now driven\n * by the shared stage classification plus the kill-zone overlay.\n */\nfunction nextMove(stage: StageKey, killZone: boolean): string {\n if (killZone) return \"Decide / kill\";\n switch (stage) {\n case \"framed\":\n return \"Finish framing\";\n case \"planned\":\n return \"Design test\";\n case \"tested\":\n return \"Record reading\";\n case \"known\":\n return \"Decide / bank it\";\n }\n}\n\n/**\n * Build the whole board from the three registers. Pass the full assumption\n * register (resolved rows included) — `portfolioProgress` needs the whole set\n * or the burn-up denominator understates.\n */\nexport function buildPipeline(\n assumptions: AnyRecord[],\n experiments: AnyRecord[],\n): PipelineView {\n // \"Evidence ≠ tested\" (OPS-1305): a belief's Planned / Tested stage is driven\n // by a LIVE plan's bar lines, never by whether readings exist. Archived plans\n // are dropped here, so a belief whose only plan is archived (or that has bare\n // readings but no live plan) reads as Framed → \"Design test\", not Tested.\n const tests = beliefTestMeters(\n liveExperiments(experiments).map(toStageExperimentInput),\n );\n\n const rows: PipelineRow[] = [];\n const resolved: ResolvedRow[] = [];\n const portfolioInput: PortfolioBeliefInput[] = [];\n let resolvedRetired = 0;\n\n for (const a of assumptions) {\n const d = derivedOf(a);\n const kind = resolvedKind(a);\n const input: PortfolioBeliefInput = {\n id: a.id,\n derivedImpact: d.derivedImpact,\n seedImpact: a.Impact == null ? null : num(a.Impact),\n risk: d.risk,\n resolved: kind !== null,\n };\n portfolioInput.push(input);\n\n if (kind) {\n const retired = beliefRisk(input).retired;\n resolvedRetired += retired;\n resolved.push({\n id: a.id,\n statement: str(a.Title),\n kind,\n retired,\n });\n continue;\n }\n\n const test: TestMeter = tests.get(a.id) ?? {\n planned: false,\n settled: 0,\n total: 0,\n };\n const framed = assumptionCompleteness(a as Record<string, unknown>);\n const stage = deriveBeliefStage({ framed, confidence: d.confidence, test });\n // DEV-5890: surface Question Type + Stage + threshold on the row.\n const questionType = str(a[\"Question Type\"]);\n const stageName = str(a.Stage);\n const stageKey =\n stageName && (STAGE_ORDER as readonly string[]).includes(stageName)\n ? (stageName as (typeof STAGE_ORDER)[number])\n : null;\n const riskThreshold = stageKey ? riskThresholdForStage(stageKey) : null;\n rows.push({\n id: a.id,\n statement: str(a.Title),\n impact: d.derivedImpact,\n risk: d.risk,\n riskTone: riskLevel(d.risk) as PipelineRow[\"riskTone\"],\n confidence: stage.confidence,\n confSign: stage.confSign,\n killZone: stage.killZone,\n framed: stage.framed,\n planned: stage.planned,\n tested: stage.tested,\n nextMove: nextMove(stage.stage, stage.killZone),\n questionType: questionType,\n stage: stageName,\n riskThreshold,\n clearedThreshold:\n riskThreshold != null ? d.risk <= riskThreshold : null,\n });\n }\n\n // Riskiest first; ties broken toward the more-negative Confidence, then id,\n // so the order is stable.\n rows.sort(\n (a, b) =>\n b.risk - a.risk ||\n a.confidence - b.confidence ||\n a.id.localeCompare(b.id),\n );\n\n return {\n rows,\n resolved,\n progress: portfolioProgress(portfolioInput),\n resolvedRetired: Math.round(resolvedRetired),\n };\n}\n\n/**\n * The headline's \"this week\" delta, in percentage points, or null when it\n * can't be told honestly. It time-travels through the readings' own dates:\n * recompute every belief's Confidence (and thus Risk) from only the readings\n * dated on or before a cutoff, roll the portfolio up at \"now\" and at a week\n * ago, and report the change. Structure and resolved-status are held at their\n * current value (the system keeps no history of those), so this is the\n * evidence-driven movement, not a full snapshot diff — hence \"this week\" reads\n * as \"what landing evidence moved\", which is the honest claim.\n *\n * Returns null when no reading carries a parseable date (nothing to travel\n * through) — the surface then simply omits the delta rather than inventing one.\n */\nexport function weekOverWeekDelta(\n assumptions: AnyRecord[],\n readings: AnyRecord[],\n now: Date,\n): number | null {\n const anyDated = readings.some((r) => {\n const t = Date.parse(str(r.Date));\n return !Number.isNaN(t);\n });\n if (!anyDated) return null;\n\n const cutoff = now.getTime() - 7 * 24 * 60 * 60 * 1000;\n // Fan every reading row out into one input per belief, then group by the\n // belief it scores — a single row can now score several beliefs (OPS-1305).\n // DEV-5890: thread the linked assumption's Question Type into each input so\n // Strength reads the right sub-ladder.\n const assumptionsById = new Map<string, AnyRecord>(\n assumptions.map((a) => [String(a.id), a]),\n );\n const byAssumption = new Map<string, BeliefReadingInput[]>();\n for (const input of readings.flatMap((r) =>\n readingBeliefInputs(r, assumptionsById),\n )) {\n if (!input.assumptionId) continue;\n const arr = byAssumption.get(input.assumptionId);\n if (arr) arr.push(input);\n else byAssumption.set(input.assumptionId, [input]);\n }\n\n const percentAsOf = (limit: number | null): number => {\n const inputs: PortfolioBeliefInput[] = assumptions.map((a) => {\n const d = derivedOf(a);\n const mine = (byAssumption.get(a.id) ?? []).filter((i) => {\n if (limit === null) return true;\n const t = Date.parse(i.date ?? \"\");\n return !Number.isNaN(t) && t <= limit;\n });\n const conf = confidence(mine);\n return {\n id: a.id,\n derivedImpact: d.derivedImpact,\n seedImpact: a.Impact == null ? null : num(a.Impact),\n risk: riskOf(d.derivedImpact, conf),\n resolved: resolvedKind(a) !== null,\n };\n });\n return portfolioProgress(inputs).percent;\n };\n\n return Math.round(percentAsOf(null) - percentAsOf(cutoff));\n}\n","/**\n * The Lens × Stage heatmap view-model (docs/stage-policy.md §The dashboard\n * surface) — pure, no React, no I/O, so the grid's shape and the drill-\n * through's Risk-ranked list are unit-tested at this seam (like\n * `pipeline.ts` / `journey.ts` / `next-move.ts`).\n *\n * The grid is the **filter**, Risk is the **rank**. Where the pipeline board\n * reads \"where every belief stands\" row-by-row, this reads the same beliefs\n * cross-tabbed by Lens (the actor — who the belief is about) × Stage (the\n * kind of response — engage / pay / scale / defend). The densest cell per\n * row is where that part of the business is — no flag, no declaration, the\n * density tells you. Click a cell → the assumptions in it, ranked by Risk.\n *\n * Pure and computed fresh on read (like `pipeline.ts`): it only reads numbers\n * already kept current (`derived.risk`), so it stays out of the OPS-1251\n * on-write recompute. The Lens list comes from the caller (the surface\n * supplies the workspace's configured vocabulary); the Stage list is fixed\n * (the four discovery stages — see `ontology.yaml §vocabularies.stage`).\n */\nimport type { AnyRecord } from \"@validation-os/core\";\nimport { derivedNum, str } from \"./derived-views.js\";\n\n/** The four discovery stages, in their canonical ordinal order (1→4). The\n * stored value is the name; the ordinal is for sort/display only. */\nexport const STAGE_ORDER = [\n \"Discovery\",\n \"Validation\",\n \"Scale\",\n \"Maturity\",\n] as const;\nexport type StageValue = (typeof STAGE_ORDER)[number];\n\n/** A short, plain-language gloss for each stage — the column header's\n * subtitle and the cell tooltip. Drawn from docs/stage-policy.md. */\nexport const STAGE_GLOSS: Record<StageValue, string> = {\n Discovery: \"Problem-solution fit — will they engage, care, disclose?\",\n Validation: \"Product-market fit — will they pay, sign, stay?\",\n Scale: \"Growth — can we acquire efficiently, does CAC<LTV hold at volume?\",\n Maturity: \"Defense — will incumbents respond, will regulators accept?\",\n};\n\n/** One cell of the Lens × Stage grid. */\nexport interface StageGridCell {\n /** The Lens (row) this cell sits under. */\n lens: string;\n /** The Stage (column) this cell sits under — one of the four canonical\n * stages, or the `NO_STAGE` (\"—\") sentinel for records with no/invalid\n * Stage (the gate-leakage bucket, only emitted when needed). */\n stage: StageValue | typeof NO_STAGE;\n /** How many assumptions hold this Lens × Stage pair. */\n count: number;\n /** The assumptions in this cell, ranked by Risk (highest first). Empty\n * when `count` is 0. The rank is the cell's drill-through order. */\n assumptions: AnyRecord[];\n /** Density in [0, 1] — `count / maxCellCount` across the whole grid, for\n * the heatmap colour scale. 0 for an empty cell. */\n density: number;\n}\n\n/** The grid view-model — rows per Lens, columns per Stage, cells with counts\n * and Risk-ranked drill-through lists. */\nexport interface StageGridView {\n /** The Lens values, in first-appearance order (the configured vocabulary\n * order is the caller's job; the grid keeps the order it sees). Includes\n * a trailing \"—\" row for assumptions with no Lens set. */\n lenses: string[];\n /** The four stages in their canonical ordinal order. */\n stages: StageValue[];\n /** One cell per (lens, stage) pair, in row-major order: lens-first,\n * stage-within-lens. */\n cells: StageGridCell[];\n /** The maximum cell count across the grid — what `density` is normalised\n * against. 0 when the grid is empty. */\n maxCellCount: number;\n /** Total assumptions counted in the grid (every cell's count summed).\n * Equal to the input length minus any rows with neither Lens nor Stage\n * set, which fall in the \"—\" row / \"—\" cell. */\n total: number;\n}\n\nconst NO_LENS = \"—\";\nconst NO_STAGE = \"—\";\n\n/** A stage value from a record, validated against the fixed vocabulary.\n * Returns null for an empty or unrecognised value — the caller decides\n * whether to bucket those or drop them. */\nexport function stageOf(record: AnyRecord): StageValue | null {\n const v = str(record.Stage);\n if (!v) return null;\n return (STAGE_ORDER as readonly string[]).includes(v)\n ? (v as StageValue)\n : null;\n}\n\n/** Sort a list of assumptions by Risk, highest first. Stable on tie by id —\n * matches the pipeline board's \"riskiest first\" convention. Pure: returns a\n * new array, leaves the input alone. */\nexport function rankByRisk(records: AnyRecord[]): AnyRecord[] {\n return [...records]\n .map((r) => ({ r, risk: derivedNum(r, \"risk\") ?? 0 }))\n .sort((a, b) =>\n a.risk !== b.risk ? b.risk - a.risk : a.r.id.localeCompare(b.r.id),\n )\n .map((x) => x.r);\n}\n\n/**\n * Build the Lens × Stage grid from the assumption register. Pure — no I/O,\n * no React. The Lens list is read off the records in first-appearance order\n * (the configured vocabulary order is the caller's concern; the grid keeps\n * what it sees, so a workspace with no Commercial-stage-4 bets simply shows\n * a 0 cell, never a missing row). A record with no Lens set falls into a\n * trailing \"—\" row; a record with no Stage set (or an unrecognised Stage)\n * falls into a trailing \"—\" column. The \"—\"/\"—\" cell holds the records the\n * gate would have caught — write-time enforcement is the gate's job, this\n * just surfaces them honestly.\n *\n * The \"—\" row and \"—\" column are **only emitted when needed** — i.e. when at\n * least one record has a missing Lens (resp. Stage). A clean register\n * renders a pure Lens × 4-Stage matrix; a register with gate-leakage gets\n * the diagnostic row/column added. This keeps the matrix rectangular and\n * matches the spec (\"if a claim doesn't fit any stage, it falls out\" — the\n * \"—\" column is a diagnostic, not a feature).\n *\n * Each cell's `assumptions` list is ranked by Risk (highest first), so the\n * drill-through reads \"the riskiest belief in this cell\" first — the grid is\n * the filter, Risk is the rank. `density` is `count / maxCellCount` across\n * the whole grid, for the heatmap colour scale; an empty cell reads 0.\n */\nexport function buildStageGrid(assumptions: AnyRecord[]): StageGridView {\n // Lens order: first-appearance, with \"—\" last (only if needed).\n const lensOrder: string[] = [];\n const seenLens = new Set<string>();\n const pushLens = (lens: string) => {\n if (!seenLens.has(lens)) {\n seenLens.add(lens);\n lensOrder.push(lens);\n }\n };\n\n // Bucket every assumption into (lens, stage).\n const buckets = new Map<string, Map<StageValue | typeof NO_STAGE, AnyRecord[]>>();\n const ensureLens = (lens: string): Map<StageValue | typeof NO_STAGE, AnyRecord[]> => {\n let m = buckets.get(lens);\n if (!m) {\n m = new Map();\n buckets.set(lens, m);\n }\n return m;\n };\n\n let hasNoLens = false;\n let hasNoStage = false;\n for (const a of assumptions) {\n const lens = str(a.Lens) ?? NO_LENS;\n const stage = stageOf(a) ?? NO_STAGE;\n if (lens === NO_LENS) hasNoLens = true;\n if (stage === NO_STAGE) hasNoStage = true;\n pushLens(lens);\n const byStage = ensureLens(lens);\n let list = byStage.get(stage);\n if (!list) {\n list = [];\n byStage.set(stage, list);\n }\n list.push(a);\n }\n\n // \"—\" lens row goes last.\n if (hasNoLens) {\n lensOrder.splice(lensOrder.indexOf(NO_LENS), 1);\n lensOrder.push(NO_LENS);\n } else {\n // No record needed a \"—\" row — drop it from the lens order so the grid\n // renders a pure Lens × Stage matrix.\n const idx = lensOrder.indexOf(NO_LENS);\n if (idx >= 0) lensOrder.splice(idx, 1);\n }\n\n // Stage order: the four canonical stages, then \"—\" last (only if needed).\n const stageOrder: (StageValue | typeof NO_STAGE)[] = [...STAGE_ORDER];\n if (hasNoStage) stageOrder.push(NO_STAGE);\n\n const cells: StageGridCell[] = [];\n let maxCellCount = 0;\n let total = 0;\n for (const lens of lensOrder) {\n const byStage = buckets.get(lens) ?? new Map();\n for (const stage of stageOrder) {\n const records = byStage.get(stage) ?? [];\n const ranked = rankByRisk(records);\n const count = ranked.length;\n maxCellCount = Math.max(maxCellCount, count);\n total += count;\n cells.push({\n lens,\n stage,\n count,\n assumptions: ranked,\n // density filled in a second pass once maxCellCount is known.\n density: 0,\n });\n }\n }\n\n // Second pass: normalise density against the grid's max cell count.\n const norm = maxCellCount > 0 ? 1 / maxCellCount : 0;\n for (const cell of cells) {\n cell.density = cell.count * norm;\n }\n\n return {\n lenses: lensOrder,\n stages: [...STAGE_ORDER],\n cells,\n maxCellCount,\n total,\n };\n}\n\n/** The cell at a given (lens, stage) — null if no such cell (e.g. a stage\n * not in the canonical order). The \"—\" row / \"—\" column are addressable\n * with the `NO_LENS` / `NO_STAGE` sentinels. */\nexport function cellAt(\n view: StageGridView,\n lens: string,\n stage: StageValue | typeof NO_STAGE,\n): StageGridCell | null {\n return view.cells.find((c) => c.lens === lens && c.stage === stage) ?? null;\n}\n\n/** Export the sentinel so the surface can address the \"no lens\" / \"no stage\"\n * buckets without hard-coding the em dash. */\nexport { NO_LENS, NO_STAGE };","/**\n * Recommended experiments (DEV-5882) — a UI-side derivation from the assumption\n * register, not a stored entity. For each cluster of risk-related assumptions\n * that share a Lens × Stage and lack a *live* experiment testing them, propose\n * one experiment (Test / Observation / Desk research / Survey) with a bar\n * preview. The user can \"Accept\" to create the experiment.\n *\n * Pure: no I/O, no React. The surface mounts thinly over this. Clusters are\n * ranked by max risk (riskiest first), so the board's \"Recommended\n * experiments\" section leads with the test that buys down the most risk.\n */\nimport type { AnyRecord } from \"@validation-os/core\";\nimport { derivedNum, str } from \"./derived-views.js\";\n\nexport type RecommendedExperimentType =\n | \"Test\"\n | \"Observation\"\n | \"Desk research\"\n | \"Survey\";\n\nexport interface RecommendedExperiment {\n /** Stable id derived from the cluster's assumption ids (so React keys are stable). */\n id: string;\n /** The experiment type — picked from the lens's do-rungs when the cluster has no evidence. */\n type: RecommendedExperimentType;\n /** One-line title, e.g. \"Test 2 Consumer · Discovery beliefs\". */\n title: string;\n /** The assumption ids this experiment would test. */\n assumptionIds: string[];\n /** The max risk across the cluster's assumptions — drives ranking. */\n maxRisk: number;\n /** Why this test, in plain language. */\n rationale: string;\n /** The pre-registered bar preview (\"Right if: …\"). */\n barPreview: string;\n /** The generated experiment body — a protocol with questions, what it tests, how to run it. */\n body: string;\n /** The lens this cluster belongs to — for tagging. */\n lens: string;\n /** Display colour for the lens tag. */\n lensColour: string;\n}\n\n/** The max number of recommended experiments to show (one per lens, up to 3). */\nexport const MAX_RECOMMENDED = 3;\n\n/** The max assumptions per cluster (tight groups, not whole cells). */\nconst MAX_CLUSTER_SIZE = 3;\n\n/** The max number of \"needs framing\" assumptions to show (one per lens, up to 3). */\nexport const MAX_NEEDS_FRAMING = 3;\n\n/** Lens display colours — one per lens for clear tagging. */\nconst LENS_COLOUR: Record<string, string> = {\n Consumer: \"#8b83f5\",\n Commercial: \"#38c793\",\n Investor: \"#e6a23c\",\n};\n\n/**\n * The \"needs framing\" list — the riskiest live, non-moot assumption *per lens*\n * whose completeness is below 100% (the belief is written but not fully framed:\n * missing the 5 Whys, the metric for truth, or the scoring justification).\n * These are the beliefs where the next move is \"frame the belief\", not \"design\n * an experiment\". At most one assumption per lens, capped at MAX_NEEDS_FRAMING\n * (3 lenses), riskiest-first across lenses.\n */\nexport interface NeedsFramingItem {\n id: string;\n title: string;\n risk: number;\n completeness: number;\n lens: string;\n stage: string;\n /** What's missing — a plain-language hint. */\n hint: string;\n /** Display colour for the lens tag. */\n lensColour: string;\n}\n\nexport function buildNeedsFraming(\n assumptions: AnyRecord[],\n): NeedsFramingItem[] {\n const live = assumptions.filter((a) => {\n const status = str(a.Status);\n const moot = a.moot === true;\n return !moot && (status === \"Live\" || status === \"Draft\");\n });\n\n const items = live\n .map((a) => {\n const id = str(a.id) ?? \"\";\n const completeness = derivedNum(a, \"completeness\") ?? 0;\n const risk = derivedNum(a, \"risk\") ?? 0;\n const lens = str(a.Lens) ?? \"—\";\n const stage = str(a.Stage) ?? \"—\";\n const title = str(a.Title) ?? id;\n const hint = framingHint(a, completeness);\n const lensColour = LENS_COLOUR[lens] ?? LENS_COLOUR[\"Investor\"] ?? \"#6b7484\";\n return { id, title, risk, completeness, lens, stage, hint, lensColour };\n })\n .filter((a) => a.completeness < 100);\n\n // Group by lens; from each lens pick the riskiest unframed assumption.\n // Then take up to MAX_NEEDS_FRAMING lenses, riskiest-first across lenses.\n const byLens = new Map<string, NeedsFramingItem>();\n for (const item of items) {\n const existing = byLens.get(item.lens);\n if (!existing || item.risk > existing.risk) {\n byLens.set(item.lens, item);\n }\n }\n\n return [...byLens.values()]\n .sort((a, b) => b.risk - a.risk)\n .slice(0, MAX_NEEDS_FRAMING);\n}\n\nfunction framingHint(a: AnyRecord, completeness: number): string {\n const hasScoring = Boolean(str(a[\"Scoring justification\"]));\n const hasDescription = Boolean(str(a.Description));\n if (completeness < 50) {\n return hasDescription\n ? \"The belief is written but incomplete — fill in the scoring justification and any missing framing fields.\"\n : \"The belief needs a description — what exactly is being claimed, in falsifiable terms.\";\n }\n if (!hasScoring) {\n return \"Add a scoring justification — why is the Impact seed scored as it is?\";\n }\n return \"Nearly framed — check the 5 Whys and the metric for truth are complete.\";\n}\n\n/**\n * The lens → do-rung mapping (DEV-5879 spec). The lens determines which \"do\"\n * rungs are available; Talk + Desk work for any lens. This is a grading\n * guideline, not a schema constraint. The recommended-experiment type is\n * picked from the lens's first do-rung when the cluster has no evidence:\n *\n * Consumer → Observation (Observed usage)\n * Commercial → Test (Signed intent)\n * any other lens → Desk research (the safe default)\n */\nconst LENS_TO_TYPE: Record<string, RecommendedExperimentType> = {\n Consumer: \"Observation\",\n Commercial: \"Test\",\n};\n\n/**\n * Build recommended experiments from the assumption + experiment registers.\n *\n * A cluster is a TIGHT group of the riskiest live, non-moot assumptions sharing\n * a Lens × Stage pair, none of which has a *live* (non-Archived) experiment\n * testing it. One recommended experiment per cluster, max 3 assumptions per\n * cluster (the riskiest ones), max 2 recommendations total (the riskiest\n * clusters). Each recommendation carries a generated experiment body — a\n * protocol with what it tests, how to run it, and the questions to ask.\n */\nexport function buildRecommendedExperiments(\n assumptions: AnyRecord[],\n experiments: AnyRecord[],\n): RecommendedExperiment[] {\n const liveAssumptions = assumptions.filter((a) => {\n const status = str(a.Status);\n const moot = a.moot === true;\n return !moot && (status === \"Live\" || status === \"Draft\");\n });\n\n // The set of assumption ids that already have a *live* experiment testing\n // them — those are covered, not candidates for a recommendation.\n const testedByLive = new Set<string>();\n for (const e of experiments) {\n const status = str(e.Status);\n if (status === \"Archived\") continue;\n const ids = Array.isArray(e.barLineAssumptionIds)\n ? (e.barLineAssumptionIds as string[])\n : [];\n for (const id of ids) testedByLive.add(id);\n }\n\n // Cluster by Lens × Stage, keeping only assumptions not covered by a live\n // experiment. Then take the riskiest MAX_CLUSTER_SIZE per cluster.\n const clusters = new Map<string, AnyRecord[]>();\n for (const a of liveAssumptions) {\n const id = str(a.id) ?? \"\";\n if (testedByLive.has(id)) continue;\n const lens = str(a.Lens) ?? \"—\";\n const stage = str(a.Stage) ?? \"—\";\n const key = `${lens}×${stage}`;\n const bucket = clusters.get(key);\n if (bucket) bucket.push(a);\n else clusters.set(key, [a]);\n }\n\n // Rank assumptions within each cluster by risk, keep the top 3.\n // Then pick one cluster per lens (the riskiest), ranked by max risk.\n const rankedClusters = [...clusters.entries()]\n .map(([key, cluster]) => {\n const ranked = cluster\n .sort((a, b) => (derivedNum(b, \"risk\") ?? 0) - (derivedNum(a, \"risk\") ?? 0))\n .slice(0, MAX_CLUSTER_SIZE);\n const maxRisk = Math.max(...ranked.map((a) => derivedNum(a, \"risk\") ?? 0), 0);\n return { key, cluster: ranked, maxRisk };\n })\n .sort((a, b) => b.maxRisk - a.maxRisk);\n\n const byLens = new Map<string, typeof rankedClusters[0]>();\n for (const entry of rankedClusters) {\n const lens = entry.key.split(\"×\")[0] ?? \"—\";\n if (!byLens.has(lens)) byLens.set(lens, entry);\n }\n const clusterEntries = [...byLens.values()]\n .sort((a, b) => b.maxRisk - a.maxRisk)\n .slice(0, MAX_RECOMMENDED);\n\n const recs: RecommendedExperiment[] = [];\n for (const { key, cluster, maxRisk } of clusterEntries) {\n const lens = key.split(\"×\")[0] ?? \"—\";\n const stage = key.split(\"×\")[1] ?? \"—\";\n const assumptionIds = cluster\n .map((a) => str(a.id) ?? \"\")\n .filter(Boolean)\n .sort();\n const type = LENS_TO_TYPE[lens ?? \"\"] ?? \"Desk research\";\n const title =\n cluster.length === 1\n ? `Test ${assumptionIds[0]}`\n : `Test ${cluster.length} ${lens} · ${stage} beliefs`;\n const rationale =\n cluster.length === 1\n ? `One belief (${assumptionIds[0]}) at ${Math.round(maxRisk)} risk with no live test. Designing an experiment here would buy down the most risk.`\n : `${cluster.length} beliefs share ${lens} · ${stage}, the riskiest at ${Math.round(maxRisk)} risk. One experiment can address them all.`;\n const barPreview = `The riskiest belief moves out of the kill zone, or stays in it.`;\n const body = generateExperimentBody(type, lens, stage, cluster, maxRisk);\n const lensColour = LENS_COLOUR[lens] ?? LENS_COLOUR[\"Investor\"] ?? \"#6b7484\";\n recs.push({\n id: assumptionIds.join(\"+\"),\n type,\n title,\n assumptionIds,\n maxRisk,\n rationale,\n barPreview,\n body,\n lens,\n lensColour,\n });\n }\n\n // Riskiest first; stable tie-break by id.\n recs.sort((a, b) =>\n a.maxRisk !== b.maxRisk\n ? b.maxRisk - a.maxRisk\n : a.id.localeCompare(b.id),\n );\n\n return recs;\n}\n\n/**\n * Generate a plain-language experiment body — a protocol with what it tests,\n * how to run it, and the questions to ask. This is a UI-side draft, not a\n * stored entity; the user accepts it to create the experiment (and can edit\n * the body before running).\n */\nfunction generateExperimentBody(\n type: RecommendedExperimentType,\n lens: string,\n stage: string,\n cluster: AnyRecord[],\n maxRisk: number,\n): string {\n const beliefs = cluster\n .map((a) => `- **${str(a.id)}**: ${str(a.Title) ?? str(a.id) ?? \"\"}`)\n .join(\"\\n\");\n const rung = type === \"Observation\" ? \"Observed usage\" : type === \"Test\" ? \"Signed intent\" : \"Desk research\";\n\n return `## What this tests\n\nThis ${type.toLowerCase()} addresses ${cluster.length} ${lens} · ${stage} belief${cluster.length === 1 ? \"\" : \"s\"} at ${Math.round(maxRisk)} risk — the riskiest untested cluster on the board.\n\n${beliefs}\n\n## How to run it\n\n${\n type === \"Observation\"\n ? `Set up a prototype or analytics instrument that captures real user behaviour. Watch how ${cluster.length === 1 ? \"this belief plays out\" : \"these beliefs play out\"} in actual usage — not what people say they'd do, but what they actually do. Log each observation as evidence at the **${rung}** rung.`\n : type === \"Test\"\n ? `Reach out to potential ${lens === \"Consumer\" ? \"customers\" : \"businesses\"} and seek a signed commitment — a letter of intent, a pre-order, a pilot agreement. The commitment is the evidence; it lands at the **${rung}** rung.`\n : `Research published sources, competitor behaviour, and market data. Find external evidence that bears on ${cluster.length === 1 ? \"this belief\" : \"these beliefs\"}. Log each source as evidence at the **Desk research** rung.`\n}\n\n## Questions to answer\n\n${cluster.map((a, i) => `${i + 1}. Does ${str(a.Title) ?? str(a.id) ?? \"\"} hold — or does the evidence break it?`).join(\"\\n\")}\n\n## Pre-registered bars\n\n- **Right if:** the riskiest belief moves out of the kill zone (Confidence > 0).\n- **Wrong if:** the evidence invalidates the riskiest belief (Confidence enters the kill zone).\n`;\n}","/**\n * The four loop meters as data — the Framed → Planned → Tested → Known spine\n * turned into captions and fills, once (OPS-1330).\n *\n * Two surfaces draw the same four meters for one belief: the pipeline board's\n * row (OPS-1300, the cross-belief altitude) and the journey rail (this ticket,\n * the same spine zoomed to one belief). The *classification* is already shared\n * in core (`deriveBeliefStage`, OPS-1329); this shares the layer above it — what\n * each meter is captioned and how full it reads — so a board row and a rail can\n * never disagree about a belief while looking at the same numbers.\n *\n * Only the mapping is shared, not the markup: each surface renders these its own\n * way (the board as a compact horizontal track, the rail as the labelled spine).\n * Pure, so the captions are unit-tested here rather than through two DOMs.\n */\nimport type { ConfSign, StageKey } from \"@validation-os/core/derivation\";\nimport { formatSigned } from \"./primitives.js\";\n\n/**\n * How a meter fills: `fill` runs left→right (0–100%); `signed` is anchored at\n * the middle and leans by sign — the Known gauge, which never \"completes\".\n */\nexport type MeterKind = \"fill\" | \"signed\";\n\n/** One meter, ready to render. */\nexport interface StageMeterView {\n /** Its place on the spine, \"1\"–\"4\" — the caption's index. */\n n: string;\n /** The stage it meters. */\n key: StageKey;\n /** Its display name — \"Framed\", \"Planned\", \"Tested\", \"Known\". */\n name: string;\n /** The caption: \"Framed 60%\", \"No test\", \"Tested 1/3\", \"Known +40\". */\n label: string;\n /**\n * How full it reads, as a percentage of the track. A `signed` meter fills\n * from the midpoint, so its span is 0–50 (a full lean is half the track).\n */\n pct: number;\n /** Nothing has happened on this meter yet — the caption reads muted. */\n muted: boolean;\n kind: MeterKind;\n /** Replaces the caption when set — the Known meter's kill-zone re-test flag. */\n flag?: string;\n /** Which way a `signed` meter leans. */\n sign?: ConfSign;\n}\n\n/**\n * The meter fields a belief carries. Both `BeliefStage` (the rail) and\n * `PipelineRow` (the board) satisfy this structurally, so neither has to be\n * converted before rendering.\n */\nexport interface StageMeterInput {\n framed: number;\n planned: boolean;\n tested: { settled: number; total: number };\n confidence: number;\n confSign: ConfSign;\n killZone: boolean;\n}\n\nfunction clamp(pct: number): number {\n if (!Number.isFinite(pct)) return 0;\n return Math.max(0, Math.min(100, pct));\n}\n\n/**\n * One belief's four meters, in spine order. Nothing is derived here — the\n * numbers arrive already computed (`deriveBeliefStage`); this only decides how\n * each one reads.\n */\nexport function stageMeters(input: StageMeterInput): StageMeterView[] {\n const { framed, planned, tested, confidence, confSign, killZone } = input;\n return [\n {\n n: \"1\",\n key: \"framed\",\n name: \"Framed\",\n label: `Framed ${framed}%`,\n pct: clamp(framed),\n muted: framed < 100,\n kind: \"fill\",\n },\n {\n n: \"2\",\n key: \"planned\",\n name: \"Planned\",\n label: planned ? \"Planned\" : \"No test\",\n pct: planned ? 100 : 0,\n muted: !planned,\n kind: \"fill\",\n },\n {\n n: \"3\",\n key: \"tested\",\n name: \"Tested\",\n label: tested.total\n ? `Tested ${tested.settled}/${tested.total}`\n : \"Untested\",\n pct: tested.total\n ? clamp(Math.round((tested.settled / tested.total) * 100))\n : 0,\n muted: tested.total === 0,\n kind: \"fill\",\n },\n {\n n: \"4\",\n key: \"known\",\n name: \"Known\",\n label: `Known ${formatSigned(confidence)}`,\n // A full lean is half the track — the gauge is anchored at zero and\n // signed, so it reads direction, not completion (it never \"completes\").\n pct: Math.min(50, (Math.abs(confidence) / 100) * 50),\n muted: confSign === \"zero\",\n kind: \"signed\",\n sign: confSign,\n // In the kill zone the caption gives way to the flag: the number stops\n // being the point once the evidence has turned.\n ...(killZone ? { flag: \"re-test\" } : {}),\n },\n ];\n}\n","import { useMemo, useState } from \"react\";\nimport type { AnyRecord, BarLine, Result } from \"@validation-os/core\";\nimport { Breadcrumb } from \"./breadcrumb.js\";\nimport { readingBeliefs } from \"./derived-views.js\";\nimport { EvidenceBody } from \"./markdown.js\";\nimport { formatSigned } from \"./primitives.js\";\nimport { ConfidenceDonut } from \"./confidence-donut.js\";\nimport type { Route } from \"./route.js\";\nimport { useList } from \"./use-records.js\";\n\n/**\n * The evidence-first experiment detail (DEV-5884): readings lead, each showing\n * date, title, and a single set of per-belief verdict cards (assumption link,\n * verdict, rung, grading rationale, bar-line context). Unstarted bars (bars\n * with no readings yet) are in a separate section below with dashed outlines.\n */\nexport interface ExperimentDetailProps {\n experimentId: string;\n basePath?: string;\n onNavigate: (route: Route) => void;\n}\n\nexport function ExperimentDetail({\n experimentId,\n basePath,\n onNavigate,\n}: ExperimentDetailProps) {\n const experiments = useList(\"experiments\", basePath);\n const readings = useList(\"readings\", basePath);\n const assumptions = useList(\"assumptions\", basePath);\n\n const loading = experiments.loading && !experiments.records;\n\n const experiment = useMemo(\n () => (experiments.records ?? []).find((e) => String(e.id) === experimentId) ?? null,\n [experiments.records, experimentId],\n );\n\n if (loading) {\n return (\n <div>\n <Breadcrumb trail={[{ label: \"Experiments\", route: { name: \"experiments\" } }]} onNavigate={onNavigate} />\n <p className=\"vos-muted\">Loading experiment…</p>\n </div>\n );\n }\n if (!experiment) {\n return (\n <div>\n <Breadcrumb trail={[{ label: \"Experiments\", route: { name: \"experiments\" } }]} onNavigate={onNavigate} />\n <p className=\"vos-error\">Experiment not found: {experimentId}</p>\n </div>\n );\n }\n\n const title = String(experiment.Title ?? experimentId);\n const status = String(experiment.Status ?? \"\");\n const body = String(experiment.body ?? \"\");\n const barLines = Array.isArray(experiment.barLines) ? (experiment.barLines as BarLine[]) : [];\n const expConf = (experiment.derived as any)?.experimentConfidence ?? 50;\n\n // Readings linked to this experiment — the evidence-first content.\n const expReadings = (readings.records ?? [])\n .filter((r) => String(r.experimentId ?? \"\") === experimentId)\n .sort((a, b) => String(b.Date ?? \"\").localeCompare(String(a.Date ?? \"\")));\n\n // Classify each bar by what the READINGS say (not just the barVerdict field,\n // which is only set at closure). A bar is validated/invalidated if any\n // reading's belief for it has that Result; in-progress if it has a reading\n // but no settled verdict; unstarted if no reading touches it.\n const validatedBars = barLines.filter((b) =>\n expReadings.some((r) =>\n readingBeliefs(r).some(\n (bl) => bl.assumptionId === b.assumptionId && bl.Result === \"Validated\",\n ),\n ),\n );\n const invalidatedBars = barLines.filter((b) =>\n expReadings.some((r) =>\n readingBeliefs(r).some(\n (bl) => bl.assumptionId === b.assumptionId && bl.Result === \"Invalidated\",\n ),\n ),\n );\n const readingAssumptionIds = new Set<string>();\n for (const r of expReadings) {\n for (const b of readingBeliefs(r)) readingAssumptionIds.add(b.assumptionId);\n }\n const inProgressBars = barLines.filter(\n (b) =>\n !validatedBars.includes(b) &&\n !invalidatedBars.includes(b) &&\n readingAssumptionIds.has(b.assumptionId),\n );\n const unstartedBars = barLines.filter(\n (b) => !readingAssumptionIds.has(b.assumptionId),\n );\n const settledBars = [...validatedBars, ...invalidatedBars];\n const validatedCount = validatedBars.length;\n const invalidatedCount = invalidatedBars.length;\n\n return (\n <div>\n <Breadcrumb\n trail={[\n { label: \"Experiments\", route: { name: \"experiments\" } },\n { label: experimentId, route: { name: \"experiment\", id: experimentId } },\n ]}\n onNavigate={onNavigate}\n />\n\n <div className=\"vos-detail-head\">\n <span className=\"vos-detail-id vos-num\">{experimentId}</span>\n <span className={`vos-pill ${status === \"Running\" ? \"vos-pill-good\" : \"vos-pill-neutral\"}`}>\n {status}\n </span>\n </div>\n <div className=\"vos-detail-title\">{title}</div>\n\n {/* Confidence gauge + coverage bar */}\n <div className=\"vos-card vos-exp-head\">\n <div className=\"vos-exp-gauge\">\n <ConfidenceDonut value={expConf} size={80} />\n <div className=\"vos-gauge-label\">exp confidence (50 = neutral)</div>\n </div>\n <div className=\"vos-exp-coverage\">\n <div className=\"vos-coverage-label\">\n COVERAGE · {settledBars.length}/{barLines.length} bars settled\n </div>\n <div className=\"vos-coverage-bar\">\n <i className=\"vos-coverage-good\" style={{ width: `${pct(validatedCount, barLines.length)}%` }} />\n <i className=\"vos-coverage-crit\" style={{ width: `${pct(invalidatedCount, barLines.length)}%` }} />\n <i className=\"vos-coverage-warn\" style={{ width: `${pct(inProgressBars.length, barLines.length)}%` }} />\n <i className=\"vos-coverage-empty\" style={{ width: `${pct(unstartedBars.length, barLines.length)}%` }} />\n </div>\n <div className=\"vos-coverage-legend\">\n <span><i className=\"vos-dot-good\" /> {validatedCount} validated</span>\n <span><i className=\"vos-dot-crit\" /> {invalidatedCount} invalidated</span>\n <span><i className=\"vos-dot-warn\" /> {inProgressBars.length} in progress</span>\n <span><i className=\"vos-dot-empty\" /> {unstartedBars.length} unstarted</span>\n </div>\n </div>\n </div>\n\n {/* Plan body */}\n {body ? (\n <div className=\"vos-card vos-detail-section\">\n <div className=\"vos-detail-section-label\">Plan body</div>\n <EvidenceBody text={body} />\n </div>\n ) : null}\n\n {/* Readings — evidence-first: readings lead, bar lines as context per reading */}\n <div className=\"vos-card vos-detail-section\">\n <div className=\"vos-detail-section-label\">\n Evidence · {expReadings.length} piece{expReadings.length === 1 ? \"\" : \"s\"} from this experiment\n </div>\n {expReadings.length === 0 ? (\n <div className=\"vos-muted vos-empty\">No evidence yet — experiment is running.</div>\n ) : (\n expReadings.map((r) => {\n const beliefs = readingBeliefs(r);\n const rDate = String(r.Date ?? \"\");\n const rTitle = String(r.Title ?? r.id);\n const rId = String(r.id);\n return (\n <details key={rId} className=\"vos-reading-card vos-reading-collapse\">\n <summary className=\"vos-reading-card-summary\">\n <span className=\"vos-reading-date vos-num\">{rDate}</span>\n <span className=\"vos-reading-title\">{rTitle}</span>\n <span className=\"vos-reading-beliefs-count vos-num\">\n {beliefs.length} belief{beliefs.length === 1 ? \"\" : \"s\"}\n </span>\n </summary>\n <div className=\"vos-reading-card-body\">\n <div className=\"vos-reading-head\">\n <span className=\"vos-reading-source\">{String(r.Source ?? \"\")}</span>\n <button\n type=\"button\"\n className=\"vos-link\"\n onClick={() => onNavigate({ name: \"reading\", id: rId })}\n >\n open reading →\n </button>\n </div>\n {/* Per-belief verdict cards — merged: assumption link, verdict,\n rung, bar-line context, and grading rationale. The\n Grading justification is the grader's rationale, NOT a\n quote; actual quotes live in the reading's body shown in\n the reading detail's Context section. */}\n {beliefs.map((b) => {\n const bl = barLines.find((x) => x.assumptionId === b.assumptionId);\n const a = (assumptions.records ?? []).find((x) => String(x.id) === b.assumptionId);\n const justification = String(b[\"Grading justification\"] ?? \"\");\n return (\n <div key={b.assumptionId} className={`vos-belief-card vos-verdict-border-${verdictTone(b.Result)}`}>\n <div className=\"vos-belief-head\">\n <button\n type=\"button\"\n className=\"vos-belief-id\"\n onClick={() => onNavigate({ name: \"assumption\", id: b.assumptionId })}\n >\n {b.assumptionId}\n </button>\n <span className=\"vos-belief-title\">{String(a?.Title ?? b.assumptionId)}</span>\n <span className={`vos-pill vos-pill-${verdictTone(b.Result)}`}>{b.Result}</span>\n <span className=\"vos-rung-tag\">{String(r.Rung ?? \"\")}</span>\n </div>\n {typeof b.excerpt === \"string\" && b.excerpt !== \"\" ? (\n <div className={`vos-belief-excerpt vos-verdict-border-${verdictTone(b.Result)}`}>\n “{b.excerpt}”\n </div>\n ) : justification ? (\n <div className={`vos-belief-rationale vos-verdict-border-${verdictTone(b.Result)}`}\n >\n <span className=\"vos-belief-rationale-label\">grading rationale:</span>\n {justification}\n </div>\n ) : null}\n {bl ? (\n <div className=\"vos-belief-bar\">\n <div className=\"vos-belief-bar-label\">Pre-registered bar</div>\n <div><strong>Right if:</strong> {String(bl.rightIf ?? \"\")}</div>\n {bl.wrongIf ? <div><strong>Wrong if:</strong> {String(bl.wrongIf)}</div> : null}\n {bl.barVerdict ? (\n <div className={`vos-text-${verdictTone(bl.barVerdict)}`}>\n Bar verdict: <strong>{bl.barVerdict}</strong>\n </div>\n ) : null}\n </div>\n ) : null}\n </div>\n );\n })}\n </div>\n </details>\n );\n })\n )}\n </div>\n\n {/* Unstarted bars — separate section below, dashed outlines */}\n {unstartedBars.length > 0 ? (\n <div className=\"vos-card vos-detail-section vos-unstarted\">\n <div className=\"vos-detail-section-label\">\n Not yet tested · {unstartedBars.length} bar{unstartedBars.length === 1 ? \"\" : \"s\"} with no evidence\n </div>\n {unstartedBars.map((bl) => {\n const a = (assumptions.records ?? []).find((x) => String(x.id) === bl.assumptionId);\n return (\n <div key={bl.assumptionId} className=\"vos-unstarted-bar\">\n <div className=\"vos-belief-head\">\n <button\n type=\"button\"\n className=\"vos-belief-id\"\n onClick={() => onNavigate({ name: \"assumption\", id: bl.assumptionId })}\n >\n {bl.assumptionId}\n </button>\n <span className=\"vos-belief-title\">{String(a?.Title ?? bl.assumptionId)}</span>\n <span className=\"vos-rung-tag\">{String(bl.plannedRung ?? \"\")}</span>\n <span className=\"vos-muted\">◌ no evidence</span>\n </div>\n <div className=\"vos-belief-bar\">\n <div><strong>Right if:</strong> {String(bl.rightIf ?? \"\")}</div>\n {bl.wrongIf ? <div><strong>Wrong if:</strong> {String(bl.wrongIf)}</div> : null}\n </div>\n </div>\n );\n })}\n </div>\n ) : null}\n </div>\n );\n}\n\nfunction pct(n: number, total: number): number {\n return total === 0 ? 0 : (n / total) * 100;\n}\n\nfunction verdictTone(verdict: Result | string | null | undefined): \"good\" | \"crit\" | \"neutral\" {\n if (verdict === \"Validated\") return \"good\";\n if (verdict === \"Invalidated\") return \"crit\";\n return \"neutral\";\n}","/**\n * A confidence donut gauge (DEV-5882 redesign) — a minimal ring gauge that\n * fills from 12 o'clock clockwise, proportional to the value (0–100, 50 = neutral).\n * The stroke is deliberately thin so the gauge reads as a subtle status\n * accent, not a pie chart. A larger centered number dominates the interior.\n * Used on the experiment list rows (56px) + the experiment detail header (80px).\n */\nexport function ConfidenceDonut({\n value,\n size = 56,\n}: {\n value: number;\n size?: number;\n}) {\n // Thin stroke keeps it elegant; radius stays well inside the square.\n const stroke = size > 60 ? 4 : 3;\n const r = (size - stroke * 3) / 2;\n const cx = size / 2;\n const cy = size / 2;\n const circumference = 2 * Math.PI * r;\n const pct = Math.max(0, Math.min(100, value)) / 100;\n const dash = pct * circumference;\n const color =\n value >= 67\n ? \"var(--vos-good)\"\n : value >= 33\n ? \"var(--vos-warn)\"\n : \"var(--vos-crit)\";\n return (\n <div className=\"vos-donut\" style={{ width: size, height: size }}>\n <svg width={size} height={size} aria-hidden=\"true\">\n <circle\n cx={cx}\n cy={cy}\n r={r}\n fill=\"none\"\n stroke=\"var(--vos-border)\"\n strokeWidth={stroke}\n />\n {value > 0 ? (\n <circle\n cx={cx}\n cy={cy}\n r={r}\n fill=\"none\"\n stroke={color}\n strokeWidth={stroke}\n strokeDasharray={`${dash} ${circumference - dash}`}\n strokeDashoffset={0}\n strokeLinecap=\"round\"\n transform={`rotate(-90 ${cx} ${cy})`}\n />\n ) : null}\n </svg>\n <span\n className=\"vos-donut-num vos-num\"\n style={{ fontSize: size > 60 ? 22 : 15 }}\n >\n {Math.round(value)}\n </span>\n </div>\n );\n}","import type { AnyRecord } from \"@validation-os/core\";\nimport { liveExperiments } from \"./derived-views.js\";\nimport type { Route } from \"./route.js\";\nimport { useList } from \"./use-records.js\";\nimport { Breadcrumb } from \"./breadcrumb.js\";\nimport { ConfidenceDonut } from \"./confidence-donut.js\";\n\n/**\n * The Experiments nav surface (DEV-5881): the live evidence plans list, with\n * bigger rows carrying a donut gauge + bar-line stats. Each row is a button;\n * clicking opens the evidence-first ExperimentDetail.\n */\nexport function ExperimentsSurface({\n basePath,\n onNavigate,\n}: {\n basePath?: string;\n onNavigate: (route: Route) => void;\n}) {\n const experiments = useList(\"experiments\", basePath);\n\n if (experiments.loading && !experiments.records) {\n return (\n <div>\n <Breadcrumb trail={[{ label: \"Experiments\", route: { name: \"experiments\" } }]} />\n <p className=\"vos-muted\">Loading experiments…</p>\n </div>\n );\n }\n if (experiments.error) {\n return (\n <div>\n <Breadcrumb trail={[{ label: \"Experiments\", route: { name: \"experiments\" } }]} />\n <p className=\"vos-error\">{experiments.error}</p>\n </div>\n );\n }\n\n const live = liveExperiments(experiments.records ?? []);\n\n return (\n <div>\n <Breadcrumb trail={[{ label: \"Experiments\", route: { name: \"experiments\" } }]} />\n <div className=\"vos-head\">\n <div>\n <h1>Experiments — the live evidence plans</h1>\n <p>{live.length} running {live.length === 1 ? \"plan\" : \"plans\"} · click to open the evidence-first view.</p>\n </div>\n </div>\n {live.length === 0 ? (\n <div className=\"vos-card vos-empty\">\n No running experiments. Design one from a belief's next move.\n </div>\n ) : (\n <div className=\"vos-card vos-exp-list\">\n {live.map((e) => {\n const id = String(e.id ?? \"\");\n const title = String(e.Title ?? id);\n const bars = Array.isArray(e.barLines) ? e.barLines.length : 0;\n const settled = Array.isArray(e.barLines)\n ? e.barLines.filter((b: any) => b?.barVerdict).length\n : 0;\n const status = String(e.Status ?? \"\");\n const expConf = (e.derived as any)?.experimentConfidence ?? 50;\n const instrument = String(e.Instrument ?? \"\");\n return (\n <button\n key={id}\n type=\"button\"\n className=\"vos-exp-row\"\n onClick={() => onNavigate({ name: \"experiment\", id })}\n >\n <ConfidenceDonut value={expConf} size={56} />\n <div className=\"vos-exp-row-body\">\n <div className=\"vos-exp-row-title\">{title}</div>\n <div className=\"vos-exp-row-meta vos-num\">\n {instrument && <span>{instrument} · </span>}\n {bars} bars · {settled} settled\n {e.Deadline ? <span> · deadline {String(e.Deadline)}</span> : null}\n </div>\n </div>\n <span className={`vos-pill ${status === \"Running\" ? \"vos-pill-good\" : \"vos-pill-neutral\"}`}>\n {status}\n </span>\n </button>\n );\n })}\n </div>\n )}\n </div>\n );\n}","import { useMemo } from \"react\";\nimport type { AnyRecord } from \"@validation-os/core\";\nimport { Breadcrumb } from \"./breadcrumb.js\";\nimport { readingBeliefs } from \"./derived-views.js\";\nimport { EvidenceBody } from \"./markdown.js\";\nimport type { Route } from \"./route.js\";\nimport { useList } from \"./use-records.js\";\n\n/**\n * The per-belief reading detail (DEV-5885): a shared Context section (who,\n * what, source — formerly \"Evidence body\") separate from per-belief verdict\n * cards. Each belief is a card with assumption link, verdict, rung, excerpt\n * (the per-assumption quote, color-coded by result), grading justification,\n * and bar-line context (if from an experiment). Multi-belief readings show all\n * beliefs as separate cards. Provenance: linked experiment with gauge, or\n * \"found evidence\" note.\n */\nexport interface ReadingDetailProps {\n readingId: string;\n basePath?: string;\n onNavigate: (route: Route) => void;\n}\n\nexport function ReadingDetail({\n readingId,\n basePath,\n onNavigate,\n}: ReadingDetailProps) {\n const readings = useList(\"readings\", basePath);\n const experiments = useList(\"experiments\", basePath);\n const assumptions = useList(\"assumptions\", basePath);\n\n const loading = readings.loading && !readings.records;\n\n const reading = useMemo(\n () => (readings.records ?? []).find((r) => String(r.id) === readingId) ?? null,\n [readings.records, readingId],\n );\n\n if (loading) {\n return (\n <div>\n <Breadcrumb trail={[{ label: \"Evidence\", route: { name: \"readings\" } }]} onNavigate={onNavigate} />\n <p className=\"vos-muted\">Loading evidence…</p>\n </div>\n );\n }\n if (!reading) {\n return (\n <div>\n <Breadcrumb trail={[{ label: \"Evidence\", route: { name: \"readings\" } }]} onNavigate={onNavigate} />\n <p className=\"vos-error\">Evidence not found: {readingId}</p>\n </div>\n );\n }\n\n const title = String(reading.Title ?? readingId);\n const source = String(reading.Source ?? \"\");\n const body = String(reading.body ?? \"\");\n const expId = reading.experimentId ? String(reading.experimentId) : null;\n const experiment = expId\n ? (experiments.records ?? []).find((e) => String(e.id) === expId) ?? null\n : null;\n const beliefs = readingBeliefs(reading);\n const rung = String(reading.Rung ?? \"\");\n\n return (\n <div>\n <Breadcrumb\n trail={[\n { label: \"Evidence\", route: { name: \"readings\" } },\n { label: readingId, route: { name: \"reading\", id: readingId } },\n ]}\n onNavigate={onNavigate}\n />\n\n <div className=\"vos-detail-head\">\n <span className=\"vos-detail-id vos-num\">{readingId}</span>\n <span className=\"vos-reading-source\">{source}</span>\n {expId ? (\n <span className=\"vos-pill vos-pill-accent\">from experiment</span>\n ) : (\n <span className=\"vos-pill vos-pill-neutral\">found evidence</span>\n )}\n </div>\n <div className=\"vos-detail-title\">{title}</div>\n\n {/* Context — shared (who, what, source). Replaces \"Evidence body\". */}\n <div className=\"vos-card vos-detail-section\">\n <div className=\"vos-detail-section-label\">Context</div>\n {body ? <EvidenceBody text={body} /> : <div className=\"vos-muted\">No context recorded.</div>}\n </div>\n\n {/* Per-belief verdicts — rich cards with excerpt + bar-line context */}\n <div className=\"vos-card vos-detail-section\">\n <div className=\"vos-detail-section-label\">\n What this evidence says · {beliefs.length} belief{beliefs.length === 1 ? \"\" : \"s\"} · each with its own quote\n </div>\n {beliefs.length === 0 ? (\n <div className=\"vos-muted\">No beliefs scored in this evidence.</div>\n ) : (\n beliefs.map((b) => {\n const a = (assumptions.records ?? []).find((x) => String(x.id) === b.assumptionId);\n const bl = experiment && Array.isArray(experiment.barLines)\n ? (experiment.barLines as any[]).find((x) => x?.assumptionId === b.assumptionId)\n : null;\n const result = String(b.Result ?? \"Inconclusive\");\n const justification = String(b[\"Grading justification\"] ?? \"\");\n return (\n <div key={b.assumptionId} className={`vos-belief-card vos-verdict-border-${verdictTone(result)}`}>\n <div className=\"vos-belief-head\">\n <button\n type=\"button\"\n className=\"vos-belief-id\"\n onClick={() => onNavigate({ name: \"assumption\", id: b.assumptionId })}\n >\n {b.assumptionId}\n </button>\n <span className=\"vos-belief-title\">{String(a?.Title ?? b.assumptionId)}</span>\n <span className={`vos-pill vos-pill-${verdictTone(result)}`}>{result}</span>\n <span className=\"vos-rung-tag\">{rung}</span>\n </div>\n {/* Grading rationale — why this evidence scores this belief\n this way. NOT a quote; the actual quotes live in the\n Context section above (the reading's body). */}\n {typeof b.excerpt === \"string\" && b.excerpt !== \"\" ? (\n <div className={`vos-belief-excerpt vos-verdict-border-${verdictTone(result)}`}>\n “{b.excerpt}”\n </div>\n ) : body ? (\n <div className={`vos-belief-excerpt vos-verdict-border-${verdictTone(result)}`}>\n “{snippetFromReadingBody(body, b.assumptionId)}”\n </div>\n ) : null}\n {justification ? (\n <div className={`vos-belief-rationale vos-verdict-border-${verdictTone(result)}`}>\n <span className=\"vos-belief-rationale-label\">grading rationale:</span>\n {justification}\n </div>\n ) : null}\n {/* Bar-line context (if from an experiment) */}\n {bl ? (\n <div className=\"vos-belief-bar\">\n <div className=\"vos-belief-bar-label\">Pre-registered bar</div>\n <div><strong>Right if:</strong> {String(bl.rightIf ?? \"\")}</div>\n {bl.wrongIf ? <div><strong>Wrong if:</strong> {String(bl.wrongIf)}</div> : null}\n {bl.barVerdict ? (\n <div className={`vos-text-${verdictTone(bl.barVerdict)}`}>\n Bar verdict: <strong>{String(bl.barVerdict)}</strong>\n </div>\n ) : null}\n </div>\n ) : null}\n </div>\n );\n })\n )}\n </div>\n\n {/* Provenance — linked experiment with gauge, or \"found evidence\" note */}\n {experiment ? (\n <div className=\"vos-card vos-detail-section\">\n <div className=\"vos-detail-section-label\">From experiment</div>\n <button\n type=\"button\"\n className=\"vos-linked-row\"\n onClick={() => onNavigate({ name: \"experiment\", id: String(experiment.id) })}\n >\n <span className=\"vos-linked-gauge vos-num\">\n {Math.round((experiment.derived as any)?.experimentConfidence ?? 50)}\n </span>\n <span className=\"vos-linked-title\">{String(experiment.Title ?? experiment.id)}</span>\n <span className=\"vos-link\">→ experiment</span>\n </button>\n </div>\n ) : (\n <div className=\"vos-card vos-detail-section\">\n <div className=\"vos-detail-section-label\">Provenance</div>\n <div className=\"vos-muted\">\n Found evidence — not linked to an experiment. This was logged directly\n (desk research, found interview, observation).\n </div>\n </div>\n )}\n </div>\n );\n}\n\nfunction verdictTone(verdict: string | null | undefined): \"good\" | \"crit\" | \"neutral\" {\n if (verdict === \"Validated\") return \"good\";\n if (verdict === \"Invalidated\") return \"crit\";\n return \"neutral\";\n}\n\nfunction snippetFromReadingBody(body: string, cue: string): string {\n if (!body) return \"\";\n const quoteMatch = body.match(/## Quote\\n+([\\s\\S]*?)(?=\\n## |\\n##$|$)/i);\n if (quoteMatch) {\n const q = quoteMatch[1]!.trim();\n return q.length > 220 ? q.slice(0, 217).trim() + \"…\" : q;\n }\n const sentences = body.split(/(?<=[.!?])\\s+/);\n const cueLower = cue.toLowerCase();\n for (const s of sentences) {\n if (s.toLowerCase().includes(cueLower)) return s.trim();\n }\n const first = sentences[0]?.trim() ?? \"\";\n return first.length > 220 ? first.slice(0, 217).trim() + \"…\" : first;\n}\n","import type { AnyRecord } from \"@validation-os/core\";\nimport type { Route } from \"./route.js\";\nimport { useList } from \"./use-records.js\";\nimport { Breadcrumb } from \"./breadcrumb.js\";\n\n/**\n * The Readings nav surface (DEV-5881): the evidence log list, sorted by date\n * desc. Each row is a button with the reading's date + title + a \"exp\"/\"found\"\n * tag + the belief count; clicking opens the per-belief ReadingDetail.\n */\nexport function ReadingsSurface({\n basePath,\n onNavigate,\n}: {\n basePath?: string;\n onNavigate: (route: Route) => void;\n}) {\n const readings = useList(\"readings\", basePath);\n\n if (readings.loading && !readings.records) {\n return (\n <div>\n <Breadcrumb trail={[{ label: \"Readings\", route: { name: \"readings\" } }]} />\n <p className=\"vos-muted\">Loading readings…</p>\n </div>\n );\n }\n if (readings.error) {\n return (\n <div>\n <Breadcrumb trail={[{ label: \"Readings\", route: { name: \"readings\" } }]} />\n <p className=\"vos-error\">{readings.error}</p>\n </div>\n );\n }\n\n const sorted = [...(readings.records ?? [])].sort((a, b) => {\n const da = String(a.Date ?? \"\");\n const db = String(b.Date ?? \"\");\n return db.localeCompare(da);\n });\n\n return (\n <div>\n <Breadcrumb trail={[{ label: \"Readings\", route: { name: \"readings\" } }]} />\n <div className=\"vos-head\">\n <div>\n <h1>Readings — the evidence log</h1>\n <p>{sorted.length} {sorted.length === 1 ? \"reading\" : \"readings\"} · click to open the per-belief view.</p>\n </div>\n </div>\n {sorted.length === 0 ? (\n <div className=\"vos-card vos-empty\">No readings logged yet.</div>\n ) : (\n <div className=\"vos-card vos-list-card\">\n {sorted.map((r) => {\n const id = String(r.id ?? \"\");\n const title = String(r.Title ?? id);\n const date = String(r.Date ?? \"\");\n const hasExperiment = Boolean(r.experimentId);\n const beliefCount = Array.isArray(r.beliefs) ? r.beliefs.length : 0;\n return (\n <button\n key={id}\n type=\"button\"\n className=\"vos-list-row\"\n onClick={() => onNavigate({ name: \"reading\", id })}\n >\n <span className=\"vos-list-row-date vos-num\">{date}</span>\n <span className=\"vos-list-row-title\">{title}</span>\n <span className={`vos-pill ${hasExperiment ? \"vos-pill-accent\" : \"vos-pill-neutral\"}`}>\n {hasExperiment ? \"exp\" : \"found\"}\n </span>\n <span className=\"vos-list-row-meta vos-num\">\n {beliefCount} belief{beliefCount === 1 ? \"\" : \"s\"}\n </span>\n </button>\n );\n })}\n </div>\n )}\n </div>\n );\n}","import { useMemo, useState } from \"react\";\nimport type { AnyRecord, BarLine, Collection } from \"@validation-os/core\";\nimport { REGISTERS } from \"@validation-os/core\";\nimport { formatValue } from \"./columns.js\";\nimport { resolveBarLines } from \"./detail-fields.js\";\nimport { buildPatch, draftErrors, draftFrom, type Draft } from \"./edit.js\";\nimport { EditFields } from \"./edit-fields.js\";\nimport { GlossaryText } from \"./glossary-text.js\";\nimport { toGlossaryTerms } from \"./glossary.js\";\nimport { buildJourney } from \"./journey.js\";\nimport { BeliefJourney } from \"./journey-surface.js\";\nimport { REGISTER_LABEL, REGISTER_SINGULAR } from \"./labels.js\";\nimport { readingBeliefs } from \"./derived-views.js\";\nimport { nestReadingsByPlan } from \"./list-surface.js\";\nimport { EvidenceBody } from \"./markdown.js\";\nimport { BeliefVerdicts } from \"./belief-verdicts.js\";\nimport {\n formatSigned,\n riskFraction,\n type Tone,\n} from \"./primitives.js\";\nimport {\n buildRecordPage,\n type BacklinkItem,\n type Meter,\n type Pill,\n type RecordTabId,\n type RelatedSet,\n type RelationPanel,\n} from \"./record-view.js\";\nimport type { Route } from \"./route.js\";\nimport { UnderstandingPanel } from \"./understanding-panel.js\";\nimport { useList, useUpdate } from \"./use-records.js\";\n\nexport interface RecordPageProps {\n /** The record being drilled into (`#record/<id>`). */\n recordId: string;\n /** Navigate elsewhere — the breadcrumb, backlinks and glossary links use it. */\n onNavigate: (route: Route) => void;\n /** Where the \"Records\" breadcrumb returns to before the record's own register\n * is known (resolved once the record loads). */\n backRegister: Collection;\n /** API base path (default `/api`). */\n basePath?: string;\n}\n\n/**\n * The record page's own edit affordance (OPS-1346) — genuine hand-input\n * fields only (seed Impact chief among them), wired through the same\n * `edit.ts`/`EditFields`/`useUpdate` seam the drawer uses. Bundled into one\n * prop so `RecordBody` doesn't grow a dozen individual callbacks.\n */\ninterface EditState {\n editing: boolean;\n draft: Draft;\n /** Validation messages keyed by field (e.g. Impact outside 0–100). */\n errors: Record<string, string>;\n saving: boolean;\n conflict: string | null;\n saveError: string | null;\n onEdit: () => void;\n onCancel: () => void;\n onSave: () => void;\n onReload: () => void;\n onField: (key: string, value: string) => void;\n}\n\nconst TAB_LABEL: Record<RecordTabId, string> = {\n overview: \"Overview\",\n evidence: \"Evidence\",\n connections: \"Connections\",\n history: \"History\",\n};\n\nconst PILL_CLASS: Record<Tone, string> = {\n good: \"vos-pill vos-pill-good\",\n warn: \"vos-pill vos-pill-warn\",\n crit: \"vos-pill vos-pill-crit\",\n accent: \"vos-pill vos-pill-accent\",\n neutral: \"vos-pill vos-pill-neutral\",\n};\n\n/**\n * The canonical full record page (OPS-1286) — promoted from the enriched drawer\n * to the one place a record lives, reachable identically from a table, a\n * backlink or a search (story 12). It loads the registers once (the related set\n * every panel reads), resolves which register the id belongs to, and renders the\n * pure `buildRecordPage` model: a status + derived lane/queue header, leading\n * scores as meters with a \"Why?\" attribution (reusing the understanding layer),\n * the genuine human-input free text (glossary auto-linked), backlink panels\n * grouped by relation with score chips, and a history/audit view. A belief's\n * page also hosts the per-belief journey (built by the OPS-1289 map).\n */\nexport function RecordPage({\n recordId,\n onNavigate,\n backRegister,\n basePath,\n}: RecordPageProps) {\n const lists = {\n assumptions: useList(\"assumptions\", basePath),\n experiments: useList(\"experiments\", basePath),\n readings: useList(\"readings\", basePath),\n decisions: useList(\"decisions\", basePath),\n glossary: useList(\"glossary\", basePath),\n };\n const [tab, setTab] = useState<RecordTabId>(\"overview\");\n const [asOf] = useState(() => new Date().toISOString().slice(0, 10));\n\n const anyLoading = REGISTERS.some((r) => lists[r].loading && !lists[r].records);\n const related: RelatedSet = {\n assumptions: lists.assumptions.records ?? [],\n experiments: lists.experiments.records ?? [],\n readings: lists.readings.records ?? [],\n decisions: lists.decisions.records ?? [],\n glossary: lists.glossary.records ?? [],\n };\n\n // Resolve the record and its register by scanning the loaded lists.\n let register: Collection | null = null;\n let record: AnyRecord | null = null;\n for (const r of REGISTERS) {\n const hit = (lists[r].records ?? []).find((x) => x.id === recordId);\n if (hit) {\n register = r;\n record = hit;\n break;\n }\n }\n\n // The per-belief journey (OPS-1330) — only a belief travels the loop, so this\n // is null for any other register. \"Now\" is supplied here so the view-model\n // stays pure (it never reads a clock); the story's last event is today.\n const journey = useMemo(() => {\n if (register !== \"assumptions\" || !record) return null;\n return buildJourney(\n recordId,\n {\n assumptions: related.assumptions ?? [],\n experiments: related.experiments ?? [],\n readings: related.readings ?? [],\n decisions: related.decisions ?? [],\n },\n asOf,\n );\n }, [register, record, recordId, asOf, related]);\n\n const refreshAll = () => {\n lists.assumptions.refresh();\n lists.experiments.refresh();\n lists.readings.refresh();\n lists.decisions.refresh();\n lists.glossary.refresh();\n };\n\n const terms = toGlossaryTerms(related.glossary ?? []);\n const openTerm = (id: string) => onNavigate({ name: \"record\", id });\n\n // Editing (OPS-1346): the record page's own edit affordance for genuine\n // hand-input fields — seed Impact on an assumption above all (the only\n // hand-scored number, `registry-schema.md`). Same edit/patch/save seam the\n // drawer uses (`edit.ts`, `EditFields`, `useUpdate`), so the two surfaces\n // never drift into different forms; derived numbers stay absent from\n // `editableFields` and so never appear here either.\n const [editing, setEditing] = useState(false);\n const [draft, setDraft] = useState<Draft>({});\n // The record as it was when editing began — diffing against this (not the\n // live `record`) means a concurrent teammate edit to an untouched field\n // survives a reload-and-retry (mirrors the drawer's conflict handling).\n const [baseline, setBaseline] = useState<AnyRecord | null>(null);\n const { save, saving, conflict, error: saveError, reset } = useUpdate(\n register ?? backRegister,\n basePath,\n );\n\n function startEditing() {\n if (!record || !register) return;\n setBaseline(record);\n setDraft(draftFrom(register, record));\n reset();\n setEditing(true);\n }\n\n function cancelEditing() {\n setEditing(false);\n reset();\n }\n\n async function onSaveEdit() {\n if (!record || !register || !baseline) return;\n // Out-of-range values (e.g. Impact outside 0–100) never reach the API —\n // the server's own check is a backstop, not the first line of defence.\n if (Object.keys(draftErrors(register, draft)).length > 0) return;\n const patch = buildPatch(register, baseline, draft);\n patch.version = record.version; // write on top of the freshest known version\n if (Object.keys(patch).length <= 1) {\n setEditing(false); // only `version` present — nothing actually changed\n return;\n }\n const result = await save(record.id, patch);\n if (result.ok) {\n setEditing(false);\n refreshAll(); // pull the recomputed record back in\n }\n // On conflict/error the hook holds the message; stay in edit mode with\n // the draft intact so nothing typed is lost.\n }\n\n function reloadLatest() {\n reset();\n refreshAll();\n }\n\n const setField = (key: string, value: string) =>\n setDraft((d) => ({ ...d, [key]: value }));\n\n const editErrors = editing && register ? draftErrors(register, draft) : {};\n const edit: EditState = {\n editing,\n draft,\n errors: editErrors,\n saving,\n conflict,\n saveError,\n onEdit: startEditing,\n onCancel: cancelEditing,\n onSave: onSaveEdit,\n onReload: reloadLatest,\n onField: setField,\n };\n\n return (\n <div>\n <nav className=\"vos-crumbs\" aria-label=\"Breadcrumb\">\n <button\n type=\"button\"\n onClick={() =>\n onNavigate({ name: \"records\", register: register ?? backRegister })\n }\n >\n {REGISTER_LABEL[register ?? backRegister]}\n </button>\n <span aria-hidden=\"true\">›</span>\n <span className=\"vos-rid\">{record ? formatValue(record.Title) : recordId}</span>\n </nav>\n\n {anyLoading ? (\n <p className=\"vos-muted\">Loading record…</p>\n ) : !record || !register ? (\n <div className=\"vos-empty\">\n Couldn't find a record with id <b>{recordId}</b>.\n </div>\n ) : (\n <RecordBody\n register={register}\n record={record}\n related={related}\n asOf={asOf}\n terms={terms}\n tab={tab}\n onTab={setTab}\n onOpenRecord={(id) => onNavigate({ name: \"record\", id })}\n onOpenTerm={openTerm}\n basePath={basePath}\n journey={journey}\n onJourneyChanged={refreshAll}\n onNavigate={onNavigate}\n edit={edit}\n />\n )}\n </div>\n );\n}\n\nfunction RecordBody({\n register,\n record,\n related,\n asOf,\n terms,\n tab,\n onTab,\n onOpenRecord,\n onOpenTerm,\n basePath,\n journey,\n onJourneyChanged,\n onNavigate,\n edit,\n}: {\n register: Collection;\n record: AnyRecord;\n related: RelatedSet;\n asOf: string;\n terms: ReturnType<typeof toGlossaryTerms>;\n tab: RecordTabId;\n onTab: (t: RecordTabId) => void;\n onOpenRecord: (id: string) => void;\n onOpenTerm: (id: string) => void;\n basePath?: string;\n journey: ReturnType<typeof buildJourney>;\n onJourneyChanged: () => void;\n onNavigate: (route: Route) => void;\n edit: EditState;\n}) {\n const page = buildRecordPage(register, record, related, { asOf });\n const activeTab = page.tabs.includes(tab) ? tab : \"overview\";\n const description = typeof record.Description === \"string\" ? record.Description : \"\";\n const bodyText = typeof record.body === \"string\" ? record.body : \"\";\n const hasErrors = Object.keys(edit.errors).length > 0;\n\n return (\n <>\n <div className=\"vos-head vos-record-head\">\n <div>\n <p className=\"vos-drawer-eyebrow\">{REGISTER_SINGULAR[register]}</p>\n <h1>{page.title}</h1>\n <div className=\"vos-pill-row\">\n {page.pills.map((p, i) => (\n <PillView key={i} pill={p} />\n ))}\n </div>\n </div>\n <div className=\"vos-spacer\" />\n <span className=\"vos-verbadge\">v{formatValue(record.version)}</span>\n {!edit.editing ? (\n <button\n type=\"button\"\n onClick={edit.onEdit}\n className=\"vos-btn vos-btn-ghost vos-btn-sm\"\n >\n Edit\n </button>\n ) : null}\n </div>\n\n <div className=\"vos-tabs\" role=\"tablist\" aria-label=\"Record sections\">\n {page.tabs.map((t) => (\n <button\n key={t}\n type=\"button\"\n role=\"tab\"\n aria-selected={t === activeTab}\n className={`vos-tab ${t === activeTab ? \"is-active\" : \"\"}`}\n onClick={() => onTab(t)}\n >\n {TAB_LABEL[t]}\n </button>\n ))}\n </div>\n\n {activeTab === \"overview\" ? (\n <div className=\"vos-record-cols\">\n <section className=\"vos-meter-grid\">\n {page.meters.map((m) => (\n <MeterView\n key={m.key}\n meter={m}\n assumption={m.hasWhy ? record : null}\n basePath={basePath}\n />\n ))}\n </section>\n {edit.editing ? (\n <section className=\"vos-record-editor\">\n <h3 className=\"vos-section-title\">Edit</h3>\n {edit.conflict ? (\n <ConflictBanner message={edit.conflict} onReload={edit.onReload} />\n ) : null}\n {edit.saveError ? (\n <p role=\"alert\" className=\"vos-error\">\n {edit.saveError}\n </p>\n ) : null}\n <EditFields\n register={register}\n draft={edit.draft}\n errors={edit.errors}\n onField={edit.onField}\n />\n <footer className=\"vos-drawer-footer\">\n <button\n type=\"button\"\n onClick={edit.onCancel}\n disabled={edit.saving}\n className=\"vos-btn vos-btn-ghost vos-btn-sm\"\n >\n Cancel\n </button>\n <button\n type=\"button\"\n onClick={edit.onSave}\n disabled={edit.saving || hasErrors}\n title={hasErrors ? \"Fix the highlighted field before saving\" : undefined}\n className=\"vos-btn vos-btn-sm\"\n >\n {edit.saving ? \"Saving…\" : \"Save\"}\n </button>\n </footer>\n </section>\n ) : (\n <>\n {description ? (\n <section className=\"vos-record-prose\">\n <h3 className=\"vos-section-title\">Description</h3>\n <p>\n <GlossaryText\n text={description}\n terms={terms}\n selfId={register === \"glossary\" ? record.id : undefined}\n onOpenTerm={onOpenTerm}\n />\n </p>\n </section>\n ) : null}\n {bodyText ? (\n <section className=\"vos-record-prose\">\n <h3 className=\"vos-section-title\">\n {register === \"readings\" ? \"Quote\" : \"Narrative\"}\n </h3>\n <EvidenceBody\n text={bodyText}\n partLabel={register === \"readings\" ? \"Finding\" : \"Part\"}\n />\n </section>\n ) : null}\n {register === \"readings\" ? (\n <section className=\"vos-record-prose vos-verdicts-section\">\n <h3 className=\"vos-section-title\">Per-belief verdicts</h3>\n <BeliefVerdicts\n reading={record}\n assumptions={related.assumptions ?? []}\n onOpenRecord={onOpenRecord}\n />\n </section>\n ) : null}\n {page.humanText.length ? (\n <section className=\"vos-record-prose\">\n <h3 className=\"vos-section-title\">\n From a human <span className=\"vos-hint\">— not computed</span>\n </h3>\n {page.humanText.map((h) => (\n <div key={h.key} className=\"vos-human-field\">\n <div className=\"vos-detail-k\">{h.label}</div>\n <p>\n <GlossaryText\n text={h.text}\n terms={terms}\n selfId={register === \"glossary\" ? record.id : undefined}\n onOpenTerm={onOpenTerm}\n />\n </p>\n </div>\n ))}\n </section>\n ) : null}\n </>\n )}\n </div>\n ) : null}\n\n {activeTab === \"evidence\" ? (\n <EvidenceTab\n register={register}\n record={record}\n related={related}\n onOpenRecord={onOpenRecord}\n basePath={basePath}\n />\n ) : null}\n\n {activeTab === \"connections\" ? (\n <div className=\"vos-panels\">\n {page.panels.map((panel) => (\n <PanelView key={panel.id} panel={panel} onOpenRecord={onOpenRecord} />\n ))}\n </div>\n ) : null}\n\n {activeTab === \"history\" ? (\n <section className=\"vos-detail-list\">\n <div className=\"vos-detail-row\">\n <span className=\"vos-detail-k\">Created</span>\n <span className=\"vos-detail-v\">{formatValue(record.createdAt)}</span>\n </div>\n <div className=\"vos-detail-row\">\n <span className=\"vos-detail-k\">Last updated</span>\n <span className=\"vos-detail-v\">{formatValue(record.updatedAt)}</span>\n </div>\n <div className=\"vos-detail-row\">\n <span className=\"vos-detail-k\">Version</span>\n <span className=\"vos-detail-v\">{formatValue(record.version)}</span>\n </div>\n <p className=\"vos-hint\">\n The full change trail lands here as the API exposes version history;\n this absorbs the retired provenance prose.\n </p>\n </section>\n ) : null}\n\n {page.hasJourney && journey ? (\n <section className=\"vos-journey-host\">\n <h3 className=\"vos-section-title\">Validation journey</h3>\n <BeliefJourney\n journey={journey}\n assumption={record}\n basePath={basePath}\n onNavigate={onNavigate}\n onChanged={onJourneyChanged}\n />\n </section>\n ) : page.hasJourney ? (\n <section className=\"vos-journey-host\">\n <h3 className=\"vos-section-title\">Validation journey</h3>\n <p className=\"vos-hint\">\n The per-belief journey (Framed → Planned → Tested → Known) mounts here\n — built by the workflow-first map (OPS-1289). This page is its host.\n </p>\n </section>\n ) : null}\n </>\n );\n}\n\nfunction PillView({ pill }: { pill: Pill }) {\n return <span className={PILL_CLASS[pill.tone]}>{pill.label}</span>;\n}\n\n/** The plain-language conflict prompt (spec user story 12) — a concurrent\n * edit surfaced gently, with a re-fetch path, never version jargon. Mirrors\n * the drawer's banner so the two edit surfaces read identically. */\nfunction ConflictBanner({\n message,\n onReload,\n}: {\n message: string;\n onReload: () => void;\n}) {\n return (\n <div role=\"alert\" className=\"vos-banner vos-banner-warn\">\n <div className=\"vos-banner-body\">\n <span>{message}</span>\n </div>\n <button type=\"button\" onClick={onReload}>\n Review the latest\n </button>\n </div>\n );\n}\n\n/** One leading-score meter — a bar (fraction fill), a signed value (centre\n * baseline fill) or a categorical pill, with an optional \"Why?\" reveal that\n * opens the understanding layer for Confidence. */\nfunction MeterView({\n meter,\n assumption,\n basePath,\n}: {\n meter: Meter;\n assumption: AnyRecord | null;\n basePath?: string;\n}) {\n const [why, setWhy] = useState(false);\n const textTone =\n meter.tone === \"crit\"\n ? \"vos-text-crit\"\n : meter.tone === \"warn\"\n ? \"vos-text-warn\"\n : \"\";\n\n return (\n <div className=\"vos-meter\">\n <div className=\"vos-meter-head\">\n <span className=\"vos-meter-label\">{meter.label}</span>\n {meter.hasWhy && assumption ? (\n <button\n type=\"button\"\n className=\"vos-why\"\n onClick={() => setWhy((w) => !w)}\n aria-expanded={why}\n >\n Why? {why ? \"▴\" : \"▾\"}\n </button>\n ) : null}\n </div>\n\n {meter.value === null ? (\n <div className=\"vos-meter-val vos-muted\">—</div>\n ) : meter.kind === \"pill\" ? (\n <span className={PILL_CLASS[meter.tone]}>{meter.value}</span>\n ) : meter.kind === \"signed\" ? (\n <>\n <div className={`vos-meter-val ${textTone}`}>\n {formatSigned(Number(meter.value))}\n </div>\n <span className=\"vos-track vos-signed\">\n <SignedFill value={Number(meter.value)} min={meter.min ?? -100} max={meter.max ?? 100} />\n </span>\n </>\n ) : (\n <>\n <div className={`vos-meter-val ${textTone}`}>\n {Math.round(Number(meter.value))}\n </div>\n <span className=\"vos-risk-bar\">\n <i\n className={\n meter.tone === \"crit\"\n ? \"vos-fill-crit\"\n : meter.tone === \"warn\"\n ? \"vos-fill-warn\"\n : \"vos-fill-good\"\n }\n style={{ width: `${Math.round(riskFraction(Number(meter.value)) * 100)}%` }}\n />\n </span>\n </>\n )}\n\n {why && assumption ? (\n <div className=\"vos-why-panel\">\n <UnderstandingPanel assumption={assumption} basePath={basePath} />\n </div>\n ) : null}\n </div>\n );\n}\n\n/** A signed meter fill: from the centre, right (green) for positive, left (red)\n * for negative — the direction the evidence pushed the number. */\nfunction SignedFill({ value, min, max }: { value: number; min: number; max: number }) {\n const span = Math.max(Math.abs(min), Math.abs(max)) || 1;\n const width = Math.round((Math.min(Math.abs(value), span) / span) * 50);\n const up = value >= 0;\n const style = up\n ? { left: \"50%\", width: `${width}%`, background: \"var(--vos-good)\" }\n : { right: \"50%\", width: `${width}%`, background: \"var(--vos-crit)\" };\n return width > 0 ? <i style={style} /> : null;\n}\n\n/** One backlink panel — a relation's rows with score chips, or \"none yet\". */\nfunction PanelView({\n panel,\n onOpenRecord,\n}: {\n panel: RelationPanel;\n onOpenRecord: (id: string) => void;\n}) {\n return (\n <section className=\"vos-panel\">\n <h3 className=\"vos-panel-head\">\n {panel.label}\n <span className=\"vos-group-n\">{panel.items.length}</span>\n </h3>\n {panel.items.length === 0 ? (\n <p className=\"vos-hint\">None yet.</p>\n ) : (\n <ul className=\"vos-backlinks\">\n {panel.items.map((item) => (\n <BacklinkRow key={item.id} item={item} onOpenRecord={onOpenRecord} />\n ))}\n </ul>\n )}\n </section>\n );\n}\n\nfunction BacklinkRow({\n item,\n onOpenRecord,\n}: {\n item: BacklinkItem;\n onOpenRecord: (id: string) => void;\n}) {\n return (\n <li>\n <button\n type=\"button\"\n className=\"vos-backlink\"\n onClick={() => onOpenRecord(item.id)}\n >\n <span className=\"vos-backlink-title\">{item.title}</span>\n <span className={`vos-chip ${PILL_CLASS[item.chip.tone]}`}>\n <span className=\"vos-chip-k\">{item.chip.label}</span>\n {item.chip.value}\n </span>\n </button>\n </li>\n );\n}\n\n/** The Evidence tab — for a belief, the understanding-layer \"Why?\"; for an\n * evidence plan, its bar lines with readings nested underneath. */\nfunction EvidenceTab({\n register,\n record,\n related,\n onOpenRecord,\n basePath,\n}: {\n register: Collection;\n record: AnyRecord;\n related: RelatedSet;\n onOpenRecord: (id: string) => void;\n basePath?: string;\n}) {\n if (register === \"assumptions\") {\n return (\n <section className=\"vos-why-panel\">\n <UnderstandingPanel assumption={record} basePath={basePath} />\n </section>\n );\n }\n\n // Experiments: bar lines + readings nested under this plan. Each bar line\n // is resolved against the loaded assumptions (OPS-1345) so it links the\n // belief's title, never its bare `assumptionId`.\n const bars = resolveBarLines(\n (record.barLines as BarLine[] | undefined) ?? [],\n related,\n );\n const mine = (related.readings ?? []).filter((r) => r.experimentId === record.id);\n const nested = nestReadingsByPlan(mine, [record]);\n return (\n <div className=\"vos-record-cols\">\n <section>\n <h3 className=\"vos-section-title\">Bar lines</h3>\n {bars.length === 0 ? (\n <p className=\"vos-hint\">No pre-registered bars.</p>\n ) : (\n <ul className=\"vos-bars\">\n {bars.map((b, i) => (\n <li key={i} className=\"vos-bar-line\">\n <span className=\"vos-bar-if\">{b.rightIf || \"—\"}</span>\n {b.assumption ? (\n <button\n type=\"button\"\n className=\"vos-inline-link\"\n onClick={() => onOpenRecord(b.assumption!.id)}\n >\n {b.assumption.title}\n </button>\n ) : null}\n <span\n className={\n b.barVerdict\n ? \"vos-pill vos-pill-good\"\n : \"vos-pill vos-pill-neutral\"\n }\n >\n {b.barVerdict ?? \"open\"}\n </span>\n </li>\n ))}\n </ul>\n )}\n </section>\n <section>\n <h3 className=\"vos-section-title\">Readings</h3>\n {nested.length === 0 ? (\n <p className=\"vos-hint\">No readings logged yet.</p>\n ) : (\n <ul className=\"vos-backlinks\">\n {nested[0]!.readings.map((r) => (\n <li key={r.id}>\n <button\n type=\"button\"\n className=\"vos-backlink\"\n onClick={() => onOpenRecord(r.id)}\n >\n <span className=\"vos-backlink-title\">{formatValue(r.Title)}</span>\n {/* A reading grades per belief now (OPS-1305) — the verdict is\n no longer a row scalar; open the reading for its verdicts.\n The chip shows how many beliefs it scored. */}\n <span className=\"vos-chip vos-pill vos-pill-neutral\">\n {readingBeliefs(r).length} belief\n {readingBeliefs(r).length === 1 ? \"\" : \"s\"}\n </span>\n </button>\n </li>\n ))}\n </ul>\n )}\n </section>\n </div>\n );\n}","/**\n * The record drawer's generic field list (OPS-1345) — the pure view-model\n * behind the \"everything else\" rows a record carries beyond its meters/\n * human-text/panels. `RecordDrawer` iterates a record's own keys (skipping\n * provenance/meta), and this module decides how each one reads: a relation\n * id/id-list (`Depends on`, `Readings`, `Assumption`…) resolves to the linked\n * record's title, `Owner`/`Agreed by` (stored as dashboard-user objects,\n * `{id, name}` — `connectors/nosql-schema.md`) reads as name(s) only, and\n * `barLines` (the embedded per-belief pre-registration on an experiment)\n * reads as structured rows with a linked assumption title — never the raw\n * stored JSON or an internal id, per this project's \"explain visually, hide\n * complexity\" bias. Everything else still formats through `columns.ts`.\n * DOM-free and unit-tested at this seam; `record-drawer.tsx` renders what it\n * returns.\n */\nimport type { AnyRecord, BarLine, Collection } from \"@validation-os/core\";\nimport { fieldLabel, formatValue, primaryLabel } from \"./columns.js\";\nimport { isArchivedExperiment } from \"./derived-views.js\";\nimport type { RelatedSet } from \"./record-view.js\";\n\nexport type { RelatedSet };\n\n/** Provider-owned/meta fields — never a content row. */\nexport const META_FIELDS = new Set([\n \"id\",\n \"version\",\n \"createdAt\",\n \"updatedAt\",\n \"derived\",\n]);\n\n/**\n * Fields dropped from the generic list because a richer row already carries\n * the same information: `barLineAssumptionIds` is a convenience projection of\n * `barLines[].assumptionId` (`connectors/nosql-schema.md`), and the `bar-lines`\n * row below already links each assumption.\n */\nconst SUPPRESSED_FIELDS = new Set([\n \"barLineAssumptionIds\",\n // A reading's `beliefs[]` is rendered as the richer per-belief verdict list\n // (OPS-1305), never as raw JSON in the generic row list.\n \"beliefs\",\n // `body` (a reading's quote / an experiment's narrative) renders as Markdown\n // in its own block, not as a raw-text row.\n \"body\",\n]);\n\n/** Which register a relation id/id-list field points at (mirrors the `from`\n * side of `RELATIONS` in `@validation-os/core`, plus the inverse single-id\n * fields `RELATIONS` only states from the other end). */\nconst RELATION_TARGET: Partial<Record<string, Collection>> = {\n dependsOnIds: \"assumptions\",\n enablesIds: \"assumptions\",\n contradictsIds: \"assumptions\",\n readingIds: \"readings\",\n assumptionId: \"assumptions\",\n assumptionIds: \"assumptions\",\n experimentId: \"experiments\",\n basedOnIds: \"assumptions\",\n resolvesIds: \"assumptions\",\n};\n\n/** Dashboard-user reference fields — an array of `{id, name}`, never a\n * navigable record (there is no `people` register, `OPS-1305`). */\nconst OWNER_FIELDS = new Set([\"Owner\", \"Agreed by\"]);\n\nexport type DetailRowKind = \"text\" | \"relation\" | \"owner\" | \"bar-lines\";\n\n/** One resolved relation target — a title to show, an id to navigate to. */\nexport interface DetailRelationItem {\n id: string;\n register: Collection;\n title: string;\n}\n\n/** One bar line, human-readable: the belief it tests resolved to a title. */\nexport interface ResolvedBarLine {\n rightIf: string;\n wrongIf: string | null;\n plannedRung: string;\n barVerdict: string | null;\n assumption: DetailRelationItem | null;\n}\n\nexport interface DetailRow {\n key: string;\n label: string;\n kind: DetailRowKind;\n /** `kind: \"text\"` — the formatted display string. */\n text?: string;\n /** `kind: \"relation\"` — the resolved link targets, in stored order. */\n items?: DetailRelationItem[];\n /** `kind: \"owner\"` — the dashboard-user name(s), never the id/object. */\n names?: string[];\n /** `kind: \"bar-lines\"` — the embedded pre-registration, resolved. */\n bars?: ResolvedBarLine[];\n}\n\nfunction relatedList(related: RelatedSet, register: Collection): AnyRecord[] {\n return related[register] ?? [];\n}\n\n/** Resolve one id against its target register's loaded rows. Falls back to\n * the bare id only when the record isn't in the loaded set (defensive — the\n * data has no dangling refs; this keeps a stale/partial fetch from crashing\n * the row rather than silently mis-linking). */\nfunction resolveItem(\n related: RelatedSet,\n register: Collection,\n id: string,\n): DetailRelationItem {\n const hit = relatedList(related, register).find((r) => r.id === id);\n return { id, register, title: hit ? primaryLabel(hit) : id };\n}\n\n/** The string ids a relation field carries — a list field or a single\n * (possibly nullable) id field, normalised the same way. */\nfunction idsOf(value: unknown): string[] {\n if (Array.isArray(value)) {\n return value.filter((v): v is string => typeof v === \"string\");\n }\n return typeof value === \"string\" && value ? [value] : [];\n}\n\n/** The dashboard-user name(s) off an `Owner`/`Agreed by` value — the stored\n * shape is `{id, name}[]`; a bare string is tolerated as a fallback. */\nexport function ownerNames(value: unknown): string[] {\n if (!Array.isArray(value)) return [];\n return value.map((v) => {\n if (v && typeof v === \"object\") {\n const name = (v as { name?: unknown }).name;\n if (typeof name === \"string\" && name) return name;\n const id = (v as { id?: unknown }).id;\n return typeof id === \"string\" ? id : \"—\";\n }\n return typeof v === \"string\" ? v : \"—\";\n });\n}\n\n/** Bar lines resolved against the loaded assumptions — shared by the drawer's\n * generic list and the record page's Evidence tab so the two never drift. */\nexport function resolveBarLines(\n bars: BarLine[],\n related: RelatedSet,\n): ResolvedBarLine[] {\n return bars.map((b) => ({\n rightIf: b.rightIf ?? \"\",\n wrongIf: b.wrongIf ?? null,\n plannedRung: b.plannedRung ?? \"\",\n barVerdict: b.barVerdict ?? null,\n assumption: b.assumptionId\n ? resolveItem(related, \"assumptions\", b.assumptionId)\n : null,\n }));\n}\n\n/**\n * The record's own fields, beyond its meta/derived tuple, as rows a drawer\n * can render directly — relation fields resolved to a title + navigate\n * target, `Owner`/`Agreed by` to plain names, `barLines` to structured rows.\n * Everything else still formats through `formatValue` (spec stories 1–3).\n */\nexport function detailRows(\n register: Collection,\n record: AnyRecord,\n related: RelatedSet = {},\n): DetailRow[] {\n const keys = Object.keys(record).filter(\n (k) => !META_FIELDS.has(k) && !SUPPRESSED_FIELDS.has(k),\n );\n\n return keys.map((key) => {\n const value = record[key];\n const label = fieldLabel(key);\n\n const target = RELATION_TARGET[key];\n if (target) {\n let items = idsOf(value).map((id) => resolveItem(related, target, id));\n // Archived plans never surface as a relation (OPS-1305): drop any\n // experiment target that resolves to an Archived record.\n if (target === \"experiments\") {\n const archived = new Set(\n (related.experiments ?? [])\n .filter((e) => isArchivedExperiment(e))\n .map((e) => e.id),\n );\n items = items.filter((it) => !archived.has(it.id));\n }\n return { key, label, kind: \"relation\", items };\n }\n\n if (OWNER_FIELDS.has(key)) {\n return { key, label, kind: \"owner\", names: ownerNames(value) };\n }\n\n if (key === \"barLines\" && Array.isArray(value)) {\n return {\n key,\n label,\n kind: \"bar-lines\",\n bars: resolveBarLines(value as BarLine[], related),\n };\n }\n\n return { key, label, kind: \"text\", text: formatValue(value) };\n });\n}\n","import type { Collection } from \"@validation-os/core\";\nimport { editableFields, type Draft, type FieldEditor } from \"./edit.js\";\n\n/**\n * The editable-field stack for a register — the inputs an edit form is made of,\n * driven by `edit.ts`'s schema (which fields are editable, and as what control).\n *\n * Factored out of the record drawer so the drawer and the journey's \"edit the\n * bet\" step-in (OPS-1330) render the same controls from the same schema: two\n * surfaces editing one register should never drift into two different forms.\n * Derived numbers are never here — they are computed on write (OPS-1251).\n */\nexport function EditFields({\n register,\n draft,\n errors,\n onField,\n}: {\n register: Collection;\n draft: Draft;\n /** Per-field validation messages (keyed by field), e.g. Impact out of\n * 0–100 — `edit.ts`'s `draftErrors`. Absent/empty = every field is valid. */\n errors?: Record<string, string>;\n onField: (key: string, value: string) => void;\n}) {\n return (\n <div className=\"vos-field-stack\">\n {editableFields(register).map((field) => (\n <FieldInput\n key={field.key}\n field={field}\n value={draft[field.key]}\n error={errors?.[field.key]}\n onChange={(v) => onField(field.key, v)}\n />\n ))}\n </div>\n );\n}\n\n/** One editable field, as the control its `kind` calls for. */\nexport function FieldInput({\n field,\n value,\n error,\n onChange,\n}: {\n field: FieldEditor;\n value: string | undefined;\n /** A validation message shown under the control, e.g. \"Impact must be at\n * most 100.\" — never blocks typing, only the Save the caller gates on it. */\n error?: string;\n onChange: (value: string) => void;\n}) {\n // Field keys can contain spaces (\"Scoring justification\"); slugify for a\n // valid DOM id.\n const id = `field-${field.key.replace(/\\s+/g, \"-\")}`;\n return (\n <div className=\"vos-field\">\n <label htmlFor={id}>{field.label}</label>\n {field.kind === \"textarea\" ? (\n <textarea\n id={id}\n value={String(value ?? \"\")}\n onChange={(e) => onChange(e.target.value)}\n rows={3}\n className=\"vos-input\"\n aria-invalid={error ? true : undefined}\n />\n ) : field.kind === \"select\" ? (\n <select\n id={id}\n value={String(value ?? \"\")}\n onChange={(e) => onChange(e.target.value)}\n className=\"vos-input\"\n >\n {field.nullable ? <option value=\"\">—</option> : null}\n {field.options?.map((opt) => (\n <option key={opt} value={opt}>\n {opt}\n </option>\n ))}\n </select>\n ) : (\n <input\n id={id}\n type={field.kind === \"number\" ? \"number\" : \"text\"}\n min={field.kind === \"number\" ? field.min : undefined}\n max={field.kind === \"number\" ? field.max : undefined}\n value={String(value ?? \"\")}\n onChange={(e) => onChange(e.target.value)}\n className=\"vos-input\"\n aria-invalid={error ? true : undefined}\n />\n )}\n {error ? (\n <p role=\"alert\" className=\"vos-field-error\">\n {error}\n </p>\n ) : null}\n </div>\n );\n}\n","/**\n * The per-belief journey view-model (OPS-1329) — pure, no React, no I/O, so the\n * whole \"story of one belief travelling the loop\" mapping is unit-tested at this\n * seam (like `understanding.ts` / `pipeline.ts`). It composes, for one belief:\n *\n * - the **rail** — its stage + four meters on the same spine the pipeline uses\n * (the single-belief `deriveBeliefStage`, so board and rail agree);\n * - the **story** — its life ordered into dated events (`assembleJourney`),\n * each given front-door copy here (the assembler stays label-free);\n * - the **next-move card** — the same OPS-1292 ranking the front door reads,\n * filtered to this belief;\n * - the **cycles** (OPS-1347) — the same history regrouped into rounds\n * (`cycles.ts`): one per Experiment run against this belief, plus one\n * closing bucket for bare/direct evidence. Where the story is a flat dated\n * log and `understanding.ts` ranks by how hard each mover pushes, this is\n * the round-by-round shape the operator asked for — \"show each cycle\".\n *\n * The `.tsx` rail + story UI (OPS-1330) mounts thinly over this. Every number is\n * derived through `@validation-os/core`, computed fresh on read, out of the\n * OPS-1251 on-write recompute.\n */\nimport {\n assumptionCompleteness,\n readingBeliefInputs,\n type AnyRecord,\n} from \"@validation-os/core\";\nimport {\n assembleJourney,\n beliefTestMeters,\n deriveBeliefStage,\n emptyTestMeter,\n rankNextMoves,\n type BeliefStage,\n type JourneyEvent,\n type JourneyEventKind,\n type NextMove,\n} from \"@validation-os/core/derivation\";\nimport { resolvedKind, toStageExperimentInput } from \"./pipeline.js\";\nimport { toNextMoveInput, type NextMoveRecords } from \"./next-move.js\";\nimport type { Tone } from \"./primitives.js\";\nimport { liveExperiments, testsAssumption } from \"./derived-views.js\";\nimport { buildCycles, type CycleView } from \"./cycles.js\";\n\n/** A journey event with its front-door copy attached. */\nexport interface JourneyEventView extends JourneyEvent {\n /** Plain-language label the story renders. */\n label: string;\n}\n\nexport interface JourneyView {\n id: string;\n /** The belief statement — the drill-in's headline. */\n statement: string;\n /** The rail: where the belief sits at rest, with its four meters. */\n stage: BeliefStage;\n /** The story: the belief's life, oldest first, `now` last. */\n events: JourneyEventView[];\n /** The loop's rounds, oldest first (OPS-1347) — the same history the story\n * tells, regrouped by Experiment run instead of by dated event. */\n cycles: CycleView[];\n /** The ranked next move for this belief; null once it is resolved. */\n nextMove: NextMove | null;\n /** Killed (Invalidated) / moot / null — the drill-in's terminal state. */\n resolved: \"killed\" | \"moot\" | null;\n}\n\nfunction str(v: unknown): string {\n return typeof v === \"string\" ? v : \"\";\n}\n\n/** The front-door copy for one event kind (the assembler stays label-free). */\nfunction labelFor(event: JourneyEvent): string {\n switch (event.kind) {\n case \"bet\":\n return \"Bet written\";\n case \"score\":\n return \"Impact scored\";\n case \"experiment\":\n return \"Test designed\";\n case \"reading\":\n return event.result ? `Reading — ${event.result}` : \"Reading\";\n case \"confidence-cross\":\n return \"Confidence crossed into the kill zone\";\n case \"now\":\n return \"Now\";\n }\n}\n\n/** The dot's tone against an event — how that moment read for the belief. */\nexport function eventTone(event: JourneyEvent): Tone {\n switch (event.kind) {\n case \"reading\":\n if (event.result === \"Validated\") return \"good\";\n if (event.result === \"Invalidated\") return \"crit\";\n return \"neutral\"; // Inconclusive — it landed, but moved nothing\n case \"confidence-cross\":\n return \"crit\";\n case \"now\":\n return \"accent\";\n default:\n return \"neutral\";\n }\n}\n\n/**\n * The step-in an event offers (OPS-1294's human set: assumption edit · score\n * impact · write decision), or null for an event there is nothing to act on.\n *\n * The story is where step-in lives — the rail is pure status (OPS-1297). Two\n * acts are deliberately absent: designing a test (no experiment-design form on\n * this surface) and recording a reading (its form lives with the evidence, not\n * the narrative). An unscored belief has no `score` event at all, so its\n * score-impact act rides the next-move card instead.\n */\nexport function eventStepIn(\n kind: JourneyEventKind,\n): { form: StoryStepIn; cta: string } | null {\n switch (kind) {\n case \"bet\":\n return { form: \"edit-belief\", cta: \"Edit the bet\" };\n case \"score\":\n return { form: \"score-impact\", cta: \"Re-score\" };\n case \"confidence-cross\":\n return { form: \"write-decision\", cta: \"Kill or re-test\" };\n default:\n return null;\n }\n}\n\n/** The forms the story can open — the OPS-1294 set, minus experiment design. */\nexport type StoryStepIn = \"edit-belief\" | \"score-impact\" | \"write-decision\";\n\n/**\n * Build one belief's journey from the four registers. Returns null when the\n * belief id isn't in the assumptions register. `now` is passed in (an ISO date)\n * so the view-model stays pure — the surface supplies it.\n */\nexport function buildJourney(\n assumptionId: string,\n records: NextMoveRecords,\n now: string,\n): JourneyView | null {\n const belief = records.assumptions.find((a) => a.id === assumptionId);\n if (!belief) return null;\n\n const derived =\n belief.derived && typeof belief.derived === \"object\"\n ? (belief.derived as Record<string, unknown>)\n : {};\n const confidence =\n typeof derived.confidence === \"number\" ? derived.confidence : 0;\n\n // The rail's test meters read only LIVE plans (OPS-1305): an archived plan is\n // no longer a test in flight, so a belief whose only plan is archived reads as\n // Planned (design a test), never Tested — the \"evidence ≠ tested\" rule.\n const live = liveExperiments(records.experiments);\n const test =\n beliefTestMeters(live.map(toStageExperimentInput)).get(assumptionId) ??\n emptyTestMeter();\n const framed = assumptionCompleteness(belief as Record<string, unknown>);\n const stage = deriveBeliefStage({ framed, confidence, test });\n\n // DEV-5890: thread the linked assumption's Question Type into each belief\n // input so Strength reads the right sub-ladder.\n const assumptionsById = new Map<string, AnyRecord>(\n records.assumptions.map((a) => [String(a.id), a]),\n );\n\n const myReadingInputs = records.readings\n .flatMap((r) => readingBeliefInputs(r, assumptionsById))\n .filter((i) => i.assumptionId === assumptionId);\n const myExperiments = live\n .filter((e) => testsAssumption(e, assumptionId))\n .map((e) => ({ id: e.id, date: str(e.Date) || str(e.createdAt) || null }));\n\n const events = assembleJourney({\n belief: {\n createdAt: str(belief.createdAt) || null,\n impactScored: belief.Impact != null,\n },\n readings: myReadingInputs,\n experiments: myExperiments,\n now,\n }).map((event) => ({ ...event, label: labelFor(event) }));\n\n const nextMove =\n rankNextMoves(toNextMoveInput(records)).find(\n (m) => m.assumptionId === assumptionId,\n ) ?? null;\n\n const cycles = buildCycles(\n assumptionId,\n records.readings,\n records.experiments,\n assumptionsById,\n );\n\n return {\n id: assumptionId,\n statement: str(belief.Title),\n stage,\n events,\n cycles,\n nextMove,\n resolved: resolvedKind(belief),\n };\n}\n","/**\n * The per-belief cycles view-model (OPS-1347) — the validation loop's rounds,\n * not just the belief's flat dated event log (`journey.ts`) or the\n * strongest-push-first attribution list (`understanding.ts`). Grounded\n * directly in the registry model (`registry-schema.md`):\n *\n * - a **cycle** is one round of the loop — an Experiment designed against\n * this belief, the (dated) Readings it produced, and the per-belief\n * bar-line verdict it settles at closure. That is literally\n * \"experiment → readings → re-score\", the round the operator asked to\n * see, and it is the only unit the data model pre-registers as a trial:\n * the bar line's `We're right if` / `We're wrong if` are written *before*\n * any Reading exists, so its verdict is a real round boundary, not one we\n * invent;\n * - readings with **no** Experiment (bare/found — a Market-rung commitment\n * or desk research dropped in directly) carry no pre-registered bar, so\n * they are not a \"round\" in that strict sense. They still move the\n * number, so they collect into one closing, kind-`\"direct\"` entry rather\n * than disappearing from the picture.\n *\n * Ordered chronologically (oldest first) — the point of this view is watching\n * the belief move round by round, which `understanding.ts`'s magnitude-first\n * ranking deliberately does not show.\n *\n * No new maths: each round's push on Confidence is read off\n * `confidenceAttribution`'s per-experiment mover — the same decomposition\n * `understanding.ts` shows, just regrouped by time instead of by size, so a\n * cycle's push and the drawer's push always agree. Computed fresh on read,\n * out of the OPS-1251 on-write recompute.\n */\nimport {\n readingBeliefInputs,\n type AnyRecord,\n type BarLine,\n type Result,\n} from \"@validation-os/core\";\nimport { confidenceAttribution } from \"@validation-os/core/derivation\";\nimport {\n isArchivedExperiment,\n liveExperiments,\n readingBeliefFor,\n readingGrades,\n str,\n testsAssumption,\n} from \"./derived-views.js\";\n\n/** The round's key: the experiment id, or `\"direct\"` for the bare-reading bucket. */\nexport const DIRECT_CYCLE_KEY = \"direct\";\n\n/** One reading's place inside a round, reduced to what the timeline draws. */\nexport interface CycleReadingView {\n id: string;\n date: string | null;\n result: Result | null;\n}\n\n/** One round of the loop. */\nexport interface CycleView {\n key: string;\n kind: \"experiment\" | \"direct\";\n /** The experiment's title; null for the direct bucket. */\n title: string | null;\n /** The experiment's lifecycle status; null for the direct bucket. */\n status: string | null;\n /** The round's anchor date: the experiment's own `Date`, or (falling back)\n * its earliest reading's date. Null only when neither is known. */\n date: string | null;\n /** This belief's bar-line verdict, once judged; null pre-closure and always\n * null for the direct bucket (it carries no bar line). */\n barVerdict: Result | null;\n /** The round's readings, oldest first. */\n readings: CycleReadingView[];\n /** Signed push on Confidence this round contributed (sums, across every\n * round, to the belief's Confidence). */\n contribution: number;\n /** |contribution| — how hard this round moved the number. */\n magnitude: number;\n}\n\nfunction readingDate(r: AnyRecord): string | null {\n return str(r.Date);\n}\n\n/** One reading reduced for the timeline — its verdict is this belief's own\n * belief-score Result (the row no longer carries a scalar Result). */\nfunction toCycleReading(r: AnyRecord, assumptionId: string): CycleReadingView {\n return {\n id: r.id,\n date: readingDate(r),\n result: readingBeliefFor(r, assumptionId)?.Result ?? null,\n };\n}\n\nfunction sortByDate(readings: CycleReadingView[]): CycleReadingView[] {\n return [...readings].sort((a, b) => {\n if (a.date === b.date) return 0;\n if (a.date === null) return 1; // undated sinks to the end of its round\n if (b.date === null) return -1;\n return a.date < b.date ? -1 : 1;\n });\n}\n\nfunction barVerdictFor(exp: AnyRecord, assumptionId: string): Result | null {\n const bars = (exp.barLines as BarLine[] | undefined) ?? [];\n const line = bars.find((b) => b.assumptionId === assumptionId);\n return (line?.barVerdict as Result | null | undefined) ?? null;\n}\n\n/**\n * Build one belief's cycles from its readings and the Experiments register.\n * Both arrays are the raw records (Title-cased fields) — the same shape\n * `understanding.ts`/`journey.ts` take — so a caller loading the registers\n * once can hand them straight through.\n */\nexport function buildCycles(\n assumptionId: string,\n readings: AnyRecord[],\n experiments: AnyRecord[],\n assumptionsById?: ReadonlyMap<string, AnyRecord>,\n): CycleView[] {\n const mine = readings.filter((r) => readingGrades(r, assumptionId));\n // DEV-5890: thread the assumption's Question Type into each input via the\n // optional assumptionsById map; defaults to Existence when absent.\n const inputs = readings\n .flatMap((r) => readingBeliefInputs(r, assumptionsById))\n .filter((i) => i.assumptionId === assumptionId);\n const { movers } = confidenceAttribution(inputs);\n const moverByKey = new Map(movers.map((m) => [m.key, m]));\n\n const byExperiment = new Map<string, AnyRecord[]>();\n const direct: AnyRecord[] = [];\n for (const r of mine) {\n const expId = str(r.experimentId);\n if (expId) {\n const bucket = byExperiment.get(expId) ?? [];\n bucket.push(r);\n byExperiment.set(expId, bucket);\n } else {\n direct.push(r);\n }\n }\n\n const experimentsById = new Map(experiments.map((e) => [e.id, e]));\n // Every LIVE experiment testing this belief (a bar line naming it) plus any\n // experiment a reading points at that isn't linked via bar lines — the same\n // union `understanding.ts` builds, so no round is silently dropped. Archived\n // plans never form a round (OPS-1305); an absent (missing) plan still does.\n const experimentIds = new Set<string>([\n ...liveExperiments(experiments)\n .filter((e) => testsAssumption(e, assumptionId))\n .map((e) => e.id),\n ...[...byExperiment.keys()].filter((id) => {\n const e = experimentsById.get(id);\n return !e || !isArchivedExperiment(e);\n }),\n ]);\n\n const cycles: CycleView[] = [...experimentIds].map((id) => {\n const exp = experimentsById.get(id);\n const readingViews = sortByDate(\n (byExperiment.get(id) ?? []).map((r) => toCycleReading(r, assumptionId)),\n );\n const mover = moverByKey.get(id);\n const date = (exp ? str(exp.Date) : null) ?? readingViews[0]?.date ?? null;\n return {\n key: id,\n kind: \"experiment\",\n title: exp ? str(exp.Title) : null,\n status: exp ? str(exp.Status) : null,\n date,\n barVerdict: exp ? barVerdictFor(exp, assumptionId) : null,\n readings: readingViews,\n contribution: mover?.contribution ?? 0,\n magnitude: mover?.magnitude ?? 0,\n };\n });\n\n if (direct.length > 0) {\n const readingViews = sortByDate(\n direct.map((r) => toCycleReading(r, assumptionId)),\n );\n const mover = moverByKey.get(DIRECT_CYCLE_KEY);\n cycles.push({\n key: DIRECT_CYCLE_KEY,\n kind: \"direct\",\n title: null,\n status: null,\n date: readingViews[0]?.date ?? null,\n barVerdict: null,\n readings: readingViews,\n contribution: mover?.contribution ?? 0,\n magnitude: mover?.magnitude ?? 0,\n });\n }\n\n // Chronological, oldest first — undated rounds sink to the end rather than\n // jumping the queue, since their place in time is genuinely unknown.\n cycles.sort((a, b) => {\n if (a.date === b.date) return a.key.localeCompare(b.key);\n if (a.date === null) return 1;\n if (b.date === null) return -1;\n return a.date < b.date ? -1 : 1;\n });\n\n return cycles;\n}\n","import { useState } from \"react\";\nimport type { AnyRecord, Result } from \"@validation-os/core\";\nimport type { BeliefStage, NextMove, StageKey } from \"@validation-os/core/derivation\";\nimport { journeyColdState } from \"./cold-start.js\";\nimport type { CycleView } from \"./cycles.js\";\nimport {\n eventStepIn,\n eventTone,\n type JourneyEventView,\n type JourneyView,\n type StoryStepIn,\n} from \"./journey.js\";\nimport { movePresentation } from \"./next-move.js\";\nimport { formatSigned, type Tone } from \"./primitives.js\";\nimport type { Route } from \"./route.js\";\nimport { stageMeters, type StageMeterView } from \"./stage-meters.js\";\nimport {\n EditBeliefForm,\n ScoreImpactForm,\n WriteDecisionForm,\n} from \"./step-in-forms.js\";\nimport { UnderstandingPanel } from \"./understanding-panel.js\";\n\n/**\n * The per-belief journey — the drill-in altitude (design OPS-1297, build\n * OPS-1330), mounted on the record page. An A+B hybrid:\n *\n * - at rest, a compact **read-only stage rail** — the same Framed → Planned →\n * Tested → Known spine the pipeline board draws, zoomed to one belief. The\n * rail is pure status: nothing to act on there;\n * - it **expands into the chronological story** through the record page's\n * existing \"Why?\" reveal idiom — the dated event log (bet → score →\n * experiment → readings → confidence-cross → now), the same history\n * regrouped into **rounds** (OPS-1347 — one card per Experiment run, plus\n * any bare/direct evidence, oldest first), and ending in the ranked\n * next-move card (OPS-1292).\n *\n * **Step-in is story-only** (OPS-1297): the next-move card and the per-event\n * edits carry the OPS-1294 human set (edit the bet · score impact · write\n * decision), and manual override lives at the foot of the story. There is\n * deliberately no experiment-design form here.\n *\n * The narrative is the *loop* story — why the number is what it is. It is not\n * the raw record history: that audit trail belongs to the record page itself\n * (OPS-1282) and this must not retell it. Every number arrives derived through\n * `buildJourney`; nothing is computed here.\n */\nexport interface BeliefJourneyProps {\n /** This belief's journey, already derived (`buildJourney`). */\n journey: JourneyView;\n /** The belief record itself — what the step-in forms write against. */\n assumption: AnyRecord;\n basePath?: string;\n /** Navigate the shell — used by the story's manual override. */\n onNavigate: (route: Route) => void;\n /** Re-read the registers after a step-in writes. */\n onChanged: () => void;\n}\n\n/** Where the belief sits, in plain language — the rail's one-line reading. */\nconst STAGE_SENTENCE: Record<StageKey, string> = {\n framed: \"Still being framed — the bet isn't complete yet.\",\n planned: \"Framed, and waiting on a test to move it.\",\n tested: \"Under test — evidence is landing.\",\n known: \"Every pre-registered bar has settled.\",\n};\n\n/** The event dot's tone → its class. */\nconst DOT_CLASS: Record<Tone, string> = {\n good: \"vos-jny-dot-good\",\n warn: \"vos-jny-dot-warn\",\n crit: \"vos-jny-dot-crit\",\n accent: \"vos-jny-dot-accent\",\n neutral: \"vos-jny-dot-neutral\",\n};\n\nexport function BeliefJourney({\n journey,\n assumption,\n basePath,\n onNavigate,\n onChanged,\n}: BeliefJourneyProps) {\n const [open, setOpen] = useState(false);\n const [stepIn, setStepIn] = useState<StoryStepIn | null>(null);\n\n const closeForm = () => setStepIn(null);\n const afterWrite = () => {\n setStepIn(null);\n onChanged(); // the API recomputed on write — pull the new numbers back in\n };\n\n const { stage, resolved } = journey;\n const coldState = journeyColdState(journey);\n\n return (\n <section className=\"vos-jny vos-card\">\n <div className=\"vos-jny-head\">\n <div>\n <span className=\"vos-jny-eyebrow\">The journey</span>\n <p className=\"vos-jny-at\">\n {resolved\n ? resolved === \"killed\"\n ? \"Killed — the evidence went against it.\"\n : \"Moot — a decision retired the question.\"\n : STAGE_SENTENCE[stage.stage]}\n </p>\n </div>\n {resolved ? (\n <span\n className={`vos-pill ${resolved === \"killed\" ? \"vos-pill-crit\" : \"vos-pill-neutral\"}`}\n >\n {resolved === \"killed\" ? \"Killed\" : \"Moot\"}\n </span>\n ) : stage.killZone ? (\n <span className=\"vos-pill vos-pill-crit\">Kill lane</span>\n ) : null}\n </div>\n\n <StageRail stage={stage} />\n\n <button\n type=\"button\"\n className=\"vos-why vos-jny-why\"\n onClick={() => setOpen((o) => !o)}\n aria-expanded={open}\n >\n {open ? \"Hide the story ▴\" : \"How did it get here? ▾\"}\n </button>\n\n {open ? (\n <div className=\"vos-why-panel vos-jny-story\">\n <section>\n <div className=\"vos-why-section-title\">The story so far</div>\n {coldState.cold ? (\n <JourneyColdCard body={coldState.body} eyebrow={coldState.eyebrow} />\n ) : (\n <ol className=\"vos-jny-events\">\n {journey.events.map((event, i) => (\n <EventRow\n key={`${event.kind}-${event.refId ?? i}`}\n event={event}\n onStepIn={setStepIn}\n />\n ))}\n </ol>\n )}\n </section>\n\n {journey.cycles.length > 0 ? (\n <section>\n <div className=\"vos-why-section-title\">Round by round</div>\n <CycleTimeline cycles={journey.cycles} />\n </section>\n ) : null}\n\n {/* OPS-1276's attribution + trajectory, reused whole — the story says\n what happened; this says what it did to the number. */}\n <section>\n <div className=\"vos-why-section-title\">What moved the number</div>\n <UnderstandingPanel assumption={assumption} basePath={basePath} />\n </section>\n\n <NextMoveCard\n move={journey.nextMove}\n resolved={resolved}\n onAct={setStepIn}\n />\n\n <button\n type=\"button\"\n className=\"vos-override\"\n onClick={() =>\n onNavigate({ name: \"records\", register: \"assumptions\" })\n }\n >\n Act on a different belief →\n </button>\n </div>\n ) : null}\n\n {stepIn === \"edit-belief\" ? (\n <EditBeliefForm\n assumption={assumption}\n basePath={basePath}\n onDone={afterWrite}\n onCancel={closeForm}\n />\n ) : null}\n {stepIn === \"score-impact\" ? (\n <ScoreImpactForm\n assumption={assumption}\n basePath={basePath}\n onDone={afterWrite}\n onCancel={closeForm}\n />\n ) : null}\n {stepIn === \"write-decision\" ? (\n <WriteDecisionForm\n assumption={assumption}\n basePath={basePath}\n kill={stage.killZone}\n onDone={afterWrite}\n onCancel={closeForm}\n />\n ) : null}\n </section>\n );\n}\n\n/** The order the spine runs in — the rail's stops, and how far along we are. */\nconst SPINE: StageKey[] = [\"framed\", \"planned\", \"tested\", \"known\"];\n\n/**\n * The resting rail: the four-stage spine with this belief's meters. Read-only —\n * every act lives in the story (OPS-1297), so nothing here is clickable.\n */\nfunction StageRail({ stage }: { stage: BeliefStage }) {\n const meters = stageMeters(stage);\n const at = SPINE.indexOf(stage.stage);\n return (\n <div\n className=\"vos-jny-rail\"\n role=\"img\"\n aria-label={`Stage ${at + 1} of 4 — ${STAGE_SENTENCE[stage.stage]}`}\n >\n {meters.map((meter, i) => (\n <RailStop\n key={meter.key}\n meter={meter}\n at={i === at}\n done={i < at}\n last={i === meters.length - 1}\n />\n ))}\n </div>\n );\n}\n\nfunction RailStop({\n meter,\n at,\n done,\n last,\n}: {\n meter: StageMeterView;\n at: boolean;\n done: boolean;\n last: boolean;\n}) {\n return (\n <>\n <div\n className={`vos-jny-stop${at ? \" vos-jny-stop-at\" : \"\"}${done ? \" vos-jny-stop-done\" : \"\"}`}\n >\n <div className=\"vos-jny-stopname\">\n <span className=\"vos-jny-stopn\">{meter.n}</span>\n {meter.name}\n </div>\n <div\n className={`vos-jny-track${meter.kind === \"signed\" ? \" vos-jny-known\" : \"\"}`}\n >\n {meter.kind === \"signed\" ? (\n <>\n <span className=\"vos-jny-mid\" />\n {meter.sign !== \"zero\" ? (\n <i\n className={\n meter.sign === \"pos\" ? \"vos-jny-pos\" : \"vos-jny-neg\"\n }\n style={{ width: `${meter.pct}%` }}\n />\n ) : null}\n </>\n ) : (\n <i className=\"vos-jny-fill\" style={{ width: `${meter.pct}%` }} />\n )}\n </div>\n <div className=\"vos-jny-cap\">\n {meter.flag ? (\n <span className=\"vos-jny-flag\">{meter.flag}</span>\n ) : (\n <span className={meter.muted ? \"vos-muted\" : \"\"}>{meter.label}</span>\n )}\n </div>\n </div>\n {last ? null : (\n <span className=\"vos-jny-arrow\" aria-hidden=\"true\">\n →\n </span>\n )}\n </>\n );\n}\n\n/** One dated moment in the belief's life, with its step-in when it has one. */\nfunction EventRow({\n event,\n onStepIn,\n}: {\n event: JourneyEventView;\n onStepIn: (form: StoryStepIn) => void;\n}) {\n const act = eventStepIn(event.kind);\n const conf = event.confidence;\n return (\n <li className={`vos-jny-ev${event.kind === \"now\" ? \" vos-jny-ev-now\" : \"\"}`}>\n <span className={`vos-jny-dot ${DOT_CLASS[eventTone(event)]}`} />\n <span className=\"vos-jny-date\">{event.date ?? \"—\"}</span>\n <span className=\"vos-jny-label\">{event.label}</span>\n {conf !== null ? (\n <span\n className={`vos-pill ${conf < 0 ? \"vos-pill-crit\" : \"vos-pill-good\"} vos-jny-conf`}\n >\n conf {formatSigned(conf)}\n </span>\n ) : null}\n {act ? (\n <button\n type=\"button\"\n className=\"vos-linkbtn vos-jny-act\"\n onClick={() => onStepIn(act.form)}\n >\n {act.cta}\n </button>\n ) : null}\n </li>\n );\n}\n\n/** A reading dot's tone, from its result alone (the cycle cards have no\n * confidence-cross / now to fold in, unlike `eventTone`). */\nfunction readingDotTone(result: Result | null): Tone {\n if (result === \"Validated\") return \"good\";\n if (result === \"Invalidated\") return \"crit\";\n return \"neutral\"; // Inconclusive, or unresolved\n}\n\nconst BAR_VERDICT_PILL: Record<Result, string> = {\n Validated: \"vos-pill vos-pill-good\",\n Invalidated: \"vos-pill vos-pill-crit\",\n Inconclusive: \"vos-pill vos-pill-neutral\",\n};\n\n/**\n * The validation loop, round by round (OPS-1347): one card per cycle — an\n * Experiment's run against this belief, or (failing that) its bare/direct\n * evidence — each with its readings as a dot row, its bar verdict, and how\n * hard the round pushed Confidence. A horizontal strip, oldest round first,\n * so scrolling it *is* watching the belief move.\n */\nfunction CycleTimeline({ cycles }: { cycles: CycleView[] }) {\n const maxMagnitude = Math.max(...cycles.map((c) => c.magnitude), 0.01);\n return (\n <ol className=\"vos-cyc-list\">\n {cycles.map((cycle, i) => (\n <CycleCard key={cycle.key} cycle={cycle} n={i + 1} max={maxMagnitude} />\n ))}\n </ol>\n );\n}\n\nfunction CycleCard({\n cycle,\n n,\n max,\n}: {\n cycle: CycleView;\n n: number;\n max: number;\n}) {\n const up = cycle.contribution >= 0;\n const moving = cycle.magnitude > 0;\n const width = Math.round((cycle.magnitude / max) * 50);\n const fill = up\n ? { left: \"50%\", width: `${width}%`, background: \"var(--vos-good)\" }\n : { right: \"50%\", width: `${width}%`, background: \"var(--vos-crit)\" };\n return (\n <li className=\"vos-cyc-card\">\n <div className=\"vos-cyc-head\">\n <span className=\"vos-cyc-num\">Round {n}</span>\n {cycle.date ? <span className=\"vos-cyc-date\">{cycle.date}</span> : null}\n </div>\n <div className=\"vos-cyc-title\">\n {cycle.kind === \"direct\"\n ? \"Direct evidence\"\n : cycle.title ?? \"Untitled experiment\"}\n </div>\n {cycle.readings.length > 0 ? (\n <div\n className=\"vos-cyc-dots\"\n role=\"img\"\n aria-label={`${cycle.readings.length} reading${cycle.readings.length === 1 ? \"\" : \"s\"}`}\n >\n {cycle.readings.map((r) => (\n <span\n key={r.id}\n className={`vos-jny-dot ${DOT_CLASS[readingDotTone(r.result)]}`}\n />\n ))}\n </div>\n ) : (\n <span className=\"vos-hint\">No readings yet</span>\n )}\n <div className=\"vos-cyc-foot\">\n {cycle.barVerdict ? (\n <span className={BAR_VERDICT_PILL[cycle.barVerdict]}>\n {cycle.barVerdict}\n </span>\n ) : cycle.kind === \"experiment\" ? (\n <span className=\"vos-hint\">\n {cycle.status === \"Closed\" ? \"No bar line\" : \"Bar pending\"}\n </span>\n ) : null}\n {moving ? (\n <span className=\"vos-cyc-push\">\n <span className=\"vos-track vos-signed vos-cyc-track\">\n <i style={fill} />\n </span>\n <span className={up ? \"vos-text-good\" : \"vos-text-crit\"}>\n {formatSigned(cycle.contribution)}\n </span>\n </span>\n ) : null}\n </div>\n </li>\n );\n}\n\n/**\n * Where the story ends: the same ranked move the front door would offer for\n * this belief (OPS-1292), or the note that its journey is over. Step-in adapts\n * to the act (OPS-1294) — a human act opens its form here; an agent-run act\n * says so plainly rather than offering a button that does nothing.\n */\nfunction NextMoveCard({\n move,\n resolved,\n onAct,\n}: {\n move: NextMove | null;\n resolved: \"killed\" | \"moot\" | null;\n onAct: (form: StoryStepIn) => void;\n}) {\n if (resolved) {\n return (\n <div className=\"vos-jny-card vos-jny-card-done\">\n <span className=\"vos-jny-card-eyebrow\">The end of the road</span>\n <p className=\"vos-jny-card-reason\">\n {resolved === \"killed\"\n ? \"This belief is killed — the evidence went against it. It retired its risk; nothing more to test.\"\n : \"This belief is moot — a decision retired the question without a test. It carries no risk now.\"}\n </p>\n </div>\n );\n }\n if (!move) return null;\n\n const pres = movePresentation(move.move);\n return (\n <div\n className={`vos-jny-card${move.killLane ? \" vos-jny-card-kill\" : \"\"}`}\n >\n <span className=\"vos-jny-card-eyebrow\">\n {move.killLane ? \"Kill lane — the evidence has turned\" : \"The next move\"}\n </span>\n <p className=\"vos-jny-card-reason\">{move.reason}</p>\n {pres.steppable && pres.form ? (\n <button\n type=\"button\"\n className=\"vos-btn\"\n onClick={() => onAct(pres.form as StoryStepIn)}\n >\n {pres.cta}\n </button>\n ) : (\n <span className=\"vos-agent-note\">\n 🤖 Claude Code runs this off the dashboard — it'll show up here when\n it lands.\n </span>\n )}\n </div>\n );\n}\n\n/** The no-history cold-state card — replaces the sparse `bet` + `now` events\n * with one guided line that names the belief's next move. */\nfunction JourneyColdCard({\n eyebrow,\n body,\n}: {\n eyebrow: string;\n body: string;\n}) {\n return (\n <div className=\"vos-jny-cold vos-card\">\n <span className=\"vos-jny-card-eyebrow\">{eyebrow}</span>\n <p className=\"vos-jny-card-reason\">{body}</p>\n </div>\n );\n}\n","import { useState } from \"react\";\nimport type { AnyRecord } from \"@validation-os/core\";\nimport { DrawerShell } from \"./drawer-shell.js\";\nimport { buildPatch, draftFrom, type Draft } from \"./edit.js\";\nimport { EditFields } from \"./edit-fields.js\";\nimport { FIELD_CONTROL_CLASS, FIELD_LABEL_CLASS } from \"./field-styles.js\";\nimport { useCreate, useLink } from \"./use-mutations.js\";\nimport { useUpdate } from \"./use-records.js\";\n\n/**\n * The human step-in set (OPS-1294): score impact, write decision, and edit the\n * belief — the small edits a founder makes on the review surface there and then,\n * not where validating happens. The reading form lives with the evidence, and\n * there is deliberately no experiment-design form here (OPS-1297).\n *\n * All three ride the shared `DrawerShell` chrome and write through the\n * Clerk-gated API, which recomputes the derived numbers on write — so the hero's\n * risk chip, the ranking and the journey rail refresh from authoritative\n * numbers, never anything the client computed.\n */\n\nfunction belief(record: AnyRecord): string {\n const title = record[\"Title\"];\n return typeof title === \"string\" && title.trim() ? title : record.id;\n}\n\n// ── Score impact ────────────────────────────────────────────────────────────\n\nexport interface ScoreImpactFormProps {\n /** The assumption being weighted (its version guards the write). */\n assumption: AnyRecord;\n basePath?: string;\n /** Called after a successful save. */\n onDone: () => void;\n onCancel: () => void;\n}\n\n/**\n * Score a belief's Impact — a real input (a slider tied to a number), not a bare\n * cell edit (OPS-1294). Impact is the one hand-scored number Risk propagates\n * from, so scoring it is what lets an unweighted belief take its place in the\n * ranking. The optional justification records *why* that weight.\n */\nexport function ScoreImpactForm({\n assumption,\n basePath,\n onDone,\n onCancel,\n}: ScoreImpactFormProps) {\n const current = assumption[\"Impact\"];\n const [impact, setImpact] = useState<number>(\n typeof current === \"number\" ? current : 50,\n );\n const justificationCurrent = assumption[\"Scoring justification\"];\n const [justification, setJustification] = useState<string>(\n typeof justificationCurrent === \"string\" ? justificationCurrent : \"\",\n );\n const { save, saving, conflict, error } = useUpdate(\"assumptions\", basePath);\n\n const onSubmit = async (e: React.FormEvent) => {\n e.preventDefault();\n if (saving) return;\n const patch: Record<string, unknown> = {\n version: assumption.version,\n Impact: impact,\n };\n const wasJustification =\n typeof justificationCurrent === \"string\" ? justificationCurrent : \"\";\n if (justification.trim() !== wasJustification.trim()) {\n patch[\"Scoring justification\"] = justification.trim();\n }\n const result = await save(assumption.id, patch);\n if (result.ok) onDone();\n };\n\n return (\n <DrawerShell open onClose={onCancel} ariaLabel=\"Score impact\">\n <header className=\"vos-drawer-header\">\n <span className=\"vos-drawer-eyebrow\">Score impact</span>\n <h2 className=\"vos-drawer-title\">{belief(assumption)}</h2>\n </header>\n <form onSubmit={onSubmit} className=\"vos-form\">\n <div className=\"vos-form-body\">\n <div className=\"vos-field\">\n <label htmlFor=\"score-impact-range\" className={FIELD_LABEL_CLASS}>\n Impact if wrong — how much of the plan rests on this?\n </label>\n <div className=\"vos-slider-row\">\n <input\n id=\"score-impact-range\"\n type=\"range\"\n min={0}\n max={100}\n value={impact}\n onChange={(e) => setImpact(Number(e.target.value))}\n className=\"vos-slider\"\n />\n <input\n type=\"number\"\n min={0}\n max={100}\n value={impact}\n onChange={(e) => {\n const n = Number(e.target.value);\n if (!Number.isNaN(n)) setImpact(Math.max(0, Math.min(100, n)));\n }}\n className={`${FIELD_CONTROL_CLASS} vos-slider-num`}\n aria-label=\"Impact (0–100)\"\n />\n </div>\n <p className=\"vos-field-hint\">\n 0 = wouldn't matter · 100 = the plan can't survive it being wrong.\n Risk follows Impact until evidence lands.\n </p>\n </div>\n\n <div className=\"vos-field\">\n <label htmlFor=\"score-impact-why\" className={FIELD_LABEL_CLASS}>\n Why this weight? <span className=\"vos-muted\">(optional)</span>\n </label>\n <textarea\n id=\"score-impact-why\"\n rows={3}\n value={justification}\n onChange={(e) => setJustification(e.target.value)}\n className={FIELD_CONTROL_CLASS}\n placeholder=\"What makes this belief matter as much (or as little) as you scored it?\"\n />\n </div>\n\n {conflict ? <p className=\"vos-error\">{conflict}</p> : null}\n {error ? <p className=\"vos-error\">{error}</p> : null}\n </div>\n <footer className=\"vos-drawer-footer\">\n <button\n type=\"button\"\n onClick={onCancel}\n className=\"vos-btn vos-btn-ghost vos-btn-sm\"\n >\n Cancel\n </button>\n <button type=\"submit\" disabled={saving} className=\"vos-btn vos-btn-sm\">\n {saving ? \"Saving…\" : \"Save impact\"}\n </button>\n </footer>\n </form>\n </DrawerShell>\n );\n}\n\n// ── Edit the belief ──────────────────────────────────────────────────────────\n\nexport interface EditBeliefFormProps {\n /** The assumption being edited (its version guards the write). */\n assumption: AnyRecord;\n basePath?: string;\n /** Called after a successful save. */\n onDone: () => void;\n onCancel: () => void;\n}\n\n/**\n * Edit the bet itself — the assumption-edit half of the OPS-1294 step-in set,\n * reached from the journey story's `bet` event. It renders the register's\n * editable fields from the same schema the drawer uses (`EditFields`), so the\n * two never drift, and writes only the fields actually changed: the patch is\n * diffed against the record it opened on, so a teammate's concurrent edit to an\n * untouched field survives. Framing completeness (the rail's Framed meter)\n * recomputes server-side on write.\n */\nexport function EditBeliefForm({\n assumption,\n basePath,\n onDone,\n onCancel,\n}: EditBeliefFormProps) {\n const [draft, setDraft] = useState<Draft>(() =>\n draftFrom(\"assumptions\", assumption),\n );\n const { save, saving, conflict, error } = useUpdate(\"assumptions\", basePath);\n\n const onSubmit = async (e: React.FormEvent) => {\n e.preventDefault();\n if (saving) return;\n const patch = buildPatch(\"assumptions\", assumption, draft);\n patch.version = assumption.version;\n if (Object.keys(patch).length <= 1) {\n onCancel(); // only `version` present — nothing actually changed\n return;\n }\n const result = await save(assumption.id, patch);\n if (result.ok) onDone();\n };\n\n return (\n <DrawerShell open onClose={onCancel} ariaLabel=\"Edit the bet\">\n <header className=\"vos-drawer-header\">\n <span className=\"vos-drawer-eyebrow\">Edit the bet</span>\n <h2 className=\"vos-drawer-title\">{belief(assumption)}</h2>\n </header>\n <form onSubmit={onSubmit} className=\"vos-form\">\n <div className=\"vos-form-body\">\n <EditFields\n register=\"assumptions\"\n draft={draft}\n onField={(key, value) =>\n setDraft((d) => ({ ...d, [key]: value }))\n }\n />\n {conflict ? <p className=\"vos-error\">{conflict}</p> : null}\n {error ? <p className=\"vos-error\">{error}</p> : null}\n </div>\n <footer className=\"vos-drawer-footer\">\n <button\n type=\"button\"\n onClick={onCancel}\n className=\"vos-btn vos-btn-ghost vos-btn-sm\"\n >\n Cancel\n </button>\n <button type=\"submit\" disabled={saving} className=\"vos-btn vos-btn-sm\">\n {saving ? \"Saving…\" : \"Save the bet\"}\n </button>\n </footer>\n </form>\n </DrawerShell>\n );\n}\n\n// ── Write decision ────────────────────────────────────────────────────────────\n\nconst DECISION_STATUS = [\"Provisional\", \"Active\"] as const;\n\nexport interface WriteDecisionFormProps {\n /** The belief the decision rests on or resolves. */\n assumption: AnyRecord;\n basePath?: string;\n /**\n * A kill-lane decision (Confidence ≤ −50) defaults to *resolving* (retiring)\n * the belief; an ordinary decide defaults to resting *on* it.\n */\n kill?: boolean;\n onDone: () => void;\n onCancel: () => void;\n}\n\n/**\n * Write a decision against a belief (OPS-1294) — create the Decision record and\n * wire it to the belief in one step, honouring the method's `based on` vs\n * `resolves` split: a decision that *rests on* a belief keeps the question open\n * (rationale); one that *resolves* it retires the question without a test\n * (Impact → 0, it goes moot). The kill lane defaults to resolving.\n */\nexport function WriteDecisionForm({\n assumption,\n basePath,\n kill = false,\n onDone,\n onCancel,\n}: WriteDecisionFormProps) {\n const [title, setTitle] = useState(\"\");\n const [status, setStatus] =\n useState<(typeof DECISION_STATUS)[number]>(\"Provisional\");\n const [relation, setRelation] = useState<\"resolves\" | \"based-on\">(\n kill ? \"resolves\" : \"based-on\",\n );\n const { create, saving: creating, error: createError } = useCreate(\n \"decisions\",\n basePath,\n );\n const { link, linking, error: linkError } = useLink(basePath);\n const [failed, setFailed] = useState<string | null>(null);\n\n const busy = creating || linking;\n const missing = title.trim() === \"\";\n\n const onSubmit = async (e: React.FormEvent) => {\n e.preventDefault();\n if (missing || busy) return;\n setFailed(null);\n try {\n const decision = await create({ Title: title.trim(), Status: status });\n await link({\n relation: relation === \"resolves\" ? \"decision-resolves\" : \"decision-based-on\",\n from: { register: \"decisions\", id: decision.id },\n to: { register: \"assumptions\", id: assumption.id },\n });\n onDone();\n } catch {\n // The hooks surface their own message; keep the form open to retry.\n setFailed(\"Couldn't write the decision — please try again.\");\n }\n };\n\n return (\n <DrawerShell open onClose={onCancel} ariaLabel=\"Write decision\">\n <header className=\"vos-drawer-header\">\n <span className=\"vos-drawer-eyebrow\">\n {kill ? \"Kill or re-test\" : \"Write a decision\"}\n </span>\n <h2 className=\"vos-drawer-title\">{belief(assumption)}</h2>\n </header>\n <form onSubmit={onSubmit} className=\"vos-form\">\n <div className=\"vos-form-body\">\n <div className=\"vos-field\">\n <label htmlFor=\"decision-title\" className={FIELD_LABEL_CLASS}>\n The decision <span className=\"vos-req\">*</span>\n </label>\n <input\n id=\"decision-title\"\n type=\"text\"\n value={title}\n onChange={(e) => setTitle(e.target.value)}\n className={FIELD_CONTROL_CLASS}\n placeholder=\"What are you deciding?\"\n />\n </div>\n\n <div className=\"vos-field\">\n <span className={FIELD_LABEL_CLASS}>How does it relate?</span>\n <label className=\"vos-radio\">\n <input\n type=\"radio\"\n name=\"decision-relation\"\n checked={relation === \"based-on\"}\n onChange={() => setRelation(\"based-on\")}\n />\n <span>\n <b>Rests on</b> this belief — the question stays open (rationale).\n </span>\n </label>\n <label className=\"vos-radio\">\n <input\n type=\"radio\"\n name=\"decision-relation\"\n checked={relation === \"resolves\"}\n onChange={() => setRelation(\"resolves\")}\n />\n <span>\n <b>Resolves</b> this belief — retires the question without a test\n (it goes moot).\n </span>\n </label>\n </div>\n\n <div className=\"vos-field\">\n <label htmlFor=\"decision-status\" className={FIELD_LABEL_CLASS}>\n Status\n </label>\n <select\n id=\"decision-status\"\n value={status}\n onChange={(e) =>\n setStatus(e.target.value as (typeof DECISION_STATUS)[number])\n }\n className={FIELD_CONTROL_CLASS}\n >\n {DECISION_STATUS.map((s) => (\n <option key={s} value={s}>\n {s}\n </option>\n ))}\n </select>\n </div>\n\n {(failed || createError || linkError) ? (\n <p className=\"vos-error\">{failed || createError || linkError}</p>\n ) : null}\n </div>\n <footer className=\"vos-drawer-footer\">\n <button\n type=\"button\"\n onClick={onCancel}\n className=\"vos-btn vos-btn-ghost vos-btn-sm\"\n >\n Cancel\n </button>\n <button\n type=\"submit\"\n disabled={missing || busy}\n title={missing ? \"Name the decision\" : undefined}\n className=\"vos-btn vos-btn-sm\"\n >\n {busy ? \"Writing…\" : \"Write decision\"}\n </button>\n </footer>\n </form>\n </DrawerShell>\n );\n}\n","import { useEffect, useRef, type ReactNode } from \"react\";\n\nexport interface DrawerShellProps {\n /** Whether the drawer is mounted/visible. */\n open: boolean;\n onClose: () => void;\n /** Accessible name for the dialog. */\n ariaLabel: string;\n children: ReactNode;\n}\n\n/**\n * The right-hand slide-over chrome shared by the record drawer and the create\n * drawer: a click-to-dismiss scrim, an `aria-modal` panel, Escape-to-close, and\n * focus moved into the panel on open so keyboard users aren't stranded behind\n * the modal. Everything inside is the caller's content. Styled with the\n * package's own token sheet — no host Tailwind.\n */\nexport function DrawerShell({\n open,\n onClose,\n ariaLabel,\n children,\n}: DrawerShellProps) {\n const panelRef = useRef<HTMLDivElement>(null);\n\n useEffect(() => {\n if (!open) return;\n const onKey = (e: KeyboardEvent) => {\n if (e.key === \"Escape\") onClose();\n };\n document.addEventListener(\"keydown\", onKey);\n panelRef.current?.focus();\n return () => document.removeEventListener(\"keydown\", onKey);\n }, [open, onClose]);\n\n if (!open) return null;\n\n return (\n <>\n {/* Scrim — click to dismiss. */}\n <button\n type=\"button\"\n aria-label=\"Close\"\n onClick={onClose}\n className=\"vos-scrim\"\n />\n <aside\n ref={panelRef}\n role=\"dialog\"\n aria-modal=\"true\"\n aria-label={ariaLabel}\n tabIndex={-1}\n className=\"vos-drawer\"\n >\n {children}\n </aside>\n </>\n );\n}\n","/**\n * Shared class names for form controls, so the create form and the relation\n * editor render identical inputs (and any restyle happens in one place). These\n * are the package's own semantic classes, backed by the `styles.css` token\n * sheet — no host Tailwind.\n */\n\nexport const FIELD_LABEL_CLASS = \"vos-field-label\";\n\nexport const FIELD_CONTROL_CLASS = \"vos-input\";\n","import { useCallback, useState } from \"react\";\nimport type { AnyRecord, Collection, Relation } from \"@validation-os/core\";\n\n/**\n * Client write hooks — the create + link counterparts to `use-records`'\n * read hooks. Both POST through the Clerk-gated API (`POST {basePath}/{register}`\n * and `POST {basePath}/link`), so the browser never touches Firestore and the\n * server always recomputes derived fields. Each returns a `pending`/`error`\n * pair and an action that resolves to the result (or throws), so the caller can\n * refresh the list/record afterwards.\n */\n\n/** Pull the API's `{ data }` envelope, or throw its plain-language message. */\nasync function postJson<T>(url: string, body: unknown): Promise<T> {\n const res = await fetch(url, {\n method: \"POST\",\n headers: { \"content-type\": \"application/json\" },\n body: JSON.stringify(body),\n });\n const payload = (await res.json().catch(() => null)) as\n | { data?: T; message?: string; error?: string }\n | null;\n if (!res.ok) {\n const message =\n payload?.message ?? payload?.error ?? `Request failed (${res.status})`;\n throw new Error(message);\n }\n return (payload as { data: T }).data;\n}\n\nexport interface UseCreateResult {\n create: (data: Record<string, unknown>) => Promise<AnyRecord>;\n saving: boolean;\n error: string | null;\n}\n\n/** Create a record in `register`; the server stamps derived fields on write. */\nexport function useCreate(\n register: Collection,\n basePath = \"/api\",\n): UseCreateResult {\n const [saving, setSaving] = useState(false);\n const [error, setError] = useState<string | null>(null);\n\n const create = useCallback(\n async (data: Record<string, unknown>) => {\n setSaving(true);\n setError(null);\n try {\n return await postJson<AnyRecord>(`${basePath}/${register}`, data);\n } catch (e) {\n const message = e instanceof Error ? e.message : \"Failed to create\";\n setError(message);\n throw e;\n } finally {\n setSaving(false);\n }\n },\n [register, basePath],\n );\n\n return { create, saving, error };\n}\n\nexport interface LinkArgs {\n relation: Relation;\n from: { register: Collection; id: string };\n to: { register: Collection; id: string };\n}\n\nexport interface UseLinkResult {\n link: (args: LinkArgs) => Promise<void>;\n linking: boolean;\n error: string | null;\n}\n\n/** Wire a relation; the API sets both ends and recomputes derived fields. */\nexport function useLink(basePath = \"/api\"): UseLinkResult {\n const [linking, setLinking] = useState(false);\n const [error, setError] = useState<string | null>(null);\n\n const link = useCallback(\n async (args: LinkArgs) => {\n setLinking(true);\n setError(null);\n try {\n await postJson<unknown>(`${basePath}/link`, args);\n } catch (e) {\n const message = e instanceof Error ? e.message : \"Failed to link\";\n setError(message);\n throw e;\n } finally {\n setLinking(false);\n }\n },\n [basePath],\n );\n\n return { link, linking, error };\n}\n","/**\n * The dashboard's visual primitives, rendered in the package's own semantic\n * classes (backed by the `styles.css` token sheet) — never host Tailwind. Each\n * is a thin wrapper over the pure logic in `primitives.ts`, so the mapping is\n * tested there and the markup stays trivial. These are the bricks the register\n * views and the assembled app compose.\n */\nimport type { ReactNode } from \"react\";\nimport {\n confidenceTone,\n formatCount,\n formatSigned,\n riskFraction,\n riskLevel,\n sparklinePath,\n sparklineY,\n statusTone,\n type Tone,\n} from \"./primitives.js\";\n\nconst PILL_CLASS: Record<Tone, string> = {\n good: \"vos-pill vos-pill-good\",\n warn: \"vos-pill vos-pill-warn\",\n crit: \"vos-pill vos-pill-crit\",\n accent: \"vos-pill vos-pill-accent\",\n neutral: \"vos-pill vos-pill-neutral\",\n};\n\n/** A colored status pill — tone from the status, the label shown verbatim. */\nexport function StatusPill({ status }: { status: string | null | undefined }) {\n if (!status) return <span className=\"vos-muted\">—</span>;\n return <span className={PILL_CLASS[statusTone(status)]}>{status}</span>;\n}\n\nconst FILL_CLASS: Record<Tone, string> = {\n good: \"vos-fill-good\",\n warn: \"vos-fill-warn\",\n crit: \"vos-fill-crit\",\n accent: \"vos-fill-good\",\n neutral: \"vos-fill-good\",\n};\nconst TEXT_CLASS: Record<Tone, string> = {\n good: \"vos-text-good\",\n warn: \"vos-text-warn\",\n crit: \"vos-text-crit\",\n accent: \"vos-text-good\",\n neutral: \"\",\n};\n\n/**\n * A risk bar (0–100) plus its number, both toned by threshold: a longer, redder\n * bar means a riskier belief the eye should land on first (spec story 5).\n */\nexport function RiskBar({ risk }: { risk: number }) {\n const level = riskLevel(risk);\n const pct = Math.round(riskFraction(risk) * 100);\n return (\n <span className=\"vos-metric-cell\">\n <span\n className=\"vos-risk-bar\"\n role=\"img\"\n aria-label={`Risk ${Math.round(risk)} of 100`}\n >\n <i className={FILL_CLASS[level]} style={{ width: `${pct}%` }} />\n </span>\n <b className={`vos-metric-num ${TEXT_CLASS[level]}`}>{Math.round(risk)}</b>\n </span>\n );\n}\n\n/**\n * A signed confidence reading: a tiny sparkline of its trajectory when a\n * history is available, always the +/- number (negative reads crit) — so a row\n * shows both where a belief stands and, when known, which way it is trending\n * (spec story 6). With no history the number stands alone; the list endpoint\n * carries no per-row series, so the in-row sparkline appears wherever a caller\n * does have one (e.g. the drawer trajectory uses `Sparkline` directly).\n */\nexport function ConfidenceCell({\n confidence,\n history,\n}: {\n confidence: number;\n history?: number[];\n}) {\n const tone = confidenceTone(confidence);\n return (\n <span className=\"vos-metric-cell\">\n {history && history.length >= 2 ? (\n <Sparkline\n values={history}\n width={46}\n height={16}\n min={-100}\n max={100}\n tone={tone}\n />\n ) : null}\n <b className={`vos-metric-num ${TEXT_CLASS[tone]}`}>\n {formatSigned(confidence)}\n </b>\n </span>\n );\n}\n\nconst STROKE_VAR: Record<Tone, string> = {\n good: \"var(--vos-good)\",\n warn: \"var(--vos-warn)\",\n crit: \"var(--vos-crit)\",\n accent: \"var(--vos-accent)\",\n neutral: \"var(--vos-muted)\",\n};\n\n/**\n * A signed sparkline over `values`. A zero baseline is drawn whenever the domain\n * spans it, so a line dipping below zero reads as a belief losing ground. The\n * last point gets a dot. `fill` shades the area under the line. Pure geometry\n * comes from `sparklinePath`/`sparklineY`.\n */\nexport function Sparkline({\n values,\n width = 240,\n height = 44,\n min,\n max,\n tone = \"good\",\n fill = false,\n ariaLabel,\n}: {\n values: number[];\n width?: number;\n height?: number;\n min?: number;\n max?: number;\n tone?: Tone;\n fill?: boolean;\n ariaLabel?: string;\n}) {\n const d = sparklinePath(values, width, height, min, max);\n if (!d) return null;\n const lo = min ?? Math.min(...values, 0);\n const hi = max ?? Math.max(...values, 0);\n const stroke = STROKE_VAR[tone];\n const last = values[values.length - 1]!;\n const lastX = width - 2;\n const lastY = sparklineY(last, height, lo, hi);\n const zeroY = sparklineY(0, height, lo, hi);\n const showBaseline = lo < 0 && hi > 0;\n return (\n <svg\n className=\"vos-spark\"\n width={width}\n height={height}\n viewBox={`0 0 ${width} ${height}`}\n preserveAspectRatio=\"none\"\n role=\"img\"\n aria-label={ariaLabel ?? `Trend, now ${formatSigned(last)}`}\n >\n {fill ? (\n <path\n d={`${d} L ${width - 2} ${height} L 2 ${height} Z`}\n fill={stroke}\n opacity=\"0.13\"\n />\n ) : null}\n {showBaseline ? (\n <line\n x1={2}\n x2={width - 2}\n y1={zeroY}\n y2={zeroY}\n stroke=\"var(--vos-border-strong)\"\n strokeWidth={1}\n strokeDasharray=\"3 3\"\n />\n ) : null}\n <path d={d} fill=\"none\" stroke={stroke} strokeWidth={2} />\n <circle cx={lastX} cy={lastY} r={3} fill={stroke} />\n </svg>\n );\n}\n\n/**\n * A glanceable stat tile — a label, a big number, and an optional sub-caption.\n * Becomes a button when `onClick` is given (counts that double as nav). Pure\n * presentation; the caller supplies the value.\n */\nexport function StatTile({\n label,\n value,\n sub,\n onClick,\n active,\n}: {\n label: string;\n value: number;\n sub?: ReactNode;\n onClick?: () => void;\n active?: boolean;\n}) {\n const body = (\n <>\n <div className=\"vos-tile-label\">{label}</div>\n <div className=\"vos-tile-value\">{formatCount(value)}</div>\n {sub ? <div className=\"vos-tile-sub\">{sub}</div> : null}\n </>\n );\n if (onClick) {\n return (\n <button\n type=\"button\"\n className=\"vos-tile\"\n onClick={onClick}\n aria-pressed={active}\n >\n {body}\n </button>\n );\n }\n return <div className=\"vos-tile\">{body}</div>;\n}\n","/**\n * The understanding layer's data join (OPS-1276). Pure: given an assumption\n * and the readings + experiments registers, it produces everything the Reveal\n * shows — the experiments testing the belief (each with how hard it moves\n * Confidence and how close it is to concluding), the goal/direct evidence that\n * also moves the number, and the Confidence-over-time trajectory.\n *\n * The record → derivation-input mapping is `@validation-os/core`'s shared\n * `readingBeliefInputs`, which fans a reading row out into one input per belief;\n * we keep this belief's inputs, so a reading is read here exactly as it is\n * server-side. Archived experiments never surface here (OPS-1305) — the \"Why?\"\n * only ever shows a live plan or direct evidence.\n */\nimport {\n readingBeliefInputs,\n type AnyRecord,\n type BarLine,\n} from \"@validation-os/core\";\nimport {\n confidenceAttribution,\n confidenceTrajectory,\n experimentProgress,\n isConcluded,\n type MoverKind,\n type Progress,\n type TrajectoryPoint,\n} from \"@validation-os/core/derivation\";\nimport {\n isArchivedExperiment,\n liveExperiments,\n str,\n testsAssumption,\n} from \"./derived-views.js\";\n\n/** An experiment testing this assumption: how hard it moves Confidence, and\n * how close it is to concluding. `contribution` is 0 for a running experiment\n * that has not produced a concluded reading yet — it still shows, so its\n * progress-to-conclusion is visible. */\nexport interface ExperimentView {\n experimentId: string;\n title: string | null;\n status: string | null;\n /** Signed push on Confidence; 0 until a concluded reading lands. */\n contribution: number;\n magnitude: number;\n /** Concluded readings this experiment has produced for the belief. */\n readingCount: number;\n progress: Progress | null;\n /** Concluded/closed — reads as done rather than in-flight. */\n done: boolean;\n}\n\n/** Direct evidence that moves Confidence but is not tied to an experiment\n * (a bare/found reading, or a Market-rung reading with no plan). */\nexport interface OtherMover {\n key: string;\n kind: Exclude<MoverKind, \"experiment\">;\n contribution: number;\n magnitude: number;\n readingCount: number;\n}\n\nexport interface Understanding {\n /** The same Confidence the derived box shows. */\n confidence: number;\n /** Experiments testing this belief, ranked by how hard they push. */\n experiments: ExperimentView[];\n /** Goal/direct evidence that also moves the number. */\n otherMovers: OtherMover[];\n /** Confidence over time; empty when no concluded reading is dated. */\n trajectory: TrajectoryPoint[];\n /** Concluded readings feeding the number, across all sources. */\n readingCount: number;\n}\n\nexport function buildUnderstanding(\n assumption: AnyRecord,\n readings: AnyRecord[],\n experiments: AnyRecord[],\n): Understanding {\n // DEV-5890: thread the assumption's Question Type into each belief input so\n // Strength reads the right sub-ladder.\n const assumptionsById = new Map<string, AnyRecord>([[String(assumption.id), assumption]]);\n const inputs = readings\n .flatMap((r) => readingBeliefInputs(r, assumptionsById))\n .filter((i) => i.assumptionId === assumption.id);\n const { confidence, movers } = confidenceAttribution(inputs);\n\n const experimentsById = new Map(experiments.map((e) => [e.id, e]));\n const moverByExperiment = new Map(\n movers.filter((m) => m.kind === \"experiment\").map((m) => [m.experimentId!, m]),\n );\n\n // Every live experiment testing this belief — whether or not it has moved the\n // number yet — plus any experiment a reading points at that isn't linked via\n // bar lines. So a freshly-started plan with no readings still shows. Archived\n // plans are dropped entirely (OPS-1305): never a mover, never a row. A plan a\n // reading points at but that isn't in the register is kept (absent ≠ archived).\n const experimentIds = new Set<string>([\n ...liveExperiments(experiments)\n .filter((e) => testsAssumption(e, assumption.id))\n .map((e) => e.id),\n ...[...moverByExperiment.keys()].filter((id) => {\n const e = experimentsById.get(id);\n return !e || !isArchivedExperiment(e);\n }),\n ]);\n\n const experimentViews: ExperimentView[] = [...experimentIds].map((id) => {\n const exp = experimentsById.get(id);\n const mover = moverByExperiment.get(id);\n const bars = (exp?.barLines as BarLine[] | undefined) ?? [];\n const progress = bars.length ? experimentProgress(bars) : null;\n const status = exp ? str(exp.Status) : null;\n return {\n experimentId: id,\n title: exp ? str(exp.Title) : null,\n status,\n contribution: mover?.contribution ?? 0,\n magnitude: mover?.magnitude ?? 0,\n readingCount: mover?.readingCount ?? 0,\n progress,\n done: status === \"Closed\" || progress?.concluded === true,\n };\n });\n // Strongest movers first; among non-movers, in-flight before done, then id.\n experimentViews.sort(\n (a, b) =>\n b.magnitude - a.magnitude ||\n Number(a.done) - Number(b.done) ||\n a.experimentId.localeCompare(b.experimentId),\n );\n\n const otherMovers: OtherMover[] = movers\n .filter((m) => m.kind !== \"experiment\")\n .map((m) => ({\n key: m.key,\n kind: m.kind as OtherMover[\"kind\"],\n contribution: m.contribution,\n magnitude: m.magnitude,\n readingCount: m.readingCount,\n }));\n\n return {\n confidence,\n experiments: experimentViews,\n otherMovers,\n trajectory: confidenceTrajectory(inputs),\n readingCount: inputs.filter((r) => isConcluded(r.result)).length,\n };\n}\n","import type { ReactNode } from \"react\";\nimport type { AnyRecord } from \"@validation-os/core\";\nimport type { TrajectoryPoint } from \"@validation-os/core/derivation\";\nimport { useList } from \"./use-records.js\";\nimport { Sparkline } from \"./primitives-view.js\";\nimport { confidenceTone, formatSigned } from \"./primitives.js\";\nimport {\n buildUnderstanding,\n type ExperimentView,\n type OtherMover,\n} from \"./understanding.js\";\n\n/**\n * The understanding layer behind the Confidence \"Why?\" (OPS-1276): which\n * experiments move the number (ranked by push) and how close each running\n * experiment is to concluding, the goal/direct evidence that also moves it, and\n * Confidence over time. It lazy-loads the readings + experiments registers (it\n * only mounts when the Reveal is open), then derives everything through the\n * shared derivation module. Restyled into the drawer's accent/pill language\n * (spec story 11): signed push tracks and a signed trajectory sparkline, in the\n * package's own token sheet — no host Tailwind.\n */\nexport function UnderstandingPanel({\n assumption,\n basePath,\n}: {\n assumption: AnyRecord;\n basePath?: string;\n}) {\n const readings = useList(\"readings\", basePath);\n const experiments = useList(\"experiments\", basePath);\n\n if (readings.loading || experiments.loading) {\n return <Muted>Working out what moved the number…</Muted>;\n }\n if (readings.error || experiments.error) {\n return <Muted>Couldn't load the evidence behind this number.</Muted>;\n }\n\n const u = buildUnderstanding(\n assumption,\n readings.records ?? [],\n experiments.records ?? [],\n );\n\n if (u.experiments.length === 0 && u.otherMovers.length === 0) {\n return (\n <Muted>\n No experiments or concluded readings yet — Confidence rests on the\n neutral prior alone.\n </Muted>\n );\n }\n\n // One scale for every push bar so experiments and other evidence compare.\n const maxMagnitude = Math.max(\n ...u.experiments.map((e) => e.magnitude),\n ...u.otherMovers.map((m) => m.magnitude),\n 0.01,\n );\n\n return (\n <>\n {u.experiments.length ? (\n <section>\n <div className=\"vos-why-section-title\">What's moving Confidence</div>\n {u.experiments.map((e) => (\n <PushRow\n key={e.experimentId}\n label={e.title ?? `Experiment ${e.experimentId}`}\n note={experimentDetail(e)}\n contribution={e.contribution}\n magnitude={e.magnitude}\n max={maxMagnitude}\n done={e.done}\n />\n ))}\n </section>\n ) : null}\n\n {u.otherMovers.length ? (\n <section>\n <div className=\"vos-why-section-title\">Other evidence</div>\n {u.otherMovers.map((m) => (\n <PushRow\n key={m.key}\n label={otherMoverLabel(m)}\n contribution={m.contribution}\n magnitude={m.magnitude}\n max={maxMagnitude}\n />\n ))}\n </section>\n ) : null}\n\n <Trajectory points={u.trajectory} />\n </>\n );\n}\n\n/** A labelled row with a signed contribution and a signed push bar (fill left\n * for negative, right for positive; width ∝ push). */\nfunction PushRow({\n label,\n note,\n contribution,\n magnitude,\n max,\n done,\n}: {\n label: string;\n note?: string;\n contribution: number;\n magnitude: number;\n max: number;\n done?: boolean;\n}) {\n const up = contribution >= 0;\n const moving = magnitude > 0;\n const width = Math.round((magnitude / max) * 50);\n const fill = up\n ? { left: \"50%\", width: `${width}%`, background: \"var(--vos-good)\" }\n : { right: \"50%\", width: `${width}%`, background: \"var(--vos-crit)\" };\n return (\n <div className=\"vos-mover\">\n <span className=\"vos-mover-name\">{label}</span>\n {note ? (\n <span className={`vos-mover-note ${done ? \"vos-text-good\" : \"vos-text-warn\"}`}>\n {note}\n </span>\n ) : null}\n <span className=\"vos-track vos-signed\">\n {moving ? <i style={fill} /> : null}\n </span>\n <span\n className=\"vos-mover-val\"\n style={{ color: up ? \"var(--vos-good)\" : \"var(--vos-crit)\" }}\n >\n {moving ? formatSigned(contribution) : \"—\"}\n </span>\n </div>\n );\n}\n\nfunction Trajectory({ points }: { points: TrajectoryPoint[] }) {\n if (points.length < 2) {\n return (\n <p className=\"vos-hint\">\n {points.length === 1\n ? `One dated reading so far — Confidence ${formatSigned(points[0]!.confidence)} on ${points[0]!.date}.`\n : \"No dated readings yet to chart a trajectory.\"}\n </p>\n );\n }\n const first = points[0]!;\n const last = points[points.length - 1]!;\n const values = points.map((p) => p.confidence);\n return (\n <div className=\"vos-traj\">\n <div className=\"vos-traj-head\">\n <span className=\"vos-lbl\">Confidence over time</span>\n </div>\n <Sparkline\n values={values}\n width={260}\n height={44}\n min={-100}\n max={100}\n tone={confidenceTone(last.confidence)}\n fill\n ariaLabel={`Confidence moved from ${formatSigned(first.confidence)} to ${formatSigned(last.confidence)}`}\n />\n <div className=\"vos-traj-foot\">\n <span>{first.date}</span>\n <span className=\"vos-num\">now {formatSigned(last.confidence)}</span>\n </div>\n </div>\n );\n}\n\nfunction experimentDetail(e: ExperimentView): string {\n const evidence =\n e.readingCount === 0\n ? \"No readings yet\"\n : `${e.readingCount} reading${e.readingCount === 1 ? \"\" : \"s\"}`;\n const p = e.progress;\n if (e.done) {\n return p\n ? `Concluded · ${p.total} of ${p.total} bars settled`\n : `Concluded · ${evidence}`;\n }\n if (!p || p.total === 0) return `${evidence} · no pre-registered bars`;\n return `${evidence} · ${p.settled} of ${p.total} bars settled · ${p.toGo} to go`;\n}\n\nfunction otherMoverLabel(m: OtherMover): string {\n return m.readingCount === 1 ? \"A direct reading\" : \"Direct readings\";\n}\n\nfunction Muted({ children }: { children: ReactNode }) {\n return <p className=\"vos-hint\">{children}</p>;\n}\n","/**\n * The list-surface view-model (OPS-1287) — the pure shaped-query layer above the\n * flat `RegisterTable`. Given a register's records (plus, for the cross-register\n * views, the other registers), it computes the canonical derived-view tabs, the\n * group-by boards, the filtered/sorted rows, the readings-under-plan nesting, and\n * the needs-a-human counts. DOM-free and unit-tested at this seam exactly like\n * `columns.ts`; `RegisterBrowser` renders what it returns.\n *\n * The tabs are **derived views, never stored** — each is a predicate over the\n * records (and, where the ontology's derived view needs it, the other\n * registers). Membership is recomputed on every read, so renames, new readings,\n * and status changes are always reflected. Saved views are the same shaped query\n * under a user name, kept as a separate list from these canonical tabs.\n */\nimport type { AnyRecord, Collection } from \"@validation-os/core\";\nimport { riskBand, type RiskBand } from \"./primitives.js\";\nimport {\n derivedNum,\n inKillLane,\n isTesting,\n readingBeliefFor,\n readingBeliefs,\n str,\n strList,\n} from \"./derived-views.js\";\n\n/** A reading is concluded when any of its belief-scores landed a verdict\n * (Validated/Invalidated); Inconclusive-only readings move nothing. */\nfunction hasConcludedBelief(r: AnyRecord): boolean {\n return readingBeliefs(r).some((b) => b.Result !== \"Inconclusive\");\n}\n\n// ── Shaped-query descriptor ──────────────────────────────────────────────────\n\n/** A group-by axis. Only assumptions expose the full set; see `groupByAxesFor`. */\nexport type GroupByAxis = \"Lens\" | \"Theme\" | \"Risk band\" | \"Status\" | \"Owner\";\n\nexport interface SortSpec {\n /** A record field or a `derived.*` key (risk / confidence / strength …). */\n key: string;\n dir: \"asc\" | \"desc\";\n}\n\n/** The query that shapes a register view — all optional, all recomputable. */\nexport interface ViewDescriptor {\n /** Which canonical tab; defaults to the register's default tab. */\n tabId?: string;\n /** Group rows by an axis, or null for a flat list. */\n groupBy?: GroupByAxis | null;\n /** Sort override; null falls back to the tab's default sort. */\n sort?: SortSpec | null;\n /** Free-text filter over Title + Description, case-insensitive. */\n query?: string;\n}\n\n/** A saved view is a named shaped query, kept apart from the canonical tabs. */\nexport interface SavedView extends ViewDescriptor {\n name: string;\n}\n\n/**\n * The other registers a cross-register tab reads (Testing/Proven/In-tension),\n * plus the reference date overdue is measured against. Everything optional: a\n * tab whose context is absent simply matches nothing rather than throwing.\n */\nexport interface RegisterContext {\n assumptions?: AnyRecord[];\n experiments?: AnyRecord[];\n readings?: AnyRecord[];\n decisions?: AnyRecord[];\n /** ISO date \"now\" for the Overdue view; omitted → nothing reads overdue. */\n asOf?: string;\n}\n\n// ── Tab catalogue ─────────────────────────────────────────────────────────────\n\n/** A tab as the caller sees it — id + label, and whether it flags a human. */\nexport interface TabDef {\n id: string;\n label: string;\n /** The register lands here first. */\n isDefault?: boolean;\n /** A state that needs a human — surfaced as a nav count badge too (story 20). */\n needsHuman?: boolean;\n}\n\ninterface InternalTab extends TabDef {\n /** Membership predicate — a derived view over the record (+ other registers). */\n predicate: (r: AnyRecord, ctx: RegisterContext) => boolean;\n /** The tab's default sort, applied unless the descriptor overrides it. */\n defaultSort?: SortSpec;\n /** Readings only: this tab nests rows under their evidence plan (story 21). */\n nested?: boolean;\n}\n\n/** Proven (ontology derived view): a Live belief whose strongest concluded\n * belief-score across its readings is Validated. A reading scores per belief\n * now (OPS-1305), so both the strength and the verdict are read off this\n * belief's own entry in each reading's `beliefs[]`, not the retired row scalars. */\nfunction isProven(a: AnyRecord, ctx: RegisterContext): boolean {\n if (str(a.Status) !== \"Live\") return false;\n const scores = (ctx.readings ?? [])\n .map((r) => readingBeliefFor(r, a.id))\n .filter((b): b is NonNullable<typeof b> => b != null && b.Result !== \"Inconclusive\");\n if (scores.length === 0) return false;\n const strongest = scores.reduce((best, b) =>\n Math.abs(b.derived?.strength ?? 0) > Math.abs(best.derived?.strength ?? 0)\n ? b\n : best,\n );\n return strongest.Result === \"Validated\";\n}\n\n/** An overdue running plan: a Deadline in the past relative to `asOf`. */\nfunction isOverdue(e: AnyRecord, ctx: RegisterContext): boolean {\n const deadline = str(e.Deadline);\n if (!ctx.asOf || !deadline || str(e.Status) !== \"Running\") return false;\n return deadline < ctx.asOf;\n}\n\n/** A standing decision in tension: it rests on a belief that has turned against\n * it — an Invalidated assumption, or one now in the kill lane. */\nfunction inTension(d: AnyRecord, ctx: RegisterContext): boolean {\n if (str(d.Status) !== \"Active\") return false;\n const based = strList(d.basedOnIds);\n if (based.length === 0) return false;\n const byId = new Map((ctx.assumptions ?? []).map((a) => [a.id, a]));\n return based.some((id) => {\n const a = byId.get(id);\n if (!a) return false;\n return str(a.Status) === \"Invalidated\" || inKillLane(a);\n });\n}\n\nconst ALWAYS = () => true;\nconst byStatus =\n (...values: string[]) =>\n (r: AnyRecord) =>\n values.includes(str(r.Status) ?? \"\");\n\nconst TAB_CATALOGUE: Record<Collection, InternalTab[]> = {\n assumptions: [\n {\n id: \"live\",\n label: \"Live\",\n isDefault: true,\n predicate: (r) => str(r.Status) === \"Live\" && r.moot !== true,\n defaultSort: { key: \"risk\", dir: \"desc\" },\n },\n {\n id: \"testing\",\n label: \"Testing\",\n predicate: (r, ctx) => isTesting(r, ctx.experiments ?? []),\n },\n {\n id: \"kill-lane\",\n label: \"Kill lane\",\n needsHuman: true,\n predicate: (r) => inKillLane(r),\n },\n { id: \"proven\", label: \"Proven\", predicate: isProven },\n { id: \"moot\", label: \"Moot\", predicate: (r) => r.moot === true },\n { id: \"draft\", label: \"Draft\", predicate: byStatus(\"Draft\") },\n { id: \"invalidated\", label: \"Invalidated\", predicate: byStatus(\"Invalidated\") },\n ],\n experiments: [\n {\n id: \"test-next\",\n label: \"Test-next\",\n isDefault: true,\n // Candidate/designed plans — the pool the prioritisation layer ranks.\n predicate: byStatus(\"Draft\"),\n },\n { id: \"running\", label: \"Running\", predicate: byStatus(\"Running\") },\n { id: \"closed\", label: \"Closed\", predicate: byStatus(\"Closed\") },\n {\n id: \"overdue\",\n label: \"Overdue\",\n needsHuman: true,\n predicate: isOverdue,\n },\n ],\n readings: [\n {\n id: \"recent\",\n label: \"Recent\",\n isDefault: true,\n predicate: ALWAYS,\n defaultSort: { key: \"Date\", dir: \"desc\" },\n },\n {\n id: \"by-origin\",\n label: \"By plan\",\n predicate: ALWAYS,\n nested: true,\n },\n {\n id: \"concluded\",\n label: \"± Concluded\",\n predicate: (r) => hasConcludedBelief(r),\n },\n {\n id: \"inconclusive\",\n label: \"Inconclusive\",\n predicate: (r) => !hasConcludedBelief(r),\n },\n ],\n decisions: [\n {\n id: \"standing\",\n label: \"Standing\",\n isDefault: true,\n predicate: byStatus(\"Active\"),\n },\n { id: \"provisional\", label: \"Provisional\", predicate: byStatus(\"Provisional\") },\n {\n id: \"superseded\",\n label: \"Superseded\",\n predicate: byStatus(\"Superseded\", \"Reversed\"),\n },\n {\n id: \"in-tension\",\n label: \"In tension\",\n needsHuman: true,\n predicate: inTension,\n },\n ],\n glossary: [\n // The migrated glossary carries no area/theme axis, so the prototype's\n // \"By-area\" tab folds into A–Z plus the status views (OPS-1305 schema).\n {\n id: \"a-z\",\n label: \"A–Z\",\n isDefault: true,\n predicate: ALWAYS,\n defaultSort: { key: \"Title\", dir: \"asc\" },\n },\n { id: \"provisional\", label: \"Provisional\", predicate: byStatus(\"Provisional\") },\n { id: \"superseded\", label: \"Superseded\", predicate: byStatus(\"Superseded\") },\n ],\n};\n\n/** The canonical derived-view tabs for a register, in display order. */\nexport function tabsFor(register: Collection): TabDef[] {\n return TAB_CATALOGUE[register].map(({ id, label, isDefault, needsHuman }) => ({\n id,\n label,\n isDefault,\n needsHuman,\n }));\n}\n\n/** The default tab id for a register (the curated front door, story 15). */\nexport function defaultTabId(register: Collection): string {\n const tab = TAB_CATALOGUE[register].find((t) => t.isDefault);\n return (tab ?? TAB_CATALOGUE[register][0]!).id;\n}\n\nfunction findTab(register: Collection, tabId: string | undefined): InternalTab {\n const tabs = TAB_CATALOGUE[register];\n return tabs.find((t) => t.id === tabId) ?? tabs.find((t) => t.isDefault) ?? tabs[0]!;\n}\n\n// ── Group-by ───────────────────────────────────────────────────────────────\n\n/** The group-by axes a register offers. Assumptions get the full set (story 18);\n * the others expose Status, the one axis every register shares. */\nexport function groupByAxesFor(register: Collection): GroupByAxis[] {\n if (register === \"assumptions\")\n return [\"Lens\", \"Theme\", \"Risk band\", \"Status\", \"Owner\"];\n return [\"Status\"];\n}\n\nexport interface GroupBucket {\n /** Stable bucket key. */\n key: string;\n /** Plain-language bucket heading. */\n label: string;\n records: AnyRecord[];\n}\n\nconst RISK_BAND_ORDER: RiskBand[] = [\"Critical\", \"High\", \"Watch\"];\n\n/**\n * Group records by an axis. Risk band uses the three fixed bands in\n * strongest-first order; multi-value axes (Theme, Owner) place a record in every\n * bucket it belongs to, with an explicit empty-value bucket. Single-value axes\n * (Lens, Status) bucket once, empty → an \"—\" bucket. Bucket order is stable:\n * risk band by severity, everything else first-appearance.\n */\nexport function groupRecords(\n records: AnyRecord[],\n axis: GroupByAxis,\n): GroupBucket[] {\n if (axis === \"Risk band\") {\n const buckets = new Map<RiskBand, AnyRecord[]>();\n for (const r of records) {\n const band = riskBand(derivedNum(r, \"risk\") ?? 0);\n (buckets.get(band) ?? buckets.set(band, []).get(band)!).push(r);\n }\n return RISK_BAND_ORDER.filter((b) => buckets.has(b)).map((b) => ({\n key: b,\n label: b,\n records: buckets.get(b)!,\n }));\n }\n\n const multi = axis === \"Theme\" || axis === \"Owner\";\n const order: string[] = [];\n const buckets = new Map<string, AnyRecord[]>();\n const push = (key: string, r: AnyRecord) => {\n if (!buckets.has(key)) {\n buckets.set(key, []);\n order.push(key);\n }\n buckets.get(key)!.push(r);\n };\n const emptyLabel = axis === \"Owner\" ? \"Unassigned\" : \"—\";\n for (const r of records) {\n if (multi) {\n const values = strList(r[axis]);\n if (values.length === 0) push(emptyLabel, r);\n else for (const v of values) push(v, r);\n } else {\n push(str(r[axis]) ?? emptyLabel, r);\n }\n }\n return order.map((key) => ({ key, label: key, records: buckets.get(key)! }));\n}\n\n// ── Filter & sort ─────────────────────────────────────────────────────────────\n\n/** Case-insensitive substring filter over Title + Description + Source. Source\n * (a reading's generator — person / dataset / cohort) is searchable so a\n * teammate can pull every reading from one source by typing its name. */\nexport function filterRecords(records: AnyRecord[], query: string): AnyRecord[] {\n const q = query.trim().toLowerCase();\n if (!q) return records;\n return records.filter((r) => {\n const hay =\n `${str(r.Title) ?? \"\"} ${str(r.Description) ?? \"\"} ${str(r.Source) ?? \"\"}`.toLowerCase();\n return hay.includes(q);\n });\n}\n\n/** Read a sort key off a record — a `derived.*` number or a top-level field. */\nfunction sortValue(r: AnyRecord, key: string): unknown {\n const derived = derivedNum(r, key);\n if (derived !== null) return derived;\n return r[key];\n}\n\n/** A stable sort by one key; numbers compare numerically, everything else by\n * locale string. Missing values sort last regardless of direction. */\nexport function sortRecords(records: AnyRecord[], sort: SortSpec): AnyRecord[] {\n const dir = sort.dir === \"asc\" ? 1 : -1;\n return [...records]\n .map((r, i) => ({ r, i }))\n .sort((a, b) => {\n const av = sortValue(a.r, sort.key);\n const bv = sortValue(b.r, sort.key);\n const aMissing = av === null || av === undefined || av === \"\";\n const bMissing = bv === null || bv === undefined || bv === \"\";\n if (aMissing && bMissing) return a.i - b.i;\n if (aMissing) return 1;\n if (bMissing) return -1;\n let cmp: number;\n if (typeof av === \"number\" && typeof bv === \"number\") cmp = av - bv;\n else cmp = String(av).localeCompare(String(bv));\n return cmp !== 0 ? cmp * dir : a.i - b.i; // stable tie-break\n })\n .map((x) => x.r);\n}\n\n// ── Nesting: readings under their evidence plan ───────────────────────────────\n\nexport interface NestedGroup {\n /** The experiment id, or null for bare/found readings. */\n experimentId: string | null;\n /** The plan's title, or a plain label for the bare bucket. */\n label: string;\n readings: AnyRecord[];\n}\n\n/** Nest readings under their originating evidence plan (story 21). Bare/found\n * readings (no `experimentId`) collect in a trailing \"No plan\" group. Plans keep\n * the order they first appear in `experiments`. */\nexport function nestReadingsByPlan(\n readings: AnyRecord[],\n experiments: AnyRecord[],\n): NestedGroup[] {\n const titleById = new Map(experiments.map((e) => [e.id, str(e.Title)]));\n const order: (string | null)[] = [];\n const groups = new Map<string | null, AnyRecord[]>();\n for (const r of readings) {\n const key = str(r.experimentId);\n if (!groups.has(key)) {\n groups.set(key, []);\n order.push(key);\n }\n groups.get(key)!.push(r);\n }\n // Bare readings last, plans in first-seen order otherwise.\n order.sort((a, b) => Number(a === null) - Number(b === null));\n return order.map((experimentId) => ({\n experimentId,\n label:\n experimentId === null\n ? \"No plan (bare readings)\"\n : titleById.get(experimentId) ?? `Experiment ${experimentId}`,\n readings: groups.get(experimentId)!,\n }));\n}\n\n// ── The shaped view ───────────────────────────────────────────────────────────\n\nexport interface ShapedRegister {\n tabs: TabDef[];\n activeTabId: string;\n groupByAxes: GroupByAxis[];\n activeGroupBy: GroupByAxis | null;\n sort: SortSpec | null;\n query: string;\n /** Rows after tab predicate + filter + sort (the flat list). */\n rows: AnyRecord[];\n /** Group buckets when an axis is active, else null. */\n groups: GroupBucket[] | null;\n /** Readings-under-plan nesting when the active tab nests, else null. */\n nested: NestedGroup[] | null;\n}\n\n/**\n * Shape a register into its tabs, active rows, groups and nesting from a view\n * descriptor. Pure: the same records + descriptor always give the same view. The\n * descriptor round-trips — a saved view's tab/group/sort/query reproduce here.\n */\nexport function shapeRegister(\n register: Collection,\n records: AnyRecord[],\n descriptor: ViewDescriptor = {},\n ctx: RegisterContext = {},\n): ShapedRegister {\n const tab = findTab(register, descriptor.tabId);\n const inTab = records.filter((r) => tab.predicate(r, ctx));\n const filtered = filterRecords(inTab, descriptor.query ?? \"\");\n const sort = descriptor.sort ?? tab.defaultSort ?? null;\n const rows = sort ? sortRecords(filtered, sort) : filtered;\n\n const axes = groupByAxesFor(register);\n const activeGroupBy =\n descriptor.groupBy && axes.includes(descriptor.groupBy)\n ? descriptor.groupBy\n : null;\n const groups = activeGroupBy ? groupRecords(rows, activeGroupBy) : null;\n\n const nested =\n tab.nested && register === \"readings\"\n ? nestReadingsByPlan(rows, ctx.experiments ?? [])\n : null;\n\n return {\n tabs: tabsFor(register),\n activeTabId: tab.id,\n groupByAxes: axes,\n activeGroupBy,\n sort,\n query: descriptor.query ?? \"\",\n rows,\n groups,\n nested,\n };\n}\n\n// ── Needs-a-human counts (the nav badges) ─────────────────────────────────────\n\n/** The needs-a-human counts that surface as nav badges (story 20). */\nexport interface NeedsHumanCounts {\n /** Live beliefs in the kill zone awaiting a human verdict. */\n killLane: number;\n /** Running plans past their deadline. */\n overdue: number;\n /** Standing decisions resting on a belief that turned against them. */\n inTension: number;\n}\n\n/** Count the needs-a-human states across the registers, reusing the same tab\n * predicates so a badge and its tab never disagree. */\nexport function needsHumanCounts(ctx: RegisterContext): NeedsHumanCounts {\n return {\n killLane: (ctx.assumptions ?? []).filter((a) => inKillLane(a)).length,\n overdue: (ctx.experiments ?? []).filter((e) => isOverdue(e, ctx)).length,\n inTension: (ctx.decisions ?? []).filter((d) => inTension(d, ctx)).length,\n };\n}\n","/**\n * The reading detail's per-belief verdict list (OPS-1305) — one artifact row\n * scores several beliefs, so this renders each belief's own take: the\n * assumption (title + link), its Result, derived Strength and the grading\n * justification. Rung AND magnitude band are NOT per belief — they are\n * row-level attributes of the reading now (0.10), shown once as a paired header\n * badge, so neither appears on these cards. This list is the reading detail's\n * centrepiece:\n * a one-line verdict tally leads, then a stack of result-toned cards — a\n * coloured rail and a bold Result pill carry the verdict at a glance, the\n * assumption title anchors each card, and the justification reads as its own\n * quote-set-off prose. Shared by the record page and the drawer so the two\n * never drift.\n */\nimport type { AnyRecord } from \"@validation-os/core\";\nimport { formatSigned } from \"./primitives.js\";\nimport {\n readingBeliefSummary,\n readingBeliefVerdicts,\n type BeliefSummary,\n} from \"./record-view.js\";\n\n/** Verdict pill tone: Validated reads good, Invalidated crit, else neutral. */\nfunction resultClass(result: string | null): string {\n if (result === \"Validated\") return \"vos-pill vos-pill-good\";\n if (result === \"Invalidated\") return \"vos-pill vos-pill-crit\";\n return \"vos-pill vos-pill-neutral\";\n}\n\n/** The card's left-rail tone class, matching the verdict's meaning. */\nfunction verdictTone(result: string | null): string {\n if (result === \"Validated\") return \"is-good\";\n if (result === \"Invalidated\") return \"is-crit\";\n return \"is-neutral\";\n}\n\n/** The one-line tally above the cards — only the non-zero outcomes, each toned,\n * so the headline reads \"3 beliefs · 2 validated · 1 inconclusive\" at a glance. */\nfunction VerdictTally({ summary }: { summary: BeliefSummary }) {\n const parts: { n: number; label: string; cls: string }[] = [\n { n: summary.validated, label: \"validated\", cls: \"vos-tally-good\" },\n { n: summary.inconclusive, label: \"inconclusive\", cls: \"vos-tally-neutral\" },\n { n: summary.invalidated, label: \"invalidated\", cls: \"vos-tally-crit\" },\n ].filter((p) => p.n > 0);\n return (\n <p className=\"vos-verdict-tally\">\n <span className=\"vos-tally-total\">\n {summary.total} belief{summary.total === 1 ? \"\" : \"s\"}\n </span>\n {parts.map((p) => (\n <span key={p.label} className={`vos-tally-part ${p.cls}`}>\n {p.n} {p.label}\n </span>\n ))}\n </p>\n );\n}\n\nexport function BeliefVerdicts({\n reading,\n assumptions,\n onOpenRecord,\n}: {\n reading: AnyRecord;\n assumptions: AnyRecord[];\n onOpenRecord?: (id: string) => void;\n}) {\n const verdicts = readingBeliefVerdicts(reading, assumptions);\n if (verdicts.length === 0) {\n return <p className=\"vos-hint\">This reading grades no beliefs yet.</p>;\n }\n const summary = readingBeliefSummary(reading, assumptions);\n return (\n <div className=\"vos-verdicts-wrap\">\n <VerdictTally summary={summary} />\n <ul className=\"vos-verdicts\">\n {verdicts.map((v) => (\n <li\n key={v.assumptionId}\n className={`vos-verdict ${verdictTone(v.result)}`}\n >\n <div className=\"vos-verdict-head\">\n {v.linked && onOpenRecord ? (\n <button\n type=\"button\"\n className=\"vos-inline-link vos-verdict-title\"\n onClick={() => onOpenRecord(v.assumptionId)}\n >\n {v.title}\n </button>\n ) : (\n <span className=\"vos-verdict-title\">{v.title}</span>\n )}\n <span className={resultClass(v.result)}>{v.result ?? \"Ungraded\"}</span>\n </div>\n {v.strength !== null ? (\n <div className=\"vos-verdict-meta\">\n <span className=\"vos-verdict-strength\">\n Strength {formatSigned(v.strength)}\n </span>\n </div>\n ) : null}\n {v.excerpt ? (\n <p className=\"vos-verdict-quote\">“{v.excerpt}”</p>\n ) : null}\n {v.justification ? (\n <p className=\"vos-verdict-why\">{v.justification}</p>\n ) : null}\n </li>\n ))}\n </ul>\n </div>\n );\n}\n","import { useMemo, useState } from \"react\";\nimport type { AnyRecord, Collection } from \"@validation-os/core\";\nimport { columnsFor, primaryLabel } from \"./columns.js\";\nimport { DrawerShell } from \"./drawer-shell.js\";\nimport { REGISTER_LABEL, REGISTER_SINGULAR } from \"./labels.js\";\nimport {\n needsHumanCounts,\n shapeRegister,\n type GroupByAxis,\n type RegisterContext,\n type SavedView,\n type SortSpec,\n type TabDef,\n type ViewDescriptor,\n} from \"./list-surface.js\";\nimport { RegisterTable } from \"./register-table.js\";\nimport { RecordDrawer } from \"./record-drawer.js\";\nimport { RecordForm } from \"./record-form.js\";\nimport type { RelatedSet } from \"./record-view.js\";\nimport { RelationEditor } from \"./relation-editor.js\";\nimport { useList, useRecord } from \"./use-records.js\";\nimport { useSavedViews } from \"./use-saved-views.js\";\n\nexport interface RegisterBrowserProps {\n register: Collection;\n /** API base path (default `/api`). */\n basePath?: string;\n /** A one-line description under the register title (spec story 7/9). */\n subtitle?: string;\n /** Open a record's canonical full page (story 12). When set, the drawer\n * offers a \"Full page\" link; reads/edits still happen in the peek drawer. */\n onOpenRecord?: (id: string) => void;\n /** Pre-filter applied before tab/free-text — Lens × Stage from the grid. */\n lens?: string;\n stage?: string;\n}\n\n/**\n * Which context registers a register's derived-view tabs — and the record\n * drawer's relation-field/bar-line links (OPS-1345) — read. `assumptions` is\n * also needed on `experiments` (a bar line's `assumptionId`) and `readings`\n * (its own `assumptionId`), not just `decisions` (`Based on`/`Resolves`).\n */\nfunction contextNeeds(register: Collection): {\n experiments: boolean;\n readings: boolean;\n assumptions: boolean;\n} {\n return {\n experiments: register === \"assumptions\" || register === \"readings\",\n readings: register === \"assumptions\",\n assumptions:\n register === \"decisions\" ||\n register === \"experiments\" ||\n register === \"readings\",\n };\n}\n\n/**\n * The browse-create-edit surface for one register. Above the flat table sits the\n * list-surface (OPS-1287): canonical derived-view tabs (a curated default first),\n * a group-by board (assumptions by Lens / Theme / Risk band / Status / Owner),\n * free-text search and sort, readings nested under their evidence plan, and a\n * count badge on the states that need a human. Everything visible is computed by\n * the pure `shapeRegister` view-model; this component just renders it and owns\n * the descriptor state.\n *\n * The write surface is unchanged: a row opens the read/edit/relations drawer, a\n * \"New\" button opens the create form, and all reads/writes go over the Clerk-\n * gated API (which recomputes derived fields on write). The canonical full record\n * page is reachable via the drawer's \"Full page\" link when `onOpenRecord` is set.\n */\nexport function RegisterBrowser({\n register,\n basePath,\n subtitle,\n onOpenRecord,\n lens,\n stage,\n}: RegisterBrowserProps) {\n const { records, loading, error, refresh: refreshList } = useList(\n register,\n basePath,\n );\n\n // Context registers — loaded only when this register's tabs read them.\n const needs = contextNeeds(register);\n const experiments = useList(\"experiments\", basePath, needs.experiments);\n const readings = useList(\"readings\", basePath, needs.readings);\n const assumptions = useList(\"assumptions\", basePath, needs.assumptions);\n\n const [descriptor, setDescriptor] = useState<ViewDescriptor>({});\n const savedViews = useSavedViews(register);\n const [openId, setOpenId] = useState<string | null>(null);\n const [creating, setCreating] = useState(false);\n const {\n record,\n loading: recordLoading,\n error: recordError,\n refresh: refreshRecord,\n } = useRecord(register, openId, basePath);\n\n // \"Today\" for the Overdue view — a stable per-mount value.\n const [asOf] = useState(() => new Date().toISOString().slice(0, 10));\n\n const rows = records ?? [];\n const prefiltered = useMemo(() => {\n return rows.filter((r) => {\n if (lens !== undefined && (r.Lens ?? \"\") !== lens) return false;\n if (stage !== undefined && (r.Stage ?? \"\") !== stage) return false;\n return true;\n });\n }, [rows, lens, stage]);\n const ctx: RegisterContext = {\n asOf,\n assumptions: register === \"assumptions\" ? prefiltered : assumptions.records ?? [],\n experiments: register === \"experiments\" ? prefiltered : experiments.records ?? [],\n readings: register === \"readings\" ? prefiltered : readings.records ?? [],\n decisions: register === \"decisions\" ? prefiltered : [],\n };\n\n const shaped = useMemo(\n () => shapeRegister(register, prefiltered, descriptor, ctx),\n // ctx is derived from the same inputs; listing them keeps the memo honest.\n // eslint-disable-next-line react-hooks/exhaustive-deps\n [register, prefiltered, descriptor, ctx.assumptions, ctx.experiments, ctx.readings, asOf],\n );\n\n // The needs-a-human badge counts, keyed by the tab they belong to — the tab\n // itself carries the `needsHuman` flag (single source in the catalogue), so\n // a badge and its tab can never disagree.\n const counts = needsHumanCounts(ctx);\n const humanCount: Record<string, number> = {\n \"kill-lane\": counts.killLane,\n overdue: counts.overdue,\n \"in-tension\": counts.inTension,\n };\n const badgeFor = (tab: TabDef): number | null => {\n if (!tab.needsHuman) return null;\n const n = humanCount[tab.id] ?? 0;\n return n > 0 ? n : null;\n };\n\n // The drawer's relation/bar-line links (OPS-1345) read the same context\n // registers the derived-view tabs already loaded above — one fetch, two\n // consumers, never the other end of a link is left unresolved.\n const related: RelatedSet = {\n assumptions: ctx.assumptions,\n experiments: ctx.experiments,\n readings: ctx.readings,\n decisions: ctx.decisions,\n };\n\n // Assumption id → title, so a reading row's belief chips (OPS-1305) read as\n // titles. Loaded already for the readings register (see `contextNeeds`).\n const assumptionTitles = new Map(\n (ctx.assumptions ?? []).map((a) => [a.id, primaryLabel(a)]),\n );\n\n const patch = (p: Partial<ViewDescriptor>) =>\n setDescriptor((d) => ({ ...d, ...p }));\n\n const saveCurrentView = () => {\n if (typeof window === \"undefined\") return;\n const name = window.prompt(\"Name this view\");\n if (name) savedViews.save(name, descriptor);\n };\n const applySavedView = (view: SavedView) => {\n const { name: _name, ...rest } = view;\n void _name;\n setDescriptor(rest);\n };\n\n return (\n <div>\n <div className=\"vos-head\">\n <div>\n <h1>{REGISTER_LABEL[register]}</h1>\n {subtitle ? <p>{subtitle}</p> : null}\n </div>\n <div className=\"vos-spacer\" />\n <button\n type=\"button\"\n onClick={() => refreshList()}\n className=\"vos-btn vos-btn-ghost\"\n >\n ↻ Refresh\n </button>\n <button\n type=\"button\"\n onClick={() => setCreating(true)}\n className=\"vos-btn\"\n >\n + New {REGISTER_SINGULAR[register]}\n </button>\n </div>\n\n {/* Canonical derived-view tabs (story 15/16). */}\n <div className=\"vos-tabs\" role=\"tablist\" aria-label=\"Views\">\n {shaped.tabs.map((tab) => {\n const active = tab.id === shaped.activeTabId;\n const badge = badgeFor(tab);\n return (\n <button\n key={tab.id}\n type=\"button\"\n role=\"tab\"\n aria-selected={active}\n className={`vos-tab ${active ? \"is-active\" : \"\"} ${\n tab.needsHuman ? \"vos-tab-human\" : \"\"\n }`}\n onClick={() => patch({ tabId: tab.id })}\n >\n {tab.label}\n {badge !== null ? <span className=\"vos-tab-badge\">{badge}</span> : null}\n </button>\n );\n })}\n </div>\n\n {/* Group-by · sort · search (stories 18/19/23). */}\n <ViewControls\n register={register}\n descriptor={descriptor}\n axes={shaped.groupByAxes}\n onGroupBy={(groupBy) => patch({ groupBy })}\n onSort={(sort) => patch({ sort })}\n onQuery={(query) => patch({ query })}\n />\n\n {/* User saved views — a separate list from the canonical tabs (story 17). */}\n <div className=\"vos-saved-views\">\n <span className=\"vos-saved-label\">Saved views</span>\n {savedViews.views.length === 0 ? (\n <span className=\"vos-hint\">none yet</span>\n ) : (\n savedViews.views.map((v) => (\n <span key={v.name} className=\"vos-saved-view\">\n <button\n type=\"button\"\n className=\"vos-saved-apply\"\n onClick={() => applySavedView(v)}\n >\n {v.name}\n </button>\n <button\n type=\"button\"\n className=\"vos-saved-x\"\n aria-label={`Delete saved view ${v.name}`}\n onClick={() => savedViews.remove(v.name)}\n >\n ×\n </button>\n </span>\n ))\n )}\n <button\n type=\"button\"\n className=\"vos-btn vos-btn-ghost vos-btn-sm\"\n onClick={saveCurrentView}\n >\n + Save this view\n </button>\n </div>\n\n {loading && !records ? (\n <p className=\"vos-muted\">\n Loading {REGISTER_LABEL[register].toLowerCase()}…\n </p>\n ) : error ? (\n <p className=\"vos-error\">{error}</p>\n ) : (\n <ShapedBody\n register={register}\n shaped={shaped}\n onRowClick={setOpenId}\n selectedId={openId}\n assumptionTitles={assumptionTitles}\n />\n )}\n\n <RecordDrawer\n register={register}\n record={record}\n loading={recordLoading}\n error={recordError}\n open={openId !== null}\n onClose={() => setOpenId(null)}\n basePath={basePath}\n onOpenFull={\n onOpenRecord && openId ? () => onOpenRecord(openId) : undefined\n }\n onOpenRecord={onOpenRecord}\n related={related}\n onChanged={() => {\n refreshRecord();\n refreshList();\n }}\n >\n {openId ? (\n <RelationEditor\n register={register}\n recordId={openId}\n basePath={basePath}\n onLinked={() => {\n refreshRecord();\n refreshList();\n }}\n />\n ) : null}\n </RecordDrawer>\n\n <DrawerShell\n open={creating}\n onClose={() => setCreating(false)}\n ariaLabel={`New ${REGISTER_SINGULAR[register]} record`}\n >\n <header className=\"vos-drawer-header\">\n <div>\n <p className=\"vos-drawer-eyebrow\">New</p>\n <h2 className=\"vos-drawer-title\">{REGISTER_SINGULAR[register]}</h2>\n </div>\n </header>\n <RecordForm\n register={register}\n basePath={basePath}\n onCreated={(id) => {\n setCreating(false);\n refreshList();\n setOpenId(id);\n }}\n onCancel={() => setCreating(false)}\n />\n </DrawerShell>\n </div>\n );\n}\n\n/** The group-by / sort / search control row. Sort options come from the\n * register's columns, so grouping never costs the derived-score columns. */\nfunction ViewControls({\n register,\n descriptor,\n axes,\n onGroupBy,\n onSort,\n onQuery,\n}: {\n register: Collection;\n descriptor: ViewDescriptor;\n axes: GroupByAxis[];\n onGroupBy: (axis: GroupByAxis | null) => void;\n onSort: (sort: SortSpec | null) => void;\n onQuery: (query: string) => void;\n}) {\n const sortable = columnsFor(register);\n const sort = descriptor.sort ?? null;\n\n return (\n <div className=\"vos-view-controls\">\n <input\n type=\"search\"\n className=\"vos-input vos-search\"\n placeholder=\"Filter…\"\n value={descriptor.query ?? \"\"}\n onChange={(e) => onQuery(e.target.value)}\n aria-label=\"Filter records\"\n />\n\n {axes.length ? (\n <label className=\"vos-control\">\n <span>Group</span>\n <select\n className=\"vos-input\"\n value={descriptor.groupBy ?? \"\"}\n onChange={(e) =>\n onGroupBy((e.target.value || null) as GroupByAxis | null)\n }\n >\n <option value=\"\">None</option>\n {axes.map((axis) => (\n <option key={axis} value={axis}>\n {axis}\n </option>\n ))}\n </select>\n </label>\n ) : null}\n\n <label className=\"vos-control\">\n <span>Sort</span>\n <select\n className=\"vos-input\"\n value={sort?.key ?? \"\"}\n onChange={(e) =>\n onSort(\n e.target.value\n ? { key: e.target.value, dir: sort?.dir ?? \"desc\" }\n : null,\n )\n }\n >\n <option value=\"\">Default</option>\n {sortable.map((c) => (\n <option key={c.key} value={c.key}>\n {c.header}\n </option>\n ))}\n </select>\n </label>\n\n {sort ? (\n <button\n type=\"button\"\n className=\"vos-btn vos-btn-ghost vos-btn-sm\"\n onClick={() =>\n onSort({ key: sort.key, dir: sort.dir === \"asc\" ? \"desc\" : \"asc\" })\n }\n aria-label={`Sort ${sort.dir === \"asc\" ? \"ascending\" : \"descending\"}`}\n >\n {sort.dir === \"asc\" ? \"↑\" : \"↓\"}\n </button>\n ) : null}\n </div>\n );\n}\n\n/** Renders the shaped view: nested (readings under plan), grouped (a heading +\n * table per bucket), or a single flat table. Every branch reuses `RegisterTable`\n * as the leaf renderer, so the derived-score columns are identical throughout. */\nfunction ShapedBody({\n register,\n shaped,\n onRowClick,\n selectedId,\n assumptionTitles,\n}: {\n register: Collection;\n shaped: ReturnType<typeof shapeRegister>;\n onRowClick: (id: string) => void;\n selectedId: string | null;\n assumptionTitles?: Map<string, string>;\n}) {\n if (shaped.nested) {\n if (shaped.nested.length === 0)\n return <p className=\"vos-empty\">No readings in this view.</p>;\n return (\n <div className=\"vos-groups\">\n {shaped.nested.map((group) => (\n <section key={group.experimentId ?? \"__none__\"} className=\"vos-group\">\n <h3 className=\"vos-group-head\">\n {group.label}\n <span className=\"vos-group-n\">{group.readings.length}</span>\n </h3>\n <RegisterTable\n register={register}\n records={group.readings}\n onRowClick={onRowClick}\n selectedId={selectedId}\n assumptionTitles={assumptionTitles}\n />\n </section>\n ))}\n </div>\n );\n }\n\n if (shaped.groups) {\n if (shaped.groups.length === 0)\n return <p className=\"vos-empty\">No records in this view.</p>;\n return (\n <div className=\"vos-groups\">\n {shaped.groups.map((group) => (\n <section key={group.key} className=\"vos-group\">\n <h3 className=\"vos-group-head\">\n {group.label}\n <span className=\"vos-group-n\">{group.records.length}</span>\n </h3>\n <RegisterTable\n register={register}\n records={group.records}\n onRowClick={onRowClick}\n selectedId={selectedId}\n assumptionTitles={assumptionTitles}\n />\n </section>\n ))}\n </div>\n );\n }\n\n return (\n <RegisterTable\n register={register}\n records={shaped.rows}\n onRowClick={onRowClick}\n selectedId={selectedId}\n assumptionTitles={assumptionTitles}\n />\n );\n}\n","import type { AnyRecord, Collection } from \"@validation-os/core\";\nimport {\n cellValue,\n columnsFor,\n formatValue,\n primaryLabel,\n readingAssumptionChips,\n type ColumnDef,\n} from \"./columns.js\";\nimport { ConfidenceCell, RiskBar, StatusPill } from \"./primitives-view.js\";\n\nexport interface RegisterTableProps {\n register: Collection;\n records: AnyRecord[];\n /** Called with the clicked record's id — opens the read-only drawer. */\n onRowClick?: (id: string) => void;\n /** The id of the currently-open record, highlighted in the list. */\n selectedId?: string | null;\n /** Assumption id → title, so a reading row's belief chips read as titles\n * rather than ids (OPS-1305). Omitted → chips fall back to the bare ids. */\n assumptionTitles?: Map<string, string>;\n}\n\n/**\n * A list table for one register — a row per record, the register's key fields\n * as columns. Assumptions read their state at a glance: a colored Status pill, a\n * signed Confidence, and a threshold-toned Risk bar (spec stories 4–6). Which\n * cells render as pills/bars/sparklines is declared on the column (`kind`), so\n * the treatment stays testable at the columns seam and this component stays a\n * dumb renderer. Presentational: the caller supplies the rows.\n */\nexport function RegisterTable({\n register,\n records,\n onRowClick,\n selectedId,\n assumptionTitles,\n}: RegisterTableProps) {\n const columns = columnsFor(register);\n\n if (records.length === 0) {\n return <p className=\"vos-empty\">No records yet.</p>;\n }\n\n return (\n <div className=\"vos-card vos-table-scroll\">\n <table className=\"vos-table\">\n <thead>\n <tr>\n {columns.map((c) => (\n <th\n key={c.key}\n scope=\"col\"\n className={c.align === \"right\" ? \"vos-r\" : undefined}\n >\n {c.header}\n </th>\n ))}\n </tr>\n </thead>\n <tbody>\n {records.map((record) => {\n const isSelected = record.id === selectedId;\n return (\n <tr\n key={record.id}\n onClick={() => onRowClick?.(record.id)}\n onKeyDown={\n onRowClick\n ? (e) => {\n if (e.key === \"Enter\" || e.key === \" \") {\n e.preventDefault();\n onRowClick(record.id);\n }\n }\n : undefined\n }\n tabIndex={onRowClick ? 0 : undefined}\n aria-selected={isSelected}\n className={isSelected ? \"is-selected\" : undefined}\n >\n {columns.map((c, i) => (\n <td\n key={c.key}\n className={c.align === \"right\" ? \"vos-r\" : undefined}\n >\n <Cell\n column={c}\n record={record}\n headline={i === 0}\n chips={\n i === 0 && register === \"readings\"\n ? readingAssumptionChips(record, assumptionTitles)\n : undefined\n }\n />\n </td>\n ))}\n </tr>\n );\n })}\n </tbody>\n </table>\n </div>\n );\n}\n\n/** One cell, rendered per its column's `kind`. The headline column falls back\n * to the record's id so a row is never blank. */\nfunction Cell({\n column,\n record,\n headline,\n chips,\n}: {\n column: ColumnDef;\n record: AnyRecord;\n headline: boolean;\n /** Belief chips shown under the headline (readings only) to disambiguate\n * same-titled readings by the belief(s) each one grades. */\n chips?: string[];\n}) {\n const raw = cellValue(column, record);\n\n if (column.kind === \"status\") {\n return <StatusPill status={raw == null ? null : String(raw)} />;\n }\n if (column.kind === \"risk\") {\n return typeof raw === \"number\" ? (\n <RiskBar risk={raw} />\n ) : (\n <span className=\"vos-muted\">—</span>\n );\n }\n if (column.kind === \"confidence\") {\n return typeof raw === \"number\" ? (\n <ConfidenceCell confidence={raw} />\n ) : (\n <span className=\"vos-muted\">—</span>\n );\n }\n\n const text =\n headline && (raw === null || raw === undefined || raw === \"\")\n ? primaryLabel(record)\n : formatValue(raw);\n if (headline && chips && chips.length > 0) {\n return (\n <span className=\"vos-ttl-wrap\">\n <span className=\"vos-ttl\">{text}</span>\n <span className=\"vos-reading-chips\">\n {chips.map((chip, n) => (\n <span key={n} className=\"vos-chip vos-pill vos-pill-neutral\">\n {chip}\n </span>\n ))}\n </span>\n </span>\n );\n }\n return <span className={headline ? \"vos-ttl\" : undefined}>{text}</span>;\n}\n","import { useEffect, useState, type ReactNode } from \"react\";\nimport type { AnyRecord, Collection } from \"@validation-os/core\";\nimport { DrawerShell } from \"./drawer-shell.js\";\nimport { REGISTER_LABEL } from \"./labels.js\";\nimport { derivedLabel, formatValue, primaryLabel } from \"./columns.js\";\nimport { detailRows, type DetailRow } from \"./detail-fields.js\";\nimport { derivedTone, formatSigned, heroToneClass } from \"./primitives.js\";\nimport { buildPatch, draftErrors, draftFrom, type Draft } from \"./edit.js\";\nimport { EditFields } from \"./edit-fields.js\";\nimport type { RelatedSet } from \"./record-view.js\";\nimport { useUpdate } from \"./use-records.js\";\nimport { UnderstandingPanel } from \"./understanding-panel.js\";\nimport { EvidenceBody } from \"./markdown.js\";\nimport { BeliefVerdicts } from \"./belief-verdicts.js\";\n\nexport interface RecordDrawerProps {\n register: Collection;\n /** The open record, or null while loading / when nothing is selected. */\n record: AnyRecord | null;\n /** True while the record is being fetched. */\n loading?: boolean;\n error?: string | null;\n /** Whether the drawer is open (a row is selected). */\n open: boolean;\n onClose: () => void;\n /** API base path (default `/api`). */\n basePath?: string;\n /** Re-fetch the record + its list — called after a save, and the re-fetch\n * path offered when a concurrent edit is detected. */\n onChanged?: () => void;\n /** Open this record's canonical full page (story 12). When set, the header\n * shows a \"Full page\" link; the drawer stays the quick read/edit peek. */\n onOpenFull?: () => void;\n /**\n * Open *any* linked record's full page (OPS-1345) — the same navigation the\n * canonical record page's Connections tab uses, reused here so a relation\n * field or a bar line's assumption is a click, not inert text. Falls back\n * to plain (unclickable) titles when omitted.\n */\n onOpenRecord?: (id: string) => void;\n /** The other registers' rows, loaded so a relation field / bar line can\n * resolve to a title instead of a raw id (OPS-1345). Omitted relations\n * simply fall back to showing the id. */\n related?: RelatedSet;\n /** Extra content below the fields in read mode — e.g. the relation editor. */\n children?: ReactNode;\n}\n\n/** Sub-captions under the derived numbers — the formula, in plain language. */\nconst DERIVED_SUB: Record<string, string> = {\n confidence: \"Signed average of concluded readings\",\n risk: \"Impact × (1 − Confidence⁺/100)\",\n derivedImpact: \"Impact re-weighted by links\",\n impact: \"Impact re-weighted by links\",\n strength: \"of the evidence base\",\n sourceQuality: \"of the source\",\n};\n\n/**\n * A record drawer that reads and edits, and wires relations. The derived\n * numbers lead as a visually distinct \"computed — not editable\" hero (spec\n * stories 4/10): a bordered box, each number big and mono, Confidence toned by\n * sign and Risk by threshold, with a \"Why?\" reveal opening the understanding\n * layer in the same accent/pill language (story 11). Editing recomputes those\n * numbers server-side on save; a concurrent edit surfaces as a gentle, jargon-\n * free prompt with a re-fetch path (story 12). In read mode the drawer hosts\n * the relation editor (`children`). Chrome is shared via `DrawerShell`; styled\n * with the package's own token sheet, no host Tailwind.\n */\nexport function RecordDrawer({\n register,\n record,\n loading,\n error,\n open,\n onClose,\n basePath,\n onChanged,\n onOpenFull,\n onOpenRecord,\n related,\n children,\n}: RecordDrawerProps) {\n const [editing, setEditing] = useState(false);\n const [draft, setDraft] = useState<Draft>({});\n // The record as it was when editing began. Diffing the draft against this\n // (not the live `record`) is what makes a conflict re-fetch safe: only the\n // fields the editor actually changed are written, on top of the latest\n // version — so a teammate's concurrent change to an untouched field survives.\n const [baseline, setBaseline] = useState<AnyRecord | null>(null);\n const [why, setWhy] = useState(false);\n const { save, saving, conflict, error: saveError, reset } = useUpdate(\n register,\n basePath,\n );\n\n // Opening a different record drops any in-progress edit and clears banners.\n const recordId = record?.id ?? null;\n useEffect(() => {\n setEditing(false);\n setBaseline(null);\n setWhy(false);\n reset();\n }, [recordId, reset]);\n\n const derived =\n record && record.derived && typeof record.derived === \"object\"\n ? (record.derived as Record<string, unknown>)\n : null;\n\n const rows = record ? detailRows(register, record, related ?? {}) : [];\n\n function startEditing() {\n if (!record) return;\n setBaseline(record);\n setDraft(draftFrom(register, record));\n reset();\n setEditing(true);\n }\n\n function cancelEditing() {\n setEditing(false);\n reset();\n }\n\n async function onSave() {\n if (!record || !baseline) return;\n // A field that fails validation (e.g. Impact outside 0–100) blocks the\n // write entirely — never sent, so the server's own range check is a\n // backstop, not the first line of defence.\n if (Object.keys(draftErrors(register, draft)).length > 0) return;\n // Diff against the baseline (the fields the editor changed), but write\n // against the freshest known version so a reloaded record rebases cleanly.\n const patch = buildPatch(register, baseline, draft);\n patch.version = record.version;\n if (Object.keys(patch).length <= 1) {\n setEditing(false); // only `version` present — nothing actually changed\n return;\n }\n const result = await save(record.id, patch);\n if (result.ok) {\n setEditing(false);\n onChanged?.(); // pull the recomputed record + refreshed list back in\n }\n // On conflict/error the hook holds the message; we stay in edit mode with\n // the draft intact so nothing the editor typed is lost.\n }\n\n function reloadLatest() {\n reset();\n // Re-fetch the latest record; the baseline is kept, so the next save still\n // writes only the fields this editor changed — never the teammate's edits.\n onChanged?.();\n }\n\n const setField = (key: string, value: string) =>\n setDraft((d) => ({ ...d, [key]: value }));\n\n const errors = editing ? draftErrors(register, draft) : {};\n const hasErrors = Object.keys(errors).length > 0;\n\n return (\n <DrawerShell\n open={open}\n onClose={onClose}\n ariaLabel={`${REGISTER_LABEL[register]} record`}\n >\n <header className=\"vos-drawer-header\">\n <div style={{ flex: 1, minWidth: 0 }}>\n <p className=\"vos-drawer-eyebrow\">{REGISTER_LABEL[register]}</p>\n <h2 className=\"vos-drawer-title\">\n {record ? primaryLabel(record) : loading ? \"Loading…\" : \"—\"}\n </h2>\n </div>\n {record ? (\n <span className=\"vos-verbadge\">v{formatValue(record.version)}</span>\n ) : null}\n {record && !editing && onOpenFull ? (\n <button\n type=\"button\"\n onClick={onOpenFull}\n className=\"vos-btn vos-btn-ghost vos-btn-sm\"\n >\n Full page ↗\n </button>\n ) : null}\n {record && !editing ? (\n <button\n type=\"button\"\n onClick={startEditing}\n className=\"vos-btn vos-btn-ghost vos-btn-sm\"\n >\n Edit\n </button>\n ) : null}\n <button\n type=\"button\"\n onClick={onClose}\n className=\"vos-iconbtn\"\n aria-label=\"Close\"\n >\n ✕\n </button>\n </header>\n\n <div className=\"vos-drawer-body\">\n {loading ? (\n <p className=\"vos-muted\">Loading record…</p>\n ) : error ? (\n <p className=\"vos-error\">{error}</p>\n ) : !record ? (\n <p className=\"vos-muted\">No record.</p>\n ) : (\n <>\n {derived ? (\n <div>\n <div className=\"vos-derived\">\n <div className=\"vos-derived-head\">\n Derived\n <span className=\"vos-lock\">🔒 computed on write — not editable</span>\n </div>\n <div className=\"vos-dgrid\">\n {Object.entries(derived).map(([key, value]) => (\n <DerivedCell\n key={key}\n field={key}\n value={value}\n showWhy={key === \"confidence\"}\n whyOpen={why}\n onWhy={() => setWhy((w) => !w)}\n />\n ))}\n </div>\n </div>\n {\"confidence\" in derived && why ? (\n <div className=\"vos-why-panel\">\n <UnderstandingPanel assumption={record} basePath={basePath} />\n </div>\n ) : null}\n </div>\n ) : null}\n\n {conflict ? (\n <ConflictBanner message={conflict} onReload={reloadLatest} />\n ) : null}\n {saveError ? (\n <p role=\"alert\" className=\"vos-banner vos-banner-crit\">\n {saveError}\n </p>\n ) : null}\n\n {editing ? (\n <EditFields\n register={register}\n draft={draft}\n errors={errors}\n onField={setField}\n />\n ) : (\n <>\n <div className=\"vos-detail-list\">\n {rows.map((row) => (\n <DetailRowView\n key={row.key}\n row={row}\n onOpenRecord={onOpenRecord}\n />\n ))}\n </div>\n {typeof record.body === \"string\" && record.body.trim() ? (\n <section className=\"vos-record-prose\">\n <div className=\"vos-detail-k\">\n {register === \"readings\" ? \"Quote\" : \"Narrative\"}\n </div>\n <EvidenceBody\n text={record.body}\n partLabel={register === \"readings\" ? \"Finding\" : \"Part\"}\n />\n </section>\n ) : null}\n {register === \"readings\" ? (\n <section className=\"vos-record-prose\">\n <div className=\"vos-detail-k\">Per-belief verdicts</div>\n <BeliefVerdicts\n reading={record}\n assumptions={related?.assumptions ?? []}\n onOpenRecord={onOpenRecord}\n />\n </section>\n ) : null}\n </>\n )}\n </>\n )}\n </div>\n\n {/* Relation editor (read mode only) — editing keeps the drawer focused. */}\n {record && !loading && !error && !editing ? children : null}\n\n {record && editing ? (\n <footer className=\"vos-drawer-footer\">\n <button\n type=\"button\"\n onClick={cancelEditing}\n disabled={saving}\n className=\"vos-btn vos-btn-ghost vos-btn-sm\"\n >\n Cancel\n </button>\n <button\n type=\"button\"\n onClick={onSave}\n disabled={saving || hasErrors}\n title={hasErrors ? \"Fix the highlighted field before saving\" : undefined}\n className=\"vos-btn vos-btn-sm\"\n >\n {saving ? \"Saving…\" : \"Save\"}\n </button>\n </footer>\n ) : record ? (\n <footer className=\"vos-drawer-footer\">\n {record.id} · updated {formatValue(record.updatedAt)}\n </footer>\n ) : null}\n </DrawerShell>\n );\n}\n\n/** One row in the generic field list (OPS-1345) — a relation field renders\n * as linked title(s), `Owner`/`Agreed by` as plain name(s), `barLines` as\n * structured rows with a linked assumption; everything else is `row.text`\n * from `formatValue`. Never the stored id or raw JSON. */\nfunction DetailRowView({\n row,\n onOpenRecord,\n}: {\n row: DetailRow;\n onOpenRecord?: (id: string) => void;\n}) {\n return (\n <div className=\"vos-detail-row\">\n <span className=\"vos-detail-k\">{row.label}</span>\n <span className=\"vos-detail-v\">\n {row.kind === \"relation\" ? (\n row.items && row.items.length ? (\n <RelationLinks items={row.items} onOpenRecord={onOpenRecord} />\n ) : (\n \"—\"\n )\n ) : row.kind === \"owner\" ? (\n row.names && row.names.length ? row.names.join(\", \") : \"—\"\n ) : row.kind === \"bar-lines\" ? (\n row.bars && row.bars.length ? (\n <ul className=\"vos-bars\">\n {row.bars.map((b, i) => (\n <li key={i} className=\"vos-bar-line\">\n <span className=\"vos-bar-if\">{b.rightIf || \"—\"}</span>\n {b.assumption ? (\n <InlineLink\n id={b.assumption.id}\n title={b.assumption.title}\n onOpenRecord={onOpenRecord}\n />\n ) : null}\n <span\n className={\n b.barVerdict\n ? \"vos-pill vos-pill-good\"\n : \"vos-pill vos-pill-neutral\"\n }\n >\n {b.barVerdict ?? \"open\"}\n </span>\n </li>\n ))}\n </ul>\n ) : (\n \"—\"\n )\n ) : (\n row.text\n )}\n </span>\n </div>\n );\n}\n\n/** A comma-separated list of clickable relation links — falls back to plain\n * (unclickable) titles when no navigate handler is wired. */\nfunction RelationLinks({\n items,\n onOpenRecord,\n}: {\n items: { id: string; title: string }[];\n onOpenRecord?: (id: string) => void;\n}) {\n return (\n <span className=\"vos-detail-links\">\n {items.map((item, i) => (\n <span key={item.id}>\n {i > 0 ? \", \" : null}\n <InlineLink id={item.id} title={item.title} onOpenRecord={onOpenRecord} />\n </span>\n ))}\n </span>\n );\n}\n\n/** One navigable title — a button when a navigate handler is wired, else\n * plain text (still a title, never a raw id). */\nfunction InlineLink({\n id,\n title,\n onOpenRecord,\n}: {\n id: string;\n title: string;\n onOpenRecord?: (id: string) => void;\n}) {\n return onOpenRecord ? (\n <button\n type=\"button\"\n className=\"vos-inline-link\"\n onClick={() => onOpenRecord(id)}\n >\n {title}\n </button>\n ) : (\n <span>{title}</span>\n );\n}\n\n/** One number in the derived hero: label (+ \"Why?\" on Confidence), the big\n * mono value toned by meaning, and the formula sub-caption. */\nfunction DerivedCell({\n field,\n value,\n showWhy,\n whyOpen,\n onWhy,\n}: {\n field: string;\n value: unknown;\n showWhy: boolean;\n whyOpen: boolean;\n onWhy: () => void;\n}) {\n const num = typeof value === \"number\" ? value : null;\n let toneClass = \"\";\n let display = formatValue(value);\n if (num !== null) {\n toneClass = heroToneClass(derivedTone(field, num));\n // Confidence is signed; the other numbers read as whole counts.\n display = field === \"confidence\" ? formatSigned(num) : String(Math.round(num));\n }\n return (\n <div className=\"vos-dcell\">\n <div className=\"vos-dcell-k\">\n {derivedLabel(field)}\n {showWhy ? (\n <button\n type=\"button\"\n className=\"vos-why\"\n onClick={onWhy}\n aria-expanded={whyOpen}\n >\n Why? {whyOpen ? \"▴\" : \"▾\"}\n </button>\n ) : null}\n </div>\n <div className={`vos-dcell-v ${toneClass}`}>{display}</div>\n {DERIVED_SUB[field] ? (\n <div className=\"vos-dcell-sub\">{DERIVED_SUB[field]}</div>\n ) : null}\n </div>\n );\n}\n\nfunction ConflictBanner({\n message,\n onReload,\n}: {\n message: string;\n onReload: () => void;\n}) {\n return (\n <div role=\"alert\" className=\"vos-banner vos-banner-warn\">\n <div className=\"vos-banner-body\">\n <span>{message}</span>\n </div>\n <button type=\"button\" onClick={onReload}>\n Review the latest\n </button>\n </div>\n );\n}\n\n","import { useMemo, useState } from \"react\";\nimport type { Collection } from \"@validation-os/core\";\nimport { REGISTER_LABEL } from \"./labels.js\";\nimport {\n emptyDraft,\n formFieldsFor,\n missingRequired,\n toCreatePayload,\n type FormField,\n} from \"./form-fields.js\";\nimport { FIELD_CONTROL_CLASS, FIELD_LABEL_CLASS } from \"./field-styles.js\";\nimport { useCreate } from \"./use-mutations.js\";\n\nexport interface RecordFormProps {\n register: Collection;\n basePath?: string;\n /** Called with the new record's id after a successful create. */\n onCreated: (id: string) => void;\n onCancel: () => void;\n}\n\n/**\n * The \"new record\" form for one register (spec user story 13). Editable own-\n * fields only — derived numbers are computed server-side and marked\n * computed-not-editable elsewhere; relations are wired by linking after the\n * record exists. Presence-gap fields (5 Whys, etc.) appear as first-class\n * textareas. On submit it POSTs through the API, which recomputes on write.\n */\nexport function RecordForm({\n register,\n basePath,\n onCreated,\n onCancel,\n}: RecordFormProps) {\n const fields = useMemo(() => formFieldsFor(register), [register]);\n const [draft, setDraft] = useState<Record<string, string>>(() =>\n emptyDraft(register),\n );\n const { create, saving, error } = useCreate(register, basePath);\n\n const missing = missingRequired(register, draft);\n const set = (key: string, value: string) =>\n setDraft((d) => ({ ...d, [key]: value }));\n\n const onSubmit = async (e: React.FormEvent) => {\n e.preventDefault();\n if (missing.length > 0 || saving) return;\n try {\n const created = await create(toCreatePayload(register, draft));\n onCreated(created.id);\n } catch {\n // The hook surfaces the message in `error`; keep the form open to retry.\n }\n };\n\n return (\n <form onSubmit={onSubmit} className=\"vos-form\">\n <div className=\"vos-form-body\">\n {fields.map((field) => (\n <Field\n key={field.key}\n field={field}\n value={draft[field.key] ?? \"\"}\n onChange={(v) => set(field.key, v)}\n />\n ))}\n {error ? <p className=\"vos-error\">{error}</p> : null}\n </div>\n\n <footer className=\"vos-drawer-footer\">\n <button type=\"button\" onClick={onCancel} className=\"vos-btn vos-btn-ghost vos-btn-sm\">\n Cancel\n </button>\n <button\n type=\"submit\"\n disabled={missing.length > 0 || saving}\n title={\n missing.length > 0 ? `Fill in: ${missing.join(\", \")}` : undefined\n }\n className=\"vos-btn vos-btn-sm\"\n >\n {saving ? \"Creating…\" : `Create ${REGISTER_LABEL[register]}`}\n </button>\n </footer>\n </form>\n );\n}\n\nfunction Field({\n field,\n value,\n onChange,\n}: {\n field: FormField;\n value: string;\n onChange: (value: string) => void;\n}) {\n const id = `field-${field.key}`;\n return (\n <div className=\"vos-field\">\n <label htmlFor={id} className={FIELD_LABEL_CLASS}>\n {field.label}\n {field.required ? <span className=\"vos-req\"> *</span> : null}\n </label>\n {field.kind === \"textarea\" ? (\n <textarea\n id={id}\n value={value}\n rows={3}\n placeholder={field.placeholder}\n onChange={(e) => onChange(e.target.value)}\n className={FIELD_CONTROL_CLASS}\n />\n ) : field.kind === \"select\" ? (\n <select\n id={id}\n value={value}\n onChange={(e) => onChange(e.target.value)}\n className={FIELD_CONTROL_CLASS}\n >\n <option value=\"\">—</option>\n {field.options?.map((opt) => (\n <option key={opt} value={opt}>\n {opt}\n </option>\n ))}\n </select>\n ) : (\n <input\n id={id}\n type={field.kind === \"number\" ? \"number\" : \"text\"}\n value={value}\n placeholder={field.placeholder}\n onChange={(e) => onChange(e.target.value)}\n className={FIELD_CONTROL_CLASS}\n />\n )}\n </div>\n );\n}\n","/**\n * The editable-field spec for the \"new record\" form, per register — kept as\n * pure data + functions (like `columns.ts`) so the create form is unit-testable\n * without a DOM. Only a record's own scalar fields appear here: derived numbers\n * are computed server-side (never typed), and relations are wired separately by\n * linking (see `relations.ts` / the relation editor), so id/relation fields are\n * deliberately absent. Vocabularies mirror `core`'s type unions.\n */\nimport type { Collection } from \"@validation-os/core\";\nimport type { FieldKind } from \"./edit.js\";\n\n// The create form and the edit form speak the same field-kind vocabulary\n// (`FieldKind` lives in `edit.js`); the create-side spec adds `required` (a\n// blank blocks submit) and numeric `coerce` (a labelled numeric select → a\n// number), which the edit side doesn't need.\n\nexport interface FormField {\n /** Record field key (what the create payload uses). */\n key: string;\n /** Plain-language label a non-technical teammate reads. */\n label: string;\n kind: FieldKind;\n /** Options for a `select`. */\n options?: readonly string[];\n /** A `select`/`text` value that should be stored as a number. */\n coerce?: \"number\";\n required?: boolean;\n placeholder?: string;\n}\n\nconst ASSUMPTION_STATUS = [\"Draft\", \"Live\", \"Invalidated\"] as const;\nconst EXPERIMENT_STATUS = [\"Draft\", \"Running\", \"Closed\"] as const;\nconst CLOSURE_REASON = [\"Completed\", \"Early-stop\", \"Kill\"] as const;\nconst EXPERIMENT_OUTCOME = [\"Achieved\", \"Missed\", \"Dropped\"] as const;\nconst DECISION_STATUS = [\"Active\", \"Provisional\", \"Superseded\", \"Reversed\"] as const;\nconst GLOSSARY_STATUS = [\"Active\", \"Provisional\", \"Superseded\"] as const;\nconst FEASIBILITY = [\"High\", \"Medium\", \"Low\"] as const;\n/** Representativeness / Credibility picks, as labelled numeric options. */\nconst QUALITY = [\"1\", \"0.7\", \"0.5\"] as const;\n\nconst FIELDS: Record<Collection, FormField[]> = {\n assumptions: [\n { key: \"Title\", label: \"Assumption\", kind: \"text\", required: true },\n { key: \"Description\", label: \"Description\", kind: \"textarea\" },\n { key: \"Lens\", label: \"Lens\", kind: \"text\" },\n { key: \"Impact\", label: \"Impact (0–100)\", kind: \"number\" },\n { key: \"Status\", label: \"Status\", kind: \"select\", options: ASSUMPTION_STATUS },\n {\n key: \"Scoring justification\",\n label: \"Scoring justification\",\n kind: \"textarea\",\n },\n ],\n experiments: [\n { key: \"Title\", label: \"Experiment\", kind: \"text\", required: true },\n { key: \"Instrument\", label: \"Instrument\", kind: \"text\" },\n { key: \"Feasibility\", label: \"Feasibility\", kind: \"select\", options: FEASIBILITY },\n { key: \"Status\", label: \"Status\", kind: \"select\", options: EXPERIMENT_STATUS },\n {\n key: \"closureReason\",\n label: \"Closure reason\",\n kind: \"select\",\n options: CLOSURE_REASON,\n },\n { key: \"Deadline\", label: \"Deadline\", kind: \"text\", placeholder: \"YYYY-MM-DD\" },\n { key: \"Outcome\", label: \"Outcome\", kind: \"select\", options: EXPERIMENT_OUTCOME },\n { key: \"Date\", label: \"Date\", kind: \"text\", placeholder: \"YYYY-MM-DD\" },\n ],\n readings: [\n { key: \"Title\", label: \"Reading\", kind: \"text\", required: true },\n { key: \"Source\", label: \"Source\", kind: \"text\" },\n // Rung / Result / Magnitude band / Grading justification are PER BELIEF now\n // (OPS-1305) — carried in `beliefs[]`, not on the row. They are omitted here\n // so the create form can never write a dead row-level field; grading a\n // reading's beliefs is a deferred follow-up (a `beliefs[]` editor).\n {\n key: \"Representativeness\",\n label: \"Representativeness\",\n kind: \"select\",\n options: QUALITY,\n coerce: \"number\",\n },\n {\n key: \"Credibility\",\n label: \"Credibility\",\n kind: \"select\",\n options: QUALITY,\n coerce: \"number\",\n },\n { key: \"body\", label: \"Quote\", kind: \"textarea\" },\n { key: \"Date\", label: \"Date\", kind: \"text\", placeholder: \"YYYY-MM-DD\" },\n ],\n decisions: [\n { key: \"Title\", label: \"Decision\", kind: \"text\", required: true },\n { key: \"Statement\", label: \"Statement\", kind: \"textarea\" },\n { key: \"Status\", label: \"Status\", kind: \"select\", options: DECISION_STATUS },\n ],\n glossary: [\n { key: \"Title\", label: \"Term\", kind: \"text\", required: true },\n { key: \"Status\", label: \"Status\", kind: \"select\", options: GLOSSARY_STATUS },\n { key: \"Definition\", label: \"Definition\", kind: \"textarea\" },\n { key: \"How it differs\", label: \"How it differs\", kind: \"textarea\" },\n ],\n};\n\n/** The editable fields for a register's create form, in display order. */\nexport function formFieldsFor(register: Collection): FormField[] {\n return FIELDS[register];\n}\n\n/** A blank draft: every field keyed to an empty string (form-friendly). */\nexport function emptyDraft(register: Collection): Record<string, string> {\n const draft: Record<string, string> = {};\n for (const f of formFieldsFor(register)) draft[f.key] = \"\";\n return draft;\n}\n\n/** Labels of required fields the draft has left blank (submit-gating). */\nexport function missingRequired(\n register: Collection,\n draft: Record<string, string>,\n): string[] {\n return formFieldsFor(register)\n .filter((f) => f.required && !String(draft[f.key] ?? \"\").trim())\n .map((f) => f.label);\n}\n\n/**\n * Turn a string-keyed form draft into a create payload: numbers coerced, blank\n * optional values dropped so the record stores only what was filled. Derived\n * and relation fields are never here — the server computes the former and\n * linking wires the latter.\n */\nexport function toCreatePayload(\n register: Collection,\n draft: Record<string, string>,\n): Record<string, unknown> {\n const out: Record<string, unknown> = {};\n for (const f of formFieldsFor(register)) {\n const raw = String(draft[f.key] ?? \"\").trim();\n if (raw === \"\") continue; // leave unfilled fields unset\n if (f.kind === \"number\" || f.coerce === \"number\") {\n const n = Number(raw);\n if (!Number.isNaN(n)) out[f.key] = n;\n } else {\n out[f.key] = raw;\n }\n }\n return out;\n}\n","import { useMemo, useState } from \"react\";\nimport type { Collection } from \"@validation-os/core\";\nimport { primaryLabel } from \"./columns.js\";\nimport { FIELD_CONTROL_CLASS } from \"./field-styles.js\";\nimport { linkChoicesFrom } from \"./link-choices.js\";\nimport { useList } from \"./use-records.js\";\nimport { useLink } from \"./use-mutations.js\";\n\nexport interface RelationEditorProps {\n /** The register of the open record initiating the link. */\n register: Collection;\n /** The open record's id (the `from` end). */\n recordId: string;\n basePath?: string;\n /** Called after a relation is wired, so the drawer can re-fetch. */\n onLinked: () => void;\n}\n\n/**\n * Wire a relation from the open record (spec user story 14). Pick an edge, then\n * a target record from the register that edge points at; linking sets both ends\n * server-side and recomputes derived fields. Registers with no outbound edges\n * (glossary, people) render nothing.\n */\nexport function RelationEditor({\n register,\n recordId,\n basePath,\n onLinked,\n}: RelationEditorProps) {\n const choices = useMemo(() => linkChoicesFrom(register), [register]);\n const [relation, setRelation] = useState(\"\");\n const [targetId, setTargetId] = useState(\"\");\n const { link, linking, error } = useLink(basePath);\n\n const active = choices.find((c) => c.relation === relation) ?? null;\n const { records } = useList(\n (active?.targetRegister ?? register) as Collection,\n basePath,\n );\n // Never offer to link a record to itself (self-referential registers).\n const targets = (records ?? []).filter(\n (r) => !(active?.targetRegister === register && r.id === recordId),\n );\n\n if (choices.length === 0) return null;\n\n const onLink = async () => {\n if (!active || !targetId || linking) return;\n try {\n await link({\n relation: active.relation,\n from: { register, id: recordId },\n to: { register: active.targetRegister, id: targetId },\n });\n setTargetId(\"\");\n setRelation(\"\");\n onLinked();\n } catch {\n // `error` carries the message; leave the picks in place to retry.\n }\n };\n\n return (\n <section className=\"vos-relation\">\n <h3 className=\"vos-sectitle\">Link a record</h3>\n <div className=\"vos-field-stack\">\n <select\n aria-label=\"Relation\"\n value={relation}\n onChange={(e) => {\n setRelation(e.target.value);\n setTargetId(\"\");\n }}\n className={FIELD_CONTROL_CLASS}\n >\n <option value=\"\">Choose a relation…</option>\n {choices.map((c) => (\n <option key={c.relation} value={c.relation}>\n {c.label}\n </option>\n ))}\n </select>\n\n {active ? (\n <select\n aria-label=\"Target record\"\n value={targetId}\n onChange={(e) => setTargetId(e.target.value)}\n className={FIELD_CONTROL_CLASS}\n >\n <option value=\"\">Choose a record…</option>\n {targets.map((r) => (\n <option key={r.id} value={r.id}>\n {primaryLabel(r)}\n </option>\n ))}\n </select>\n ) : null}\n\n {error ? <p className=\"vos-error\">{error}</p> : null}\n\n <button\n type=\"button\"\n onClick={onLink}\n disabled={!active || !targetId || linking}\n className=\"vos-btn vos-btn-sm\"\n style={{ alignSelf: \"flex-start\" }}\n >\n {linking ? \"Linking…\" : \"Link\"}\n </button>\n </div>\n </section>\n );\n}\n","/**\n * Which relations a record of a given register can initiate — the menu the\n * relation editor offers. Derived from `core`'s single `RELATIONS` table (so\n * the two never drift) and turned into plain-language choices, each naming the\n * register whose records are valid link targets.\n */\nimport { RELATIONS, type Collection, type Relation } from \"@validation-os/core\";\n\nexport interface LinkChoice {\n relation: Relation;\n /** Plain-language name of the edge, from the initiating record's side. */\n label: string;\n /** The register to pick a target record from. */\n targetRegister: Collection;\n}\n\n/** Plain-language label for each relation, read from the `from` side. */\nconst RELATION_LABEL: Record<Relation, string> = {\n \"assumption-reading\": \"Add reading\",\n \"assumption-depends-on\": \"Depends on\",\n \"assumption-contradicts\": \"Contradicts\",\n \"reading-experiment\": \"From experiment\",\n \"decision-based-on\": \"Based on assumption\",\n \"decision-resolves\": \"Resolves assumption\",\n};\n\n/** The relations a record of `register` can initiate, in table order. */\nexport function linkChoicesFrom(register: Collection): LinkChoice[] {\n return (Object.keys(RELATIONS) as Relation[])\n .filter((r) => RELATIONS[r].from.register === register)\n .map((relation) => ({\n relation,\n label: RELATION_LABEL[relation],\n targetRegister: RELATIONS[relation].targetRegister,\n }));\n}\n","import { useCallback, useEffect, useState } from \"react\";\nimport type { Collection } from \"@validation-os/core\";\nimport type { SavedView, ViewDescriptor } from \"./list-surface.js\";\n\n/**\n * Client hook for a register's user saved views (OPS-1287 story 17) — the same\n * shaped query (tab · group · filter · sort) under a user-chosen name, kept as a\n * **separate list** from the shipped canonical tabs so a working view never\n * clobbers them. Persisted per-register in `localStorage` (no backend, no schema\n * change); a save under an existing name overwrites it. SSR-safe: with no\n * `window` the list is simply empty.\n */\nconst storageKey = (register: Collection) => `vos:saved-views:${register}`;\n\nfunction read(register: Collection): SavedView[] {\n if (typeof window === \"undefined\") return [];\n try {\n const raw = window.localStorage.getItem(storageKey(register));\n const parsed = raw ? (JSON.parse(raw) as unknown) : [];\n return Array.isArray(parsed) ? (parsed as SavedView[]) : [];\n } catch {\n return [];\n }\n}\n\nfunction write(register: Collection, views: SavedView[]): void {\n if (typeof window === \"undefined\") return;\n try {\n window.localStorage.setItem(storageKey(register), JSON.stringify(views));\n } catch {\n // A full or unavailable store is non-fatal — the views just don't persist.\n }\n}\n\nexport interface UseSavedViewsResult {\n views: SavedView[];\n /** Save (or overwrite by name) the current shaped query under a name. */\n save: (name: string, descriptor: ViewDescriptor) => void;\n /** Drop a saved view by name. */\n remove: (name: string) => void;\n}\n\nexport function useSavedViews(register: Collection): UseSavedViewsResult {\n const [views, setViews] = useState<SavedView[]>(() => read(register));\n\n // Re-read when the register changes (the browser remounts per register, but\n // this keeps the hook correct if reused without a key).\n useEffect(() => setViews(read(register)), [register]);\n\n const save = useCallback(\n (name: string, descriptor: ViewDescriptor) => {\n const trimmed = name.trim();\n if (!trimmed) return;\n setViews((prev) => {\n const next = [\n ...prev.filter((v) => v.name !== trimmed),\n { name: trimmed, ...descriptor },\n ];\n write(register, next);\n return next;\n });\n },\n [register],\n );\n\n const remove = useCallback(\n (name: string) => {\n setViews((prev) => {\n const next = prev.filter((v) => v.name !== name);\n write(register, next);\n return next;\n });\n },\n [register],\n );\n\n return { views, save, remove };\n}\n","import type { Collection } from \"@validation-os/core\";\n\n/**\n * The dashboard's client-owned navigation state (OPS-1298 / DEV-5879 redesign).\n * One `<ValidationOSDashboard/>` mounts at a single host route and drives\n * everything off the URL hash — there is no second entry point (OPS-1280).\n *\n * - `assumptions` — the Assumptions nav item. The grid (Lens × Stage) is the\n * default landing; `view: \"all\"` switches to the pipeline board; `lens` +\n * `stage` drill into a single cell's assumptions (pipeline view filtered).\n * - `experiments` — the Experiments nav item (the live evidence plans list).\n * - `readings` — the Readings nav item (the evidence log list).\n * - `assumption` — the assumption detail (next-move, relations, glossary,\n * evidence-first readings). The id is the assumption id.\n * - `experiment` — the evidence-first experiment detail (readings lead, bar\n * lines as context, unstarted bars separate). The id is the experiment id.\n * - `reading` — the per-belief reading detail (Context + per-belief verdicts\n * with excerpts). The id is the reading id.\n * - `records` — one register's browse table (the manual-override surface,\n * kept from the original scheme). Backward-compatible with `#<register>`.\n * - `record` — the legacy unified record page (still mounted for decisions +\n * glossary, which keep the tabbed layout). The id is the record id.\n *\n * The legacy `next`, `pipeline`, and `stage-grid` routes still parse (they\n * map onto the new nav: `next`→`assumptions`, `pipeline`→`assumptions` with\n * `view: \"all\"`, `stage-grid`→`assumptions`) so old deep links keep working.\n */\nexport type Route =\n | { name: \"assumptions\"; lens?: string; stage?: string; view?: \"all\" }\n | { name: \"experiments\" }\n | { name: \"readings\" }\n | { name: \"assumption\"; id: string }\n | { name: \"experiment\"; id: string }\n | { name: \"reading\"; id: string }\n | { name: \"records\"; register: Collection; lens?: string; stage?: string; view?: \"all\" }\n | { name: \"record\"; id: string };\n\nconst DEFAULT_ROUTE: Route = { name: \"assumptions\" };\n\n/**\n * Parse a URL hash into a Route. The empty hash and anything unrecognised fall\n * back to the Assumptions grid (the default landing). A bare register name\n * (`#assumptions`) stays backward-compatible with the original `#<register>`\n * scheme, so it resolves to that register's Records table; `registers` is the\n * set the instance allows, so an unknown or disallowed register name falls\n * through to the default.\n *\n * Legacy routes `#next`, `#pipeline`, and `#stage-grid` still parse — they map\n * onto the new nav so old deep links keep working.\n */\nexport function parseRoute(hash: string, registers: Collection[]): Route {\n const h = hash.replace(/^#\\/?/, \"\");\n if (!h) return DEFAULT_ROUTE;\n const [pathPart = \"\", queryPart = \"\"] = h.split(\"?\");\n const parts = pathPart.split(\"/\");\n const head = parts[0] ?? \"\";\n const query = new URLSearchParams(queryPart ?? \"\");\n const lens = query.get(\"lens\") ?? undefined;\n const stage = query.get(\"stage\") ?? undefined;\n const view = (query.get(\"view\") as \"all\" | null) ?? undefined;\n\n // Legacy routes → new nav.\n if (head === \"next\") return { name: \"assumptions\" };\n if (head === \"pipeline\") return { name: \"assumptions\", view: \"all\" };\n if (head === \"stage-grid\") return { name: \"assumptions\" };\n\n // New detail routes.\n if (head === \"assumption\") {\n const id = parts.slice(1).join(\"/\");\n return id ? { name: \"assumption\", id } : DEFAULT_ROUTE;\n }\n if (head === \"experiment\") {\n const id = parts.slice(1).join(\"/\");\n return id ? { name: \"experiment\", id } : DEFAULT_ROUTE;\n }\n if (head === \"reading\") {\n const id = parts.slice(1).join(\"/\");\n return id ? { name: \"reading\", id } : DEFAULT_ROUTE;\n }\n\n // New top-level nav routes.\n if (head === \"assumptions\") {\n const r: Route = { name: \"assumptions\" };\n if (lens) r.lens = lens;\n if (stage) r.stage = stage;\n if (view) r.view = view;\n return r;\n }\n if (head === \"experiments\") return { name: \"experiments\" };\n if (head === \"readings\") return { name: \"readings\" };\n\n // Legacy record drill-in + records table.\n if (head === \"record\") {\n const id = parts.slice(1).join(\"/\");\n return id ? { name: \"record\", id } : DEFAULT_ROUTE;\n }\n if ((registers as string[]).includes(head)) {\n return { name: \"records\", register: head as Collection, lens, stage, view };\n }\n return DEFAULT_ROUTE;\n}\n\n/**\n * The hash fragment (no leading `#`) for a Route — the inverse of `parseRoute`.\n * `records` serialises to the bare register name to keep deep links stable with\n * the original scheme.\n */\nexport function formatRoute(route: Route): string {\n switch (route.name) {\n case \"assumptions\": {\n const q = new URLSearchParams();\n if (route.lens) q.set(\"lens\", route.lens);\n if (route.stage) q.set(\"stage\", route.stage);\n if (route.view) q.set(\"view\", route.view);\n const qs = q.toString();\n return qs ? `assumptions?${qs}` : \"assumptions\";\n }\n case \"assumption\":\n return `assumption/${route.id}`;\n case \"experiment\":\n return `experiment/${route.id}`;\n case \"reading\":\n return `reading/${route.id}`;\n case \"records\": {\n const q = new URLSearchParams();\n if (route.lens) q.set(\"lens\", route.lens);\n if (route.stage) q.set(\"stage\", route.stage);\n if (route.view) q.set(\"view\", route.view);\n const qs = q.toString();\n return qs ? `${route.register}?${qs}` : route.register;\n }\n case \"record\":\n return `record/${route.id}`;\n default:\n return route.name;\n }\n}\n","import type { Collection } from \"@validation-os/core\";\nimport { REGISTER_ICON, REGISTER_LABEL, WORKFLOW_NAV } from \"./labels.js\";\nimport { formatCount } from \"./primitives.js\";\nimport type { Route } from \"./route.js\";\nimport type { Counts } from \"./use-counts.js\";\n\nexport interface SidebarNavProps {\n /** The active route — drives which item is highlighted. A detail route\n * (`assumption` / `experiment` / `reading` / `record`) highlights its\n * parent nav item. */\n route: Route;\n /** Called when a nav item is chosen, with the route it selects. */\n onNavigate: (route: Route) => void;\n /** Live per-register counts; a middle dot shows until they load. */\n counts?: Counts | null;\n /** Per-register needs-a-human counts — a persistent alert badge on the\n * register that needs attention (kill lane, overdue plans, tensions; story 20). */\n needsHuman?: Partial<Record<Collection, number>>;\n /** The registers shown under a \"Registers\" group (decisions + glossary keep\n * the legacy records-table surface). The three nav-owned registers\n * (assumptions / experiments / readings) are not duplicated here. */\n registers: Collection[];\n}\n\n/**\n * The sidebar nav (DEV-5879 redesign): three top-level items — Assumptions\n * (the default landing, Lens × Stage grid with a \"View all\" toggle to the\n * pipeline board), Experiments (the live evidence plans), Readings (the\n * evidence log) — above a small \"Registers\" group for decisions + glossary,\n * which keep the legacy records-table surface. A presentational brick: the\n * caller owns the active route and supplies the counts. The assembled\n * `<ValidationOSDashboard/>` composes this; it's also exported for anyone\n * building their own surface. Styled with the package's own token sheet.\n */\nexport function SidebarNav({\n route,\n onNavigate,\n counts,\n needsHuman,\n registers,\n}: SidebarNavProps) {\n // The three nav items own assumptions / experiments / readings; the records\n // group holds the rest (decisions, glossary).\n const recordsRegisters = registers.filter(\n (r) => r !== \"assumptions\" && r !== \"experiments\" && r !== \"readings\",\n );\n const activeRegister =\n route.name === \"records\" ? route.register : null;\n\n // Which nav item is active for a given route — detail routes highlight\n // their parent (assumption → assumptions, experiment → experiments, etc).\n function activeNav(): string | null {\n switch (route.name) {\n case \"assumptions\":\n case \"assumption\":\n return \"assumptions\";\n case \"experiments\":\n case \"experiment\":\n return \"experiments\";\n case \"readings\":\n case \"reading\":\n return \"readings\";\n default:\n return null;\n }\n }\n const active = activeNav();\n\n return (\n <nav className=\"vos-nav\" aria-label=\"Navigation\">\n <div>\n <div className=\"vos-nav-group\">Workflow</div>\n {WORKFLOW_NAV.map((item) => {\n const isActive = active === item.route;\n const count =\n counts?.[item.route as Collection] ??\n (item.route === \"assumptions\"\n ? counts?.assumptions\n : item.route === \"experiments\"\n ? counts?.experiments\n : counts?.readings);\n return (\n <button\n key={item.route}\n type=\"button\"\n className={`vos-nav-item ${isActive ? \"is-active\" : \"\"}`}\n aria-current={isActive ? \"page\" : undefined}\n onClick={() => onNavigate({ name: item.route })}\n >\n <span className=\"vos-nav-ic\" aria-hidden=\"true\">\n {item.icon}\n </span>\n {item.label}\n {item.isDefault ? (\n <span className=\"vos-nav-default\">home</span>\n ) : null}\n <span className=\"vos-nav-count vos-num\">\n {count !== undefined ? formatCount(count) : \"·\"}\n </span>\n </button>\n );\n })}\n </div>\n\n {recordsRegisters.length > 0 ? (\n <div>\n <div className=\"vos-nav-group\">Registers</div>\n {recordsRegisters.map((register) => {\n const isActive = register === activeRegister;\n return (\n <button\n key={register}\n type=\"button\"\n className={`vos-nav-item ${isActive ? \"is-active\" : \"\"}`}\n aria-current={isActive ? \"page\" : undefined}\n onClick={() => onNavigate({ name: \"records\", register })}\n >\n <span className=\"vos-nav-ic\" aria-hidden=\"true\">\n {REGISTER_ICON[register]}\n </span>\n {REGISTER_LABEL[register]}\n {needsHuman?.[register] ? (\n <span\n className=\"vos-nav-alert\"\n title={`${needsHuman[register]} need a human`}\n >\n {formatCount(needsHuman[register] ?? 0)}\n </span>\n ) : null}\n <span className=\"vos-nav-count vos-num\">\n {counts?.[register] !== undefined\n ? formatCount(counts[register] ?? 0)\n : \"·\"}\n </span>\n </button>\n );\n })}\n </div>\n ) : null}\n </nav>\n );\n}\n","import { useCallback, useEffect, useMemo, useState } from \"react\";\nimport type { Collection } from \"@validation-os/core\";\nimport { liveExperiments } from \"./derived-views.js\";\nimport { needsHumanCounts, type NeedsHumanCounts } from \"./list-surface.js\";\nimport { useList } from \"./use-records.js\";\n\nexport type Counts = Partial<Record<Collection, number>>;\n\nexport interface UseCountsResult {\n counts: Counts | null;\n loading: boolean;\n error: string | null;\n refresh: () => void;\n}\n\n/**\n * Client hook: fetch per-register counts from the API (`GET {basePath}/counts`).\n * The API reads Firestore server-side through the adapter; this only speaks\n * HTTP, so no backend credentials ever reach the browser.\n */\nexport function useCounts(basePath = \"/api\"): UseCountsResult {\n const [counts, setCounts] = useState<Counts | null>(null);\n const [loading, setLoading] = useState(true);\n const [error, setError] = useState<string | null>(null);\n const [tick, setTick] = useState(0);\n\n useEffect(() => {\n let live = true;\n setLoading(true);\n fetch(`${basePath}/counts`)\n .then(async (res) => {\n if (!res.ok) throw new Error(`Counts request failed (${res.status})`);\n return (await res.json()) as { counts: Counts };\n })\n .then((body) => {\n if (!live) return;\n setCounts(body.counts);\n setError(null);\n })\n .catch((e: unknown) => {\n if (!live) return;\n setError(e instanceof Error ? e.message : \"Failed to load counts\");\n })\n .finally(() => {\n if (live) setLoading(false);\n });\n return () => {\n live = false;\n };\n }, [basePath, tick]);\n\n const refresh = useCallback(() => setTick((t) => t + 1), []);\n return { counts, loading, error, refresh };\n}\n\n/** The needs-a-human counts mapped to the register that owns each badge — kill\n * lane → assumptions, overdue → experiments, in-tension → decisions. */\nexport type NeedsHumanByRegister = Partial<Record<Collection, number>>;\n\nexport interface UseNeedsHumanResult {\n counts: NeedsHumanCounts;\n byRegister: NeedsHumanByRegister;\n /**\n * Live-only experiment count — archived plans excluded (OPS-1305). The API's\n * `/counts` tallies every stored row, but an archived plan never surfaces\n * anywhere in the UI, so the nav badge would overcount (66 vs the live few).\n * `null` until the experiments list loads, so the caller falls back to the\n * API count rather than flashing a wrong number.\n */\n liveExperimentCount: number | null;\n}\n\n/**\n * Client hook: load the assumptions / experiments / decisions registers and\n * derive the needs-a-human counts (kill lane, overdue, in tension) so the nav\n * can carry a persistent badge on the register that needs a human (story 20).\n * Reuses the same `needsHumanCounts` view-model the tabs and their badges use, so\n * a nav badge and its tab never disagree.\n */\nexport function useNeedsHuman(basePath = \"/api\"): UseNeedsHumanResult {\n const assumptions = useList(\"assumptions\", basePath);\n const experiments = useList(\"experiments\", basePath);\n const decisions = useList(\"decisions\", basePath);\n const [asOf] = useState(() => new Date().toISOString().slice(0, 10));\n\n return useMemo(() => {\n const counts = needsHumanCounts({\n asOf,\n assumptions: assumptions.records ?? [],\n experiments: experiments.records ?? [],\n decisions: decisions.records ?? [],\n });\n const byRegister: NeedsHumanByRegister = {};\n if (counts.killLane > 0) byRegister.assumptions = counts.killLane;\n if (counts.overdue > 0) byRegister.experiments = counts.overdue;\n if (counts.inTension > 0) byRegister.decisions = counts.inTension;\n const liveExperimentCount = experiments.records\n ? liveExperiments(experiments.records).length\n : null;\n return { counts, byRegister, liveExperimentCount };\n }, [asOf, assumptions.records, experiments.records, decisions.records]);\n}\n","/**\n * The \"Connect Claude Code\" command composer (OPS-1349). A person signed into\n * the dashboard mints a personal token and gets back ONE ready-to-paste command\n * that points their own Claude Code at this hosted register through the\n * `remote-api` connector. Everything environmental — the API URL, the env-var\n * name — is baked in here; the person supplies only their minted token.\n *\n * Pure and deterministic so it can be unit-tested exactly (prior art:\n * `route.ts`). The config keys it writes (`api_base_url`, `token_env`) are the\n * `remote-api` connector's contract, fixed by the spec — so this does not\n * depend on the connector doc or the setup wizard shipping first.\n */\n\n/** The env var the `remote-api` connector reads the bearer token from. */\nexport const DEFAULT_TOKEN_ENV = \"VALIDATION_OS_TOKEN\";\n\nexport interface ConnectCommandInput {\n /** The personal bearer token the deployment minted for the signed-in user. */\n token: string;\n /** The hosted API root, baked in by the deployment. */\n apiBaseUrl: string;\n /** Override the token env-var name; defaults to {@link DEFAULT_TOKEN_ENV}. */\n tokenEnv?: string;\n}\n\n// A single quote, backslash, or any whitespace would break the single-quoted\n// shell literal (or let a crafted value inject shell) — reject rather than\n// silently emit a broken/unsafe command. Minted tokens and real URLs never\n// contain these.\nconst SHELL_UNSAFE = /['\"\\\\\\s]/;\n\n/**\n * Build the paste command: export the token into its env var, then write a\n * `remote-api` `validation-os.config.yaml` at the workspace root. Running it\n * leaves the workspace ready for `/setup-validation-os` to confirm, or for the\n * skills to use directly.\n */\nexport function composeConnectCommand(input: ConnectCommandInput): string {\n const tokenEnv = input.tokenEnv ?? DEFAULT_TOKEN_ENV;\n const guarded: [string, string][] = [\n [\"Token\", input.token],\n [\"API base URL\", input.apiBaseUrl],\n ];\n for (const [label, value] of guarded) {\n if (SHELL_UNSAFE.test(value)) {\n throw new Error(`${label} contains characters that can't be safely pasted.`);\n }\n }\n return [\n `export ${tokenEnv}='${input.token}'`,\n `cat > validation-os.config.yaml <<'EOF'`,\n `connector: remote-api`,\n `remote_api:`,\n ` api_base_url: ${input.apiBaseUrl}`,\n ` token_env: ${tokenEnv}`,\n `EOF`,\n ].join(\"\\n\");\n}\n","import { useState } from \"react\";\nimport { composeConnectCommand } from \"./connect.js\";\n\n/**\n * The \"Connect Claude Code\" page (OPS-1349). A person already signed into the\n * dashboard mints a personal token and gets one ready-to-paste command that\n * points their own Claude Code at this hosted register.\n *\n * Auth-vendor-free by construction: token minting is INJECTED (`mintToken`), so\n * this package never imports Clerk — the deployment wires a mint function that\n * creates the signed-in user's personal API key and hands back the token\n * (mirrors how the API's `authenticate` is injected). The command itself is the\n * pure `composeConnectCommand`; this component is only the chrome around it.\n */\nexport interface ConnectClaudeCodeProps {\n /** The hosted API root, baked into the emitted command. */\n apiBaseUrl: string;\n /** Override the token env-var name written into the config. */\n tokenEnv?: string;\n /**\n * Mint a personal bearer token for the signed-in user. Injected by the\n * deployment (e.g. create a Clerk API key whose subject is the user's ID).\n */\n mintToken: () => Promise<string>;\n}\n\ntype State =\n | { phase: \"idle\" }\n | { phase: \"minting\" }\n | { phase: \"ready\"; command: string }\n | { phase: \"error\"; message: string };\n\nexport function ConnectClaudeCode({\n apiBaseUrl,\n tokenEnv,\n mintToken,\n}: ConnectClaudeCodeProps) {\n const [state, setState] = useState<State>({ phase: \"idle\" });\n const [copied, setCopied] = useState(false);\n\n async function generate() {\n setState({ phase: \"minting\" });\n setCopied(false);\n try {\n const token = await mintToken();\n const command = composeConnectCommand({ token, apiBaseUrl, tokenEnv });\n setState({ phase: \"ready\", command });\n } catch (e) {\n setState({\n phase: \"error\",\n message:\n e instanceof Error\n ? e.message\n : \"Couldn't generate your connection command.\",\n });\n }\n }\n\n async function copy(command: string) {\n try {\n await navigator.clipboard.writeText(command);\n setCopied(true);\n } catch {\n // Clipboard blocked — the person can still select the text manually.\n }\n }\n\n return (\n <div>\n <div className=\"vos-head\">\n <div>\n <h1>Connect Claude Code</h1>\n <p>\n Run the validation skills against this register from your own Claude\n Code — no repo, no keys to hunt down.\n </p>\n </div>\n </div>\n\n <ol className=\"vos-hint\" style={{ lineHeight: 1.8 }}>\n <li>Generate your personal connection command below.</li>\n <li>Paste it into a terminal in the workspace you'll run the skills in.</li>\n <li>\n The command carries a token tied to <strong>you</strong> — anything you\n write lands under your name. Don't share it.\n </li>\n </ol>\n\n {state.phase !== \"ready\" ? (\n <button\n type=\"button\"\n className=\"vos-btn\"\n onClick={generate}\n disabled={state.phase === \"minting\"}\n >\n {state.phase === \"minting\"\n ? \"Generating…\"\n : \"Generate connection command\"}\n </button>\n ) : null}\n\n {state.phase === \"error\" ? (\n <p className=\"vos-hint\" role=\"alert\">\n {state.message}\n </p>\n ) : null}\n\n {state.phase === \"ready\" ? (\n <div>\n <pre className=\"vos-code\" aria-label=\"Connection command\">\n {state.command}\n </pre>\n <div style={{ display: \"flex\", gap: 8 }}>\n <button\n type=\"button\"\n className=\"vos-btn\"\n onClick={() => copy(state.command)}\n >\n {copied ? \"Copied\" : \"Copy command\"}\n </button>\n <button type=\"button\" className=\"vos-btn-ghost\" onClick={generate}>\n Regenerate\n </button>\n </div>\n <p className=\"vos-hint\" style={{ marginTop: 12 }}>\n Generating again revokes nothing on its own — remove old keys from\n your account settings when you rotate.\n </p>\n </div>\n ) : null}\n </div>\n );\n}\n","import type { ReactNode } from \"react\";\n\nexport interface SurfacePlaceholderProps {\n /** The surface's title, shown as the pane heading. */\n title: string;\n /** A one-line description under the title. */\n subtitle: string;\n /** What fills this pane, and which build ships it. */\n detail: ReactNode;\n}\n\n/**\n * A pane the navigation shell reserves for a surface built in its own step\n * (OPS-1298: \"the shell can land first; each surface fills its pane as it\n * ships\"). It renders the surface's heading and a labelled placeholder so the\n * route, nav slot, and title are real and reachable while the surface itself is\n * still to come. Each later build swaps this out for the real component.\n */\nexport function SurfacePlaceholder({\n title,\n subtitle,\n detail,\n}: SurfacePlaceholderProps) {\n return (\n <div>\n <div className=\"vos-head\">\n <div>\n <h1>{title}</h1>\n <p>{subtitle}</p>\n </div>\n </div>\n <div className=\"vos-empty\">{detail}</div>\n </div>\n );\n}\n","import type { ReactNode } from \"react\";\nimport type { AnyRecord } from \"@validation-os/core\";\nimport { coldStartFor, FIRST_RUN_LINE } from \"./cold-start.js\";\nimport { formatSigned } from \"./primitives.js\";\nimport { buildPipeline, weekOverWeekDelta, type PipelineRow } from \"./pipeline.js\";\nimport type { Route } from \"./route.js\";\nimport { stageMeters } from \"./stage-meters.js\";\nimport { useList } from \"./use-records.js\";\n\n/**\n * The step-back portfolio pipeline (OPS-1300) — the middle altitude of the\n * workflow dashboard. One row per live belief, sorted riskiest first, each\n * carrying the four loop meters (Framed → Planned → Tested → Known) as a\n * connected track, with a stage-aware next move on hover. Above them, the\n * single burn-up headline: \"% of risk bought down\". Resolved beliefs are set\n * apart behind a disclosure; the raw Impact shows only as a faint bar.\n *\n * It lazy-loads the assumption, experiment and reading registers and derives\n * everything through the pure `pipeline` view-model — no number is computed\n * here (spec: explain from inputs). Clicking a belief, its next move, or its\n * Journey link routes to that belief's record page (OPS-1298), the review\n * surface where step-in happens.\n */\nexport function PipelineSurface({\n basePath,\n onNavigate,\n}: {\n basePath?: string;\n onNavigate: (route: Route) => void;\n}) {\n const assumptions = useList(\"assumptions\", basePath);\n const experiments = useList(\"experiments\", basePath);\n const readings = useList(\"readings\", basePath);\n\n const loading =\n assumptions.loading || experiments.loading || readings.loading;\n const error = assumptions.error || experiments.error || readings.error;\n\n return (\n <div>\n <div className=\"vos-head\">\n <div>\n <h1>Portfolio — where everything stands</h1>\n <p>\n Every belief the business depends on, and how far each has travelled\n from bet to known.\n </p>\n </div>\n <div className=\"vos-spacer\" />\n <button\n type=\"button\"\n className=\"vos-btn vos-btn-ghost\"\n onClick={() => {\n assumptions.refresh();\n experiments.refresh();\n readings.refresh();\n }}\n >\n ↻ Refresh\n </button>\n </div>\n\n {loading && !assumptions.records ? (\n <p className=\"vos-muted\">Reading where every belief stands…</p>\n ) : error ? (\n <p className=\"vos-error\">{error}</p>\n ) : (\n <PipelineBoard\n assumptions={assumptions.records ?? []}\n experiments={experiments.records ?? []}\n readings={readings.records ?? []}\n onNavigate={onNavigate}\n />\n )}\n </div>\n );\n}\n\nfunction PipelineBoard({\n assumptions,\n experiments,\n readings,\n onNavigate,\n}: {\n assumptions: AnyRecord[];\n experiments: AnyRecord[];\n readings: AnyRecord[];\n onNavigate: (route: Route) => void;\n}) {\n const view = buildPipeline(assumptions, experiments);\n const delta = weekOverWeekDelta(assumptions, readings, new Date());\n const { progress, rows, resolved, resolvedRetired } = view;\n\n const cold = coldStartFor({\n assumptions,\n experiments,\n readings,\n // The pipeline surface doesn't load decisions (the burn-up reads only\n // assumptions + experiments + readings); coldStartFor only reads\n // assumptions.length, so an empty decisions array is honest here.\n decisions: [],\n });\n if (cold.cold) {\n return (\n <>\n <div className=\"vos-firstrun\">{FIRST_RUN_LINE}</div>\n <section className=\"vos-pipe-hero vos-cold vos-cold-pipe-hero\">\n <div className=\"vos-pipe-read\">\n <div className=\"vos-pipe-eyebrow\">Risk bought down</div>\n <div className=\"vos-pipe-big vos-num\">\n {cold.pipeline.headline}\n </div>\n <div className=\"vos-pipe-sub\">{cold.pipeline.invitation}</div>\n </div>\n </section>\n\n <StageSpine />\n\n <div className=\"vos-card vos-pipe-board vos-cold vos-cold-pipe-board\">\n <div className=\"vos-pipe-boardhead\">\n <div className=\"vos-pipe-bt\">\n Pipeline <span>· 0 live beliefs</span>\n </div>\n </div>\n <div className=\"vos-cold-pipe-body\">\n <p>{cold.pipeline.boardBody}</p>\n <button\n type=\"button\"\n className=\"vos-btn\"\n onClick={() => onNavigate({ name: \"records\", register: \"assumptions\" })}\n >\n {cold.pipeline.boardCta}\n </button>\n </div>\n </div>\n </>\n );\n }\n\n const openRecord = (id: string) => onNavigate({ name: \"record\", id });\n\n return (\n <>\n {/* Headline: the one burn-up reading, a single meter (not a chart). */}\n <section className=\"vos-pipe-hero\">\n <div className=\"vos-pipe-read\">\n <div className=\"vos-pipe-eyebrow\">Risk bought down</div>\n <div className=\"vos-pipe-big vos-num\">\n {Math.round(progress.percent)}\n <span>%</span>\n </div>\n <div className=\"vos-pipe-sub\">\n of all risk you've ever identified\n {delta !== null ? (\n <>\n {\" · \"}\n <span className={delta >= 0 ? \"vos-text-good\" : \"vos-text-crit\"}>\n {formatSigned(delta)} pts this week\n </span>\n </>\n ) : null}\n </div>\n </div>\n <div className=\"vos-pipe-figs\">\n <Fig value={progress.retired} label=\"risk retired\" good />\n <Fig value={progress.identified} label=\"risk identified\" />\n <Fig value={progress.live} label=\"still live\" />\n </div>\n </section>\n\n {/* The four meters every belief carries, in order. */}\n <StageSpine />\n\n <div className=\"vos-card vos-pipe-board\">\n <div className=\"vos-pipe-boardhead\">\n <div className=\"vos-pipe-bt\">\n Pipeline <span>· {rows.length} live {rows.length === 1 ? \"belief\" : \"beliefs\"}</span>\n </div>\n <div className=\"vos-pipe-sortnote\">sorted by live risk — riskiest first</div>\n </div>\n {rows.length === 0 ? (\n <div className=\"vos-empty\" style={{ margin: 16 }}>\n Every belief is resolved — nothing live to test right now.\n </div>\n ) : (\n rows.map((row) => (\n <RowView key={row.id} row={row} onOpen={() => openRecord(row.id)} />\n ))\n )}\n </div>\n\n {resolved.length > 0 ? (\n <details className=\"vos-pipe-resolved\">\n <summary className=\"vos-pipe-disclosure\">\n Resolved &amp; set apart — <b>{resolved.length}</b>{\" \"}\n {resolved.length === 1 ? \"belief\" : \"beliefs\"} (killed or made moot) ·\n retired {resolvedRetired} risk\n </summary>\n <div className=\"vos-pipe-resolved-body\">\n {resolved.map((r) => (\n <button\n type=\"button\"\n key={r.id}\n className=\"vos-pipe-rrow\"\n onClick={() => openRecord(r.id)}\n >\n <span className=\"vos-pipe-rstmt\">{r.statement || r.id}</span>\n <span\n className={`vos-pill ${\n r.kind === \"killed\" ? \"vos-pill-crit\" : \"vos-pill-neutral\"\n }`}\n >\n {r.kind === \"killed\" ? \"Killed\" : \"Moot\"}\n </span>\n <span className=\"vos-pipe-retired\">retired {r.retired} risk</span>\n </button>\n ))}\n </div>\n </details>\n ) : null}\n\n <p className=\"vos-hint vos-pipe-foot\">\n <b>Hidden by default:</b> resolved beliefs (above), the raw Impact score\n (shown only as a faint bar — the machinery, not the move), and the\n confidence derivation (it lives on the belief's journey page). The\n headline is a <b>burn-up</b>: writing a new bet grows \"risk identified\",\n so fresh risk never reads as backsliding.\n </p>\n </>\n );\n}\n\nfunction Fig({\n value,\n label,\n good,\n}: {\n value: number;\n label: string;\n good?: boolean;\n}) {\n return (\n <div className=\"vos-pipe-fig\">\n <div className={`vos-pipe-fv vos-num ${good ? \"vos-text-good\" : \"\"}`}>\n {Math.round(value)}\n </div>\n <div className=\"vos-pipe-fl\">{label}</div>\n </div>\n );\n}\n\nfunction StageKey({\n idx,\n name,\n desc,\n open,\n}: {\n idx: string;\n name: string;\n desc: string;\n open?: boolean;\n}) {\n return (\n <div className=\"vos-pipe-stage\">\n <span className={`vos-pipe-idx ${open ? \"vos-pipe-idx-open\" : \"\"}`}>{idx}</span>\n <div>\n <div className=\"vos-pipe-skname\">{name}</div>\n <div className=\"vos-pipe-skdesc\">{desc}</div>\n </div>\n </div>\n );\n}\n\n/** The four-stage spine — Framed → Planned → Tested → Known — shared by the\n * cold and warm paths so the legend never drifts between them. */\nfunction StageSpine() {\n return (\n <div className=\"vos-pipe-stages\">\n <StageKey idx=\"1\" name=\"Framed\" desc=\"The bet is written & complete\" />\n <span className=\"vos-pipe-arrow\" aria-hidden=\"true\">→</span>\n <StageKey idx=\"2\" name=\"Planned\" desc=\"A test is designed to move it\" />\n <span className=\"vos-pipe-arrow\" aria-hidden=\"true\">→</span>\n <StageKey idx=\"3\" name=\"Tested\" desc=\"Evidence landing, bars settling\" />\n <span className=\"vos-pipe-arrow\" aria-hidden=\"true\">→</span>\n <StageKey idx=\"4\" open name=\"Known\" desc={'Signed confidence — never \"done\"'} />\n </div>\n );\n}\n\nfunction RowView({ row, onOpen }: { row: PipelineRow; onOpen: () => void }) {\n const confClass =\n row.confSign === \"pos\"\n ? \"vos-pill-good\"\n : row.confSign === \"neg\"\n ? \"vos-pill-crit\"\n : \"vos-pill-neutral\";\n const impactPct = Math.max(0, Math.min(100, Math.round(row.impact)));\n return (\n <div className=\"vos-pipe-row\">\n <div className={`vos-pipe-stripe vos-fill-${row.riskTone}`} />\n\n <button type=\"button\" className=\"vos-pipe-belief\" onClick={onOpen}>\n <span className=\"vos-pipe-stmt\">{row.statement || row.id}</span>\n <span className=\"vos-pipe-bmeta\">\n <span className=\"vos-pipe-impact-track\" title={`Derived Impact ${row.impact}`}>\n <i style={{ width: `${impactPct}%` }} />\n </span>\n <span className=\"vos-num\">impact {Math.round(row.impact)}</span>\n </span>\n </button>\n\n {/* The four meters, captioned by the shared mapping the journey rail also\n reads (`stageMeters`) — a row and a belief's rail can't disagree. */}\n <div className=\"vos-pipe-prog\" aria-label=\"Loop progress\">\n {stageMeters(row).map((m) => (\n <Meter\n key={m.key}\n n={m.n}\n label={m.flag ? undefined : m.label}\n flag={m.flag}\n muted={m.muted}\n >\n {m.kind === \"signed\" ? (\n <div className=\"vos-pipe-track vos-pipe-known\">\n <span className=\"vos-pipe-known-mid\" />\n {m.sign !== \"zero\" ? (\n <i\n className={\n m.sign === \"pos\" ? \"vos-pipe-known-pos\" : \"vos-pipe-known-neg\"\n }\n style={{ width: `${m.pct}%` }}\n />\n ) : null}\n </div>\n ) : (\n <div className=\"vos-pipe-track\">\n <i className=\"vos-pipe-fill-accent\" style={{ width: `${m.pct}%` }} />\n </div>\n )}\n </Meter>\n ))}\n </div>\n\n <div className=\"vos-pipe-risk\">\n <div className={`vos-pipe-rv vos-text-${row.riskTone} vos-num`}>\n {Math.round(row.risk)}\n </div>\n <div className=\"vos-pipe-rl\">risk</div>\n <span className={`vos-pill ${confClass} vos-pipe-conf`}>\n conf {formatSigned(row.confidence)}\n </span>\n </div>\n\n <div className=\"vos-pipe-actions\">\n <button type=\"button\" className=\"vos-btn vos-btn-sm\" onClick={onOpen}>\n {row.nextMove}\n </button>\n <button\n type=\"button\"\n className=\"vos-btn vos-btn-ghost vos-btn-sm\"\n onClick={onOpen}\n >\n Journey →\n </button>\n </div>\n </div>\n );\n}\n\nfunction Meter({\n n,\n label,\n flag,\n muted,\n children,\n}: {\n n: string;\n label?: string;\n flag?: string;\n muted?: boolean;\n children: ReactNode;\n}) {\n return (\n <div className=\"vos-pipe-seg\">\n {children}\n <div className=\"vos-pipe-cap\">\n <span className=\"vos-pipe-capn\">{n}</span>\n {flag ? (\n <span className=\"vos-pipe-flag\">{flag}</span>\n ) : (\n <span className={`vos-pipe-capv ${muted ? \"vos-muted\" : \"\"}`}>{label}</span>\n )}\n </div>\n </div>\n );\n}\n","import type { Collection } from \"@validation-os/core\";\nimport { REGISTER_LABEL, REGISTER_ORDER } from \"./labels.js\";\nimport { StatTile } from \"./primitives-view.js\";\nimport type { Counts } from \"./use-counts.js\";\n\nexport interface RegisterCountsProps {\n counts: Counts;\n /** Optional caption under the tiles (e.g. the backend the numbers came from). */\n caption?: string;\n /** Optional click handler per register — makes each tile a nav button. */\n onSelect?: (register: Collection) => void;\n /** The active register, highlighted when tiles are nav. */\n active?: Collection | null;\n}\n\n/**\n * A glanceable grid of stat tiles — one per register, the register's row count\n * as the hero number. A brick kept for a counts landing; the assembled app\n * surfaces the same counts in the sidebar nav. Presentational: the caller reads\n * the counts (server-side, through the adapter) and hands them in. Rendered in\n * the package's own token sheet — no host Tailwind.\n */\nexport function RegisterCounts({\n counts,\n caption,\n onSelect,\n active,\n}: RegisterCountsProps) {\n const registers = REGISTER_ORDER.filter(\n (r): r is Collection => counts[r] !== undefined,\n );\n return (\n <section aria-label=\"Register counts\">\n <div className=\"vos-tile-grid\">\n {registers.map((register) => (\n <StatTile\n key={register}\n label={REGISTER_LABEL[register]}\n value={counts[register] ?? 0}\n onClick={onSelect ? () => onSelect(register) : undefined}\n active={active === register}\n />\n ))}\n </div>\n {caption ? <p className=\"vos-hint\" style={{ marginTop: 16 }}>{caption}</p> : null}\n </section>\n );\n}\n","import { useMemo, useState } from \"react\";\nimport type { AnyRecord } from \"@validation-os/core\";\nimport { rankNextMoves, type MoveKind, type NextMove } from \"@validation-os/core/derivation\";\nimport { coldStartFor, FIRST_RUN_LINE } from \"./cold-start.js\";\nimport { movePresentation, toNextMoveInput } from \"./next-move.js\";\nimport { riskFraction, riskLevel, type Tone } from \"./primitives.js\";\nimport type { Route } from \"./route.js\";\nimport { ScoreImpactForm, WriteDecisionForm } from \"./step-in-forms.js\";\nimport { useList } from \"./use-records.js\";\n\n/**\n * The front door — \"what's my next move\" (design OPS-1295, build OPS-1304): the\n * map's headline surface. One belief, one act, all machinery behind one \"Why\n * this?\" (progressive disclosure — the hero stays clean). The single riskiest\n * unresolved belief leads (Model A, OPS-1291); a kill-lane belief (Confidence ≤\n * −50) raises a crit banner above the hero; three runners-up sit \"On deck\"; and\n * a quiet pick-list lets you act on any belief the ranking wouldn't pick (manual\n * override). Step-in adapts to the act (OPS-1294): human acts open a form here,\n * agent-run acts point at the record for review.\n *\n * The ranking itself lives once in `packages/core` (OPS-1292); this surface only\n * fetches the registers, folds them into that function, and renders the result.\n */\nexport interface NextMoveSurfaceProps {\n basePath?: string;\n /** Navigate across the shell (belief → record, override → records). */\n onNavigate: (route: Route) => void;\n}\n\n/** The four registers the ranking reads. */\nconst REGISTERS = [\"assumptions\", \"experiments\", \"readings\", \"decisions\"] as const;\n\n/** Which Framed→Planned→Tested→Known stage an act sits at (behind \"Why this?\"). */\nconst STAGES = [\"Framed\", \"Planned\", \"Tested\", \"Known\"] as const;\nconst MOVE_STAGE: Record<MoveKind, number> = {\n \"score-impact\": 0,\n \"design-experiment\": 1,\n \"record-reading\": 2,\n decide: 3,\n retest: 3,\n};\n\nconst RISK_PHRASE: Record<Tone, string> = {\n crit: \"Your riskiest belief\",\n warn: \"Worth a look\",\n good: \"Low risk\",\n accent: \"\",\n neutral: \"\",\n};\n\nexport function NextMoveSurface({ basePath, onNavigate }: NextMoveSurfaceProps) {\n const assumptions = useList(\"assumptions\", basePath);\n const experiments = useList(\"experiments\", basePath);\n const readings = useList(\"readings\", basePath);\n const decisions = useList(\"decisions\", basePath);\n\n const [why, setWhy] = useState(false);\n /** An open step-in form, keyed by the belief record it acts on. */\n const [stepIn, setStepIn] = useState<{\n form: \"score-impact\" | \"write-decision\";\n assumption: AnyRecord;\n kill: boolean;\n } | null>(null);\n\n const lists = [assumptions, experiments, readings, decisions];\n const loading = lists.some((l) => l.loading);\n const error = lists.map((l) => l.error).find(Boolean) ?? null;\n\n const moves = useMemo(() => {\n if (!assumptions.records) return [];\n return rankNextMoves(\n toNextMoveInput({\n assumptions: assumptions.records ?? [],\n experiments: experiments.records ?? [],\n readings: readings.records ?? [],\n decisions: decisions.records ?? [],\n }),\n );\n }, [assumptions.records, experiments.records, readings.records, decisions.records]);\n\n const byId = useMemo(() => {\n const m = new Map<string, AnyRecord>();\n for (const a of assumptions.records ?? []) m.set(a.id, a);\n return m;\n }, [assumptions.records]);\n\n const refreshAll = () => lists.forEach((l) => l.refresh());\n const openRecord = (id: string) => onNavigate({ name: \"record\", id });\n\n const startStepIn = (move: NextMove) => {\n const assumption = byId.get(move.assumptionId);\n const pres = movePresentation(move.move);\n if (!assumption || !pres.form) {\n openRecord(move.assumptionId); // agent-run act → review on the record\n return;\n }\n setStepIn({\n form: pres.form,\n assumption,\n kill: move.killLane,\n });\n };\n\n if (loading) {\n return (\n <NextMoveFrame>\n <div className=\"vos-empty\">Reading your beliefs…</div>\n </NextMoveFrame>\n );\n }\n if (error) {\n return (\n <NextMoveFrame>\n <div className=\"vos-banner vos-banner-crit\">\n <div className=\"vos-banner-body\">\n <b>Couldn't load the workflow.</b>\n <span>{error}</span>\n </div>\n </div>\n </NextMoveFrame>\n );\n }\n if (moves.length === 0) {\n const records = {\n assumptions: assumptions.records ?? [],\n experiments: experiments.records ?? [],\n readings: readings.records ?? [],\n decisions: decisions.records ?? [],\n };\n const cold = coldStartFor(records);\n if (cold.cold) {\n return (\n <NextMoveFrame>\n <div className=\"vos-firstrun\">{FIRST_RUN_LINE}</div>\n <div className=\"vos-card vos-cold vos-cold-next\">\n <span className=\"vos-cold-eyebrow\">{cold.next.eyebrow}</span>\n <h2 className=\"vos-cold-headline\">{cold.next.headline}</h2>\n <p className=\"vos-cold-body\">{cold.next.body}</p>\n <button\n type=\"button\"\n className=\"vos-btn vos-hero-act\"\n onClick={() => onNavigate({ name: \"records\", register: \"assumptions\" })}\n >\n {cold.next.cta}\n </button>\n </div>\n </NextMoveFrame>\n );\n }\n return (\n <NextMoveFrame>\n <div className=\"vos-empty\">\n Nothing needs your attention right now — every belief is either resting\n on a decision or waiting on a test. Add a new belief from{\" \"}\n <button\n type=\"button\"\n className=\"vos-linkbtn\"\n onClick={() => onNavigate({ name: \"records\", register: \"assumptions\" })}\n >\n Assumptions\n </button>\n .\n </div>\n </NextMoveFrame>\n );\n }\n\n const top = moves[0]!; // moves.length === 0 handled above\n const rest = moves.slice(1);\n const killMoves = moves.filter((m) => m.killLane);\n // The kill lane owns the top slot when present; the crit banner names the\n // dying belief and the hero shows it, so don't double-count it in On deck.\n const onDeck = rest.filter((m) => m.assumptionId !== top.assumptionId).slice(0, 3);\n const topPres = movePresentation(top.move);\n const topTone = riskLevel(top.risk);\n\n return (\n <NextMoveFrame>\n {killMoves.length > 0 && !top.killLane ? (\n <KillBanner count={killMoves.length} onReview={() => startStepIn(killMoves[0]!)} />\n ) : null}\n\n <div className={`vos-hero vos-card${top.killLane ? \" vos-hero-kill\" : \"\"}`}>\n <span className=\"vos-hero-eyebrow\">\n {top.killLane ? \"Kill lane — turning against you\" : \"Your next move\"}\n </span>\n\n <button\n type=\"button\"\n className=\"vos-hero-belief\"\n onClick={() => openRecord(top.assumptionId)}\n title=\"Open the full record\"\n >\n {top.title}\n </button>\n\n {/* Risk chip — seen, not read (a bar + a plain label, no number). */}\n <div className=\"vos-riskchip\" aria-label={`Risk: ${RISK_PHRASE[topTone]}`}>\n <span className=\"vos-risk-bar\" aria-hidden=\"true\">\n <i\n className={`vos-fill-${topTone}`}\n style={{ width: `${riskFraction(top.risk) * 100}%` }}\n />\n </span>\n <span className={`vos-riskchip-label vos-text-${topTone}`}>\n {top.killLane ? \"Confidence has turned negative\" : RISK_PHRASE[topTone]}\n </span>\n </div>\n\n <ActButton move={top} onStepIn={() => startStepIn(top)} onReview={() => openRecord(top.assumptionId)} />\n\n <button type=\"button\" className=\"vos-why\" onClick={() => setWhy((w) => !w)}>\n {why ? \"Hide details\" : \"Why this?\"}\n </button>\n </div>\n\n {why ? <WhyPanel top={top} ranked={moves} /> : null}\n\n {onDeck.length > 0 ? (\n <section className=\"vos-ondeck\">\n <h3 className=\"vos-sectitle\">On deck</h3>\n {onDeck.map((m) => (\n <OnDeckRow\n key={m.assumptionId}\n move={m}\n onOpen={() => openRecord(m.assumptionId)}\n onAct={() => startStepIn(m)}\n />\n ))}\n </section>\n ) : null}\n\n <button\n type=\"button\"\n className=\"vos-override\"\n onClick={() => onNavigate({ name: \"records\", register: \"assumptions\" })}\n >\n Act on a different belief →\n </button>\n\n {stepIn?.form === \"score-impact\" ? (\n <ScoreImpactForm\n assumption={stepIn.assumption}\n basePath={basePath}\n onDone={() => {\n setStepIn(null);\n refreshAll();\n }}\n onCancel={() => setStepIn(null)}\n />\n ) : null}\n {stepIn?.form === \"write-decision\" ? (\n <WriteDecisionForm\n assumption={stepIn.assumption}\n basePath={basePath}\n kill={stepIn.kill}\n onDone={() => {\n setStepIn(null);\n refreshAll();\n }}\n onCancel={() => setStepIn(null)}\n />\n ) : null}\n </NextMoveFrame>\n );\n}\n\nfunction NextMoveFrame({ children }: { children: React.ReactNode }) {\n return (\n <div>\n <div className=\"vos-head\">\n <div>\n <h1>Next move</h1>\n <p>The single next move to make — and what's on deck.</p>\n </div>\n </div>\n <div className=\"vos-next\">{children}</div>\n </div>\n );\n}\n\n/** The hero's act control — a form CTA for human acts, a review link for\n * agent-run acts (OPS-1294 step-in adaptation). */\nfunction ActButton({\n move,\n onStepIn,\n onReview,\n}: {\n move: NextMove;\n onStepIn: () => void;\n onReview: () => void;\n}) {\n const pres = movePresentation(move.move);\n if (pres.steppable) {\n return (\n <button type=\"button\" className=\"vos-btn vos-hero-act\" onClick={onStepIn}>\n {pres.cta}\n </button>\n );\n }\n return (\n <div className=\"vos-hero-agent\">\n <span className=\"vos-agent-note\">🤖 Claude Code runs this off the dashboard</span>\n <button type=\"button\" className=\"vos-btn vos-btn-ghost vos-hero-act\" onClick={onReview}>\n Review on the record →\n </button>\n </div>\n );\n}\n\nfunction KillBanner({ count, onReview }: { count: number; onReview: () => void }) {\n return (\n <div className=\"vos-banner vos-banner-crit\">\n <div className=\"vos-banner-body\">\n <b>\n {count === 1\n ? \"A belief has fallen into the kill lane\"\n : `${count} beliefs have fallen into the kill lane`}\n </b>\n <span>Confidence ≤ −50 — the evidence is against it. Kill it or test it again.</span>\n </div>\n <button type=\"button\" onClick={onReview}>\n Review\n </button>\n </div>\n );\n}\n\nfunction OnDeckRow({\n move,\n onOpen,\n onAct,\n}: {\n move: NextMove;\n onOpen: () => void;\n onAct: () => void;\n}) {\n const pres = movePresentation(move.move);\n const tone = riskLevel(move.risk);\n return (\n <div className=\"vos-ondeck-row\">\n <span className=\"vos-risk-bar\" aria-hidden=\"true\">\n <i className={`vos-fill-${tone}`} style={{ width: `${riskFraction(move.risk) * 100}%` }} />\n </span>\n <button type=\"button\" className=\"vos-ondeck-title\" onClick={onOpen}>\n {move.title}\n </button>\n <button type=\"button\" className=\"vos-pill vos-pill-accent vos-ondeck-act\" onClick={onAct}>\n {pres.pill}\n </button>\n </div>\n );\n}\n\n/** All the machinery, revealed on demand: the numeric risk, the Feasibility ×\n * Risk formula, the stage stepper, and the full ranked list (OPS-1295). */\nfunction WhyPanel({ top, ranked }: { top: NextMove; ranked: NextMove[] }) {\n return (\n <div className=\"vos-why-panel vos-next-why\">\n <p className=\"vos-why-reason\">{top.reason}</p>\n\n <div>\n <div className=\"vos-why-section-title\">Where it sits</div>\n <StageStepper move={top.move} />\n </div>\n\n <div>\n <div className=\"vos-why-section-title\">Why it's on top</div>\n <p className=\"vos-why-formula\">\n Ranked by <b>Feasibility × Risk</b> — Risk <b>{Math.round(top.risk)}</b>\n {top.feasibility ? (\n <>\n {\" \"}\n × Feasibility <b>{top.feasibility}</b>\n </>\n ) : (\n <> (no test planned yet — neutral feasibility)</>\n )}\n {top.killLane ? \" · in the kill lane, so it jumps the queue\" : null}.\n </p>\n </div>\n\n <div>\n <div className=\"vos-why-section-title\">The ranking</div>\n <ol className=\"vos-why-rank\">\n {ranked.slice(0, 6).map((m) => (\n <li key={m.assumptionId} className={m.assumptionId === top.assumptionId ? \"vos-why-rank-top\" : \"\"}>\n <span className=\"vos-why-rank-title\">{m.title}</span>\n <span className=\"vos-why-rank-score\">{Math.round(m.score)}</span>\n </li>\n ))}\n </ol>\n </div>\n </div>\n );\n}\n\nfunction StageStepper({ move }: { move: MoveKind }) {\n const at = MOVE_STAGE[move];\n return (\n <div className=\"vos-stepper\" aria-label={`Stage: ${STAGES[at]}`}>\n {STAGES.map((label, i) => (\n <span\n key={label}\n className={`vos-step${i === at ? \" vos-step-at\" : \"\"}${i < at ? \" vos-step-done\" : \"\"}`}\n >\n {label}\n </span>\n ))}\n </div>\n );\n}\n","import { useMemo, useState, type ReactNode } from \"react\";\nimport type { AnyRecord } from \"@validation-os/core\";\nimport { coldStartFor, FIRST_RUN_LINE } from \"./cold-start.js\";\nimport { DrawerShell } from \"./drawer-shell.js\";\nimport { RegisterTable } from \"./register-table.js\";\nimport type { Route } from \"./route.js\";\nimport {\n buildStageGrid,\n cellAt,\n NO_LENS,\n NO_STAGE,\n rankByRisk,\n STAGE_GLOSS,\n STAGE_ORDER,\n type StageGridCell,\n type StageGridView,\n type StageValue,\n} from \"./stage-grid-model.js\";\nimport { useList } from \"./use-records.js\";\n\n/**\n * The Lens × Stage heatmap surface (docs/stage-policy.md §The dashboard\n * surface) — the workflow dashboard's portfolio lens, mounted alongside\n * `NextMoveSurface` and `PipelineSurface`. One row per Lens (the actor — who\n * the belief is about), one column per Stage (the kind of response — engage\n * / pay / scale / defend), each cell carrying its assumption count and a\n * heatmap colour by density. Click a cell → a drill-through drawer with the\n * assumptions in that cell, ranked by Risk (the grid is the filter, Risk is\n * the rank).\n *\n * No stage-flag selector, no \"what stage am I\" prompt, no per-stage\n * confidence model — the grid reads the business state off where the bets\n * cluster, and lets you drill into any cell ranked by Risk. The densest cell\n * per row is where that part of the business is; thin/empty cells are gaps\n * (Consumer × Maturity is honestly 0 — consumers don't drive defense bets).\n *\n * Lazy-loads the assumption register and derives everything through the pure\n * `buildStageGrid` view-model — no number is computed here (spec: explain\n * from inputs). Clicking a belief in the drill-through routes to that\n * belief's record page (OPS-1298), the review surface where step-in happens.\n */\nexport interface StageGridSurfaceProps {\n basePath?: string;\n /** Navigate across the shell (belief → record). */\n onNavigate: (route: Route) => void;\n}\n\nexport function StageGridSurface({ basePath, onNavigate }: StageGridSurfaceProps) {\n const assumptions = useList(\"assumptions\", basePath);\n\n const loading = assumptions.loading;\n const error = assumptions.error;\n\n const [open, setOpen] = useState<StageGridCell | null>(null);\n\n const view = useMemo(\n () => buildStageGrid(assumptions.records ?? []),\n [assumptions.records],\n );\n\n const refresh = () => assumptions.refresh();\n const openRecord = (id: string) => onNavigate({ name: \"record\", id });\n\n if (loading && !assumptions.records) {\n return (\n <StageGridFrame>\n <div className=\"vos-empty\">Reading where your bets cluster…</div>\n </StageGridFrame>\n );\n }\n if (error) {\n return (\n <StageGridFrame>\n <div className=\"vos-banner vos-banner-crit\">\n <div className=\"vos-banner-body\">\n <b>Couldn't load the grid.</b>\n <span>{error}</span>\n </div>\n </div>\n </StageGridFrame>\n );\n }\n\n const cold = coldStartFor({\n assumptions: assumptions.records ?? [],\n experiments: [],\n readings: [],\n decisions: [],\n });\n if (cold.cold) {\n return (\n <StageGridFrame>\n <div className=\"vos-firstrun\">{FIRST_RUN_LINE}</div>\n <div className=\"vos-card vos-cold vos-cold-stage-grid\">\n <span className=\"vos-cold-eyebrow\">No bets yet</span>\n <p className=\"vos-cold-body\">\n The Lens × Stage grid reads your business state off where your\n bets cluster. Write your first belief and the grid fills in —\n the densest cell per row is where that part of the business is.\n </p>\n <button\n type=\"button\"\n className=\"vos-btn\"\n onClick={() => onNavigate({ name: \"records\", register: \"assumptions\", view: \"all\" })}\n >\n Write your first bet\n </button>\n </div>\n </StageGridFrame>\n );\n }\n\n return (\n <StageGridFrame total={view.total} onRefresh={refresh} onNavigate={onNavigate}>\n <div className=\"vos-card vos-stage-grid-card\">\n <div className=\"vos-stage-grid-scroll\">\n <table className=\"vos-stage-grid\" role=\"grid\" aria-label=\"Lens × Stage heatmap\">\n <thead>\n <tr>\n <th scope=\"col\" className=\"vos-stage-grid-corner\">Lens ↓ / Stage →</th>\n {view.stages.map((stage) => (\n <th key={stage} scope=\"col\" className=\"vos-stage-grid-col\">\n <span className=\"vos-stage-grid-stagename\">{stage}</span>\n <span className=\"vos-stage-grid-stagegloss\">{STAGE_GLOSS[stage]}</span>\n </th>\n ))}\n </tr>\n </thead>\n <tbody>\n {view.lenses.map((lens) => (\n <tr key={lens}>\n <th scope=\"row\" className=\"vos-stage-grid-rowhead\">\n {lens}\n </th>\n {view.stages.map((stage) => {\n const cell = cellAt(view, lens, stage)!;\n return (\n <StageCell\n key={stage}\n cell={cell}\n onClick={() => setOpen(cell)}\n />\n );\n })}\n </tr>\n ))}\n </tbody>\n </table>\n </div>\n <p className=\"vos-hint vos-stage-grid-foot\">\n The densest cell per row is where that part of the business is — no\n flag, no declaration, the density tells you. Click a cell to drill\n into its assumptions, ranked by Risk. Thin/empty cells are gaps:\n Consumer × Maturity is honestly 0 (consumers don't drive defense\n bets); a thin Commercial × Scale row is under-tracking scale.\n </p>\n </div>\n\n <CellDrawer\n cell={open}\n onClose={() => setOpen(null)}\n onOpenRecord={openRecord}\n onNavigate={onNavigate}\n />\n </StageGridFrame>\n );\n}\n\n/** The frame — title, subtitle, optional total + refresh. */\nfunction StageGridFrame({\n total,\n onRefresh,\n onNavigate,\n children,\n}: {\n total?: number;\n onRefresh?: () => void;\n onNavigate?: (route: Route) => void;\n children: ReactNode;\n}) {\n return (\n <div>\n <div className=\"vos-head\">\n <div>\n <h1>Lens × Stage — where your bets cluster</h1>\n <p>\n Every belief cross-tabbed by the actor it's about (Lens) and the\n kind of response it tests (Stage). The grid is the filter; Risk\n is the rank.\n </p>\n </div>\n <div className=\"vos-spacer\" />\n {total !== undefined ? (\n <span className=\"vos-hint vos-stage-grid-total\">\n {total} {total === 1 ? \"belief\" : \"beliefs\"}\n </span>\n ) : null}\n {onRefresh ? (\n <button\n type=\"button\"\n className=\"vos-btn vos-btn-ghost\"\n onClick={onRefresh}\n >\n ↻ Refresh\n </button>\n ) : null}\n {onNavigate ? (\n <button\n type=\"button\"\n className=\"vos-btn vos-btn-ghost\"\n onClick={() =>\n onNavigate({ name: \"records\", register: \"assumptions\", view: \"all\" })\n }\n >\n View all →\n </button>\n ) : null}\n </div>\n <div className=\"vos-stage-grid-host\">{children}</div>\n </div>\n );\n}\n\n/** One heatmap cell — a button (drill-through) when populated, a muted span\n * when empty (still clickable so a 0 cell is addressable, but reads as\n * quiet). The fill opacity tracks the cell's density. */\nfunction StageCell({\n cell,\n onClick,\n}: {\n cell: StageGridCell;\n onClick: () => void;\n}) {\n const empty = cell.count === 0;\n const style = empty\n ? undefined\n : {\n // Heatmap fill: opacity 0.08 → 0.92 across the density range, on the\n // accent token. Keeps the grid readable in both themes.\n \"--vos-cell-alpha\": (0.08 + cell.density * 0.84).toFixed(3),\n } as React.CSSProperties;\n return (\n <td\n className={`vos-stage-grid-cell${empty ? \" vos-stage-grid-cell-empty\" : \"\"}`}\n style={style}\n >\n <button\n type=\"button\"\n className=\"vos-stage-grid-btn\"\n onClick={onClick}\n aria-label={`${cell.lens} × ${cell.stage}: ${cell.count} ${cell.count === 1 ? \"belief\" : \"beliefs\"}`}\n title={empty ? \"No beliefs in this cell\" : `Riskiest: ${cell.assumptions[0]?.Title ?? \"—\"}`}\n >\n <span className=\"vos-stage-grid-count vos-num\">{cell.count}</span>\n </button>\n </td>\n );\n}\n\n/** The drill-through drawer — a cell's assumptions, ranked by Risk. Reuses\n * `RegisterTable` as the leaf renderer so the columns stay identical to the\n * assumptions browse table (Title, Status, Impact, Confidence, Risk). */\nfunction CellDrawer({\n cell,\n onClose,\n onOpenRecord,\n onNavigate,\n}: {\n cell: StageGridCell | null;\n onClose: () => void;\n onOpenRecord: (id: string) => void;\n onNavigate?: (route: Route) => void;\n}) {\n return (\n <DrawerShell\n open={cell !== null}\n onClose={onClose}\n ariaLabel={\n cell\n ? `${cell.lens} × ${cell.stage} — ${cell.count} ${cell.count === 1 ? \"belief\" : \"beliefs\"}`\n : \"Cell drill-through\"\n }\n >\n <header className=\"vos-drawer-header\">\n <div>\n <p className=\"vos-drawer-eyebrow\">Lens × Stage</p>\n <h2 className=\"vos-drawer-title\">\n {cell?.lens} × {cell?.stage}\n </h2>\n <p className=\"vos-hint\">\n {cell && cell.count > 0\n ? `${cell.count} ${cell.count === 1 ? \"belief\" : \"beliefs\"}, ranked by Risk — riskiest first.`\n : \"No beliefs in this cell.\"}\n </p>\n </div>\n {cell && cell.stage !== \"—\" && onNavigate && (\n <button\n type=\"button\"\n className=\"vos-btn vos-btn-secondary\"\n onClick={() =>\n onNavigate({\n name: \"records\",\n register: \"assumptions\",\n lens: cell.lens === \"—\" ? undefined : cell.lens,\n stage: cell.stage,\n })\n }\n >\n Open in table →\n </button>\n )}\n </header>\n {cell && cell.count > 0 ? (\n <div className=\"vos-stage-grid-drawer-body\">\n <RegisterTable\n register=\"assumptions\"\n records={cell.assumptions}\n onRowClick={onOpenRecord}\n />\n </div>\n ) : cell ? (\n <p className=\"vos-empty\" style={{ margin: 16 }}>\n No beliefs in this cell — a gap, not a bug.\n </p>\n ) : null}\n </DrawerShell>\n );\n}\n\n// Re-export the pure view-model exports for callers building their own surface\n// (matches the pattern `pipeline-surface.tsx` sets for `buildPipeline`).\nexport {\n buildStageGrid,\n cellAt,\n NO_LENS,\n NO_STAGE,\n rankByRisk,\n STAGE_GLOSS,\n STAGE_ORDER,\n};\nexport type { StageGridCell, StageGridView, StageValue };"],"mappings":"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","names":["useCallback","useEffect","useState","t","belief","RUNG_ANCHOR","RUNG_ANCHOR","confidence","jsx","jsxs","rule","m","confidence","t","Fragment","jsx","jsxs","useState","str","useState","t","Fragment","jsx","jsxs","confidence","nextMove","flagged","belief","snippetFromBody","pct","useMemo","useState","str","riskThresholdForStage","norm","num","str","riskThresholdForStage","t","pct","confidence","Fragment","jsx","jsxs","useMemo","Breadcrumb","useState","Breadcrumb","jsx","t","jsxs","useMemo","jsx","jsxs","pct","jsx","jsxs","useMemo","verdictTone","jsx","jsxs","useMemo","jsx","jsxs","useMemo","verdictTone","jsx","jsxs","useMemo","useState","jsx","jsxs","assumptionCompleteness","readingBeliefInputs","beliefTestMeters","deriveBeliefStage","readingBeliefInputs","readingBeliefInputs","str","belief","confidence","beliefTestMeters","assumptionCompleteness","deriveBeliefStage","readingBeliefInputs","nextMove","useState","useState","useEffect","Fragment","jsx","jsxs","useCallback","useState","jsx","jsxs","useState","Fragment","jsx","jsxs","PILL_CLASS","pct","confidence","readingBeliefInputs","confidenceAttribution","experimentProgress","isConcluded","readingBeliefInputs","confidence","confidenceAttribution","experimentProgress","isConcluded","Fragment","jsx","jsxs","Fragment","jsx","jsxs","useState","t","buckets","jsx","jsxs","verdictTone","Fragment","jsx","jsxs","PILL_CLASS","useState","useMemo","t","useMemo","useState","jsx","jsxs","useEffect","useState","Fragment","jsx","jsxs","useState","useEffect","ConflictBanner","num","useMemo","useState","DECISION_STATUS","jsx","jsxs","useMemo","useState","useMemo","useState","jsx","jsxs","useMemo","useState","useCallback","useEffect","useState","jsx","jsxs","useState","useMemo","groupBy","jsx","jsxs","useCallback","useEffect","useMemo","useState","useState","useEffect","useCallback","t","useMemo","jsx","jsxs","useState","useEffect","useCallback","useState","jsx","jsxs","useState","jsx","jsxs","Fragment","jsx","jsxs","PipelineBoard","jsx","jsxs","useMemo","useState","rankNextMoves","Fragment","jsx","jsxs","STAGES","useState","useMemo","rankNextMoves","jsx","jsxs","Fragment","useMemo","useState","jsx","jsxs","useState","useMemo"]}