Files
git.stella-ops.org/docs/modules/web/triage-component-catalog.md
StellaOps Bot 907783f625 Add property-based tests for SBOM/VEX document ordering and Unicode normalization determinism
- Implement `SbomVexOrderingDeterminismProperties` for testing component list and vulnerability metadata hash consistency.
- Create `UnicodeNormalizationDeterminismProperties` to validate NFC normalization and Unicode string handling.
- Add project file for `StellaOps.Testing.Determinism.Properties` with necessary dependencies.
- Introduce CI/CD template validation tests including YAML syntax checks and documentation content verification.
- Create validation script for CI/CD templates ensuring all required files and structures are present.
2025-12-26 15:17:58 +02:00

16 KiB

Triage Component Catalog

Version: 1.0 Status: Active Last Updated: 2025-12-26 Sprint: SPRINT_20251226_014_DOCS_triage_consolidation

Overview

This document catalogs all Angular components used in the unified triage experience, including the Smart-Diff Compare View, Triage Canvas, and Risk Dashboard. Each component is documented with its responsibilities, inputs/outputs, and relationships.

Component Hierarchy

src/Web/StellaOps.Web/src/app/
├── features/
│   ├── triage/
│   │   ├── triage-canvas/
│   │   │   ├── triage-canvas.component.ts          [Container]
│   │   │   ├── triage-list.component.ts
│   │   │   ├── triage-detail.component.ts
│   │   │   ├── ai-recommendation-panel.component.ts
│   │   │   ├── vex-decision-modal.component.ts
│   │   │   └── vex-history.component.ts
│   │   └── compare/
│   │       ├── compare-view.component.ts           [Container]
│   │       ├── baseline-selector.component.ts
│   │       ├── trust-indicators.component.ts
│   │       ├── delta-summary-strip.component.ts
│   │       ├── three-pane-layout.component.ts
│   │       ├── categories-pane.component.ts
│   │       ├── items-pane.component.ts
│   │       ├── proof-pane.component.ts
│   │       └── export-actions.component.ts
│   ├── risk-budget/
│   │   ├── risk-dashboard.component.ts             [Container]
│   │   ├── burn-up-chart.component.ts
│   │   ├── unknowns-heatmap.component.ts
│   │   ├── delta-table.component.ts
│   │   ├── exception-ledger.component.ts
│   │   └── kpi-tiles.component.ts
│   └── vulnerabilities/
│       └── vulnerability-detail.component.ts
└── shared/
    └── components/
        ├── confidence-badge.component.ts
        ├── determinism-badge.component.ts
        ├── severity-indicator.component.ts
        └── evidence-chain.component.ts

Container Components

TriageCanvasComponent

Location: features/triage/triage-canvas/triage-canvas.component.ts Sprint: SPRINT_20251226_013_FE Status: TODO

Purpose: Main container for the unified triage experience. Orchestrates list, detail, and decision panels.

Inputs:

Name Type Description
initialVulnId string? Pre-select vulnerability by ID
environment string? Filter by environment

Outputs:

Name Type Description
triageComplete EventEmitter Emitted when triage decision saved
queueExhausted EventEmitter Emitted when all items triaged

Child Components:

  • TriageListComponent
  • TriageDetailComponent
  • AiRecommendationPanel
  • VexDecisionModalComponent
  • VexHistoryComponent

CompareViewComponent

Location: features/triage/compare/compare-view.component.ts Sprint: SPRINT_20251226_012_FE Status: TODO

Purpose: Three-pane Smart-Diff comparison view with baseline selection and proof display.

Inputs:

Name Type Description
currentDigest string Digest of current scan
baselineDigest string? Digest of baseline (auto-selected if not provided)

Outputs:

Name Type Description
baselineChanged EventEmitter New baseline selected
exportRequested EventEmitter Export action triggered

Child Components:

  • BaselineSelectorComponent
  • TrustIndicatorsComponent
  • DeltaSummaryStripComponent
  • ThreePaneLayoutComponent
  • ExportActionsComponent

RiskDashboardComponent

Location: features/risk-budget/risk-dashboard.component.ts Sprint: SPRINT_20251226_004_FE Status: TODO

