Skip to content

Commit ceb4c7d

Browse files
authored
fix: health score total with sum, instead of mean (#4532)
Signed-off-by: Joana Maia <jmaia@contractor.linuxfoundation.org>
1 parent cde5fa1 commit ceb4c7d

4 files changed

Lines changed: 21 additions & 9 deletions

File tree

services/libs/tinybird/datasources/project_insights_copy_ds.datasource

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ DESCRIPTION >
3232
- `activeContributorsPrevious365Days` column is the unique count of active contributors in the previous 365 days (365-730 days ago).
3333
- `activeOrganizationsPrevious365Days` column is the unique count of active organizations in the previous 365 days (365-730 days ago).
3434
- `status` column is the current status of the project (e.g., 'active', 'archived').
35-
- `healthScoreV2` column is the Akrites-methodology composite health score (0-100). For project records (`type='project'`): median (`quantileExact(0.5)`) of per-repo scores across the project's enabled, non-excluded repos; null when no such repos exist or all have null scores. For repo records (`type='repo'`): per-repo score passed through from `health_score_v2_repo_copy_ds`. Distinct from the legacy `healthScore` column (community/contributor-based).
35+
- `healthScoreV2` column is the Akrites-methodology composite health score (0-100). For project records (`type='project'`): sum of the three per-category medians (maintainerHealthScoreV2 + securitySupplyChainScoreV2 + developmentActivityScoreV2), null-guarded per IN-1248 (null when fewer than 2 categories are present). For repo records (`type='repo'`): per-repo score passed through from `health_score_v2_repo_copy_ds`. Distinct from the legacy `healthScore` column (community/contributor-based).
3636
- `healthLabel` column buckets `healthScoreV2`: 'excellent' (85+), 'healthy' (70-84), 'fair' (50-69), 'concerning' (30-49), 'critical' (<30). Lowercase, matches `ossPackages_enriched_ds.healthLabel` convention.
3737
- `lifecycleLabel` column is the project's aggregated maintenance state across its packages, using best-state-wins precedence (active > stable > declining > abandoned > archived) over `ossPackages_enriched_ds.lifecycleLabel`.
3838
- `impactScore` column is the average Osprey criticality `impact` (0-100) across the project's packages. Null when the project has no linked package data.

services/libs/tinybird/pipes/project_insights.pipe

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ DESCRIPTION >
1313
- `page`: Optional integer for pagination offset calculation, defaults to 0
1414
- Response: Project records with all insights metrics including achievements as array of (leaderboardType, rank, totalCount) tuples
1515
- `healthScoreV2`, `healthLabel`, `lifecycleLabel`, `impactScore`, `impactLabel` are the Akrites-methodology fields (see `project_insights_copy_ds` for band definitions); may be null when the project has no linked package data. `healthScoreV2` is distinct from the legacy `healthScore` field.
16-
- `maintainerHealthScoreV2` (0-40), `securitySupplyChainScoreV2` (0-35), `developmentActivityScoreV2` (0-25) are the project-level rollup of the Health Score v2 category breakdown (IN-1212) — independent medians (`quantileExact(0.5)`) over the same enabled, non-excluded repo set as `healthScoreV2`; they do not necessarily sum to `healthScoreV2`. Null when no repo in the project has a value for that category.
16+
- `maintainerHealthScoreV2` (0-40), `securitySupplyChainScoreV2` (0-35), `developmentActivityScoreV2` (0-25) are the project-level rollup of the Health Score v2 category breakdown (IN-1212) — independent medians (`quantileExact(0.5)`) over the project's enabled, non-excluded repos. For project records, `healthScoreV2` is their sum (null-guarded per IN-1248). Null when no repo in the project has a value for that category.
1717

1818
TAGS "Insights, Widget", "Project"
1919

services/libs/tinybird/pipes/project_insights_copy.pipe

Lines changed: 18 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -90,7 +90,8 @@ DESCRIPTION >
9090
Lifecycle, Health Score v2, and Impact Score all rolled up to project level from the pre-computed
9191
per-repo values in health_score_v2_repo_copy_ds (materialized by health_score_v2.pipe — the
9292
expensive per-signal joins run there as their own copy job, not inline here). Per spec section 5/6:
93-
- healthScoreV2: exact median (`quantileExact(0.5)`) across the project's enabled, non-excluded repos.
93+
- healthScoreV2: sum of the three per-category medians (maintainer + security + development), null-guarded
94+
per IN-1248 (NULL when fewer than 2 categories are present). See the node SQL for the full expression.
9495
- lifecycleLabelV2: best-state-wins (active > stable > declining > inert > abandoned > archived), with
9596
NULL (no usable signal, see health_score_v2_lifecycle.pipe) as the most-cautious outcome.
9697
`groupArray` silently drops NULL entries, so a project with at least one repo in a real state
@@ -111,16 +112,27 @@ DESCRIPTION >
111112
- impactScoreRaw: MAX across the project's repos (each repo's own value is already a MAX over its
112113
published packages) — matches the spec's "MAX(packages.impact) over packages published by any
113114
repo in the project," since max-of-maxes = max-over-all.
115+
- healthScoreV2: sum of the three per-category medians below, null-guarded per IN-1248 (NULL when
116+
fewer than 2 categories are present). `quantileExactOrNull` is used instead of `quantileExact` so
117+
the guard and coalesce can see NULL explicitly — `quantileExact` returns 0 on an empty set, which
118+
would defeat the "< 2 categories → NULL" rule.
114119
- maintainerHealthScoreV2 / securitySupplyChainScoreV2 / developmentActivityScoreV2 (IN-1212):
115-
independent per-category medians (`quantileExact(0.5)`) over repos where that category is non-NULL —
116-
their repo set differs from healthScoreV2 (which includes repos with one imputed category), so they
117-
do not necessarily reconcile with the project score. NULL when every repo is NULL for a category.
120+
independent per-category medians (`quantileExact(0.5)`) over repos where that category is non-NULL.
121+
NULL when every repo is NULL for a category.
118122

