fix(workbench-ui): harden practice evidence panel model guards

This commit is contained in:
Shay 2026-06-23 16:01:23 -07:00
parent e2c7840a4d
commit 0074897c7a

View file

@ -40,18 +40,19 @@ function boolLabel(value: boolean): string {
return value ? "true" : "false"; return value ? "true" : "false";
} }
function listLabel(values: readonly string[]): string { function listLabel(values: readonly string[] | null | undefined): string {
return values.length > 0 ? values.join(", ") : "none"; return values && values.length > 0 ? values.join(", ") : "none";
} }
function sourceSpanRows(evidence: PracticeEvidence): PracticeEvidenceSummaryRow[] { function sourceSpanRows(evidence: PracticeEvidence): PracticeEvidenceSummaryRow[] {
const rows: PracticeEvidenceSummaryRow[] = []; const rows: PracticeEvidenceSummaryRow[] = [];
const append = (prefix: string, spans: readonly PracticeSourceSpanView[]) => { const append = (prefix: string, spans: readonly PracticeSourceSpanView[] | null | undefined) => {
if (!spans) return;
spans.forEach((span, index) => { spans.forEach((span, index) => {
rows.push({ key: `${prefix}.${index + 1}`, value: practiceSourceSpanLabel(span) }); rows.push({ key: `${prefix}.${index + 1}`, value: practiceSourceSpanLabel(span) });
}); });
}; };
if (evidence.sealed_trace !== null) { if (evidence.sealed_trace != null) {
append("sealed_trace", evidence.sealed_trace.evidence_spans); append("sealed_trace", evidence.sealed_trace.evidence_spans);
} }
return rows; return rows;
@ -105,11 +106,12 @@ function traceRefusalRows(refusal: PracticeTraceRefusalView): PracticeEvidenceSu
} }
function detailSections(evidence: PracticeEvidence): PracticeEvidenceDetailSection[] { function detailSections(evidence: PracticeEvidence): PracticeEvidenceDetailSection[] {
const chain = evidence.chain ?? [];
return [ return [
{ {
title: "Evidence chain", title: "Evidence chain",
emptyMessage: "No sealed practice chain cards recorded.", emptyMessage: "No sealed practice chain cards recorded.",
items: evidence.chain.map((card, index) => ({ items: chain.map((card, index) => ({
title: `card ${index + 1}: ${card.kind}`, title: `card ${index + 1}: ${card.kind}`,
rows: cardRows(card), rows: cardRows(card),
})), })),
@ -118,7 +120,7 @@ function detailSections(evidence: PracticeEvidence): PracticeEvidenceDetailSecti
title: "Sealed trace", title: "Sealed trace",
emptyMessage: "No sealed practice trace recorded.", emptyMessage: "No sealed practice trace recorded.",
items: items:
evidence.sealed_trace === null evidence.sealed_trace == null
? [] ? []
: [ : [
{ {
@ -131,7 +133,7 @@ function detailSections(evidence: PracticeEvidence): PracticeEvidenceDetailSecti
title: "Trace refusal", title: "Trace refusal",
emptyMessage: "No practice trace refusal recorded.", emptyMessage: "No practice trace refusal recorded.",
items: items:
evidence.trace_refusal === null evidence.trace_refusal == null
? [] ? []
: [ : [
{ {
@ -144,6 +146,11 @@ function detailSections(evidence: PracticeEvidence): PracticeEvidenceDetailSecti
} }
export function practiceEvidencePanelModel(evidence: PracticeEvidence): PracticeEvidencePanelModel { export function practiceEvidencePanelModel(evidence: PracticeEvidence): PracticeEvidencePanelModel {
const chain = evidence.chain ?? [];
const sealedTrace = evidence.sealed_trace;
const traceRefusal = evidence.trace_refusal;
const sourceSpanCount = sealedTrace?.evidence_spans?.length ?? 0;
return { return {
status: evidence.status, status: evidence.status,
emptyMessage: practiceEvidenceEmptyMessage(evidence), emptyMessage: practiceEvidenceEmptyMessage(evidence),
@ -161,15 +168,12 @@ export function practiceEvidencePanelModel(evidence: PracticeEvidence): Practice
{ key: "missing_reason", value: evidence.missing_reason ?? "none" }, { key: "missing_reason", value: evidence.missing_reason ?? "none" },
], ],
countRows: [ countRows: [
{ key: "chain_cards", value: String(evidence.chain.length) }, { key: "chain_cards", value: String(chain.length) },
{ key: "sealed_trace", value: evidence.sealed_trace === null ? "0" : "1" }, { key: "sealed_trace", value: sealedTrace == null ? "0" : "1" },
{ key: "trace_refusal", value: evidence.trace_refusal === null ? "0" : "1" }, { key: "trace_refusal", value: traceRefusal == null ? "0" : "1" },
{ { key: "source_spans", value: String(sourceSpanCount) },
key: "source_spans",
value: String(evidence.sealed_trace === null ? 0 : evidence.sealed_trace.evidence_spans.length),
},
], ],
chainRows: evidence.chain.map((card) => ({ chainRows: chain.map((card) => ({
key: card.kind, key: card.kind,
value: `${card.status}${listLabel(card.refs)}`, value: `${card.status}${listLabel(card.refs)}`,
})), })),