Skip to content

feat: add health score v2 to project lists and re-source dependency metrics (IN-1222) - #4920

Merged
gaspergrom merged 3 commits into
mainfrom
feat/IN-1222-health-v2-osi-dependency-source
Oct 13, 2026
Merged

gaspergrom merged 3 commits into
mainfrom
feat/IN-1222-health-v2-osi-dependency-source

Conversation

@gaspergrom

@gaspergrom gaspergrom commented Oct 12, 2026 •

Copy link
Copy Markdown
Contributor

Prod Tinybird already runs this branch, so merge it soon. Until it merges, a tb push of any file this PR changes from main reverts the live change, and nothing warns you.

Summary

  • Adds healthScoreV2, healthLabel, healthScoreV2Normalized and healthMaxScore to the project list. They pass through insights_projects_populated_ds, insightsProjects_filtered and projects_list, and they are appended to the Open Source Index collection, category and category group tuples. Insights reads them for the index pills and sort.
  • Keeps the v1 healthScore column and its tuple slot. Existing readers see no change. crowd.dev PR 3 removes them.
  • Re-sources the dependency metrics in project_insights_copy. Project and repo rows now join the health_score_*_dependency pipes directly. They used to come from health_score_copy_ds and repo_health_score_copy_ds, and the removals later in this series delete those. The repo source had no scheduled prod run since 2026-09-14, so repo values are current again.
  • Keeps the v2 names. The existing healthScore column is non-null, and some projects have no v2 score. Writing v2 into it would need a type change on a heavily read datasource. Writing 0 would show as Critical.
  • The copy job throws and keeps the previous snapshot when contributor or organization dependency counts sum to zero across every project row or every repo row. The COALESCE(..., 0) would otherwise write zeros.
  • Removes no v1 column, pipe or sink. Those removals are the gated follow-ups.

Deploy status

Live in production Tinybird. Both commits on this branch were deployed on 2026-10-12. Merging brings main in line with prod. It does not change prod.

Post-deploy checks in prod:

  • insights_projects_populated_ds.healthScoreV2: 11,158 non-null, sum 695,058. Unchanged.
  • Dependency sums, contributor / organization: projects 31,746 / 14,481; repos 39,644 / 21,111.
  • healthMaxScore: 0 mismatches.
  • project_insights_copy now runs about 237 s (was about 90 s), reads 142 GB and peaks at 2.79 GB. It finishes near 03:04, before the 03:10 readers.

Staging could not run project_insights_copy (staging caps copy pipes at 20) or the OSI pipes (staging collections lack ssoUserId). Prod was the only real test for these pipes.

Deploy steps (run 2026-10-12)

  1. Datasource alter on insights_projects_populated_ds: four appended columns.
  2. Push project_insights_copy, insights_projects_populated_copy, insightsProjects_filtered, projects_list, collections_oss_index, categories_oss_index and category_groups_oss_index.
  3. tbc project_insights_copy, poll to done. Then tbc insights_projects_populated_copy, poll to done.

What breaks if out of order

  • If insights PR 1 reaches a Tinybird without these columns, /api/project returns 500 on the healthScoreV2Normalized sort. Prod has the columns, so insights PR 1 can deploy now.
  • Until insights PR 1 deploys, nothing reads the new fields, and the OSI pages keep showing the v1 score.

