Witness Visualization Components

Sprint: SPRINT_20260118_020_FE_witness_visualization

The witness visualization component suite provides UI for displaying runtime witness data, comparing static analysis paths with runtime observations, and managing witness gate results in release promotion flows.

Overview

Runtime witnesses confirm that static analysis reachability paths are actually exercised during application execution. These components visualize:

Components

Core Components

ComponentPurposeLocation
WitnessStatusChipComponentStatus badge showing witness stateshared/domain/witness-status-chip/
WitnessComparisonComponentStatic vs runtime path comparisonshared/components/witness-comparison/
UnwitnessedAdvisoryComponentAdvisory panel for unwitnessed pathsshared/components/unwitnessed-advisory/
GateSummaryPanelComponentGate results with witness metricsshared/domain/gate-summary-panel/

Witness Status Chip

Displays the witness status of a reachability path with color-coded badges.

import { WitnessStatusChipComponent, WitnessStatus } from '@app/shared/domain/witness-status-chip';

States

StateColorIconDescription
witnessedGreenPath confirmed by runtime observation
unwitnessedYellowPath not yet observed at runtime
staleOrangeWitness data is outdated
failedRedWitness verification failed

Usage

<!-- Basic usage -->
<app-witness-status-chip [status]="'witnessed'" />

<!-- With details for tooltip -->
<app-witness-status-chip
  [status]="'witnessed'"
  [details]="{
    status: 'witnessed',
    lastObserved: '2026-01-15T10:30:00Z',
    observationCount: 42,
    rekorLogIndex: 12345
  }"
  [showCount]="true"
  (chipClick)="onChipClick()"
/>

Input Properties

PropertyTypeDefaultDescription
statusWitnessStatusrequiredWitness status to display
detailsWitnessStatusDetailsnullOptional metadata for tooltip
showCountbooleantrueWhether to show observation count

Witness Comparison Component

Side-by-side or overlay view comparing static analysis paths with runtime observations. The main visualization for understanding witness coverage.

import {
  WitnessComparisonComponent,
  WitnessComparisonData,
  ComparisonPathStep,
  ComparisonMetrics,
} from '@app/shared/components/witness-comparison';

Features

Usage

<app-witness-comparison
  [data]="comparisonData"
  (stepClick)="onStepClick($event)"
  (refresh)="onRefresh()"
/>

Input Properties

PropertyTypeDescription
dataWitnessComparisonDataComparison data with paths and metrics

Output Events

EventTypeDescription
stepClickComparisonPathStepEmitted when user clicks a step
refreshvoidEmitted when user requests data refresh

Data Models

interface ComparisonPathStep {
  nodeId: string;
  symbol: string;
  file?: string;
  line?: number;
  package?: string;
  inStatic: boolean;      // Found in static analysis
  inRuntime: boolean;     // Observed at runtime
  runtimeInvocations?: number;
  lastObserved?: string;
}

interface ComparisonMetrics {
  totalSteps: number;
  confirmedSteps: number;      // Both static and runtime
  staticOnlySteps: number;     // Static only (unwitnessed)
  runtimeOnlySteps: number;    // Runtime only (unexpected)
  confirmationRate: number;    // Percentage confirmed
}

interface WitnessComparisonData {
  claimId: string;
  cveId?: string;
  packageName: string;
  packageVersion?: string;
  pathSteps: ComparisonPathStep[];
  metrics: ComparisonMetrics;
  generatedAt: string;
}

Unwitnessed Advisory Component

Advisory panel displayed when release promotion encounters paths without runtime witnesses. Used in the gate flow to inform operators about witness coverage gaps.

import {
  UnwitnessedAdvisoryComponent,
  UnwitnessedAdvisoryData,
  UnwitnessedPath,
} from '@app/shared/components/unwitnessed-advisory';

Features

Usage

<app-unwitnessed-advisory
  [data]="advisoryData"
  (createTestTask)="onCreateTestTask($event)"
  (createAllTestTasks)="onCreateAllTestTasks()"
  (viewComparison)="onViewComparison()"
/>

Input Properties

PropertyTypeDescription
dataUnwitnessedAdvisoryDataAdvisory data with paths and configuration

Output Events

EventTypeDescription
createTestTaskUnwitnessedPathCreate test task for specific path
createAllTestTasksvoidCreate test tasks for all paths
viewComparisonvoidOpen full comparison view

Data Models

interface UnwitnessedPath {
  pathId: string;
  cveId?: string;
  vulnId: string;
  packageName: string;
  packageVersion?: string;
  entrypoint: string;
  sink: string;
  severity: 'critical' | 'high' | 'medium' | 'low' | 'unknown';
  confidence: number;
  lastAnalyzed?: string;
}

interface UnwitnessedAdvisoryData {
  totalUnwitnessed: number;
  paths: UnwitnessedPath[];
  targetEnvironment?: string;
  isBlocking: boolean;
}

Gate Summary Panel (Extended)

Extended to support witness gate display with metrics, expandable details, and comparison links.

import {
  GateSummaryPanelComponent,
  GateResult,
  WitnessGateMetrics,
  WitnessPathSummary,
} from '@app/shared/domain/gate-summary-panel';

Witness Gate Support

The GateResult interface now supports witness-specific properties:

interface GateResult {
  id: string;
  name: string;
  state: 'PASS' | 'WARN' | 'BLOCK' | 'SKIP';
  reason?: string;
  ruleHits?: number;
  gateType?: 'standard' | 'witness' | 'cve' | 'sbom';
  witnessMetrics?: WitnessGateMetrics;
}

interface WitnessGateMetrics {
  totalPaths: number;
  witnessedPaths: number;
  unwitnessedPaths: number;
  stalePaths?: number;
  unwitnessedPathDetails?: WitnessPathSummary[];
}

interface WitnessPathSummary {
  pathId: string;
  entrypoint: string;
  sink: string;
  severity?: 'critical' | 'high' | 'medium' | 'low' | 'unknown';
  vulnId?: string;
}

Usage

<app-gate-summary-panel
  [gates]="gates"
  [policyRef]="policyReference"
  [snapshotRef]="snapshotReference"
  (openExplain)="onOpenExplain($event)"
  (openEvidence)="onOpenEvidence()"
  (openComparison)="onOpenComparison($event)"
/>

Witness Gate Features


Color Coding Reference

Comparison States

StateColorCSS VariableMeaning
ConfirmedGreen--green-500Path in both static and runtime
Static OnlyYellow--yellow-500Path predicted but not observed
Runtime OnlyOrange--orange-500Unexpected path observed

Severity Colors

SeverityColorCSS Variable
CriticalRed--red-500
HighOrange--orange-500
MediumYellow--yellow-500
LowBlue--blue-500
UnknownGray--gray-400

Integration with Existing Components

The witness visualization components integrate with several existing UI elements:

Existing ComponentIntegration
WitnessDrawerComponentCan embed comparison view
WitnessPageComponentFull reachability analysis page
TimelineListComponentDisplay witness observation timeline
GateExplainDrawerComponentShow witness gate explanation

Accessibility

All witness visualization components follow WCAG 2.1 AA guidelines:


Testing

Unit tests are located alongside components:

Run tests:

cd src/Web/StellaOps.Web
npm test -- --include="**/*witness*" --include="**/*gate-summary*"