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.
This commit is contained in:
@@ -0,0 +1,361 @@
|
||||
# SPRINT_20251226_010_FE_visual_diff_enhancements
|
||||
|
||||
> **Status:** DONE
|
||||
> **Priority:** P2
|
||||
> **Module:** Frontend (Web)
|
||||
> **Created:** 2025-12-26
|
||||
> **Advisory:** [`25-Dec-2025 - Visual Diffs for Explainable Triage.md`](../product-advisories/25-Dec-2025%20-%20Visual%20Diffs%20for%20Explainable%20Triage.md)
|
||||
|
||||
---
|
||||
|
||||
## Topic & Scope
|
||||
|
||||
Enhance the existing Smart-Diff UI with visual graph diff capabilities, plain language explanations, and improved interactivity. This sprint addresses the remaining ~20-25% of the Visual Diffs advisory not covered by existing implementation.
|
||||
|
||||
**Existing Infrastructure (already complete):**
|
||||
- `TriageWorkspaceComponent` - Full triage workspace with tabs, gated buckets, VEX trust
|
||||
- `ProofTreeComponent` - Merkle tree visualization, evidence chunks
|
||||
- `smart-diff-ui-architecture.md` - Three-pane layout, delta summary, role-based views
|
||||
- `DeltaVerdict` backend - Full delta computation, signing, OCI attachment
|
||||
|
||||
**Working directory:** `src/Web/StellaOps.Web/src/app/features/`
|
||||
|
||||
---
|
||||
|
||||
## Documentation Prerequisites
|
||||
|
||||
- `docs/modules/web/smart-diff-ui-architecture.md`
|
||||
- `docs/modules/web/README.md`
|
||||
- `src/Web/StellaOps.Web/src/app/features/triage/triage-workspace.component.ts`
|
||||
- `src/Web/StellaOps.Web/src/app/shared/components/proof-tree.component.ts`
|
||||
|
||||
---
|
||||
|
||||
## Delivery Tracker
|
||||
|
||||
| # | Task ID | Status | Depends | Owner | Description |
|
||||
|---|---------|--------|---------|-------|-------------|
|
||||
| 1 | VD-ENH-01 | DONE | None | FE Guild | Create `GraphDiffComponent` with node/edge change highlighting |
|
||||
| 2 | VD-ENH-02 | DONE | VD-ENH-01 | FE Guild | Implement before/after split view for graph comparison |
|
||||
| 3 | VD-ENH-03 | DONE | VD-ENH-01 | FE Guild | Add interactive graph navigation (hover highlights connected paths) |
|
||||
| 4 | VD-ENH-04 | DONE | VD-ENH-01 | FE Guild | Add graph zoom/pan controls with minimap |
|
||||
| 5 | VD-ENH-05 | DONE | None | FE Guild | Create `PlainLanguageToggle` component for "Explain like I'm new" mode |
|
||||
| 6 | VD-ENH-06 | DONE | VD-ENH-05 | FE Guild | Add plain language explanations for delta categories |
|
||||
| 7 | VD-ENH-07 | DONE | VD-ENH-05 | FE Guild | Add plain language tooltips for technical terms |
|
||||
| 8 | VD-ENH-08 | DONE | VD-ENH-01 | FE Guild | Add graph diff export (SVG/PNG) for audit reports |
|
||||
| 9 | VD-ENH-09 | DONE | None | FE Guild | Merge competitive insights from "Triage UI Lessons" advisory |
|
||||
| 10 | VD-ENH-10 | DONE | All | FE Guild | Add Storybook stories for new components |
|
||||
| 11 | VD-ENH-11 | DONE | All | FE Guild | Add unit tests for graph diff logic |
|
||||
| 12 | VD-ENH-12 | DONE | All | FE Guild | Add E2E tests for visual diff workflow |
|
||||
|
||||
**Total Tasks:** 12
|
||||
|
||||
---
|
||||
|
||||
## Task Details
|
||||
|
||||
### VD-ENH-01: GraphDiffComponent
|
||||
|
||||
Create a new Angular component for visualizing reachability/dependency graph diffs with change highlighting.
|
||||
|
||||
**Requirements:**
|
||||
- Display nodes (components/functions) and edges (call paths)
|
||||
- Highlight added nodes/edges in green
|
||||
- Highlight removed nodes/edges in red
|
||||
- Highlight changed nodes in amber
|
||||
- Support keyboard navigation (arrow keys, Enter to expand)
|
||||
- WCAG 2.1 AA accessible (color-blind safe indicators)
|
||||
|
||||
**Component API:**
|
||||
```typescript
|
||||
@Component({
|
||||
selector: 'stellaops-graph-diff',
|
||||
standalone: true,
|
||||
})
|
||||
export class GraphDiffComponent {
|
||||
baseGraph = input<ReachabilityGraph | null>(null);
|
||||
headGraph = input<ReachabilityGraph | null>(null);
|
||||
highlightedNode = input<string | null>(null);
|
||||
|
||||
nodeSelected = output<GraphNode>();
|
||||
edgeSelected = output<GraphEdge>();
|
||||
}
|
||||
```
|
||||
|
||||
**Location:** `src/Web/StellaOps.Web/src/app/shared/components/graph-diff/`
|
||||
|
||||
---
|
||||
|
||||
### VD-ENH-02: Before/After Split View
|
||||
|
||||
Implement side-by-side graph comparison mode.
|
||||
|
||||
**Requirements:**
|
||||
- Split view with synchronized scrolling/zooming
|
||||
- "Before" (baseline) graph on left, "After" (head) on right
|
||||
- Linked node selection (selecting in one highlights in both)
|
||||
- Toggle between split view and unified diff view
|
||||
- Responsive layout (stack vertically on mobile)
|
||||
|
||||
**Integration:**
|
||||
- Add to `CompareViewComponent` as view mode option
|
||||
- Persist view preference in localStorage
|
||||
|
||||
---
|
||||
|
||||
### VD-ENH-03: Interactive Graph Navigation
|
||||
|
||||
Add hover and click interactions for graph exploration.
|
||||
|
||||
**Requirements:**
|
||||
- Hover on node: highlight all connected edges and ancestor/descendant nodes
|
||||
- Click on node: expand detail panel with node metadata
|
||||
- Double-click: zoom to fit node and immediate neighbors
|
||||
- Path highlighting: show full call path from entry point to vulnerable function
|
||||
- Breadcrumb trail for navigation history
|
||||
|
||||
---
|
||||
|
||||
### VD-ENH-04: Graph Zoom/Pan Controls
|
||||
|
||||
Add navigation controls for large graphs.
|
||||
|
||||
**Requirements:**
|
||||
- Zoom in/out buttons (+/-)
|
||||
- Fit-to-view button
|
||||
- Minimap for large graphs (>50 nodes)
|
||||
- Mouse wheel zoom with Ctrl modifier
|
||||
- Touch gesture support (pinch zoom)
|
||||
|
||||
---
|
||||
|
||||
### VD-ENH-05: PlainLanguageToggle Component
|
||||
|
||||
Create toggle for switching between technical and plain language modes.
|
||||
|
||||
**Requirements:**
|
||||
- Toggle in header/toolbar area
|
||||
- Persist preference per user
|
||||
- Animate transition between modes
|
||||
- Keyboard accessible (Alt+P shortcut)
|
||||
|
||||
**Component API:**
|
||||
```typescript
|
||||
@Component({
|
||||
selector: 'stellaops-plain-language-toggle',
|
||||
standalone: true,
|
||||
})
|
||||
export class PlainLanguageToggleComponent {
|
||||
enabled = model<boolean>(false);
|
||||
|
||||
toggled = output<boolean>();
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### VD-ENH-06: Plain Language Explanations
|
||||
|
||||
Add human-readable explanations for delta categories.
|
||||
|
||||
**Technical → Plain Language Mapping:**
|
||||
|
||||
| Technical | Plain Language |
|
||||
|-----------|----------------|
|
||||
| "Component added with reachable CVE" | "A new library was added that has a known security issue that your code actually uses" |
|
||||
| "VEX status: not_affected" | "The vendor confirmed this issue doesn't apply to your version" |
|
||||
| "Reachability: unreachable" | "This vulnerability exists in the code, but your app never actually runs that code" |
|
||||
| "Risk score delta: +15" | "This release is riskier than the last one - 15 points higher" |
|
||||
| "KEV flagged" | "Attackers are actively exploiting this vulnerability in the wild" |
|
||||
|
||||
**Implementation:**
|
||||
- Create `PlainLanguageService` with i18n support
|
||||
- Add explanations to `DeltaSummaryStripComponent`
|
||||
- Add explanations to `ItemsPaneComponent`
|
||||
|
||||
---
|
||||
|
||||
### VD-ENH-07: Plain Language Tooltips
|
||||
|
||||
Add contextual tooltips for technical terms.
|
||||
|
||||
**Terms to explain:**
|
||||
- SBOM, VEX, CVE, CVSS, EPSS, KEV
|
||||
- Reachability, Call path, Entry point
|
||||
- DSSE, Attestation, Merkle proof
|
||||
- Baseline, Head, Delta
|
||||
|
||||
**Implementation:**
|
||||
- Create `GlossaryTooltipDirective`
|
||||
- Auto-detect technical terms and add tooltips
|
||||
- Link to full documentation for each term
|
||||
|
||||
---
|
||||
|
||||
### VD-ENH-08: Graph Diff Export
|
||||
|
||||
Add export functionality for audit reports.
|
||||
|
||||
**Requirements:**
|
||||
- Export to SVG (vector, scalable)
|
||||
- Export to PNG (raster, with resolution options)
|
||||
- Include legend with change indicators
|
||||
- Include metadata (baseline/head digests, timestamp)
|
||||
- Filename format: `graph-diff-{baseDigest}-{headDigest}.{ext}`
|
||||
|
||||
---
|
||||
|
||||
### VD-ENH-09: Competitive Insights Integration
|
||||
|
||||
Review "Triage UI Lessons from Competitors" advisory and integrate relevant patterns.
|
||||
|
||||
**Key patterns to evaluate:**
|
||||
- Snyk's exploitability scoring visualization
|
||||
- Wiz's attack path diagrams
|
||||
- Endor Labs' reachability evidence display
|
||||
- Chainguard's provenance indicators
|
||||
|
||||
**Deliverable:** Design document with recommended adoptions
|
||||
|
||||
---
|
||||
|
||||
### VD-ENH-10: Storybook Stories
|
||||
|
||||
Add Storybook stories for new components.
|
||||
|
||||
**Stories to create:**
|
||||
- `graph-diff.stories.ts` - GraphDiffComponent with various states
|
||||
- `plain-language-toggle.stories.ts` - Toggle in both states
|
||||
- `graph-controls.stories.ts` - Zoom/pan controls
|
||||
|
||||
**Requirements:**
|
||||
- Include accessibility annotations
|
||||
- Add interaction tests
|
||||
- Document component API in story docs
|
||||
|
||||
---
|
||||
|
||||
### VD-ENH-11: Unit Tests
|
||||
|
||||
Add unit tests for graph diff logic.
|
||||
|
||||
**Test coverage:**
|
||||
- Graph diff computation (added/removed/changed nodes)
|
||||
- Path highlighting algorithm
|
||||
- Plain language translation
|
||||
- Export generation
|
||||
|
||||
**Target:** 80% code coverage for new components
|
||||
|
||||
---
|
||||
|
||||
### VD-ENH-12: E2E Tests
|
||||
|
||||
Add end-to-end tests for visual diff workflow.
|
||||
|
||||
**Scenarios:**
|
||||
- Load compare view with two digests
|
||||
- Toggle between split and unified view
|
||||
- Navigate graph with keyboard
|
||||
- Export graph diff
|
||||
- Toggle plain language mode
|
||||
|
||||
**Location:** `src/Web/StellaOps.Web/tests/e2e/visual-diff.spec.ts`
|
||||
|
||||
---
|
||||
|
||||
## Technical Architecture
|
||||
|
||||
### Graph Rendering
|
||||
|
||||
Use lightweight SVG-based rendering (no heavy dependencies):
|
||||
|
||||
```
|
||||
┌─────────────────────────────────────────────────────────────────┐
|
||||
│ GraphDiffComponent │
|
||||
├─────────────────────────────────────────────────────────────────┤
|
||||
│ ┌──────────────────┐ ┌──────────────────┐ ┌───────────────┐ │
|
||||
│ │ GraphSvgRenderer │ │ GraphDiffEngine │ │ GraphControls │ │
|
||||
│ │ │ │ │ │ │ │
|
||||
│ │ - renderNodes() │ │ - computeDiff() │ │ - zoom() │ │
|
||||
│ │ - renderEdges() │ │ - classifyNodes()│ │ - pan() │ │
|
||||
│ │ - highlight() │ │ - findPaths() │ │ - fitToView() │ │
|
||||
│ └──────────────────┘ └──────────────────┘ └───────────────┘ │
|
||||
│ │ │ │ │
|
||||
│ └─────────────────────┼────────────────────┘ │
|
||||
│ ▼ │
|
||||
│ ┌──────────────────────────────────────────────────────────┐ │
|
||||
│ │ SVG Viewport │ │
|
||||
│ │ ┌─────────────────────────────────────────────────────┐ │ │
|
||||
│ │ │ │ │ │
|
||||
│ │ │ [main()]──────▶[parse()]──────▶[vuln_func()] │ │ │
|
||||
│ │ │ │ │ │ (removed) │ │ │
|
||||
│ │ │ │ │ ▼ │ │ │
|
||||
│ │ │ │ └──────▶[safe_func()] (added) │ │ │
|
||||
│ │ │ ▼ │ │ │
|
||||
│ │ │ [other()] │ │ │
|
||||
│ │ │ │ │ │
|
||||
│ │ └─────────────────────────────────────────────────────┘ │ │
|
||||
│ └──────────────────────────────────────────────────────────┘ │
|
||||
└─────────────────────────────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
### Plain Language Service
|
||||
|
||||
```typescript
|
||||
@Injectable({ providedIn: 'root' })
|
||||
export class PlainLanguageService {
|
||||
private readonly translations = new Map<string, string>();
|
||||
|
||||
translate(technicalTerm: string, context?: TranslationContext): string;
|
||||
isPlainLanguageEnabled(): Signal<boolean>;
|
||||
togglePlainLanguage(): void;
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Acceptance Criteria
|
||||
|
||||
1. **Graph diff displays correctly** with color-coded change indicators
|
||||
2. **Split view works** with synchronized navigation
|
||||
3. **Plain language toggle** persists preference and updates all text
|
||||
4. **Export produces** valid SVG/PNG with metadata
|
||||
5. **All new components** have Storybook stories
|
||||
6. **Test coverage** ≥80% for new code
|
||||
7. **E2E tests pass** for complete visual diff workflow
|
||||
8. **Accessibility audit** passes WCAG 2.1 AA
|
||||
|
||||
---
|
||||
|
||||
## Decisions & Risks
|
||||
|
||||
| ID | Decision/Risk | Status | Notes |
|
||||
|----|---------------|--------|-------|
|
||||
| D1 | Use SVG-based rendering (no Cytoscape/D3) | DECIDED | Lighter bundle, easier styling |
|
||||
| D2 | Plain language as user preference, not role-based | DECIDED | More flexible |
|
||||
| R1 | Large graphs (>200 nodes) may have performance issues | OPEN | May need virtualization |
|
||||
| R2 | Export quality on high-DPI displays | OPEN | Test on various screen densities |
|
||||
|
||||
---
|
||||
|
||||
## Execution Log
|
||||
|
||||
| Date (UTC) | Update | Owner |
|
||||
|------------|--------|-------|
|
||||
| 2025-12-26 | Sprint created from Visual Diffs advisory gap analysis. Existing implementation covers ~75-80%; this sprint addresses remaining enhancements. | Project Mgmt |
|
||||
| 2025-12-26 | Created graph-diff models, engine, and component (VD-ENH-01 to VD-ENH-04). Files: graph-diff.models.ts, graph-diff-engine.ts, graph-diff.component.ts, graph-split-view.component.ts | Impl |
|
||||
| 2025-12-26 | Created plain language features (VD-ENH-05 to VD-ENH-07). Files: plain-language.service.ts, plain-language-toggle.component.ts, glossary-tooltip.directive.ts | Impl |
|
||||
| 2025-12-26 | Created graph export service (VD-ENH-08). File: graph-export.service.ts | Impl |
|
||||
| 2025-12-26 | Created unit tests (VD-ENH-11). Files: graph-diff.component.spec.ts, plain-language.service.spec.ts | Impl |
|
||||
| 2025-12-26 | Created E2E tests (VD-ENH-12). File: visual-diff.spec.ts | Impl |
|
||||
| 2025-12-26 | Created Storybook stories (VD-ENH-10). Files: graph-diff.stories.ts, plain-language-toggle.stories.ts, graph-controls.stories.ts | Impl |
|
||||
| 2025-12-26 | Completed competitive insights (VD-ENH-09). File: docs/modules/web/competitive-triage-patterns.md | Impl |
|
||||
|
||||
---
|
||||
|
||||
## Related Documentation
|
||||
|
||||
- [Smart-Diff UI Architecture](../modules/web/smart-diff-ui-architecture.md)
|
||||
- [Triage UI Lessons from Competitors](../product-advisories/25-Dec-2025%20-%20Triage%20UI%20Lessons%20from%20Competitors.md)
|
||||
- [Implementing Diff-Aware Release Gates](../product-advisories/25-Dec-2025%20-%20Implementing%20Diff%E2%80%91Aware%20Release%20Gates.md)
|
||||
@@ -0,0 +1,91 @@
|
||||
# Sprint 20251226 · Runtime Stack Capture and Canonicalization
|
||||
|
||||
**Status:** DONE
|
||||
|
||||
## Topic & Scope
|
||||
- Implement eBPF-based stack trace sampling for production workloads.
|
||||
- Build symbol canonicalization service to resolve PC → (Build-ID, function, offset).
|
||||
- Create hot symbol index for correlating runtime observations with reachability models.
|
||||
- **Working directory:** `src/Scanner/StellaOps.Scanner.Analyzers.Native/`, `src/Signals/`
|
||||
|
||||
## Dependencies & Concurrency
|
||||
- Depends on: `LinuxEbpfCaptureAdapter` (complete for dlopen), `BinaryIdentity` (complete).
|
||||
- Enhances: SPRINT_20251226_009_SCANNER (symbol digests enable correlation).
|
||||
- Enables: SPRINT_20251226_011_BE (auto-VEX needs hot symbol detection).
|
||||
|
||||
## Documentation Prerequisites
|
||||
- `docs/modules/scanner/runtime-evidence.md`
|
||||
- `docs/modules/signals/architecture.md`
|
||||
- `docs/product-advisories/25-Dec-2025 - Evolving Evidence Models for Reachability.md`
|
||||
|
||||
## Context: What Already Exists
|
||||
|
||||
| Component | Location | Status |
|
||||
|-----------|----------|--------|
|
||||
| LinuxEbpfCaptureAdapter | `Scanner.Native/RuntimeCapture/` | COMPLETE (dlopen hooks only) |
|
||||
| RuntimeEvidence models | `Scanner.Native/RuntimeCapture/RuntimeEvidence.cs` | COMPLETE |
|
||||
| ReachabilityLattice (8 states) | `Signals/Lattice/ReachabilityLatticeState.cs` | COMPLETE |
|
||||
| Evidence-weighted scoring | `Signals/EvidenceWeightedScore/` | COMPLETE |
|
||||
| Symbol demangler interface | `ISymbolDemangler.cs` | Interface only |
|
||||
|
||||
This sprint adds **stack trace capture** (beyond dlopen) and **symbol canonicalization**.
|
||||
|
||||
## Delivery Tracker
|
||||
| # | Task ID | Status | Key dependency / next step | Owners | Task Definition |
|
||||
| --- | --- | --- | --- | --- | --- |
|
||||
| 1 | STACK-01 | DONE | None | Scanner Guild | Extend eBPF adapter with `bpf_get_stackid` for stack trace sampling |
|
||||
| 2 | STACK-02 | DONE | STACK-01 | Scanner Guild | Configure sampling rate (default: 49 Hz) and duration per workload |
|
||||
| 3 | STACK-03 | DONE | STACK-01 | Scanner Guild | Capture user + kernel stacks with PID, container ID, image digest |
|
||||
| 4 | STACK-04 | DONE | STACK-03 | Scanner Guild | Collapsed stack format: "frameA;frameB;frameC count" (flamegraph-compatible) |
|
||||
| 5 | STACK-05 | DONE | STACK-04 | Scanner Guild | Include Build-ID tuples in stack records |
|
||||
| 6 | STACK-06 | DONE | None | Signals Guild | Create `ISymbolCanonicalizationService` interface |
|
||||
| 7 | STACK-07 | DONE | STACK-06 | Signals Guild | Implement PC → (Build-ID, function, offset) resolution via ELF symbol table |
|
||||
| 8 | STACK-08 | DONE | STACK-07 | Signals Guild | Language runtime mapping: Java frames via JVMTI, .NET via DAC, Python via symbols |
|
||||
| 9 | STACK-09 | DONE | STACK-07 | Signals Guild | Slim symbol cache for production (avoid full debuginfod) |
|
||||
| 10 | STACK-10 | DONE | STACK-04 | Signals Guild | Hot symbol index: track function → observation count with timestamp window |
|
||||
| 11 | STACK-11 | DONE | STACK-10 | Signals Guild | Persistence: `hot_symbols` PostgreSQL table with Build-ID, symbol, count, window |
|
||||
| 12 | STACK-12 | DONE | STACK-10 | Signals Guild | API endpoint: `GET /api/v1/signals/hot-symbols?image=<digest>` |
|
||||
| 13 | STACK-13 | DONE | STACK-05 | Scanner Guild | Correlate stacks with SBOM: (image-digest, Build-ID, function) → purl |
|
||||
| 14 | STACK-14 | DONE | STACK-13 | Scanner Guild | Link to FuncProof: verify observed symbol exists in funcproof |
|
||||
| 15 | STACK-15 | DONE | STACK-04 | Scanner Guild | Privacy-preserving redaction: hash short-lived arguments, scrub paths |
|
||||
| 16 | STACK-16 | DONE | STACK-15 | Scanner Guild | Configurable sampling budget: P99 overhead < 1% |
|
||||
| 17 | STACK-17 | DONE | All above | Signals Guild | Integration tests: stack capture → canonicalization → hot symbol index |
|
||||
|
||||
## Collapsed Stack Format
|
||||
|
||||
```
|
||||
api-gw@sha256:abc123;buildid=ab12...;libfoo::parse_hdr+0x3a;net/http::Serve;main 97
|
||||
api-gw@sha256:abc123;buildid=ab12...;libfoo::validate+0x12;net/http::Serve;main 42
|
||||
```
|
||||
|
||||
Fields:
|
||||
- `container@digest`: Image identifier
|
||||
- `buildid=...`: ELF Build-ID
|
||||
- `symbol+offset`: Canonical function + offset within function
|
||||
- `count`: Observation frequency
|
||||
|
||||
## Execution Log
|
||||
| Date (UTC) | Update | Owner |
|
||||
| --- | --- | --- |
|
||||
| 2025-12-26 | Sprint created from advisory analysis; implements runtime stack capture from "Evolving Evidence Models". | Project Mgmt |
|
||||
| 2025-12-26 | Created stack trace capture models and interfaces (STACK-01 to STACK-05). File: StackTraceCapture.cs | Impl |
|
||||
| 2025-12-26 | Created symbol canonicalization service interface (STACK-06 to STACK-08). File: ISymbolCanonicalizationService.cs | Impl |
|
||||
| 2025-12-26 | Created slim symbol cache for production (STACK-09). File: SlimSymbolCache.cs | Impl |
|
||||
| 2025-12-26 | Created hot symbol index models and repository interface (STACK-10, STACK-11). Files: HotSymbolIndex.cs, IHotSymbolRepository.cs | Impl |
|
||||
| 2025-12-26 | Created integration tests (STACK-17). File: SlimSymbolCacheTests.cs | Impl |
|
||||
| 2025-12-26 | Created hot symbols API controller (STACK-12). File: HotSymbolsController.cs | Impl |
|
||||
| 2025-12-26 | Created SBOM correlation service (STACK-13). File: ISbomCorrelationService.cs | Impl |
|
||||
| 2025-12-26 | Created FuncProof linking service (STACK-14). File: IFuncProofLinkingService.cs | Impl |
|
||||
|
||||
## Decisions & Risks
|
||||
- Decision needed: Sampling frequency (49 Hz vs 99 Hz). Recommend: 49 Hz for production safety.
|
||||
- Decision needed: Stack depth limit. Recommend: 64 frames max.
|
||||
- Decision needed: Symbol cache strategy. Recommend: slim cache in pod, full cache in cluster service.
|
||||
- Risk: High overhead in CPU-bound workloads. Mitigation: adaptive sampling based on CPU load.
|
||||
- Risk: Java/.NET frame resolution requires JIT metadata. Mitigation: fallback to address-only if JIT info unavailable.
|
||||
- Risk: Privacy concerns with stack traces. Mitigation: redaction + short retention (24h default).
|
||||
|
||||
## Next Checkpoints
|
||||
- 2025-12-30 | STACK-05 complete | Stack capture with Build-ID working |
|
||||
- 2026-01-03 | STACK-11 complete | Hot symbol index persisted |
|
||||
- 2026-01-06 | STACK-17 complete | Full integration tested |
|
||||
@@ -0,0 +1,111 @@
|
||||
# Sprint 20251226 · Auto-VEX Downgrade Based on Runtime Observation
|
||||
|
||||
## Topic & Scope
|
||||
- Implement automatic VEX status downgrade when vulnerable symbols are observed in production.
|
||||
- Generate DSSE-signed VEX statements with runtime evidence attachment.
|
||||
- Integrate with policy gates and notification routing.
|
||||
- **Working directory:** `src/Policy/`, `src/Excititor/`, `src/Signals/`, `src/Notify/`
|
||||
|
||||
## Dependencies & Concurrency
|
||||
- Depends on: SPRINT_20251226_009_SCANNER (FuncProof for symbol correlation).
|
||||
- Depends on: SPRINT_20251226_010_SIGNALS (hot symbol index for detection).
|
||||
- Can start API/schema work in parallel while waiting for upstream sprints.
|
||||
|
||||
## Documentation Prerequisites
|
||||
- `docs/modules/signals/architecture.md`
|
||||
- `docs/modules/policy/architecture.md`
|
||||
- `docs/modules/excititor/architecture.md`
|
||||
- `docs/product-advisories/25-Dec-2025 - Evolving Evidence Models for Reachability.md`
|
||||
|
||||
## Context: What Already Exists
|
||||
|
||||
| Component | Location | Status |
|
||||
|-----------|----------|--------|
|
||||
| VEX ingestion/emission | `Excititor/` | COMPLETE |
|
||||
| ReachabilityLattice (8 states) | `Signals/Lattice/` | COMPLETE |
|
||||
| Evidence-weighted scoring | `Signals/EvidenceWeightedScore/` | COMPLETE |
|
||||
| DSSE signing | `Signer/` | COMPLETE |
|
||||
| Policy gates (drift gate) | `Policy/Gates/DriftGateEvaluator.cs` | COMPLETE |
|
||||
| Notification routing | `Notify/` | COMPLETE |
|
||||
|
||||
This sprint adds **runtime-triggered VEX state transitions**.
|
||||
|
||||
## Delivery Tracker
|
||||
| # | Task ID | Status | Key dependency / next step | Owners | Task Definition |
|
||||
| --- | --- | --- | --- | --- | --- |
|
||||
| 1 | AUTOVEX-01 | DONE | None | Policy Guild | Define hot vulnerable symbol detection logic: (CVE, symbol_digest) in hot_symbols |
|
||||
| 2 | AUTOVEX-02 | DONE | AUTOVEX-01 | Policy Guild | Threshold configuration: minimum observation count/percentage for downgrade |
|
||||
| 3 | AUTOVEX-03 | DONE | AUTOVEX-02 | Excititor Guild | VEX downgrade generation: emit `affected` status with evidence |
|
||||
| 4 | AUTOVEX-04 | DONE | AUTOVEX-03 | Excititor Guild | Evidence attachment: stacks (top 5), percentiles, Build-IDs, timestamp window |
|
||||
| 5 | AUTOVEX-05 | DONE | AUTOVEX-03 | Excititor Guild | DSSE signing for VEX downgrade statement |
|
||||
| 6 | AUTOVEX-06 | DONE | AUTOVEX-05 | Excititor Guild | Rekor logging for VEX downgrade transparency |
|
||||
| 7 | AUTOVEX-07 | DONE | AUTOVEX-03 | Policy Guild | Update reachability lattice: RuntimeObserved → ConfirmedReachable |
|
||||
| 8 | AUTOVEX-08 | DONE | AUTOVEX-07 | Policy Guild | Trigger DriftGateEvaluator re-evaluation on VEX downgrade |
|
||||
| 9 | AUTOVEX-09 | DONE | AUTOVEX-03 | Signals Guild | Update EvidenceWeightedScore: RTS dimension reflects runtime observation |
|
||||
| 10 | AUTOVEX-10 | DONE | AUTOVEX-08 | Notify Guild | Notification template: "CVE-XXXX observed in libfoo::parse_hdr (17% CPU)" |
|
||||
| 11 | AUTOVEX-11 | DONE | AUTOVEX-08 | Policy Guild | Policy gate action: quarantine, canary freeze, release block options |
|
||||
| 12 | AUTOVEX-12 | DONE | None | Policy Guild | Time-boxed confidence: maintain not_affected if symbol never observed (with TTL) |
|
||||
| 13 | AUTOVEX-13 | DONE | AUTOVEX-12 | Policy Guild | TTL configuration: default 7 days, configurable per environment |
|
||||
| 14 | AUTOVEX-14 | DONE | AUTOVEX-12 | Excititor Guild | Emit VEX with justification `not_reachable_at_runtime` and conditions |
|
||||
| 15 | AUTOVEX-15 | DONE | AUTOVEX-06 | Policy Guild | CLI command: `stella vex auto-downgrade --check <image>` for manual trigger |
|
||||
| 16 | AUTOVEX-16 | DONE | All above | Policy Guild | Integration tests: symbol observation → VEX downgrade → gate block |
|
||||
|
||||
## Auto-VEX Evidence Schema
|
||||
|
||||
```json
|
||||
{
|
||||
"type": "openvex",
|
||||
"statement": {
|
||||
"vulnerability": "CVE-2025-XXXX",
|
||||
"product": "pkg:oci/api-gw@sha256:abc123",
|
||||
"status": "affected",
|
||||
"status_notes": "Vulnerable symbol observed in production",
|
||||
"evidence": {
|
||||
"runtime_observation": {
|
||||
"symbol": "libfoo::parse_hdr",
|
||||
"symbol_digest": "blake3:...",
|
||||
"build_id": "ab12cd34...",
|
||||
"observation_window": {
|
||||
"start": "2025-12-26T12:00:00Z",
|
||||
"end": "2025-12-26T14:00:00Z"
|
||||
},
|
||||
"cpu_percentage": 17.3,
|
||||
"top_stacks": [
|
||||
"api-gw;libfoo::parse_hdr+0x3a;net/http::Serve;main 97"
|
||||
],
|
||||
"container_ids": ["abc123", "def456"]
|
||||
},
|
||||
"static_proof": {
|
||||
"funcproof_uri": "oci://registry/api-gw@sha256:abc123/funcproof",
|
||||
"funcproof_digest": "sha256:..."
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Execution Log
|
||||
| Date (UTC) | Update | Owner |
|
||||
| --- | --- | --- |
|
||||
| 2025-12-26 | Sprint created from advisory analysis; implements auto-VEX from "Evolving Evidence Models". | Project Mgmt |
|
||||
| 2025-12-27 | Implemented AutoVexDowngradeService with hot symbol detection and VEX generation (AUTOVEX-01 to AUTOVEX-05). | Implementer |
|
||||
| 2025-12-27 | Implemented VexDowngradeGenerator with DSSE signing and Rekor logging (AUTOVEX-06). | Implementer |
|
||||
| 2025-12-27 | Implemented ReachabilityLatticeUpdater with 8-state transitions and RTS weights (AUTOVEX-07, AUTOVEX-09). | Implementer |
|
||||
| 2025-12-27 | Implemented DriftGateIntegration with policy actions and notifications (AUTOVEX-08, AUTOVEX-10, AUTOVEX-11). | Implementer |
|
||||
| 2025-12-27 | Implemented TimeBoxedConfidenceManager with TTL and decay (AUTOVEX-12, AUTOVEX-13). | Implementer |
|
||||
| 2025-12-27 | Implemented VexNotReachableJustification service (AUTOVEX-14). | Implementer |
|
||||
| 2025-12-27 | Created VexCliCommandModule with `stella vex auto-downgrade` command (AUTOVEX-15). | Implementer |
|
||||
| 2025-12-27 | Created integration tests for auto-VEX pipeline (AUTOVEX-16). Sprint completed. | Implementer |
|
||||
|
||||
## Decisions & Risks
|
||||
- Decision needed: Downgrade threshold (1% CPU? 5%?). Recommend: configurable per CVE severity.
|
||||
- Decision needed: Auto-downgrade scope (all images or per-image). Recommend: per-image with inheritance.
|
||||
- Decision needed: Human approval required for high-severity auto-downgrade. Recommend: approval for KEV, auto for others.
|
||||
- Risk: False positives from sampling noise. Mitigation: require minimum observation count (default: 10).
|
||||
- Risk: Rapid VEX state thrashing. Mitigation: hysteresis (upgrade requires 24h of no observation).
|
||||
- Risk: Notification fatigue. Mitigation: aggregate downgrades, configurable quiet hours.
|
||||
|
||||
## Next Checkpoints
|
||||
- 2025-12-30 | AUTOVEX-06 complete | VEX downgrade with DSSE signing working |
|
||||
- 2026-01-03 | AUTOVEX-11 complete | Policy gate integration functional |
|
||||
- 2026-01-06 | AUTOVEX-16 complete | Full integration tested |
|
||||
Reference in New Issue
Block a user