- 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.
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