Purpose: Risk budget visualization with burn-up charts, heatmaps, and exception ledger.

Inputs:

Name Type Description
serviceId string Service to display budget for
window BudgetWindow Budget window (monthly, weekly)

Outputs:

Name Type Description
exceptionCreated EventEmitter New exception added
thresholdAlert EventEmitter Budget threshold crossed

Child Components:

  • BurnUpChartComponent
  • UnknownsHeatmapComponent
  • DeltaTableComponent
  • ExceptionLedgerComponent
  • KpiTilesComponent

Presentation Components

TriageListComponent

Location: features/triage/triage-canvas/triage-list.component.ts Sprint: SPRINT_20251226_013_FE Status: TODO

Purpose: Paginated, filterable list of vulnerabilities for triage.

Inputs:

Name Type Description
vulnerabilities Vulnerability[] List of vulnerabilities
selectedId string? Currently selected vulnerability
filters TriageFilters Active filters

Outputs:

Name Type Description
selectionChange EventEmitter Vulnerability selected
bulkAction EventEmitter Bulk triage requested

Features:

  • Virtual scrolling (cdk-virtual-scroll) for large lists
  • Filter chips: severity, KEV, exploitability, fix-available
  • Quick actions: "Mark Not Affected", "Request Analysis"

VexDecisionModalComponent

Location: features/triage/triage-canvas/vex-decision-modal.component.ts Sprint: SPRINT_20251226_013_FE Status: TODO

Purpose: Modal for creating/editing VEX decisions with full form controls.

Inputs:

Name Type Description
vulnerability Vulnerability Target vulnerability
existingDecision VexDecision? Decision to edit
suggestedJustification string? AI-suggested justification

Outputs:

Name Type Description
save EventEmitter Decision saved
cancel EventEmitter Modal cancelled

Form Fields:

  • Status: NotAffected, AffectedMitigated, AffectedUnmitigated, Fixed
  • Justification type (matches VexJustificationType enum)
  • Evidence references (PR, Ticket, Doc, Commit links)
  • Scope: environments and projects
  • Validity window: NotBefore/NotAfter dates
  • "Sign as Attestation" checkbox

ThreePaneLayoutComponent

Location: features/triage/compare/three-pane-layout.component.ts Sprint: SPRINT_20251226_012_FE Status: TODO

Purpose: Responsive three-column layout for Categories, Items, and Proof panes.

Inputs:

Name Type Description
delta Delta Computed delta with items
selectedCategory Category? Currently selected category
selectedItem DeltaItem? Currently selected item

Outputs:

Name Type Description
categorySelected EventEmitter Category clicked
itemSelected EventEmitter Item clicked

Layout Behavior:

  • Desktop: 3 columns (20% / 40% / 40%)
  • Tablet: 2 columns (collapsed categories)
  • Mobile: Single pane with navigation

BurnUpChartComponent

Location: features/risk-budget/burn-up-chart.component.ts Sprint: SPRINT_20251226_004_FE Status: TODO

Purpose: Risk budget burn-up chart showing budget line vs actual risk over time.

Inputs:

Name Type Description
budgetData BudgetTimeSeries Historical budget data
releaseDate Date Target release date
showMarkers boolean Show milestone markers

Outputs:

Name Type Description
pointClicked EventEmitter Chart point clicked

Chart Features:

  • X-axis: Calendar dates
  • Y-axis: Risk points
  • Lines: Budget (flat), Actual (cumulative)
  • Shaded regions: Headroom (green), Overrun (red)
  • Markers: Feature freeze, pen-test, dependency bumps

Shared Components

ConfidenceBadgeComponent

Location: shared/components/confidence-badge.component.ts Status: COMPLETE

Purpose: Displays confidence level with color-coded visual indicator.

Inputs:

Name Type Description
confidence number 0-1 confidence value
showValue boolean Display numeric value

DeterminismBadgeComponent

Location: shared/components/determinism-badge.component.ts Status: COMPLETE

Purpose: Shows determinism status with hash verification.

Inputs:

Name Type Description
hash string Determinism hash
verified boolean Hash verification status
copyable boolean Show copy button

