feat: Add PathViewer and RiskDriftCard components with templates and styles
- Implemented PathViewerComponent for visualizing reachability call paths. - Added RiskDriftCardComponent to display reachability drift results. - Created corresponding HTML templates and SCSS styles for both components. - Introduced test fixtures for reachability analysis in JSON format. - Enhanced user interaction with collapsible and expandable features in PathViewer. - Included risk trend visualization and summary metrics in RiskDriftCard.
This commit is contained in:
@@ -64,12 +64,40 @@ Before starting, read:
|
||||
| 4 | T4 | DONE | Expose verification settings | Attestor Guild | Add `RekorVerificationOptions` in Configuration/ |
|
||||
| 5 | T5 | DONE | Use verifiers in HTTP client | Attestor Guild | Implement `HttpRekorClient.VerifyInclusionAsync` |
|
||||
| 6 | T6 | DONE | Stub verification behavior | Attestor Guild | Implement `StubRekorClient.VerifyInclusionAsync` |
|
||||
| 7 | T7 | BLOCKED | Wire verification pipeline | Attestor Guild | Requires T8 for offline mode before full pipeline integration |
|
||||
| 8 | T8 | BLOCKED | Add sealed/offline checkpoint mode | Attestor Guild | Depends on finalized offline checkpoint bundle format contract |
|
||||
| 9 | T9 | DONE | Add unit coverage | Attestor Guild | Add unit tests for Merkle proof verification |
|
||||
| 10 | T10 | DONE | Add integration coverage | Attestor Guild | RekorInclusionVerificationIntegrationTests.cs added |
|
||||
| 11 | T11 | DONE | Expose verification counters | Attestor Guild | Added Rekor counters to AttestorMetrics |
|
||||
| 12 | T12 | DONE | Sync docs | Attestor Guild | Added Rekor verification section to architecture.md |
|
||||
| 7 | T6a | TODO | Freeze offline checkpoint/receipt contract | Attestor Guild · AirGap Guild | Publish canonical offline layout + schema for: tlog root key, checkpoint signature, and inclusion proof pack (docs + fixtures) |
|
||||
| 8 | T6b | TODO | Add offline fixtures + validation harness | Attestor Guild | Add deterministic fixtures + parsing helpers so offline mode can be tested without network |
|
||||
| 9 | T7 | BLOCKED | Wire verification pipeline | Attestor Guild | BLOCKED on T8 (and its prerequisites T6a/T6b) before full pipeline integration |
|
||||
| 10 | T8 | BLOCKED | Add sealed/offline checkpoint mode | Attestor Guild | BLOCKED on T6a/T6b (offline checkpoint/receipt contract + fixtures) |
|
||||
| 11 | T9 | DONE | Add unit coverage | Attestor Guild | Add unit tests for Merkle proof verification |
|
||||
| 12 | T10 | DONE | Add integration coverage | Attestor Guild | RekorInclusionVerificationIntegrationTests.cs added |
|
||||
| 13 | T11 | DONE | Expose verification counters | Attestor Guild | Added Rekor counters to AttestorMetrics |
|
||||
| 14 | T12 | DONE | Sync docs | Attestor Guild | Added Rekor verification section to architecture.md |
|
||||
|
||||
---
|
||||
|
||||
## Unblock Task Notes (T6a/T6b)
|
||||
|
||||
### T6a: Freeze offline checkpoint/receipt contract
|
||||
- **Goal:** define the canonical offline inputs required to verify inclusion proofs without network access.
|
||||
- **Use these docs as the baseline (do not invent new shapes):**
|
||||
- `docs/product-advisories/14-Dec-2025 - Rekor Integration Technical Reference.md` (§13)
|
||||
- `docs/product-advisories/14-Dec-2025 - Offline and Air-Gap Technical Reference.md` (§3–4; `evidence/tlog/checkpoint.sig` + `entries/`)
|
||||
- **Minimum deliverables:**
|
||||
- A single canonical contract doc (new or existing) that answers:
|
||||
- Where the **tlog public key** comes from (file path, rotation/versioning)
|
||||
- Where the **signed checkpoint/tree head** lives (file path; signature format)
|
||||
- Where the **inclusion proof pack** lives (file path; entry + hashes; deterministic ordering rules)
|
||||
- How the checkpoint is bound to the proof pack (tree size, root hash)
|
||||
- A schema file (JSON Schema) for the on-disk checkpoint/receipt shape used by Attestor offline verification.
|
||||
|
||||
### T6b: Offline fixtures + validation harness
|
||||
- **Goal:** make offline mode testable and reproducible.
|
||||
- **Minimum deliverables:**
|
||||
- Deterministic fixtures committed under `src/Attestor/StellaOps.Attestor.Tests/Fixtures/` (checkpoint, pubkey, valid/invalid proof material).
|
||||
- Tests that verify:
|
||||
- checkpoint signature verification succeeds/fails as expected
|
||||
- recomputed Merkle root matches checkpoint for valid entries and fails for tampered fixtures
|
||||
- no network calls are required for offline mode
|
||||
|
||||
---
|
||||
|
||||
@@ -285,6 +313,7 @@ public Counter<long> CheckpointVerifyTotal { get; } // attestor.checkpoint_
|
||||
## Interlocks
|
||||
- Rekor public key distribution must be configured via `AttestorOptions` and documented for offline bundles.
|
||||
- Offline checkpoints must be pre-distributed; `AllowOfflineWithoutSignature` policy requires explicit operator intent.
|
||||
- T6a/T6b define the concrete offline checkpoint/receipt contract and fixtures; do not implement T8 until those are published and reviewed.
|
||||
|
||||
---
|
||||
|
||||
@@ -320,6 +349,7 @@ public Counter<long> CheckpointVerifyTotal { get; } // attestor.checkpoint_
|
||||
| Date (UTC) | Update | Owner |
|
||||
| --- | --- | --- |
|
||||
| 2025-12-14 | Normalised sprint file to standard template sections; started implementation and moved `T1` to `DOING`. | Implementer |
|
||||
| 2025-12-18 | Added unblock tasks (T6a/T6b) for offline checkpoint/receipt contract + fixtures; updated T7/T8 to be BLOCKED on them. | Project Mgmt |
|
||||
|
||||
---
|
||||
|
||||
|
||||
@@ -160,11 +160,13 @@ External Dependencies:
|
||||
| **EPSS-3410-011** | Implement outbox event schema | DONE | Agent | 2h | `src/Scanner/__Libraries/StellaOps.Scanner.Storage/Epss/Events/EpssUpdatedEvent.cs` |
|
||||
| **EPSS-3410-012** | Unit tests (parser, detector, flags) | DONE | Agent | 6h | `EpssCsvStreamParserTests.cs`, `EpssChangeDetectorTests.cs` |
|
||||
| **EPSS-3410-013** | Integration tests (Testcontainers) | DONE | Agent | 8h | `EpssRepositoryIntegrationTests.cs` |
|
||||
| **EPSS-3410-014** | Performance test (300k rows) | BLOCKED | Backend | 4h | Requires CI infrastructure for benchmark runs with Testcontainers + 300k row dataset. Repository uses NpgsqlBinaryImporter for bulk insert; expected <120s based on similar workloads. |
|
||||
| **EPSS-3410-013A** | Perf harness + deterministic dataset generator | TODO | Backend | 4h | Add a perf test project and deterministic 310k-row CSV generator (fixed seed, no network). Produce local run instructions and baseline output format. |
|
||||
| **EPSS-3410-013B** | CI perf runner + workflow for EPSS ingest | TODO | DevOps | 4h | Add a Gitea workflow (nightly/manual) + runner requirements so perf tests can run with Docker/Testcontainers; publish runner label/capacity requirements and artifact retention. |
|
||||
| **EPSS-3410-014** | Performance test (300k rows) | BLOCKED | Backend | 4h | BLOCKED on EPSS-3410-013A/013B. Once harness + CI runner exist, execute and record baseline (<120s) with environment details. |
|
||||
| **EPSS-3410-015** | Observability (metrics, logs, traces) | DONE | Agent | 4h | ActivitySource with tags (model_date, row_count, cve_count, duration_ms); structured logging at Info/Warning/Error levels. |
|
||||
| **EPSS-3410-016** | Documentation (runbook, troubleshooting) | DONE | Agent | 3h | Added Operations Runbook (§10) to `docs/modules/scanner/epss-integration.md` with configuration, modes, manual ingestion, troubleshooting, and monitoring guidance. |
|
||||
|
||||
**Total Estimated Effort**: 65 hours (~2 weeks for 1 developer)
|
||||
**Total Estimated Effort**: 73 hours (~2 weeks for 1 developer)
|
||||
|
||||
---
|
||||
|
||||
@@ -604,11 +606,46 @@ public async Task ComputeChanges_DetectsFlags_Correctly()
|
||||
|
||||
---
|
||||
|
||||
### EPSS-3410-013A: Perf Harness + Deterministic Dataset Generator
|
||||
|
||||
**Description**: Add an offline-friendly perf harness for EPSS ingest without committing a huge static dataset.
|
||||
|
||||
**Deliverables**:
|
||||
- New test project: `src/Scanner/__Tests/StellaOps.Scanner.Storage.Performance.Tests/`
|
||||
- Deterministic generator: 310k rows with fixed seed, stable row order, and controlled CVE distribution.
|
||||
- Test tagged so it does not run in default CI (`[Trait("Category","Performance")]` or equivalent).
|
||||
- Local run snippet (exact `dotnet test` invocation + required env vars for Testcontainers).
|
||||
|
||||
**Acceptance Criteria**:
|
||||
- [ ] Generator produces identical output across runs (same seed ⇒ same SHA-256 of CSV bytes)
|
||||
- [ ] Perf test runs locally in <= 5 minutes on a dev machine (budget validation happens in CI)
|
||||
- [ ] No network required beyond local Docker engine for Testcontainers
|
||||
|
||||
---
|
||||
|
||||
### EPSS-3410-013B: CI Perf Runner + Workflow
|
||||
|
||||
**Description**: Enable deterministic perf execution in CI with known hardware + reproducible logs.
|
||||
|
||||
**Deliverables**:
|
||||
- Gitea workflow (nightly + manual): `.gitea/workflows/epss-perf.yml`
|
||||
- Runner requirements documented (label, OS/arch, CPU/RAM, Docker/Testcontainers support).
|
||||
- Artifacts retained: perf logs + environment metadata (CPU model, cores, memory, Docker version, image digests).
|
||||
|
||||
**Acceptance Criteria**:
|
||||
- [ ] CI job can spin up PostgreSQL via Testcontainers reliably
|
||||
- [ ] Perf test output includes total duration + phase breakdowns (parse/insert/changes/current)
|
||||
- [ ] Budgets enforced only in this workflow (does not break default PR CI)
|
||||
|
||||
---
|
||||
|
||||
### EPSS-3410-014: Performance Test (300k rows)
|
||||
|
||||
**Description**: Verify ingestion meets performance budget.
|
||||
|
||||
**File**: `src/Concelier/__Tests/StellaOps.Concelier.Epss.Performance.Tests/EpssIngestPerformanceTests.cs`
|
||||
**BLOCKED ON:** EPSS-3410-013A, EPSS-3410-013B
|
||||
|
||||
**File**: `src/Scanner/__Tests/StellaOps.Scanner.Storage.Performance.Tests/EpssIngestPerformanceTests.cs` (new project)
|
||||
|
||||
**Requirements**:
|
||||
- Synthetic CSV: 310,000 rows (close to real-world)
|
||||
@@ -865,11 +902,12 @@ concelier:
|
||||
| 2025-12-18 | Completed EPSS-3410-015: Verified ActivitySource tracing with model_date, row_count, cve_count, duration_ms tags; structured logging in place. | Agent |
|
||||
| 2025-12-18 | Completed EPSS-3410-016: Added Operations Runbook (§10) to docs/modules/scanner/epss-integration.md covering config, online/bundle modes, manual trigger, troubleshooting, monitoring. | Agent |
|
||||
| 2025-12-18 | BLOCKED EPSS-3410-014: Performance test requires CI infrastructure and 300k row dataset. BULK INSERT uses NpgsqlBinaryImporter; expected to meet <120s budget. | Agent |
|
||||
| 2025-12-18 | Added unblock tasks EPSS-3410-013A/013B; EPSS-3410-014 remains BLOCKED until harness + CI perf runner/workflow are available. | Project Mgmt |
|
||||
|
||||
## Next Checkpoints
|
||||
|
||||
- Unblock performance test (014) when CI infrastructure is available.
|
||||
- Unblock performance test (EPSS-3410-014) by completing EPSS-3410-013A (harness) and EPSS-3410-013B (CI perf runner/workflow).
|
||||
- Close Scanner integration (SPRINT_3410_0002_0001).
|
||||
|
||||
**Sprint Status**: BLOCKED (1 task pending CI infrastructure)
|
||||
**Sprint Status**: BLOCKED (EPSS-3410-014 pending EPSS-3410-013B CI perf runner/workflow)
|
||||
**Approval**: _____________________ Date: ___________
|
||||
|
||||
@@ -47,8 +47,8 @@ Integrate EPSS v4 data into the Scanner WebService for vulnerability scoring and
|
||||
| 2 | EPSS-SCAN-002 | DONE | Agent | 2h | Create `EpssEvidence` record type |
|
||||
| 3 | EPSS-SCAN-003 | DONE | Agent | 4h | Implement `IEpssProvider` interface |
|
||||
| 4 | EPSS-SCAN-004 | DONE | Agent | 4h | Implement `EpssProvider` with PostgreSQL lookup |
|
||||
| 5 | EPSS-SCAN-005 | TODO | Backend | 2h | Add optional Valkey cache layer |
|
||||
| 6 | EPSS-SCAN-006 | TODO | Backend | 4h | Integrate EPSS into `ScanProcessor` |
|
||||
| 5 | EPSS-SCAN-005 | DONE | Agent | 2h | Add optional Valkey cache layer |
|
||||
| 6 | EPSS-SCAN-006 | DONE | Agent | 4h | Integrate EPSS into `ScanProcessor` via EpssEnrichmentStageExecutor |
|
||||
| 7 | EPSS-SCAN-007 | DONE | — | 2h | Add EPSS weight to scoring configuration (EpssMultiplier in ScoreExplanationWeights) |
|
||||
| 8 | EPSS-SCAN-008 | DONE | Agent | 4h | Implement `GET /epss/current` bulk lookup API |
|
||||
| 9 | EPSS-SCAN-009 | DONE | Agent | 2h | Implement `GET /epss/history` time-series API |
|
||||
@@ -132,6 +132,7 @@ scoring:
|
||||
| 2025-12-17 | Sprint created from advisory processing | Agent |
|
||||
| 2025-12-17 | EPSS-SCAN-001: Created 008_epss_integration.sql in Scanner Storage | Agent |
|
||||
| 2025-12-17 | EPSS-SCAN-012: Created docs/modules/scanner/epss-integration.md | Agent |
|
||||
| 2025-12-18 | EPSS-SCAN-005: Implemented CachingEpssProvider with Valkey cache layer. Created EpssServiceCollectionExtensions for DI registration. | Agent |
|
||||
|
||||
---
|
||||
|
||||
|
||||
@@ -37,14 +37,14 @@ This sprint implements live EPSS enrichment for existing vulnerability instances
|
||||
|
||||
| # | Status | Task | Notes |
|
||||
|---|--------|------|-------|
|
||||
| 1 | TODO | Implement `EpssEnrichmentJob` service | Core enrichment logic |
|
||||
| 2 | TODO | Create `vuln_instance_triage` schema updates | Add `current_epss_*` columns |
|
||||
| 1 | DONE | Implement `EpssEnrichmentJob` service | Created EpssEnrichmentJob.cs with background processing |
|
||||
| 2 | DONE | Create `vuln_instance_triage` schema updates | Created 014_epss_triage_columns.sql with EPSS columns and batch_update_epss_triage() |
|
||||
| 3 | DONE | Implement `epss_changes` flag logic | `EpssChangeFlags` enum with NEW_SCORED, CROSSED_HIGH, BIG_JUMP, DROPPED_LOW |
|
||||
| 4 | TODO | Add efficient targeting filter | Only update instances with flags set |
|
||||
| 4 | DONE | Add efficient targeting filter | Added GetChangesAsync() to IEpssRepository; EpssEnrichmentJob uses flag filtering |
|
||||
| 5 | DONE | Implement priority band calculation | `EpssPriorityCalculator` maps percentile to CRITICAL/HIGH/MEDIUM/LOW |
|
||||
| 6 | TODO | Emit `vuln.priority.changed` event | Only when band changes |
|
||||
| 6 | DONE | Emit `vuln.priority.changed` event | Added IEpssSignalPublisher.PublishPriorityChangedAsync() in EpssEnrichmentJob |
|
||||
| 7 | DONE | Add configurable thresholds | `EpssEnrichmentOptions` with HighPercentile, HighScore, BigJumpDelta, etc. |
|
||||
| 8 | TODO | Implement bulk update optimization | Batch updates for performance |
|
||||
| 8 | DONE | Implement bulk update optimization | Added batch_update_epss_triage() PostgreSQL function |
|
||||
| 9 | DONE | Add `EpssEnrichmentOptions` configuration | Environment-specific settings in Scanner.Core.Configuration |
|
||||
| 10 | TODO | Create unit tests for enrichment logic | Flag detection, band calculation |
|
||||
| 11 | TODO | Create integration tests | End-to-end enrichment flow |
|
||||
@@ -58,10 +58,12 @@ This sprint implements live EPSS enrichment for existing vulnerability instances
|
||||
|
||||
| # | Status | Task | Notes |
|
||||
|---|--------|------|-------|
|
||||
| R1 | TODO | Create `epss_raw` table migration | `011_epss_raw_layer.sql` - Full JSONB payload storage |
|
||||
| R2 | TODO | Update `EpssIngestJob` to store raw payload | Decompress CSV, convert to JSONB array, store in `epss_raw` |
|
||||
| R3 | TODO | Add retention policy for raw data | `prune_epss_raw()` function - Keep 365 days |
|
||||
| R4 | TODO | Implement `ReplayFromRawAsync()` method | Re-normalize from stored raw without re-downloading |
|
||||
| R1 | DONE | Create `epss_raw` table migration | `011_epss_raw_layer.sql` - Full JSONB payload storage |
|
||||
| R2 | DONE | Update `EpssIngestJob` to store raw payload | Added StoreRawPayloadAsync(), converts to JSONB, stores in `epss_raw` |
|
||||
| R3 | DONE | Add retention policy for raw data | `prune_epss_raw()` function in migration - Keep 365 days |
|
||||
| R4 | DONE | Implement `ReplayFromRawAsync()` method | Created EpssReplayService with ReplayFromRawAsync() and ReplayRangeAsync() |
|
||||
| R5 | DONE | Implement `IEpssRawRepository` interface | Created with CRUD operations |
|
||||
| R6 | DONE | Implement `PostgresEpssRawRepository` | PostgreSQL implementation with DI registration |
|
||||
|
||||
### Signal-Ready Layer Tasks (S1-S12)
|
||||
|
||||
@@ -69,16 +71,16 @@ This sprint implements live EPSS enrichment for existing vulnerability instances
|
||||
|
||||
| # | Status | Task | Notes |
|
||||
|---|--------|------|-------|
|
||||
| S1 | TODO | Create `epss_signal` table migration | `012_epss_signal_layer.sql` - Tenant-scoped with dedupe_key |
|
||||
| S2 | TODO | Implement `IEpssSignalRepository` interface | Signal CRUD operations |
|
||||
| S3 | TODO | Implement `PostgresEpssSignalRepository` | PostgreSQL implementation |
|
||||
| S4 | TODO | Implement `ComputeExplainHash()` | Deterministic SHA-256 of signal inputs |
|
||||
| S5 | TODO | Create `EpssSignalJob` service | Runs after enrichment, per-tenant |
|
||||
| S6 | TODO | Add "observed CVEs" filter | Only signal for CVEs in tenant's inventory |
|
||||
| S7 | TODO | Implement model version change detection | Compare vs previous day's `model_version_tag` |
|
||||
| S8 | TODO | Add `MODEL_UPDATED` event type | Summary event instead of 300k individual deltas |
|
||||
| S9 | TODO | Connect to Notify/Router | Publish to `signals.epss` topic |
|
||||
| S10 | TODO | Add signal deduplication | Idempotent via `dedupe_key` constraint |
|
||||
| S1 | DONE | Create `epss_signal` table migration | `012_epss_signal_layer.sql` - Tenant-scoped with dedupe_key |
|
||||
| S2 | DONE | Implement `IEpssSignalRepository` interface | Signal CRUD operations with config support |
|
||||
| S3 | DONE | Implement `PostgresEpssSignalRepository` | PostgreSQL implementation with DI registration |
|
||||
| S4 | DONE | Implement `ComputeExplainHash()` | Created EpssExplainHashCalculator with deterministic SHA-256 |
|
||||
| S5 | DONE | Create `EpssSignalJob` service | Created EpssSignalJob.cs with batch processing and tenant support |
|
||||
| S6 | DONE | Add "observed CVEs" filter | Created IObservedCveRepository and PostgresObservedCveRepository; integrated in EpssSignalJob |
|
||||
| S7 | DONE | Implement model version change detection | Added in EpssSignalJob with _lastModelVersion tracking |
|
||||
| S8 | DONE | Add `MODEL_UPDATED` event type | EmitModelUpdatedSignalAsync() creates summary event |
|
||||
| S9 | DONE | Connect to Notify/Router | Created IEpssSignalPublisher interface; EpssSignalJob publishes via PublishBatchAsync() |
|
||||
| S10 | DONE | Add signal deduplication | Idempotent via `dedupe_key` constraint in repository |
|
||||
| S11 | TODO | Unit tests for signal generation | Flag logic, explain hash, dedupe key |
|
||||
| S12 | TODO | Integration tests for signal flow | End-to-end tenant-scoped signal emission |
|
||||
| S13 | TODO | Add Prometheus metrics for signals | `epss_signals_emitted_total{event_type, tenant_id}` |
|
||||
@@ -175,15 +177,36 @@ concelier:
|
||||
|
||||
---
|
||||
|
||||
## Execution Log
|
||||
|
||||
| Date (UTC) | Update | Owner |
|
||||
|------------|--------|-------|
|
||||
| 2025-12-18 | Task #1: Implemented `EpssEnrichmentJob` with batch processing, priority band calculation, and trigger mechanism | Agent |
|
||||
| 2025-12-18 | R5-R6: Implemented `IEpssRawRepository` and `PostgresEpssRawRepository` for raw payload storage | Agent |
|
||||
| 2025-12-18 | S2-S3: Implemented `IEpssSignalRepository` and `PostgresEpssSignalRepository` with tenant config support | Agent |
|
||||
| 2025-12-18 | Registered new repositories in DI: `EpssRawRepository`, `EpssSignalRepository` | Agent |
|
||||
| 2025-12-18 | Task #2: Created 014_epss_triage_columns.sql migration with EPSS columns and batch_update_epss_triage() function | Agent |
|
||||
| 2025-12-18 | R2: Updated EpssIngestJob with StoreRawPayloadAsync() to store raw JSONB payload | Agent |
|
||||
| 2025-12-18 | S4: Created EpssExplainHashCalculator with ComputeExplainHash() and ComputeDedupeKey() | Agent |
|
||||
| 2025-12-18 | S5, S7, S8: Created EpssSignalJob with model version detection and MODEL_UPDATED event support | Agent |
|
||||
| 2025-12-18 | EPSS-SCAN-006: Created EpssEnrichmentStageExecutor for scan pipeline integration | Agent |
|
||||
| 2025-12-18 | R4: Created EpssReplayService with ReplayFromRawAsync() and ReplayRangeAsync() | Agent |
|
||||
| 2025-12-18 | S6: Created IObservedCveRepository, PostgresObservedCveRepository; integrated tenant-scoped filtering in EpssSignalJob | Agent |
|
||||
| 2025-12-18 | S9: Created IEpssSignalPublisher interface; integrated PublishBatchAsync() in EpssSignalJob | Agent |
|
||||
| 2025-12-18 | Task #4: Added GetChangesAsync() to IEpssRepository; EpssEnrichmentJob uses flag-based targeting | Agent |
|
||||
| 2025-12-18 | Task #6: Added PublishPriorityChangedAsync() to IEpssSignalPublisher; EpssEnrichmentJob emits events | Agent |
|
||||
|
||||
---
|
||||
|
||||
## Exit Criteria
|
||||
|
||||
- [ ] `EpssEnrichmentJob` updates vuln_instance_triage with current EPSS
|
||||
- [ ] Only instances with material changes are updated (flag-based targeting)
|
||||
- [ ] `vuln.priority.changed` event emitted only when band changes
|
||||
- [ ] Raw payload stored in `epss_raw` for replay capability
|
||||
- [ ] Signals emitted only for observed CVEs per tenant
|
||||
- [ ] Model version changes suppress noisy delta signals
|
||||
- [ ] Each signal has deterministic `explain_hash`
|
||||
- [x] `EpssEnrichmentJob` updates vuln_instance_triage with current EPSS
|
||||
- [x] Only instances with material changes are updated (flag-based targeting)
|
||||
- [x] `vuln.priority.changed` event emitted only when band changes
|
||||
- [x] Raw payload stored in `epss_raw` for replay capability
|
||||
- [x] Signals emitted only for observed CVEs per tenant
|
||||
- [x] Model version changes suppress noisy delta signals
|
||||
- [x] Each signal has deterministic `explain_hash`
|
||||
- [ ] All unit and integration tests pass
|
||||
- [ ] Documentation updated
|
||||
|
||||
@@ -195,17 +218,29 @@ concelier:
|
||||
|
||||
- `src/Scanner/__Libraries/StellaOps.Scanner.Storage/Postgres/Migrations/011_epss_raw_layer.sql`
|
||||
- `src/Scanner/__Libraries/StellaOps.Scanner.Storage/Postgres/Migrations/012_epss_signal_layer.sql`
|
||||
- `src/Concelier/__Libraries/StellaOps.Concelier.Epss/Services/EpssSignalJob.cs`
|
||||
- `src/Concelier/__Libraries/StellaOps.Concelier.Epss/Services/EpssExplainHashCalculator.cs`
|
||||
- `src/Concelier/__Libraries/StellaOps.Concelier.Epss/Repositories/IEpssSignalRepository.cs`
|
||||
- `src/Concelier/__Libraries/StellaOps.Concelier.Epss/Repositories/PostgresEpssSignalRepository.cs`
|
||||
- `src/Concelier/__Libraries/StellaOps.Concelier.Epss/Repositories/IEpssRawRepository.cs`
|
||||
- `src/Concelier/__Libraries/StellaOps.Concelier.Epss/Repositories/PostgresEpssRawRepository.cs`
|
||||
- `src/Scanner/__Libraries/StellaOps.Scanner.Storage/Postgres/Migrations/014_epss_triage_columns.sql`
|
||||
- `src/Scanner/__Libraries/StellaOps.Scanner.Storage/Repositories/IEpssSignalRepository.cs`
|
||||
- `src/Scanner/__Libraries/StellaOps.Scanner.Storage/Repositories/IEpssRawRepository.cs`
|
||||
- `src/Scanner/__Libraries/StellaOps.Scanner.Storage/Repositories/IObservedCveRepository.cs`
|
||||
- `src/Scanner/__Libraries/StellaOps.Scanner.Storage/Postgres/PostgresEpssSignalRepository.cs`
|
||||
- `src/Scanner/__Libraries/StellaOps.Scanner.Storage/Postgres/PostgresEpssRawRepository.cs`
|
||||
- `src/Scanner/__Libraries/StellaOps.Scanner.Storage/Postgres/PostgresObservedCveRepository.cs`
|
||||
- `src/Scanner/__Libraries/StellaOps.Scanner.Storage/Epss/EpssReplayService.cs`
|
||||
- `src/Scanner/__Libraries/StellaOps.Scanner.Storage/Epss/IEpssSignalPublisher.cs`
|
||||
- `src/Scanner/__Libraries/StellaOps.Scanner.Storage/Epss/CachingEpssProvider.cs`
|
||||
- `src/Scanner/__Libraries/StellaOps.Scanner.Storage/Epss/EpssExplainHashCalculator.cs`
|
||||
- `src/Scanner/__Libraries/StellaOps.Scanner.Storage/Extensions/EpssServiceCollectionExtensions.cs`
|
||||
- `src/Scanner/StellaOps.Scanner.Worker/Processing/EpssEnrichmentJob.cs`
|
||||
- `src/Scanner/StellaOps.Scanner.Worker/Processing/EpssEnrichmentStageExecutor.cs`
|
||||
- `src/Scanner/StellaOps.Scanner.Worker/Processing/EpssSignalJob.cs`
|
||||
|
||||
### Existing Files to Update
|
||||
### Existing Files Updated
|
||||
|
||||
- `src/Concelier/__Libraries/StellaOps.Concelier.Epss/Jobs/EpssIngestJob.cs` - Store raw payload
|
||||
- `src/Concelier/__Libraries/StellaOps.Concelier.Epss/Jobs/EpssEnrichmentJob.cs` - Add model version detection
|
||||
- `src/Scanner/__Libraries/StellaOps.Scanner.Storage/Extensions/ServiceCollectionExtensions.cs` - Added EPSS repository registrations
|
||||
- `src/Scanner/__Libraries/StellaOps.Scanner.Storage/Postgres/Migrations/MigrationIds.cs` - Added new migration IDs
|
||||
- `src/Scanner/StellaOps.Scanner.Worker/Processing/ScanStageNames.cs` - Added EpssEnrichment stage
|
||||
- `src/Scanner/StellaOps.Scanner.Worker/Processing/EpssIngestJob.cs` - Added raw payload storage
|
||||
- `src/Scanner/StellaOps.Scanner.Worker/Program.cs` - Registered EpssEnrichmentStageExecutor
|
||||
|
||||
---
|
||||
|
||||
|
||||
@@ -60,9 +60,9 @@ public sealed record NativeBinaryMetadata {
|
||||
| 2 | BSE-002 | DONE | Create NativeComponentEmitter |
|
||||
| 3 | BSE-003 | DONE | Create NativePurlBuilder |
|
||||
| 4 | BSE-004 | DONE | Create NativeComponentMapper (layer fragment generation) |
|
||||
| 5 | BSE-005 | DONE | Add NativeBinaryMetadata (with Imports/Exports) |
|
||||
| 6 | BSE-006 | TODO | Update CycloneDxComposer |
|
||||
| 7 | BSE-007 | TODO | Add stellaops:binary.* properties |
|
||||
| 5 | BSE-005 | DONE | Add NativeBinaryMetadata (with Imports/Exports/PE/Mach-O fields) |
|
||||
| 6 | BSE-006 | DONE | Update CycloneDxComposer via LayerComponentMapping.ToFragment() |
|
||||
| 7 | BSE-007 | DONE | Add stellaops:binary.* properties in ToComponentRecord() |
|
||||
| 8 | BSE-008 | DONE | Unit tests (22 tests passing) |
|
||||
| 9 | BSE-009 | TODO | Integration tests |
|
||||
|
||||
|
||||
@@ -48,8 +48,30 @@ Extend the Unknowns registry with native binary-specific classification reasons,
|
||||
| 1 | NUC-001 | DONE | Add UnknownKind enum values (MissingBuildId, UnknownBuildId, UnresolvedNativeLibrary, HeuristicDependency, UnsupportedBinaryFormat) |
|
||||
| 2 | NUC-002 | DONE | Create NativeUnknownContext model |
|
||||
| 3 | NUC-003 | DONE | Create NativeUnknownClassifier service |
|
||||
| 4 | NUC-004 | TODO | Integration with native analyzer |
|
||||
| 5 | NUC-005 | TODO | Unit tests |
|
||||
| 4 | NUC-003A | TODO | Approve + add `StellaOps.Unknowns.Core` reference from `src/Scanner/StellaOps.Scanner.Worker` (avoid circular deps; document final dependency direction) |
|
||||
| 5 | NUC-003B | TODO | Wire native analyzer outputs to Unknowns: call `NativeUnknownClassifier` and persist via Unknowns repository/service from scan pipeline |
|
||||
| 6 | NUC-004 | BLOCKED | Integrate with native analyzer (BLOCKED on NUC-003A/NUC-003B) |
|
||||
| 7 | NUC-005 | TODO | Unit tests |
|
||||
|
||||
---
|
||||
|
||||
## Unblock Task Notes (NUC-003A/NUC-003B)
|
||||
|
||||
### NUC-003A: Project reference + dependency direction
|
||||
- **Goal:** make the integration unambiguous: Scanner Worker emits Unknowns during scan; Unknowns.Core provides the domain + classifier.
|
||||
- **Touchpoints (expected):**
|
||||
- `src/Scanner/StellaOps.Scanner.Worker/StellaOps.Scanner.Worker.csproj` (add project reference)
|
||||
- If persistence from Worker is required, also reference `src/Unknowns/__Libraries/StellaOps.Unknowns.Storage.Postgres/` and ensure migrations are applied by Scanner startup.
|
||||
- **Acceptance criteria (minimum):**
|
||||
- `dotnet build src/Scanner/StellaOps.Scanner.Worker/StellaOps.Scanner.Worker.csproj` succeeds with no circular references.
|
||||
|
||||
### NUC-003B: Wiring from native analyzer to Unknowns
|
||||
- **Goal:** convert analyzer-side identification/resolution gaps into first-class Unknowns records.
|
||||
- **Touchpoints (expected):**
|
||||
- `src/Scanner/StellaOps.Scanner.Analyzers.Native/` (where classification context is produced)
|
||||
- `src/Scanner/StellaOps.Scanner.Worker/` (where results are persisted/emitted)
|
||||
- **Acceptance criteria (minimum):**
|
||||
- A missing build-id produces `UnknownKind.MissingBuildId` with a populated `NativeUnknownContext` and is visible via existing Unknowns API surfaces.
|
||||
|
||||
---
|
||||
|
||||
@@ -58,3 +80,11 @@ Extend the Unknowns registry with native binary-specific classification reasons,
|
||||
- [ ] Binaries without build-id create MissingBuildId unknowns
|
||||
- [ ] Build-IDs not in index create UnknownBuildId unknowns
|
||||
- [ ] Unknowns emit to registry, not core SBOM
|
||||
|
||||
---
|
||||
|
||||
## Execution Log
|
||||
|
||||
| Date (UTC) | Update | Owner |
|
||||
| --- | --- | --- |
|
||||
| 2025-12-18 | Added unblock tasks NUC-003A/NUC-003B; NUC-004 remains BLOCKED until dependency direction + wiring are implemented. | Project Mgmt |
|
||||
|
||||
@@ -789,12 +789,12 @@ public sealed class DriftSarifGenerator
|
||||
|---|---------|--------|-------------|-------|
|
||||
| 1 | UI-001 | DONE | Create PathNode TypeScript interface | `path-viewer.models.ts` |
|
||||
| 2 | UI-002 | DONE | Create CompressedPath TypeScript interface | `path-viewer.models.ts` |
|
||||
| 3 | UI-003 | TODO | Create PathViewerComponent | Core visualization |
|
||||
| 4 | UI-004 | TODO | Style PathViewerComponent | SCSS styling |
|
||||
| 3 | UI-003 | DONE | Create PathViewerComponent | `components/path-viewer/` |
|
||||
| 4 | UI-004 | DONE | Style PathViewerComponent | SCSS with BEM |
|
||||
| 5 | UI-005 | DONE | Create DriftedSink TypeScript interface | `drift.models.ts` |
|
||||
| 6 | UI-006 | DONE | Create DriftResult TypeScript interface | `drift.models.ts` |
|
||||
| 7 | UI-007 | TODO | Create RiskDriftCardComponent | Summary card |
|
||||
| 8 | UI-008 | TODO | Style RiskDriftCardComponent | SCSS styling |
|
||||
| 7 | UI-007 | DONE | Create RiskDriftCardComponent | `components/risk-drift-card/` |
|
||||
| 8 | UI-008 | DONE | Style RiskDriftCardComponent | SCSS with BEM |
|
||||
| 9 | UI-009 | DONE | Create drift API service | `drift-api.service.ts` |
|
||||
| 10 | UI-010 | TODO | Integrate PathViewer into scan details | Page integration |
|
||||
| 11 | UI-011 | TODO | Integrate RiskDriftCard into PR view | Page integration |
|
||||
@@ -805,12 +805,12 @@ public sealed class DriftSarifGenerator
|
||||
| 16 | UI-016 | TODO | Implement drift attestation service | DSSE signing |
|
||||
| 17 | UI-017 | TODO | Add attestation to drift API | API integration |
|
||||
| 18 | UI-018 | TODO | Unit tests for attestation | Predicate validation |
|
||||
| 19 | UI-019 | TODO | Create DriftCommand for CLI | CLI command |
|
||||
| 20 | UI-020 | TODO | Implement table output | Spectre.Console |
|
||||
| 21 | UI-021 | TODO | Implement JSON output | JSON serialization |
|
||||
| 22 | UI-022 | TODO | Create DriftSarifGenerator | SARIF 2.1.0 |
|
||||
| 23 | UI-023 | TODO | Implement SARIF output for CLI | CLI integration |
|
||||
| 24 | UI-024 | TODO | Update CLI documentation | docs/cli/ |
|
||||
| 19 | UI-019 | DONE | Create DriftCommand for CLI | `Commands/DriftCommandGroup.cs` |
|
||||
| 20 | UI-020 | DONE | Implement table output | Spectre.Console tables |
|
||||
| 21 | UI-021 | DONE | Implement JSON output | JSON serialization |
|
||||
| 22 | UI-022 | DONE | Create DriftSarifGenerator | SARIF 2.1.0 (placeholder) |
|
||||
| 23 | UI-023 | DONE | Implement SARIF output for CLI | `CommandHandlers.Drift.cs` |
|
||||
| 24 | UI-024 | DONE | Update CLI documentation | `docs/cli/drift-cli.md` |
|
||||
| 25 | UI-025 | TODO | Integration tests for CLI | End-to-end |
|
||||
|
||||
---
|
||||
|
||||
@@ -334,20 +334,20 @@ cas://reachability/graphs/{blake3:hash}/
|
||||
|---|---------|--------|-------------|
|
||||
| 1 | RWD-001 | DONE | Create ReachabilityWitnessStatement.cs |
|
||||
| 2 | RWD-002 | DONE | Create ReachabilityWitnessOptions.cs |
|
||||
| 3 | RWD-003 | TODO | Add PredicateTypes.StellaOpsReachabilityWitness |
|
||||
| 3 | RWD-003 | DONE | Add PredicateTypes.StellaOpsReachabilityWitness |
|
||||
| 4 | RWD-004 | DONE | Create ReachabilityWitnessDsseBuilder.cs |
|
||||
| 5 | RWD-005 | DONE | Create IReachabilityWitnessPublisher.cs |
|
||||
| 6 | RWD-006 | DONE | Create ReachabilityWitnessPublisher.cs |
|
||||
| 7 | RWD-007 | TODO | Implement CAS storage integration (placeholder done) |
|
||||
| 8 | RWD-008 | TODO | Implement Rekor submission (placeholder done) |
|
||||
| 9 | RWD-009 | TODO | Integrate with RichGraphWriter |
|
||||
| 10 | RWD-010 | TODO | Add service registration |
|
||||
| 9 | RWD-009 | DONE | Integrate with RichGraphWriter (AttestingRichGraphWriter) |
|
||||
| 10 | RWD-010 | DONE | Add service registration |
|
||||
| 11 | RWD-011 | DONE | Unit tests for DSSE builder (15 tests) |
|
||||
| 12 | RWD-012 | TODO | Unit tests for publisher |
|
||||
| 12 | RWD-012 | DONE | Unit tests for publisher (8 tests) |
|
||||
| 13 | RWD-013 | TODO | Integration tests with Attestor |
|
||||
| 14 | RWD-014 | TODO | Add golden fixture: graph-only.golden.json |
|
||||
| 15 | RWD-015 | TODO | Add golden fixture: graph-with-runtime.golden.json |
|
||||
| 16 | RWD-016 | TODO | Verify deterministic DSSE output |
|
||||
| 14 | RWD-014 | DONE | Add golden fixture: graph-only.golden.json |
|
||||
| 15 | RWD-015 | DONE | Add golden fixture: graph-with-runtime.golden.json |
|
||||
| 16 | RWD-016 | DONE | Verify deterministic DSSE output (4 tests) |
|
||||
|
||||
---
|
||||
|
||||
@@ -356,6 +356,9 @@ cas://reachability/graphs/{blake3:hash}/
|
||||
| Date | Update | Owner |
|
||||
|------|--------|-------|
|
||||
| 2025-12-18 | Created ReachabilityWitnessStatement, ReachabilityWitnessOptions, ReachabilityWitnessDsseBuilder, IReachabilityWitnessPublisher, ReachabilityWitnessPublisher. Created 15 DSSE builder tests. 6/16 tasks DONE. | Agent |
|
||||
| 2025-12-18 | Added PredicateTypes.StellaOpsReachabilityWitness to Signer.Core. Created ReachabilityAttestationServiceCollectionExtensions.cs for DI. Created ReachabilityWitnessPublisherTests.cs (8 tests). 9/16 tasks DONE. | Agent |
|
||||
| 2025-12-18 | Fixed PathExplanationServiceTests.cs (RichGraph/RichGraphEdge constructor updates). Fixed RichGraphWriterTests.cs assertion. All 119 tests pass. | Agent |
|
||||
| 2025-12-18 | Created AttestingRichGraphWriter.cs for integrated attestation. Created golden fixtures. Created AttestingRichGraphWriterTests.cs (4 tests). 13/16 tasks DONE. All 123 tests pass. | Agent |
|
||||
|
||||
---
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
# SPRINT_3700_0001_0001 - Witness Foundation
|
||||
|
||||
**Status:** BLOCKED (2 tasks pending integration: WIT-008, WIT-009)
|
||||
**Status:** BLOCKED (WIT-008 blocked on WIT-007A/WIT-007B; WIT-009 blocked on WIT-007C/WIT-007D)
|
||||
**Priority:** P0 - CRITICAL
|
||||
**Module:** Scanner, Attestor
|
||||
**Working Directory:** `src/Scanner/__Libraries/StellaOps.Scanner.Reachability/`
|
||||
@@ -46,14 +46,38 @@ Before starting, read:
|
||||
| 5 | WIT-005 | DONE | Create PathWitness record model |
|
||||
| 6 | WIT-006 | DONE | Create IPathWitnessBuilder interface |
|
||||
| 7 | WIT-007 | DONE | Implement PathWitnessBuilder service |
|
||||
| 8 | WIT-008 | BLOCKED | Integrate with ReachabilityAnalyzer output - requires ReachabilityAnalyzer refactoring |
|
||||
| 9 | WIT-009 | BLOCKED | Add DSSE envelope generation - requires Attestor service integration |
|
||||
| 10 | WIT-010 | DONE | Create WitnessEndpoints.cs (GET /witness/{id}, list, verify) |
|
||||
| 11 | WIT-011 | DONE | Create 013_witness_storage.sql migration |
|
||||
| 12 | WIT-012 | DONE | Create PostgresWitnessRepository + IWitnessRepository |
|
||||
| 13 | WIT-013 | DONE | Add UsesBlake3HashForDefaultProfile test to RichGraphWriterTests |
|
||||
| 14 | WIT-014 | DONE | Add PathWitnessBuilderTests |
|
||||
| 15 | WIT-015 | DONE | Create docs/contracts/witness-v1.md |
|
||||
| 8 | WIT-007A | TODO | Define ReachabilityAnalyzer → PathWitnessBuilder output contract (types, ordering, limits, fixtures) |
|
||||
| 9 | WIT-007B | TODO | Refactor ReachabilityAnalyzer to surface deterministic paths to sinks (enables witness generation) |
|
||||
| 10 | WIT-007C | TODO | Define witness predicate + DSSE payloadType constants (Attestor) and align `docs/contracts/witness-v1.md` |
|
||||
| 11 | WIT-007D | TODO | Implement DSSE sign+verify for witness payload using `StellaOps.Attestor.Envelope`; add golden fixtures |
|
||||
| 12 | WIT-008 | BLOCKED | Integrate witness generation with ReachabilityAnalyzer output (BLOCKED on WIT-007A, WIT-007B) |
|
||||
| 13 | WIT-009 | BLOCKED | Add DSSE envelope generation (BLOCKED on WIT-007C, WIT-007D) |
|
||||
| 14 | WIT-010 | DONE | Create WitnessEndpoints.cs (GET /witness/{id}, list, verify) |
|
||||
| 15 | WIT-011 | DONE | Create 013_witness_storage.sql migration |
|
||||
| 16 | WIT-012 | DONE | Create PostgresWitnessRepository + IWitnessRepository |
|
||||
| 17 | WIT-013 | DONE | Add UsesBlake3HashForDefaultProfile test to RichGraphWriterTests |
|
||||
| 18 | WIT-014 | DONE | Add PathWitnessBuilderTests |
|
||||
| 19 | WIT-015 | DONE | Create docs/contracts/witness-v1.md |
|
||||
|
||||
---
|
||||
|
||||
## Unblock Task Notes (WIT-007A..WIT-007D)
|
||||
|
||||
### WIT-007A: ReachabilityAnalyzer → witness output contract
|
||||
- **Goal:** define the exact path output shape (entrypoint → sink), including stable ordering and caps (max depth/path count) so witness generation is deterministic.
|
||||
- **Touchpoints (expected):** `src/Scanner/__Libraries/StellaOps.Scanner.CallGraph/Analysis/ReachabilityAnalyzer.cs` and `src/Scanner/__Tests/StellaOps.Scanner.CallGraph.Tests/` (fixtures + determinism assertions).
|
||||
- **Evidence:** fixture graphs + expected path lists committed and validated by tests.
|
||||
|
||||
### WIT-007B: ReachabilityAnalyzer refactor (sink-aware + path export)
|
||||
- **Acceptance criteria (minimum):** analyzer accepts explicit sinks and returns deterministic path(s) per reachable sink without breaking existing tests/behaviour.
|
||||
|
||||
### WIT-007C: Witness predicate + DSSE payloadType constants
|
||||
- **Goal:** remove ambiguity about predicate URI/media type; Scanner/Attestor must sign/verify the same bytes.
|
||||
- **Touchpoints (expected):** `src/Attestor/StellaOps.Attestor/Predicates/` and `docs/contracts/witness-v1.md`.
|
||||
|
||||
### WIT-007D: DSSE signing + verification for witnesses
|
||||
- **Preferred implementation:** use `src/Attestor/StellaOps.Attestor.Envelope/` (serializer + `EnvelopeSignatureService`) for Ed25519 first.
|
||||
- **Evidence:** golden fixture payload + DSSE envelope + public key, plus unit tests proving deterministic serialization and successful verification.
|
||||
|
||||
---
|
||||
|
||||
@@ -345,7 +369,7 @@ public static class WitnessPredicates
|
||||
- [x] All existing RichGraph tests pass
|
||||
- [x] PathWitness model serializes correctly
|
||||
- [x] PathWitnessBuilder generates valid witnesses
|
||||
- [ ] DSSE signatures verify correctly (BLOCKED: WIT-009)
|
||||
- [ ] DSSE signatures verify correctly (BLOCKED: WIT-009; blocked on WIT-007C/WIT-007D)
|
||||
- [x] `/witness/{id}` endpoint returns witness JSON
|
||||
- [x] Documentation complete
|
||||
|
||||
@@ -358,8 +382,8 @@ public static class WitnessPredicates
|
||||
| WIT-DEC-001 | Use Blake3.NET library | Well-tested, MIT license |
|
||||
| WIT-DEC-002 | Store witnesses in Postgres JSONB | Flexible queries, no separate store |
|
||||
| WIT-DEC-003 | Ed25519 signatures only | Simplicity, Ed25519 is default for DSSE |
|
||||
| WIT-DEC-004 | Defer ReachabilityAnalyzer integration | Requires understanding of call flow; new sprint needed |
|
||||
| WIT-DEC-005 | Defer DSSE signing to Attestor sprint | DSSE signing belongs in Attestor module |
|
||||
| WIT-DEC-004 | Convert ReachabilityAnalyzer blocker into explicit tasks | Track contract+refactor as WIT-007A/WIT-007B; keep WIT-008 BLOCKED until complete |
|
||||
| WIT-DEC-005 | Convert DSSE signing blocker into explicit tasks | Track predicate+sign/verify as WIT-007C/WIT-007D; keep WIT-009 BLOCKED until complete |
|
||||
|
||||
| Risk | Likelihood | Impact | Mitigation |
|
||||
|------|------------|--------|------------|
|
||||
@@ -381,3 +405,4 @@ public static class WitnessPredicates
|
||||
| 2025-12-18 | Completed WIT-010: Created WitnessEndpoints.cs with GET /witnesses/{id}, list (by scan/cve/graphHash), by-hash, verify endpoints | Agent |
|
||||
| 2025-12-18 | Registered MapWitnessEndpoints() in Scanner.WebService Program.cs | Agent |
|
||||
| 2025-12-18 | Completed WIT-013: Added UsesBlake3HashForDefaultProfile test to RichGraphWriterTests.cs | Agent |
|
||||
| 2025-12-18 | Added unblock tasks WIT-007A..WIT-007D and updated WIT-008/WIT-009 dependencies accordingly. | Project Mgmt |
|
||||
|
||||
@@ -101,17 +101,17 @@ Before starting, read:
|
||||
| 11 | SURF-011 | TODO | Implement PythonAstFingerprinter |
|
||||
| 12 | SURF-012 | TODO | Create MethodKey normalizer per ecosystem |
|
||||
| 13 | SURF-013 | DONE | Create MethodDiffEngine service |
|
||||
| 14 | SURF-014 | TODO | Create 011_vuln_surfaces.sql migration |
|
||||
| 14 | SURF-014 | DONE | Create 014_vuln_surfaces.sql migration |
|
||||
| 15 | SURF-015 | DONE | Create VulnSurface, VulnSurfaceSink models |
|
||||
| 16 | SURF-016 | TODO | Create PostgresVulnSurfaceRepository |
|
||||
| 16 | SURF-016 | DONE | Create PostgresVulnSurfaceRepository |
|
||||
| 17 | SURF-017 | DONE | Create VulnSurfaceBuilder orchestrator service |
|
||||
| 18 | SURF-018 | DONE | Create IVulnSurfaceBuilder interface |
|
||||
| 19 | SURF-019 | TODO | Add surface builder metrics |
|
||||
| 20 | SURF-020 | TODO | Create NuGetDownloaderTests |
|
||||
| 21 | SURF-021 | TODO | Create CecilFingerprinterTests |
|
||||
| 22 | SURF-022 | TODO | Create MethodDiffEngineTests |
|
||||
| 19 | SURF-019 | DONE | Add surface builder metrics |
|
||||
| 20 | SURF-020 | DONE | Create NuGetDownloaderTests (9 tests) |
|
||||
| 21 | SURF-021 | DONE | Create CecilFingerprinterTests (7 tests) |
|
||||
| 22 | SURF-022 | DONE | Create MethodDiffEngineTests (8 tests) |
|
||||
| 23 | SURF-023 | TODO | Integration test with real CVE (Newtonsoft.Json) |
|
||||
| 24 | SURF-024 | TODO | Create docs/contracts/vuln-surface-v1.md |
|
||||
| 24 | SURF-024 | DONE | Create docs/contracts/vuln-surface-v1.md |
|
||||
|
||||
---
|
||||
|
||||
@@ -447,3 +447,6 @@ Expected Changed Methods:
|
||||
| Date (UTC) | Update | Owner |
|
||||
|---|---|---|
|
||||
| 2025-12-18 | Created sprint from advisory analysis | Agent |
|
||||
| 2025-12-18 | Created CecilMethodFingerprinterTests.cs (7 tests) and MethodDiffEngineTests.cs (8 tests). 12/24 tasks DONE. All 26 VulnSurfaces tests pass. | Agent |
|
||||
| 2025-12-18 | Created NuGetPackageDownloaderTests.cs (9 tests). Fixed IVulnSurfaceRepository interface/implementation mismatch. Added missing properties to VulnSurfaceSink model. 19/24 tasks DONE. All 35 VulnSurfaces tests pass. | Agent |
|
||||
| 2025-12-18 | Created VulnSurfaceMetrics.cs with counters, histograms, and gauges. Integrated metrics into VulnSurfaceBuilder. 20/24 tasks DONE. | Agent |
|
||||
Reference in New Issue
Block a user