119123
SQL >
120124
SELECT
121125
rep.insightsProjectId AS insightsProjectId,
122-
quantileExact(0.5)
123-
(hv2.healthScoreV2) AS healthScoreV2,
126+
if(
127+
(quantileExactOrNull(0.5)(hv2.maintainerHealthScoreV2) IS NOT NULL)
128+
+ (quantileExactOrNull(0.5)(hv2.securitySupplyChainScoreV2) IS NOT NULL)
129+
+ (quantileExactOrNull(0.5)(hv2.developmentActivityScoreV2) IS NOT NULL)
130+
< 2,
131+
NULL,
132+
coalesce(quantileExactOrNull(0.5)(hv2.maintainerHealthScoreV2), 0)
133+
+ coalesce(quantileExactOrNull(0.5)(hv2.securitySupplyChainScoreV2), 0)
134+
+ coalesce(quantileExactOrNull(0.5)(hv2.developmentActivityScoreV2), 0)
135+
) AS healthScoreV2,
124136
if(
125137
empty(groupArray(hv2.lifecycleLabelV2)),
126138
NULL,

services/libs/tinybird/pipes/project_repo_insights.pipe

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ DESCRIPTION >
1212
- `page`: Optional integer for pagination offset calculation, defaults to 0
1313
- Response: Project and repository records with insights metrics
1414
- `healthScoreV2`, `healthLabel`, `lifecycleLabel`, `impactScore`, `impactLabel` are the Akrites-methodology fields (see `project_insights_copy_ds` for band definitions); may be null when the record has no linked package data. `healthScoreV2` is distinct from the legacy `healthScore` field.
15-
- `maintainerHealthScoreV2` (0-40), `securitySupplyChainScoreV2` (0-35), `developmentActivityScoreV2` (0-25) are the Health Score v2 category breakdown (IN-1212). For project records: independent medians (`quantileExact(0.5)`) over the project's enabled, non-excluded repos — they do not necessarily sum to `healthScoreV2`. For repo records: per-repo values passed through from `health_score_v2_repo_copy_ds`; they sum to `healthScoreV2` only when all three categories are available; missing categories are imputed at the population median rate (IN-1249). Null when the record has no value for that category.
15+
- `maintainerHealthScoreV2` (0-40), `securitySupplyChainScoreV2` (0-35), `developmentActivityScoreV2` (0-25) are the Health Score v2 category breakdown (IN-1212). For project records: independent medians (`quantileExact(0.5)`) over the project's enabled, non-excluded repos; `healthScoreV2` is their sum (null-guarded per IN-1248). For repo records: per-repo values passed through from `health_score_v2_repo_copy_ds`; they sum to `healthScoreV2` only when all three categories are available; missing categories are imputed at the population median rate (IN-1249). Null when the record has no value for that category.
1616

1717
TAGS "Insights, Widget", "Project", "Repository"
1818

0 commit comments

Comments
 (0)