Cross-repo order

  1. crowd.dev PR 1 (this PR): live.
  2. insights PR 1: deploys after this PR.
  3. lf-dbt PR 1
  4. lf-dbt PR 2
  5. Sign-off gate, then insights PR 2
  6. lf-dbt PR 3
  7. lf-dbt PR 4
  8. crowd.dev PR 2
  9. crowd-kube connector change (human)
  10. Snowflake DROPs (human)
  11. crowd.dev PR 3
  12. insights PR 3: remove transitional v1 compatibility (chore: remove transitional health score v1 compatibility insights#2376, gated)
  13. crowd.dev PR 4

Related PRs

  • crowd.dev PR 2: remove the v1 health score Snowflake sink (gated)
  • crowd.dev PR 3: remove v1 health score computation and columns from Tinybird (gated)
  • crowd.dev PR 4: remove the v1 repository health score pipes (gated)
  • insights PR 1: show health score v2 in the open source index
  • insights PR 2: remove health score v1 fields and routes (gated)
  • lf-dbt PR 1: expose the v2 sink leg marker on gold project health metrics
  • lf-dbt PR 2: source health score v2 columns from the v2 sink
  • lf-dbt PR 3: drop v1 health score columns from gold, platinum and silver dim (gated)
  • lf-dbt PR 4: remove the v1 health score sink source and silver leg (gated)
  • lfx-self-serve PR (This is a test issue #3465): remove the v1 health band shim
  • crowd-kube connector change: removing the sink topic from the Snowflake connector is a human step (crowd-kube connector runbook, gated). No PR exists yet; the human opens one during that runbook. crowd-kube Add links to dashboard sentiment widget #205 is docs only.

JIRA

IN-1222: Deprecate v1 health score sinks and tables
https://linuxfoundation.atlassian.net/browse/IN-1222

Copilot AI balanced review requested due to automatic review settings October 12, 2026 20:46
@cursor

cursor Bot commented Oct 12, 2026 •

Copy link
Copy Markdown

PR Summary

Medium Risk
Changes heavily read analytics copy pipes and OSS index tuple shapes; the new dependency guard can block project_insights_copy updates if upstream dependency sources are empty.

Overview
Adds Health Score v2 (healthScoreV2, healthLabel, healthScoreV2Normalized, healthMaxScore) to the enriched project datasource and threads them through the projects list filter/sort APIs and Open Source Index pipes (collections, categories, category groups) in top-project tuples. v1 healthScore stays for backward compatibility.

insights_projects_populated_copy now joins project_insights_copy_ds for v2 fields and computes normalized scores; project_insights_copy re-sources contributor and organization dependency from health_score_*_dependency / repo_health_score_*_dependency instead of the legacy health score copy datasources, and fails the copy (keeping the prior snapshot) if dependency counts sum to zero for all project or all repo rows.

Reviewed by Cursor Bugbot for commit 75675a4. Bugbot is set up for automated code reviews on this repo. Configure here.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🔵 Needs a closer look

Production-only validation of a 142 GB scheduled copy change deployed before merge requires human operational sign-off.

0 open findings

What changed in this PR

Adds Health Score v2 fields to project-list and OSS Index outputs while sourcing dependency metrics directly from current Tinybird pipes.

Changes:

  • Propagates Health Score v2 fields through project APIs and OSS Index tuples.
  • Re-sources project and repository dependency metrics.
  • Prevents replacing snapshots when dependency totals are zero.
File Description
projects_list.pipe Documents new sortable fields.
project_insights_copy.pipe Re-sources dependency metrics and adds snapshot guards.
insightsProjects_filtered.pipe Exposes Health Score v2 fields.
insights_projects_populated_copy.pipe Joins and normalizes v2 scores.
collections_oss_index.pipe Appends v2 fields to project tuples.
category_groups_oss_index.pipe Appends v2 fields to project tuples.
categories_oss_index.pipe Appends v2 fields to project tuples.
insights_projects_populated_ds.datasource Adds the four v2 columns.

🧠 Review effort: Balanced


💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

…etrics (IN-1222)

Add healthScoreV2, healthLabel and healthScoreV2Normalized to insights_projects_populated_ds,
insightsProjects_filtered and projects_list, and append them to the OSI topProjects tuples. The
v1 healthScore slot keeps its index.

Read project and repository dependency metrics from the live health_score_*_dependency and
repo_health_score_*_dependency pipes instead of health_score_copy_ds and repo_health_score_copy_ds,
and fail the project_insights_copy job when a row type has no non-zero dependency metric.

Signed-off-by: Gašper Grom <gasper.grom@gmail.com>
Add healthMaxScore to insights_projects_populated_ds, insightsProjects_filtered and projects_list,
and append it as the last element of the OSI topProjects tuples, so the UI can mark partial scores.

Signed-off-by: Gašper Grom <gasper.grom@gmail.com>
@gaspergrom
gaspergrom force-pushed the feat/IN-1222-health-v2-osi-dependency-source branch from 97349cb to 84e7b83 Compare October 12, 2026 22:42

@cursor cursor Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cursor Bugbot has reviewed your changes and found 2 potential issues.

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, have a team admin enable autofix in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit 84e7b83. Configure here.

id,
healthScoreV2,
healthLabel,
if(healthMaxScore > 0, healthScoreV2 * 100.0 / healthMaxScore, NULL) AS healthScoreV2Normalized,

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Normalized score disagrees with label

Medium Severity

healthScoreV2Normalized is computed from the stored healthScoreV2, which is already toUInt8(round(...)), while healthLabel is copied from the pre-round sum divided by healthMaxScore. On partial denominators such as 60, rounding by less than a point can cross a band threshold, so the index pill and the normalized sort disagree.

Additional Locations (1)
Fix in Cursor Fix in Web

Reviewed by Cursor Bugbot for commit 84e7b83. Configure here.

ON base.segmentId = cdep.dependencySegmentId
LEFT JOIN
project_insights_copy_organization_dependency AS odep
ON base.segmentId = odep.dependencySegmentId

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Blank segment inherits dependency counts

Medium Severity

Project dependency counts now join health_score_contributor_dependency and health_score_organization_dependency on segmentId alone. Those pipes group every activity segment, including ''. Projects with an empty segment that previously missed health_score_copy_ds (that copy keeps segmentId != '') now pick up the shared orphan bucket instead of 0.

Fix in Cursor Fix in Web

Reviewed by Cursor Bugbot for commit 84e7b83. Configure here.

@themarolt themarolt left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

lgtm

…2-osi-dependency-source

Signed-off-by: Gašper Grom <gasper.grom@gmail.com>
Copilot AI balanced review requested due to automatic review settings October 13, 2026 13:13

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Changes recommended

Empty-segment dependency rows can be misattributed, and normalized sorting can disagree with health labels at rounding thresholds.

2 open findings

🧠 Review effort: Balanced


SQL >
SELECT segmentId AS dependencySegmentId, contributorDependencyCount, contributorDependencyPercentage
FROM health_score_contributor_dependency
id,
healthScoreV2,
healthLabel,
if(healthMaxScore > 0, healthScoreV2 * 100.0 / healthMaxScore, NULL) AS healthScoreV2Normalized,
@gaspergrom
gaspergrom merged commit 1a25638 into main Oct 13, 2026
15 checks passed
@gaspergrom
gaspergrom deleted the feat/IN-1222-health-v2-osi-dependency-source branch October 13, 2026 13:22
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants