save development progress

This commit is contained in:
StellaOps Bot
2025-12-25 23:09:58 +02:00
parent d71853ad7e
commit aa70af062e
351 changed files with 37683 additions and 150156 deletions

View File

@@ -0,0 +1,461 @@
# Provcache UI Components
This document describes the Angular components for visualizing provenance cache data, trust scores, and proof trees in the StellaOps Console.
## Overview
The Provcache UI components provide visual feedback for:
- **Cache state awareness** — Users see whether decisions come from cache (fast) or are freshly computed
- **Trust transparency** — Trust scores with breakdowns by evidence component
- **Proof visualization** — Interactive proof trees showing evidence chain
- **Input manifest** — Details of all inputs that form a cached decision
## Components
### ProvenanceBadgeComponent
**Selector:** `stellaops-provenance-badge`
Displays a compact badge indicating the provenance state of a decision.
#### Inputs
| Input | Type | Default | Description |
|-------|------|---------|-------------|
| `state` | `'cached' \| 'computed' \| 'stale' \| 'unknown'` | `'unknown'` | Current provenance state |
| `cacheDetails` | `CacheDetails \| null` | `null` | Optional cache metadata |
| `trustScore` | `number \| null` | `null` | Optional trust score (0-100) |
| `size` | `'small' \| 'medium' \| 'large'` | `'medium'` | Badge size variant |
#### Outputs
| Output | Type | Description |
|--------|------|-------------|
| `viewProofTree` | `EventEmitter<void>` | Emitted when user clicks to view proof |
#### States & Icons
| State | Icon | Tooltip | CSS Class |
|-------|------|---------|-----------|
| `cached` | ⚡ | "Provenance-cached" | `badge--cached` |
| `computed` | 🔄 | "Freshly computed" | `badge--computed` |
| `stale` | ⏳ | "Stale - recomputing" | `badge--stale` |
| `unknown` | ❓ | "Unknown provenance" | `badge--unknown` |
#### Usage
```html
<!-- Basic usage -->
<stellaops-provenance-badge [state]="'cached'"></stellaops-provenance-badge>
<!-- With cache details -->
<stellaops-provenance-badge
[state]="'cached'"
[cacheDetails]="{ source: 'valkey', ageSeconds: 45, veriKey: 'sha256:abc...' }"
[trustScore]="85"
(viewProofTree)="openProofTree()">
</stellaops-provenance-badge>
```
#### Accessibility
- Uses `role="status"` for screen reader announcements
- Tooltip content exposed via `aria-label`
- Color is not the sole indicator — icons and text labels provided
---
### TrustScoreDisplayComponent
**Selector:** `stellaops-trust-score-display`
Visualizes a trust score (0-100) with optional breakdown by evidence component.
#### Inputs
| Input | Type | Default | Description |
|-------|------|---------|-------------|
| `score` | `number` | `0` | Overall trust score (0-100) |
| `breakdown` | `TrustScoreBreakdown \| null` | `null` | Component-level scores |
| `mode` | `'donut' \| 'badge' \| 'inline'` | `'donut'` | Display mode |
| `showBreakdown` | `boolean` | `false` | Show breakdown tooltip |
| `compact` | `boolean` | `false` | Use compact sizing |
| `thresholds` | `{ high: number; medium: number }` | `{ high: 80, medium: 50 }` | Color thresholds |
#### TrustScoreBreakdown Interface
```typescript
interface TrustScoreBreakdown {
reachability: number; // 0.0-1.0 (25% weight)
sbomCompleteness: number; // 0.0-1.0 (20% weight)
vexCoverage: number; // 0.0-1.0 (20% weight)
policyFreshness: number; // 0.0-1.0 (15% weight)
signerTrust: number; // 0.0-1.0 (20% weight)
}
```
#### Display Modes
| Mode | Description |
|------|-------------|
| `donut` | Circular SVG chart with score in center |
| `badge` | Compact pill-shaped badge |
| `inline` | Text-only display for tight spaces |
#### Color Coding
| Score Range | Class | Color |
|-------------|-------|-------|
| ≥ high (80) | `score--high` | Green (#4caf50) |
| ≥ medium (50) | `score--medium` | Yellow (#ff9800) |
| < medium | `score--low` | Red (#f44336) |
#### Usage
```html
<!-- Donut chart with breakdown -->
<stellaops-trust-score-display
[score]="85"
[breakdown]="breakdown"
[mode]="'donut'"
[showBreakdown]="true">
</stellaops-trust-score-display>
<!-- Compact badge -->
<stellaops-trust-score-display
[score]="72"
[mode]="'badge'"
[compact]="true">
</stellaops-trust-score-display>
```
---
### ProofTreeComponent
**Selector:** `stellaops-proof-tree`
Renders a decision's proof chain as a collapsible tree with verification capabilities.
#### Inputs
| Input | Type | Default | Description |
|-------|------|---------|-------------|
| `digest` | `DecisionDigest \| null` | `null` | The decision digest to display |
| `merkleTree` | `MerkleTree \| null` | `null` | Optional Merkle tree structure |
| `verdicts` | `VerdictEntry[]` | `[]` | Vulnerability verdicts |
| `evidenceChunks` | `EvidenceChunk[]` | `[]` | Evidence artifacts |
| `isVerifying` | `boolean` | `false` | Show verification spinner |
#### Outputs
| Output | Type | Description |
|--------|------|-------------|
| `copyVeriKey` | `EventEmitter<string>` | VeriKey copied to clipboard |
| `copyHash` | `EventEmitter<string>` | Any hash copied |
| `verify` | `EventEmitter<void>` | Verify button clicked |
| `downloadEvidence` | `EventEmitter<EvidenceChunk>` | Evidence download requested |
#### Tree Structure
```
DecisionDigest
├── VeriKey: sha256:abc123...
├── Trust Score: 85
│ ├── Reachability: 95%
│ ├── SBOM Completeness: 85%
│ ├── VEX Coverage: 90%
│ ├── Policy Freshness: 88%
│ └── Signer Trust: 92%
├── Verdicts (12)
│ ├── CVE-2025-1234 → not_affected
│ ├── CVE-2025-5678 → fixed
│ └── ...
├── Merkle Tree
│ ├── Root: sha256:root...
│ ├── Left
│ │ ├── sha256:sbom... (sbom-hash)
│ │ └── sha256:vex... (vex-set-hash)
│ └── Right
│ ├── sha256:policy... (policy-hash)
│ └── sha256:signers... (signers-hash)
└── Evidence Chunks (5)
├── [sbom] SPDX 2.3 SBOM document
├── [vex] VEX statement bundle
└── ...
```
#### Verdict Statuses
| Status | Color | Meaning |
|--------|-------|---------|
| `not_affected` | Green | Vulnerability not applicable |
| `fixed` | Blue | Patched/remediated |
| `affected` | Red | Vulnerable |
| `under_investigation` | Yellow | Pending analysis |
| `mitigated` | Cyan | Mitigating controls in place |
#### Usage
```html
<stellaops-proof-tree
[digest]="decisionDigest"
[merkleTree]="merkleTree"
[verdicts]="verdicts"
[evidenceChunks]="chunks"
[isVerifying]="verifying"
(verify)="verifyProof()"
(copyVeriKey)="copyToClipboard($event)"
(downloadEvidence)="downloadChunk($event)">
</stellaops-proof-tree>
```
---
### InputManifestComponent
**Selector:** `stellaops-input-manifest`
Displays the exact inputs that formed a VeriKey and cached decision.
#### Inputs
| Input | Type | Default | Description |
|-------|------|---------|-------------|
| `manifest` | `InputManifest \| null` | `null` | The manifest to display |
| `mode` | `'full' \| 'compact' \| 'summary'` | `'full'` | Display mode |
| `displayConfig` | `InputManifestDisplayConfig` | (all true) | Section visibility |
#### Outputs
| Output | Type | Description |
|--------|------|-------------|
| `copyVeriKey` | `EventEmitter<string>` | VeriKey copied |
| `refresh` | `EventEmitter<void>` | Refresh requested |
#### InputManifest Interface
```typescript
interface InputManifest {
veriKey: string;
sourceArtifact: SourceArtifactInfo;
sbom: SbomInfo;
vex: VexInfo;
policy: PolicyInfoManifest;
signers: SignerInfo;
timeWindow: TimeWindowInfo;
generatedAt: string;
}
interface SourceArtifactInfo {
digest: string;
artifactType: string;
ociReference?: string;
sizeBytes?: number;
}
interface SbomInfo {
hash: string;
format: string; // 'spdx-2.3', 'cyclonedx-1.6'
packageCount: number;
completenessScore: number;
createdAt: string;
}
interface VexInfo {
hashSetHash: string;
statementCount: number;
sources: string[];
latestStatementAt: string;
}
interface PolicyInfoManifest {
hash: string;
packId: string;
version: number;
lastUpdatedAt: string;
name?: string;
}
interface SignerInfo {
setHash: string;
signerCount: number;
certificates?: CertificateInfo[];
}
interface CertificateInfo {
subject: string;
issuer: string;
fingerprint: string;
expiresAt: string;
trustLevel: 'fulcio' | 'enterprise-ca' | 'self-signed';
}
interface TimeWindowInfo {
bucket: string;
startsAt: string;
endsAt: string;
}
```
#### Display Modes
| Mode | Description |
|------|-------------|
| `full` | All sections with full details |
| `compact` | Reduced spacing, abbreviated values |
| `summary` | Grid layout for quick overview |
#### Section Visibility
```typescript
interface InputManifestDisplayConfig {
showSource: boolean;
showSbom: boolean;
showVex: boolean;
showPolicy: boolean;
showSigners: boolean;
showTimeWindow: boolean;
}
```
#### Usage
```html
<!-- Full manifest display -->
<stellaops-input-manifest
[manifest]="inputManifest"
[mode]="'full'"
(copyVeriKey)="copyToClipboard($event)">
</stellaops-input-manifest>
<!-- Security-focused view -->
<stellaops-input-manifest
[manifest]="inputManifest"
[mode]="'compact'"
[displayConfig]="{ showSource: false, showSbom: false, showVex: true, showPolicy: true, showSigners: true, showTimeWindow: false }">
</stellaops-input-manifest>
```
---
## Storybook Documentation
All components have Storybook stories in `src/Web/StellaOps.Web/src/stories/provcache/`:
| File | Description |
|------|-------------|
| `provenance-badge.stories.ts` | All badge states, trust scores, sizes |
| `trust-score-display.stories.ts` | Score ranges, modes, breakdowns |
| `input-manifest.stories.ts` | Modes, SBOM formats, certificates |
| `proof-tree.stories.ts` | Tree depths, verdicts, verification |
Run Storybook to explore:
```bash
cd src/Web/StellaOps.Web
npm run storybook
```
---
## Integration Examples
### Finding Row Integration
```typescript
// finding-row.component.ts
@Component({
selector: 'stellaops-finding-row',
template: `
<div class="finding-row">
<stellaops-provenance-badge
[state]="finding.provenanceState"
[cacheDetails]="finding.cacheDetails"
[trustScore]="finding.trustScore"
(viewProofTree)="openProofPanel.emit(finding)">
</stellaops-provenance-badge>
<!-- ... rest of finding row -->
</div>
`
})
export class FindingRowComponent {
@Input() finding!: FindingRow;
@Output() openProofPanel = new EventEmitter<FindingRow>();
}
```
### Decision Detail Panel
```typescript
// decision-detail-panel.component.ts
@Component({
template: `
<div class="decision-detail-panel">
<stellaops-trust-score-display
[score]="digest.trustScore"
[breakdown]="digest.trustScoreBreakdown"
[mode]="'donut'"
[showBreakdown]="true">
</stellaops-trust-score-display>
<stellaops-proof-tree
[digest]="digest"
[merkleTree]="merkleTree"
[verdicts]="verdicts"
[evidenceChunks]="chunks"
[isVerifying]="verifying$ | async"
(verify)="verifyProof()"
(downloadEvidence)="downloadChunk($event)">
</stellaops-proof-tree>
<stellaops-input-manifest
[manifest]="manifest"
[mode]="'full'">
</stellaops-input-manifest>
</div>
`
})
export class DecisionDetailPanelComponent {
// ...
}
```
---
## Theming
Components use CSS custom properties for theming:
```css
/* Dark mode overrides */
@media (prefers-color-scheme: dark) {
--trust-score-high: #81c784;
--trust-score-medium: #ffb74d;
--trust-score-low: #e57373;
--badge-cached-bg: #1b5e20;
--badge-computed-bg: #0d47a1;
}
```
---
## Accessibility
All components follow WCAG 2.1 AA guidelines:
- **Keyboard navigation** All interactive elements focusable and operable
- **Screen reader support** ARIA labels, roles, and live regions
- **Color independence** Icons and text supplement color coding
- **Focus indicators** Visible focus outlines on interactive elements
- **Motion preferences** Reduced motion respected where applicable
---
## Related Documentation
- [Provcache Module README](../provcache/README.md) Core concepts and architecture
- [Provcache Architecture](../provcache/architecture.md) Technical deep-dive
- [UI Architecture](./architecture.md) Angular patterns and state management
- [Accessibility Guide](../../accessibility.md) WCAG compliance guidelines