Lane 5: UI Trace Updates for Geometric Invariants

This commit is contained in:
Shay 2026-07-04 15:12:48 -07:00
parent 2a17d5b6f3
commit 8d1eb8af5d
5 changed files with 64 additions and 4 deletions

View file

@ -1,4 +1,4 @@
import { useMemo } from "react";
import { useMemo, type ReactNode } from "react";
import type { ConstructionEvidence } from "../../types/constructionEvidence";
import { MetadataTable } from "../../design/components/MetadataTable/MetadataTable";
import { StableJsonViewer } from "../../design/components/StableJsonViewer";
@ -19,6 +19,27 @@ export interface ConstructionEvidencePanelProps {
errorMessage: (error: unknown) => string;
}
function renderValue(val: string | ReactNode) {
if (typeof val === "string" && val.includes("(invariant met: versor_error < 1e-6)")) {
const parts = val.split("(invariant met: versor_error < 1e-6)");
return (
<span className="flex flex-wrap items-center gap-1">
{parts.map((part, index) => (
<span key={index} className="flex items-center gap-1">
{part}
{index < parts.length - 1 && (
<span className="inline-flex items-center rounded-full bg-emerald-500/10 px-1.5 py-0.5 text-[10px] font-medium text-emerald-600 ring-1 ring-inset ring-emerald-500/20 dark:bg-emerald-500/10 dark:text-emerald-400 dark:ring-emerald-500/20">
invariant met: versor_error &lt; 1e-6
</span>
)}
</span>
))}
</span>
);
}
return val;
}
function rowValue(value: string) {
return value;
}
@ -41,7 +62,7 @@ function DetailSection({ section }: { section: ConstructionEvidenceDetailSection
<MetadataTable
rows={item.rows.map((row) => ({
key: row.key,
value: row.value,
value: renderValue(row.value),
mono: true,
}))}
/>
@ -119,7 +140,7 @@ export function ConstructionEvidencePanel({
<MetadataTable
rows={model.assessmentRows.map((row) => ({
key: row.key,
value: row.value,
value: renderValue(row.value),
}))}
/>
) : null}
@ -138,7 +159,7 @@ export function ConstructionEvidencePanel({
<MetadataTable
rows={model.sourceSpanRows.map((row) => ({
key: row.key,
value: row.value,
value: renderValue(row.value),
mono: true,
}))}
/>

View file

@ -17,6 +17,8 @@ export interface ConstructionEvidenceSummaryRow {
value: string;
}
import { AssessmentBindingView } from "../../types/constructionEvidence";
export interface ConstructionEvidenceDetailItem {
title: string;
rows: ConstructionEvidenceSummaryRow[];
@ -209,6 +211,12 @@ function detailSections(evidence: ConstructionEvidence): ConstructionEvidenceDet
{ key: "unresolved_hazards", value: noneIfEmpty(assessment.unresolved_hazards) },
{ key: "explanation", value: assessment.explanation || "none" },
{ key: "evidence_spans", value: spanList(evidence.problem_text, assessment.evidence_spans) },
{
key: "bindings",
value: assessment.bindings && assessment.bindings.length > 0
? assessment.bindings.map(b => `${b.role}=${b.target_id}${b.versor_error !== undefined && b.versor_error < 1e-6 ? " (invariant met: versor_error < 1e-6)" : (b.versor_error !== undefined ? ` (versor_error: ${b.versor_error})` : "")}`).join("; ")
: "none"
},
],
})),
},

View file

@ -36,6 +36,7 @@ export interface MentionBindingView {
source_mention_id: string;
target_mention_id: string;
evidence_spans: SourceSpanView[];
bindings?: AssessmentBindingView[];
}
export interface BoundRelationRoleView {
@ -50,6 +51,12 @@ export interface BoundRelationView {
evidence_spans: SourceSpanView[];
}
export interface AssessmentBindingView {
role: string;
target_id: string;
versor_error?: number;
}
export interface ContractAssessmentView {
candidate_organ: string;
family_id: string | null;

12
workbench-ui/update.cjs Normal file
View file

@ -0,0 +1,12 @@
const fs = require('fs');
const file = 'src/types/constructionEvidence.ts';
let content = fs.readFileSync(file, 'utf8');
content = content.replace(
'export interface ContractAssessmentView {',
'export interface AssessmentBindingView {\n role: string;\n target_id: string;\n versor_error?: number;\n}\n\nexport interface ContractAssessmentView {'
);
content = content.replace(
'evidence_spans: SourceSpanView[];\n}',
'evidence_spans: SourceSpanView[];\n bindings?: AssessmentBindingView[];\n}'
);
fs.writeFileSync(file, content, 'utf8');

12
workbench-ui/update.js Normal file
View file

@ -0,0 +1,12 @@
const fs = require('fs');
const file = 'src/types/constructionEvidence.ts';
let content = fs.readFileSync(file, 'utf8');
content = content.replace(
'export interface ContractAssessmentView {',
'export interface AssessmentBindingView {\n role: string;\n target_id: string;\n versor_error?: number;\n}\n\nexport interface ContractAssessmentView {'
);
content = content.replace(
'evidence_spans: SourceSpanView[];\n}',
'evidence_spans: SourceSpanView[];\n bindings?: AssessmentBindingView[];\n}'
);
fs.writeFileSync(file, content, 'utf8');