From 40408fb351b89506ae30c9693b5e405db79a5c01 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ga=C5=A1per=20Grom?= Date: Mon, 31 Aug 2026 10:46:02 +0100 Subject: [PATCH 1/3] fix: track UNKNOWN/LOW severity open vulns in health score v2 security pipeline (IN-1255) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Widens openModerates to severity IN ('MEDIUM','LOW') and adds a new openUnknowns bucket (severity NOT IN the four known values), threaded through health_score_v2_security -> health_score_v2_signal_detail -> project_insights_health_breakdown(_copy) so open vulns of every severity land in exactly one bucket instead of LOW/UNKNOWN falling through unnoticed. Signed-off-by: Gašper Grom --- .../health_score_v2_security_ds.datasource | 6 ++++-- .../health_score_v2_signal_detail_ds.datasource | 3 ++- .../project_insights_health_breakdown_ds.datasource | 3 ++- .../tinybird/pipes/health_score_v2_security.pipe | 13 ++++++++++++- .../pipes/health_score_v2_signal_detail.pipe | 1 + .../pipes/project_insights_health_breakdown.pipe | 1 + .../project_insights_health_breakdown_copy.pipe | 11 ++++++----- 7 files changed, 28 insertions(+), 10 deletions(-) diff --git a/services/libs/tinybird/datasources/health_score_v2_security_ds.datasource b/services/libs/tinybird/datasources/health_score_v2_security_ds.datasource index c376fe98af..e70c7f707e 100644 --- a/services/libs/tinybird/datasources/health_score_v2_security_ds.datasource +++ b/services/libs/tinybird/datasources/health_score_v2_security_ds.datasource @@ -12,8 +12,9 @@ DESCRIPTION > (no data), not scored 0. `openVulnAvailable` is 0 when the repo has never completed a vulnerability scan (see `vulnerability_scans`), so "0 open vulns" isn't conflated with "never scanned". - - `openCriticals`/`openHighs`/`openModerates` (IN-1212) are the raw open-vulnerability counts by - severity; NULL when the repo has no rows in `vulnerabilities`. + - `openCriticals`/`openHighs`/`openModerates`/`openUnknowns` (IN-1212; `openUnknowns` and + `openModerates`'s widened `MEDIUM`/`LOW` predicate added IN-1255) are the raw open-vulnerability + counts by severity; NULL when the repo has no rows in `vulnerabilities`. - `scorecardScore` (IN-1212) is the raw OpenSSF Scorecard aggregate score (0-10 as a string, passed through from `repos.scorecardScore`; empty string when unavailable). - `securityPolicyEnabled`/`branchProtectionEnabled`/`branchProtectionRequiredReviews`/ @@ -30,6 +31,7 @@ SCHEMA > `openCriticals` Nullable(UInt64), `openHighs` Nullable(UInt64), `openModerates` Nullable(UInt64), + `openUnknowns` Nullable(UInt64), `scorecardScorePts` UInt8, `scorecardAvailable` UInt8, `scorecardScore` String, diff --git a/services/libs/tinybird/datasources/health_score_v2_signal_detail_ds.datasource b/services/libs/tinybird/datasources/health_score_v2_signal_detail_ds.datasource index fa4fffb0c0..5ba71a8a06 100644 --- a/services/libs/tinybird/datasources/health_score_v2_signal_detail_ds.datasource +++ b/services/libs/tinybird/datasources/health_score_v2_signal_detail_ds.datasource @@ -10,7 +10,7 @@ DESCRIPTION > `responsivenessAvailable`, `medianPrResponseS`, `medianIssueResponseS`, `isGerrit`, `isExcluded` — see `health_score_v2_maintainer_ds` for definitions. - Security signals: `openVulnScore`, `openVulnAvailable`, `openCriticals`, `openHighs`, `openModerates`, - `scorecardScorePts`, `scorecardAvailable`, `scorecardScore`, `securityPracticesScore`, + `openUnknowns`, `scorecardScorePts`, `scorecardAvailable`, `scorecardScore`, `securityPracticesScore`, `securityPracticesAvailable`, `securityPolicyEnabled`, `branchProtectionEnabled`, `branchProtectionRequiredReviews`, `branchProtectionRequiresStatusChecks`, `branchProtectionAllowsForcePush`, `dependencyHealthScore`, `dependencyHealthAvailable`, @@ -43,6 +43,7 @@ SCHEMA > `openCriticals` Nullable(UInt64), `openHighs` Nullable(UInt64), `openModerates` Nullable(UInt64), + `openUnknowns` Nullable(UInt64), `scorecardScorePts` Nullable(UInt8), `scorecardAvailable` Nullable(UInt8), `scorecardScore` Nullable(String), diff --git a/services/libs/tinybird/datasources/project_insights_health_breakdown_ds.datasource b/services/libs/tinybird/datasources/project_insights_health_breakdown_ds.datasource index 2e15838b30..9781eed92b 100644 --- a/services/libs/tinybird/datasources/project_insights_health_breakdown_ds.datasource +++ b/services/libs/tinybird/datasources/project_insights_health_breakdown_ds.datasource @@ -15,7 +15,7 @@ DESCRIPTION > `medianIssueResponseS` (avg), `isGerrit` (min), `isExcluded` (min), `busFactorScoreActivityWeightedMean` (activity-weighted mean of bus-factor score across repos). - Security signals: `openVulnScore` (avg), `openVulnAvailable` (max), - `openCriticals`/`openHighs`/`openModerates` (max), + `openCriticals`/`openHighs`/`openModerates`/`openUnknowns` (max), `scorecardScorePts` (avg), `scorecardAvailable` (max), `scorecardScore` (avg, cast from the raw String), `securityPracticesScore` (avg), `securityPracticesAvailable` (max), `securityPolicyEnabled`/`branchProtectionEnabled`/`branchProtectionRequiredReviews`/ @@ -49,6 +49,7 @@ SCHEMA > `openCriticals` Nullable(UInt64), `openHighs` Nullable(UInt64), `openModerates` Nullable(UInt64), + `openUnknowns` Nullable(UInt64), `scorecardScorePts` Nullable(Float64), `scorecardAvailable` Nullable(UInt8), `scorecardScore` Nullable(Float64), diff --git a/services/libs/tinybird/pipes/health_score_v2_security.pipe b/services/libs/tinybird/pipes/health_score_v2_security.pipe index 94fed83c39..0af9ff2fc5 100644 --- a/services/libs/tinybird/pipes/health_score_v2_security.pipe +++ b/services/libs/tinybird/pipes/health_score_v2_security.pipe @@ -21,6 +21,10 @@ DESCRIPTION > now recovered via `* 8.0/7` scaling) distributed as openVuln +2, scorecard +1, practices +1 (via 8.0/7), deps +2 → 12/8/8/7. Rescale factor is now 1.0 for fully-covered repos. Category max and Layer 2 weight unchanged. + - UNKNOWN/LOW severity blind spot fix (2026-08-31, IN-1255): `openModerates`'s predicate widened + from `severity = 'MEDIUM'` to `severity IN ('MEDIUM', 'LOW')`, and a new `openUnknowns` bucket + added (`severity NOT IN ('CRITICAL', 'HIGH', 'MEDIUM', 'LOW')`) so every open vuln lands in + exactly one bucket — previously LOW and UNKNOWN severities fell through every bucket entirely. NODE health_score_v2_security_calc SQL > @@ -36,6 +40,7 @@ SQL > openCriticals, openHighs, openModerates, + openUnknowns, scorecardScorePts, scorecardAvailable, scorecardScore, @@ -59,6 +64,7 @@ SQL > openCriticals, openHighs, openModerates, + openUnknowns, scorecardScorePts, scorecardAvailable, scorecardScore, @@ -101,6 +107,7 @@ SQL > vc.openCriticals AS openCriticals, vc.openHighs AS openHighs, vc.openModerates AS openModerates, + vc.openUnknowns AS openUnknowns, toUInt8( multiIf( toFloat64OrZero(rd.scorecardScore) >= 7, @@ -173,7 +180,11 @@ SQL > repoUrl, countIf(status = 'OPEN' AND severity = 'CRITICAL') AS openCriticals, countIf(status = 'OPEN' AND severity = 'HIGH') AS openHighs, - countIf(status = 'OPEN' AND severity = 'MEDIUM') AS openModerates + countIf(status = 'OPEN' AND severity IN ('MEDIUM', 'LOW')) AS openModerates, + countIf( + status = 'OPEN' + AND severity NOT IN ('CRITICAL', 'HIGH', 'MEDIUM', 'LOW') + ) AS openUnknowns FROM vulnerabilities FINAL GROUP BY repoUrl ) AS vc diff --git a/services/libs/tinybird/pipes/health_score_v2_signal_detail.pipe b/services/libs/tinybird/pipes/health_score_v2_signal_detail.pipe index c1e39dece3..9827d34cb6 100644 --- a/services/libs/tinybird/pipes/health_score_v2_signal_detail.pipe +++ b/services/libs/tinybird/pipes/health_score_v2_signal_detail.pipe @@ -39,6 +39,7 @@ SQL > s.openCriticals AS openCriticals, s.openHighs AS openHighs, s.openModerates AS openModerates, + s.openUnknowns AS openUnknowns, s.scorecardScorePts AS scorecardScorePts, s.scorecardAvailable AS scorecardAvailable, s.scorecardScore AS scorecardScore, diff --git a/services/libs/tinybird/pipes/project_insights_health_breakdown.pipe b/services/libs/tinybird/pipes/project_insights_health_breakdown.pipe index a6aadfae61..6614818157 100644 --- a/services/libs/tinybird/pipes/project_insights_health_breakdown.pipe +++ b/services/libs/tinybird/pipes/project_insights_health_breakdown.pipe @@ -37,6 +37,7 @@ SQL > openCriticals, openHighs, openModerates, + openUnknowns, scorecardScorePts, scorecardAvailable, scorecardScore, diff --git a/services/libs/tinybird/pipes/project_insights_health_breakdown_copy.pipe b/services/libs/tinybird/pipes/project_insights_health_breakdown_copy.pipe index b8aeeb19fa..77fc3c953f 100644 --- a/services/libs/tinybird/pipes/project_insights_health_breakdown_copy.pipe +++ b/services/libs/tinybird/pipes/project_insights_health_breakdown_copy.pipe @@ -29,11 +29,11 @@ DESCRIPTION > was previously indistinguishable from a genuinely clean repo, both defaulting to a perfect `openVulnScore` of 10. - Count columns (`busFactorCount`, `orgCount`, `openCriticals`, `openHighs`, `openModerates`, - `vulnerableDeps`, `commitsLast6m`, `closed12m`, `opened12m`, `merged12m`, `closedUnmerged12m`, - `branchProtectionRequiredReviews`): `max()` across repos — the most-staffed/most-active/ - most-protected repo is the meaningful project-level signal, matching the precedent set by - `project_insights_impact_breakdown_copy.pipe`'s `directDependents` MAX rollup and bus factor's - own per-repo tiering logic. + `openUnknowns`, `vulnerableDeps`, `commitsLast6m`, `closed12m`, `opened12m`, `merged12m`, + `closedUnmerged12m`, `branchProtectionRequiredReviews`): `max()` across repos — the + most-staffed/most-active/most-protected repo is the meaningful project-level signal, matching the + precedent set by `project_insights_impact_breakdown_copy.pipe`'s `directDependents` MAX rollup + and bus factor's own per-repo tiering logic. - `daysSinceLatest`/`daysBetweenRecent`: `min()`, not `max()` — these are inverse-activity durations (per `health_score_v2_development.pipe`'s own scoring: smaller = more recent/frequent releases = higher score). `max()` here would silently pick the stalest repo as the project-level @@ -93,6 +93,7 @@ SQL > max(sd.openCriticals) AS openCriticals, max(sd.openHighs) AS openHighs, max(sd.openModerates) AS openModerates, + max(sd.openUnknowns) AS openUnknowns, sumIf(sd.scorecardScorePts, sd.scorecardAvailable) / nullIf(countIf(sd.scorecardAvailable), 0) AS scorecardScorePts, max(sd.scorecardAvailable) AS scorecardAvailable, From fedfd9a81ca2b1a7c31e4bed59aa0098fa841b86 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ga=C5=A1per=20Grom?= Date: Mon, 31 Aug 2026 13:46:33 +0100 Subject: [PATCH 2/3] chore: run tbf on health_score_v2_security.pipe IN-1255 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Gašper Grom --- services/libs/tinybird/pipes/health_score_v2_security.pipe | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/services/libs/tinybird/pipes/health_score_v2_security.pipe b/services/libs/tinybird/pipes/health_score_v2_security.pipe index 0af9ff2fc5..66d2787671 100644 --- a/services/libs/tinybird/pipes/health_score_v2_security.pipe +++ b/services/libs/tinybird/pipes/health_score_v2_security.pipe @@ -180,7 +180,9 @@ SQL > repoUrl, countIf(status = 'OPEN' AND severity = 'CRITICAL') AS openCriticals, countIf(status = 'OPEN' AND severity = 'HIGH') AS openHighs, - countIf(status = 'OPEN' AND severity IN ('MEDIUM', 'LOW')) AS openModerates, + countIf( + status = 'OPEN' AND severity IN ('MEDIUM', 'LOW') + ) AS openModerates, countIf( status = 'OPEN' AND severity NOT IN ('CRITICAL', 'HIGH', 'MEDIUM', 'LOW') From 9e49db8af438951fffaa8bf40b685146ee35a62e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ga=C5=A1per=20Grom?= Date: Mon, 31 Aug 2026 17:18:07 +0100 Subject: [PATCH 3/3] fix(review): propagate openUnknowns to repo_health_score_v2_breakdown pipe MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Gašper Grom --- services/libs/tinybird/pipes/repo_health_score_v2_breakdown.pipe | 1 + 1 file changed, 1 insertion(+) diff --git a/services/libs/tinybird/pipes/repo_health_score_v2_breakdown.pipe b/services/libs/tinybird/pipes/repo_health_score_v2_breakdown.pipe index b8f18090dc..f3c23bd306 100644 --- a/services/libs/tinybird/pipes/repo_health_score_v2_breakdown.pipe +++ b/services/libs/tinybird/pipes/repo_health_score_v2_breakdown.pipe @@ -63,6 +63,7 @@ SQL > max(sd.openCriticals) AS openCriticals, max(sd.openHighs) AS openHighs, max(sd.openModerates) AS openModerates, + max(sd.openUnknowns) AS openUnknowns, sumIf(sd.scorecardScorePts, sd.scorecardAvailable) / nullIf(countIf(sd.scorecardAvailable), 0) AS scorecardScorePts, max(sd.scorecardAvailable) AS scorecardAvailable,