diff --git a/turnstone/ui/static/app.js b/turnstone/ui/static/app.js index 05fd08fa..7ce613f9 100644 --- a/turnstone/ui/static/app.js +++ b/turnstone/ui/static/app.js @@ -1437,10 +1437,7 @@ class Pane { // judgePending=false because any verdict on replay is // final — no spinner. if (tc.verdict) { - div.insertAdjacentHTML( - "beforeend", - renderVerdictBadge(tc.verdict, false), - ); + div.appendChild(renderVerdictBadge(tc.verdict, false)); } block.appendChild(div); // Output-guard finding — defer insertion until the tool @@ -1652,10 +1649,7 @@ class Pane { // key in case a stale SSE payload arrives mid-deploy. const heuristic = item.heuristic_verdict || item.verdict; if (heuristic) { - block.insertAdjacentHTML( - "beforeend", - renderVerdictBadge(heuristic, judgePending), - ); + block.appendChild(renderVerdictBadge(heuristic, judgePending)); const rec = heuristic.recommendation || "review"; if ( !glowRec || @@ -4838,61 +4832,83 @@ function buildToolDiv(item) { } function renderVerdictBadge(verdict, judgePending) { - if (!verdict) return ""; + if (!verdict) return document.createDocumentFragment(); const risk = verdict.risk_level || "medium"; const rec = verdict.recommendation || "review"; const conf = Math.round((verdict.confidence || 0) * 100); - const summary = verdict.intent_summary || ""; - let spinnerHtml = ""; + + const badge = document.createElement("div"); + badge.className = "verdict-badge verdict-" + risk + " ts-verdict-badge"; + badge.setAttribute("data-risk", risk); + if (verdict.call_id) badge.setAttribute("data-call-id", verdict.call_id); + + const riskSpan = document.createElement("span"); + riskSpan.className = "verdict-risk"; + riskSpan.textContent = risk.toUpperCase(); + + const recSpan = document.createElement("span"); + recSpan.className = "verdict-rec"; + recSpan.textContent = rec; + + const confSpan = document.createElement("span"); + confSpan.className = "verdict-conf"; + confSpan.textContent = conf + "%"; + + badge.append(riskSpan, recSpan, confSpan); + if (judgePending) { - spinnerHtml = - '' + - ' judge analyzing\u2026'; + const spinner = document.createElement("span"); + spinner.className = "verdict-judge-spinner"; + const dot = document.createElement("span"); + dot.className = "judge-spinner-dot"; + spinner.append(dot, " judge analyzing\u2026"); + badge.appendChild(spinner); } - const callId = escapeHtml(verdict.call_id || ""); - return ( - '