From f1d00fec0f64d10c622b0d5a06d0720b8af41dca Mon Sep 17 00:00:00 2001 From: Oliver Kieselbach Date: Fri, 10 Jul 2026 12:59:22 +0200 Subject: [PATCH] fix(web): dedupe rule-result evidence chips by eventId Multiple matched conditions often extract different fields from the same event (e.g. enrollment_failed + enrollment_failed_reason), which rendered duplicate identically-labeled chips all jumping to the same timeline event. Co-Authored-By: Claude Fable 5 --- .../autopilot-monitor-web/app/diagnosis/[sessionId]/page.tsx | 5 +++++ .../[sessionId]/components/AnalysisResultsSection.tsx | 5 +++++ 2 files changed, 10 insertions(+) diff --git a/src/Web/autopilot-monitor-web/app/diagnosis/[sessionId]/page.tsx b/src/Web/autopilot-monitor-web/app/diagnosis/[sessionId]/page.tsx index 63286cb4..680ba523 100644 --- a/src/Web/autopilot-monitor-web/app/diagnosis/[sessionId]/page.tsx +++ b/src/Web/autopilot-monitor-web/app/diagnosis/[sessionId]/page.tsx @@ -794,10 +794,15 @@ export default function DiagnosisPage() { function EvidenceEventLinks({ matchedConditions, sessionId }: { matchedConditions: Record; sessionId: string }) { const eventLinks: { signal: string; eventId: string; eventType?: string }[] = []; + const seenEventIds = new Set(); for (const [signal, evidence] of Object.entries(matchedConditions)) { if (signal.startsWith("factor_")) continue; if (evidence && typeof evidence === "object" && evidence.eventId) { + // Multiple matched conditions can extract different fields from the + // same event — one chip per distinct event, not per condition. + if (seenEventIds.has(evidence.eventId)) continue; + seenEventIds.add(evidence.eventId); eventLinks.push({ signal, eventId: evidence.eventId, eventType: evidence.eventType }); } } diff --git a/src/Web/autopilot-monitor-web/app/sessions/[sessionId]/components/AnalysisResultsSection.tsx b/src/Web/autopilot-monitor-web/app/sessions/[sessionId]/components/AnalysisResultsSection.tsx index 59368963..b9b7e927 100644 --- a/src/Web/autopilot-monitor-web/app/sessions/[sessionId]/components/AnalysisResultsSection.tsx +++ b/src/Web/autopilot-monitor-web/app/sessions/[sessionId]/components/AnalysisResultsSection.tsx @@ -306,10 +306,15 @@ function scrollToEvent(eventId: string) { function EvidenceEventLinks({ matchedConditions }: { matchedConditions: Record }) { const eventLinks: { signal: string; eventId: string; eventType?: string }[] = []; + const seenEventIds = new Set(); for (const [signal, evidence] of Object.entries(matchedConditions)) { if (signal.startsWith("factor_")) continue; if (evidence && typeof evidence === "object" && evidence.eventId) { + // Multiple matched conditions can extract different fields from the + // same event — one chip per distinct event, not per condition. + if (seenEventIds.has(evidence.eventId)) continue; + seenEventIds.add(evidence.eventId); eventLinks.push({ signal, eventId: evidence.eventId, eventType: evidence.eventType }); } }