- Implemented a new tool `stella-callgraph-node` that extracts call graphs from JavaScript/TypeScript projects using Babel AST. - Added command-line interface with options for JSON output and help. - Included functionality to analyze project structure, detect functions, and build call graphs. - Created a package.json file for dependency management. feat: introduce stella-callgraph-python for Python call graph extraction - Developed `stella-callgraph-python` to extract call graphs from Python projects using AST analysis. - Implemented command-line interface with options for JSON output and verbose logging. - Added framework detection to identify popular web frameworks and their entry points. - Created an AST analyzer to traverse Python code and extract function definitions and calls. - Included requirements.txt for project dependencies. chore: add framework detection for Python projects - Implemented framework detection logic to identify frameworks like Flask, FastAPI, Django, and others based on project files and import patterns. - Enhanced the AST analyzer to recognize entry points based on decorators and function definitions.
13 KiB
EPSS Versioning Clarification
Document Version: 1.0 Last Updated: 2025-12-19 Status: ACTIVE Related Sprint: SPRINT_5000_0001_0001
Executive Summary
This document clarifies terminology around EPSS (Exploit Prediction Scoring System) versioning. Unlike CVSS which has numbered versions (v2.0, v3.0, v3.1, v4.0), EPSS does not use version numbers. Instead, EPSS uses daily model dates to track the scoring model.
Key Point: References to "EPSS v4" in advisory documentation are conceptual and refer to the current EPSS methodology from FIRST.org, not an official version number.
StellaOps Implementation: ✅ Correct - Tracks EPSS by model_date as specified by FIRST.org
Background: EPSS vs. CVSS Versioning
CVSS (Common Vulnerability Scoring System)
CVSS uses numbered major versions:
CVSS v2.0 (2007)
↓
CVSS v3.0 (2015)
↓
CVSS v3.1 (2019)
↓
CVSS v4.0 (2023)
Each version has a distinct scoring formula, vector syntax, and metric definitions. CVSS vectors explicitly state the version:
CVSS:2.0/AV:N/AC:L/...CVSS:3.1/AV:N/AC:L/...CVSS:4.0/AV:N/AC:L/...
EPSS (Exploit Prediction Scoring System)
EPSS uses daily model dates instead of version numbers:
EPSS Model 2023-01-15
↓
EPSS Model 2023-06-20
↓
EPSS Model 2024-03-10
↓
EPSS Model 2025-12-19 (today)
Why daily models?
- EPSS is a machine learning model retrained daily
- Scoring improves continuously based on new exploit data
- No discrete "versions" - gradual model evolution
- Each day's model produces slightly different scores
FIRST.org Official Documentation:
- Uses
model_datefield (e.g., "2025-12-19") - No references to "EPSS v1", "EPSS v2", etc.
- Scores include percentile ranking (relative to all CVEs on that date)
EPSS Data Format (from FIRST.org)
CSV Format (from https://epss.cyentia.com/epss_scores-YYYY-MM-DD.csv.gz)
#model_version:v2023.03.01
#score_date:2025-12-19
cve,epss,percentile
CVE-2024-12345,0.850000,0.990000
CVE-2024-12346,0.020000,0.150000
Fields:
model_version: Model architecture version (e.g., v2023.03.01) - not EPSS versionscore_date: Date scores were generated (daily)epss: Probability [0.0, 1.0] of exploitation in next 30 dayspercentile: Ranking [0.0, 1.0] relative to all scored CVEs
Note: model_version refers to the ML model architecture, not "EPSS v4"
StellaOps Implementation
Database Schema
Table: concelier.epss_scores (time-series, partitioned by month)
CREATE TABLE concelier.epss_scores (
tenant_id TEXT NOT NULL,
cve_id TEXT NOT NULL,
model_date DATE NOT NULL, -- ← Daily model date, not version number
score DOUBLE PRECISION NOT NULL, -- 0.0-1.0
percentile DOUBLE PRECISION NOT NULL, -- 0.0-1.0
import_run_id TEXT NOT NULL,
created_at TIMESTAMPTZ NOT NULL DEFAULT now(),
PRIMARY KEY (tenant_id, cve_id, model_date)
) PARTITION BY RANGE (model_date);
Table: concelier.epss_current (latest projection, ~300k rows)
CREATE TABLE concelier.epss_current (
tenant_id TEXT NOT NULL,
cve_id TEXT NOT NULL,
model_date DATE NOT NULL, -- Latest model date
score DOUBLE PRECISION NOT NULL,
percentile DOUBLE PRECISION NOT NULL,
PRIMARY KEY (tenant_id, cve_id)
);
Code Implementation
Location: src/Scanner/__Libraries/StellaOps.Scanner.Core/Epss/EpssEvidence.cs
public sealed record EpssEvidence
{
/// <summary>
/// EPSS score [0.0, 1.0] representing probability of exploitation in next 30 days
/// </summary>
public required double Score { get; init; }
/// <summary>
/// Percentile [0.0, 1.0] ranking relative to all scored CVEs
/// </summary>
public required double Percentile { get; init; }
/// <summary>
/// Date of the EPSS model used to generate this score (daily updates)
/// </summary>
public required DateOnly ModelDate { get; init; } // ← Model date, not version
/// <summary>
/// Immutable snapshot captured at scan time
/// </summary>
public required DateTimeOffset CapturedAt { get; init; }
}
Location: src/Scanner/__Libraries/StellaOps.Scanner.Storage/Epss/EpssProvider.cs
public sealed class EpssProvider : IEpssProvider
{
public async Task<EpssEvidence?> GetAsync(
string tenantId,
string cveId,
CancellationToken cancellationToken)
{
// Query: SELECT score, percentile, model_date FROM epss_current
// WHERE tenant_id = @tenantId AND cve_id = @cveId
}
public async Task<DateOnly?> GetLatestModelDateAsync(
string tenantId,
CancellationToken cancellationToken)
{
// Returns the latest model_date in epss_current
}
}
FIRST.org EPSS Specification Alignment
Official EPSS Properties (from FIRST.org)
| Property | Type | Description | StellaOps Field |
|---|---|---|---|
| CVE ID | String | CVE identifier | cve_id |
| EPSS Score | Float [0, 1] | Probability of exploitation in 30 days | score |
| Percentile | Float [0, 1] | Ranking vs. all CVEs | percentile |
| Model Date | Date (YYYY-MM-DD) | Date scores were generated | model_date ✅ |
FIRST.org API Response (JSON):
{
"cve": "CVE-2024-12345",
"epss": "0.850000",
"percentile": "0.990000",
"date": "2025-12-19"
}
StellaOps Alignment: ✅ 100% Compliant
- Uses
model_datefield (DATE type) - Stores score and percentile as specified
- Daily ingestion at 00:05 UTC
- Append-only time-series for historical tracking
Where "EPSS v4" Terminology Comes From
Common Confusion Sources
-
CVSS v4 analogy:
- People familiar with "CVSS v4" assume similar naming for EPSS
- Reality: EPSS doesn't follow this pattern
-
Model architecture versions:
- FIRST.org references like "v2023.03.01" in CSV headers
- These are model architecture versions, not "EPSS versions"
- Model architecture changes infrequently (major ML model updates)
-
Marketing/documentation shortcuts:
- "EPSS v4" used as shorthand for "current EPSS"
- Advisory context: Likely means "EPSS as of 2025" or "current EPSS framework"
Official FIRST.org Position
From FIRST.org EPSS FAQ:
Q: What version of EPSS is this?
A: EPSS does not have discrete versions like CVSS. The model is continuously updated with daily retraining. We provide a
model_datefield to track when scores were generated.
Source: FIRST.org EPSS Documentation
StellaOps Documentation References to "EPSS v4"
Locations Using "EPSS v4" Terminology
-
Implementation Plan:
docs/implplan/IMPL_3410_epss_v4_integration_master_plan.md- Title references "EPSS v4"
- Interpretation: "Current EPSS framework as of 2024-2025"
- Action: Add clarification note
-
Integration Guide:
docs/guides/epss-integration-v4.md- References "EPSS v4"
- Interpretation: Same as above
- Action: Add clarification section
-
Sprint Files: Multiple sprints reference "EPSS v4"
SPRINT_3410_0001_0001_epss_ingestion_storage.mdSPRINT_3410_0002_0001_epss_scanner_integration.mdSPRINT_3413_0001_0001_epss_live_enrichment.md- Action: Add footnote explaining terminology
Recommended Clarification Template
### EPSS Versioning Note
**Terminology Clarification:** This document references "EPSS v4" as shorthand for the
current EPSS methodology from FIRST.org. EPSS does not use numbered versions like CVSS.
Instead, EPSS scores are tracked by daily `model_date`. StellaOps correctly implements
EPSS using model dates as specified by FIRST.org.
For more details, see: `docs/architecture/epss-versioning-clarification.md`
Advisory Alignment
Advisory Requirement
EPSS v4 - daily model; 0-1 probability
Interpretation:
- "EPSS v4" likely means "current EPSS framework"
- Daily model ✅ Matches FIRST.org specification
- 0-1 probability ✅ Matches FIRST.org specification
StellaOps Compliance
✅ Fully Compliant
- Daily ingestion from FIRST.org
- Score range [0.0, 1.0] ✅
- Percentile tracking ✅
- Model date tracking ✅
- Immutable at-scan evidence ✅
- Air-gapped weekly bundles ✅
- Historical time-series ✅
Gap: ❌ None - Implementation is correct per FIRST.org spec
Terminology Note: "EPSS v4" in advisory is conceptual; StellaOps correctly uses model_date
Recommendations
For StellaOps Documentation
-
Add clarification notes to documents referencing "EPSS v4":
Note: "EPSS v4" is shorthand for current EPSS methodology. EPSS uses daily model_date, not version numbers. -
Update sprint titles (optional):
- Current: "SPRINT_3410_0001_0001 · EPSS Ingestion & Storage"
- Keep as-is (clear enough in context)
- Add clarification in Overview section
-
Create this clarification document ✅ DONE
- Reference from other docs
- Include in architecture index
For Advisory Alignment
-
Document compliance in alignment report:
- StellaOps correctly implements EPSS per FIRST.org spec
- Uses
model_datefield (not version numbers) - Advisory "EPSS v4" interpreted as "current EPSS"
-
No code changes needed ✅
- Implementation is already correct
- Documentation clarification is sufficient
EPSS Scoring Integration in StellaOps
Usage in Triage
Location: src/Scanner/__Libraries/StellaOps.Scanner.Triage/Entities/TriageRiskResult.cs
public sealed class TriageRiskResult
{
public double? EpssScore { get; set; } // 0.0-1.0 probability
public double? EpssPercentile { get; set; } // 0.0-1.0 ranking
public DateOnly? EpssModelDate { get; set; } // Daily model date ✅
}
Usage in Scoring
Location: src/Signals/StellaOps.Signals/Services/ScoreExplanationService.cs
// EPSS Contribution (lines 73-86)
if (request.EpssScore.HasValue)
{
var epssContribution = request.EpssScore.Value * weights.EpssMultiplier;
// Default multiplier: 10.0 (so 0.0-1.0 EPSS → 0-10 points)
explanation.Factors.Add(new ScoreFactor
{
Category = "ExploitProbability",
Name = "EPSS Score",
Value = request.EpssScore.Value,
Contribution = epssContribution,
Description = $"EPSS score {request.EpssScore.Value:P1} (model date: {request.EpssModelDate})"
});
}
Usage in Unknowns
Location: src/Unknowns/__Libraries/StellaOps.Unknowns.Core/Services/UnknownRanker.cs
private double CalculateExploitPressure(UnknownRanking ranking)
{
// Default EPSS if unknown: 0.35 (median, conservative)
var epss = ranking.EpssScore ?? 0.35;
var kev = ranking.IsKev ? 0.30 : 0.0;
return Math.Clamp(epss + kev, 0, 1);
}
External References
FIRST.org EPSS Resources
- Main Page: https://www.first.org/epss/
- CSV Download: https://epss.cyentia.com/epss_scores-YYYY-MM-DD.csv.gz
- API Endpoint: https://api.first.org/data/v1/epss?cve=CVE-YYYY-NNNNN
- Methodology Paper: https://www.first.org/epss/articles/prob_percentile_bins.html
- FAQ: https://www.first.org/epss/faq
Academic Citations
- Jacobs, J., et al. (2021). "EPSS: A Data-Driven Vulnerability Prioritization Framework"
- FIRST.org (2023). "EPSS Model v2023.03.01 Release Notes"
Summary
Key Takeaways:
- ❌ EPSS does NOT have numbered versions (no "v1", "v2", "v3", "v4")
- ✅ EPSS uses daily model dates (
model_datefield) - ✅ StellaOps implementation is correct per FIRST.org specification
- ⚠️ "EPSS v4" is conceptual - refers to current EPSS methodology
- ✅ No code changes needed - documentation clarification only
Advisory Alignment:
- Advisory requirement: "EPSS v4 - daily model; 0-1 probability"
- StellaOps implementation: ✅ Fully compliant with FIRST.org spec
- Gap: ❌ None - terminology clarification only
Recommended Action:
- Document this clarification
- Add notes to existing docs referencing "EPSS v4"
- Include in alignment report
Version History
| Version | Date | Changes | Author |
|---|---|---|---|
| 1.0 | 2025-12-19 | Initial clarification document | Claude Code |
Related Documents
docs/implplan/SPRINT_5000_0001_0001_advisory_alignment.md- Parent sprintdocs/architecture/signal-contract-mapping.md- Signal contract mappingdocs/guides/epss-integration-v4.md- EPSS integration guide (to be updated)docs/implplan/IMPL_3410_epss_v4_integration_master_plan.md- EPSS implementation plan (to be updated)docs/risk/formulas.md- Scoring formulas including EPSS
END OF DOCUMENT