Service Layer

TriageService

Location: core/services/triage.service.ts Sprint: SPRINT_20251226_013_FE

Methods:

getVulnerabilities(filters: TriageFilters): Observable<Page<Vulnerability>>
getVulnerability(id: string): Observable<Vulnerability>
getReachability(id: string): Observable<CallGraphSlice>

VexDecisionService

Location: core/services/vex-decision.service.ts Sprint: SPRINT_20251226_013_FE

Methods:

create(decision: CreateVexDecision): Observable<VexDecision>
update(id: string, decision: UpdateVexDecision): Observable<VexDecision>
getHistory(vulnId: string): Observable<VexDecision[]>

CompareService

Location: core/services/compare.service.ts Sprint: SPRINT_20251226_012_FE

Methods:

getBaselineRecommendations(digest: string): Observable<BaselineRecommendation[]>
computeDelta(current: string, baseline: string): Observable<Delta>
getTrustIndicators(deltaId: string): Observable<TrustIndicators>

RiskBudgetService

Location: core/services/risk-budget.service.ts Sprint: SPRINT_20251226_004_FE

Methods:

getBudgetStatus(serviceId: string): Observable<BudgetStatus>
getBurnUpData(serviceId: string, window: BudgetWindow): Observable<BudgetTimeSeries>
createException(exception: CreateException): Observable<Exception>

Interaction Diagrams

Triage Flow

User Action                    Component                      Service
    │                             │                              │
    │ Select vulnerability        │                              │
    ├────────────────────────────►│ TriageListComponent          │
    │                             ├─────────────────────────────►│
    │                             │                              │ getVulnerability()
    │                             │◄─────────────────────────────┤
    │                             │                              │
    │                             │ TriageDetailComponent        │
    │                             ├─────────────────────────────►│
    │                             │                              │ getReachability()
    │                             │◄─────────────────────────────┤
    │                             │                              │
    │ Click "Mark Not Affected"   │                              │
    ├────────────────────────────►│ VexDecisionModalComponent    │
    │                             │                              │
    │ Submit form                 │                              │
    ├────────────────────────────►│                              │
    │                             ├─────────────────────────────►│
    │                             │                              │ VexDecisionService.create()
    │                             │◄─────────────────────────────┤
    │                             │                              │
    │                             │ Update list, advance queue   │
    │◄────────────────────────────┤                              │

Compare Flow

User Action                    Component                      Service
    │                             │                              │
    │ Navigate to /compare/:id    │                              │
    ├────────────────────────────►│ CompareViewComponent         │
    │                             ├─────────────────────────────►│
    │                             │                              │ getBaselineRecommendations()
    │                             │◄─────────────────────────────┤
    │                             │                              │
    │                             │ Auto-select baseline         │
    │                             ├─────────────────────────────►│
    │                             │                              │ computeDelta()
    │                             │◄─────────────────────────────┤
    │                             │                              │
    │                             │ ThreePaneLayoutComponent     │
    │                             │  ├ CategoriesPaneComponent   │
    │                             │  ├ ItemsPaneComponent        │
    │                             │  └ ProofPaneComponent        │
    │                             │                              │
    │ Select category             │                              │
    ├────────────────────────────►│                              │
    │                             │ Filter items by category     │
    │                             │                              │
    │ Select item                 │                              │
    ├────────────────────────────►│                              │
    │                             │ Display proof in right pane  │
    │◄────────────────────────────┤                              │

Accessibility Requirements

All triage components must meet WCAG 2.1 AA compliance:

Requirement Implementation
Keyboard navigation Tab/Arrow/Enter/Escape, documented shortcuts
Focus management Visible focus indicators, logical tab order
Screen reader ARIA labels, live regions for updates
Color contrast 4.5:1 minimum for text, 3:1 for UI elements
Error messages Associated with inputs, announced immediately

Testing Requirements

Unit Tests

  • Component behavior (selection, filtering, expansion)
  • Signal/computed derivations
  • Form validation

Integration Tests

  • Service API calls
  • Route navigation
  • State persistence

E2E Tests (Playwright)

  • Full triage workflow
  • Comparison workflow
  • Keyboard navigation

References