Skip to content

feat: contributors from crowd.dev git activity, refreshed daily (CM-1824) - #4887

Open
mbani01 wants to merge 7 commits into
mainfrom
feat/repo-contributors-git-activity-sync
Open

mbani01 wants to merge 7 commits into
mainfrom
feat/repo-contributors-git-activity-sync

Conversation

@mbani01

@mbani01 mbani01 commented Oct 2, 2026 •

Copy link
Copy Markdown
Contributor

Summary

Second half of CM-1824, consuming the Tinybird snapshot shipped in #4886 (repo_commit_contributors_copy_ds, now live in lfx_insights).

Adds git_activity rows to repo_contributors: one commit-author row per repo and identity, for every repo crowd.dev tracks, with the CDP member id and the first/last commit timestamps (authored + co-authored). Bots, team members and organization profiles are already excluded upstream by the cleaned Tinybird source.

Changes

  • Migration V1790954467: nullable cdp_member_id UUID on repo_contributors, plus repo_contributors_sync_state (source PK, watermark, updated_at).
  • Sync module member-contributors/git-activity/: pages the Tinybird datasource in sorting-key order with a 4-column keyset cursor, maps channel to a packages-db repo (same canonicalisation as the governance sync) and username to an email or github-login identity, upserts with cdp_member_id; first_seen_at / last_seen_at use LEAST / GREATEST so channel spelling variants of one repo widen the window instead of overwriting it.
  • Workflow + schedules on the security-contacts-worker queue, next to the governance sync:
    • git-activity-contributors-incremental-sync, 0 6 2-14,16-31 * *
    • git-activity-contributors-full-sync, 0 6 1,15 * *
  • Tests for mapping, merging, watermark resolution, snapshot freshness, keyset paging and the sync paths.

How the incremental sync works

  • The Tinybird copy pipe rebuilds the snapshot nightly at 03:30 UTC. Each row carries lastUpdatedAt = max(activityRelations.updatedAt), which moves on ingestion and on member merges.
  • A run first reads max(computedAt) and throws if the snapshot is empty or not newer than the stored watermark, so a copy job that did not run is loud instead of silently reprocessing the same data.
  • Daily runs read only rows with lastUpdatedAt > watermark - 1 day and upsert them. Nothing is deleted.
  • The first run (no watermark) and the 1st/15th runs read the whole snapshot and reconcile: rows upserted get updated_at = NOW(), then git_activity rows with updated_at < run start are deleted. This closes the gaps a pure watermark cannot see (bot flag flips, repos disabled or re-enabled, identities absorbed by a merge, hard-deleted activities).
  • A full run refuses to reconcile when more than 20% of the existing git_activity rows would be deleted, which is what a truncated-but-non-empty snapshot (truncate + Sequin backfill during the copy) looks like.
  • The watermark is written only after the last page succeeded. A run that reads zero rows, reads rows but upserts none, or trips the reconcile guard throws and leaves state untouched.

Deployment

  • CROWD_TINYBIRD_BASE_URL and CROWD_TINYBIRD_ACTIVITIES_TOKEN must be present in the security-contacts-worker deployment, and the token needs read access to repo_commit_contributors_copy_ds. To be checked after deploy.
  • The first run is a full backfill of roughly 7M rows.

Depends on #4886 (merged).

…ibutors (CM-1824)

Signed-off-by: Mouad BANI <mouad-mb@outlook.com>
…ark (CM-1824)

Signed-off-by: Mouad BANI <mouad-mb@outlook.com>
…-1824)

Signed-off-by: Mouad BANI <mouad-mb@outlook.com>
Signed-off-by: Mouad BANI <mouad-mb@outlook.com>
Copilot AI balanced review requested due to automatic review settings October 2, 2026 15:52
@cursor

cursor Bot commented Oct 2, 2026 •

Copy link
Copy Markdown

PR Summary

Medium Risk
Large-scale writes and periodic DELETE reconciliation on repo_contributors depend on Tinybird snapshot freshness; misconfiguration or a bad full run could remove or skew contributor data until caught by guards.

Overview
Adds a git activity contributor pipeline that reads crowd.dev commit-author data from Tinybird (repo_commit_contributors_copy_ds) and upserts git_activity rows into repo_contributors, including cdp_member_id and first/last commit windows.

Schema migration adds nullable cdp_member_id and repo_contributors_sync_state for per-source watermarks. The sync pages Tinybird with a keyset cursor, maps channels to packages-db repos (same URL canonicalization as governance), and upserts with LEAST/GREATEST on seen timestamps. Incremental runs filter by lastUpdatedAt (watermark minus one day) and never delete; full runs (no watermark, explicit full, or 1st/15th cron) reconcile by deleting untouched git_activity rows after upsert, with a 20% removal cap and guards for stale/empty snapshots and zero upserts.

Wires syncGitActivityContributors through Temporal on security-contacts-worker: daily incremental schedule plus bi-monthly full sync, alongside the existing governance contributors job. Includes broad unit tests for mapping, paging, watermarks, and reconcile safety.

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

@CLAassistant

Copy link
Copy Markdown

CLA assistant check
Thank you for your submission! We really appreciate it. Like many open source projects, we ask that you sign our Contributor License Agreement before we can accept your contribution.
You have signed the CLA already but the status is still pending? Let us recheck it.

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.

Copilot review overview

🟡 Changes recommended

Page-local aggregation can corrupt commit totals, and completed activity retries can fail due to the persisted watermark.

Review effort: Balanced
Findings: 1 High severity · 1 Medium severity

Open (2)
What changed in this PR

Adds daily Tinybird-to-packages-db synchronization for repository commit contributors.

Changes:

  • Adds contributor schema and watermark state.
  • Implements full/incremental synchronization and mapping.
  • Registers Temporal workflows, schedules, and tests.
File Description
backend/​src/​osspckgs/​migrations/​V1790954467__repo_contributors_git_activity.sql Adds contributor metrics and sync state.
services/​apps/​packages_worker/​src/​activities.ts Exports the sync activity.
services/​apps/​packages_worker/​src/​bin/​security-contacts-worker.ts Registers the new schedules.
services/​apps/​packages_worker/​src/​member-contributors/​activities.ts Exposes the member-contributor activity.
services/​apps/​packages_worker/​src/​member-contributors/​git-activity/​mapRows.ts Maps Tinybird rows to contributors.
services/​apps/​packages_worker/​src/​member-contributors/​git-activity/​readCommitContributors.ts Implements Tinybird keyset paging.
services/​apps/​packages_worker/​src/​member-contributors/​git-activity/​syncGitActivityContributors.ts Implements synchronization and reconciliation.
services/​apps/​packages_worker/​src/​member-contributors/​schedule.ts Defines full and incremental schedules.
services/​apps/​packages_worker/​src/​member-contributors/​workflows.ts Adds the Temporal workflow.
services/​apps/​packages_worker/​src/​member-contributors/​__tests__/​syncGitActivityContributors.test.ts Tests mapping and synchronization behavior.
services/​apps/​packages_worker/​src/​workflows/​index.ts Exports the workflow.

💡 Configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

@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 1 potential issue.

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 2ccbe53. Configure here.

Signed-off-by: Mouad BANI <mouad-mb@outlook.com>
…824)

Signed-off-by: Mouad BANI <mouad-mb@outlook.com>
Copilot AI balanced review requested due to automatic review settings October 2, 2026 16:47
@mbani01

mbani01 commented Oct 2, 2026

Copy link
Copy Markdown
Contributor Author

Review Feedback Addressed

Commits: 0628316, d0e97f5

Changes Made

  • syncGitActivityContributors.ts / mapRows.ts / migration: dropped commit_count. Not required by the ticket or any consumer, and not computable correctly from a snapshot keyed by raw channel + username: 5,899 canonical repos have more than one channel spelling in repos_to_channels, so page-local merging could not produce an all-time sum (per copilot-pull-request-reviewer, cursor)
  • syncGitActivityContributors.ts: first_seen_at / last_seen_at now use LEAST / GREATEST in the upsert so channel variants widen the window instead of overwriting it, independent of page order or which variant an incremental run re-reads (per copilot-pull-request-reviewer, cursor)

No Change Needed

  • syncGitActivityContributors.ts:96: the "not newer" retry failure is kept on purpose. The window is milliseconds at the end of the run, the data is already correct, and the failure self-heals at the next schedule. Treating computedAt == watermark as already applied would silently skip the more likely failure, a copy job that did not run (flagged by copilot-pull-request-reviewer)

Threads Resolved

3 of 3 unresolved threads addressed in this iteration.

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.

Copilot review overview

🟡 Changes recommended

Full reconciliation needs protection against deleting valid data when a nonempty but unexpectedly partial snapshot is received.

Review effort: Balanced
Findings: 1 High severity

Open (1)
Resolved since last review (2)

…snapshot (CM-1824)

Signed-off-by: Mouad BANI <mouad-mb@outlook.com>
Copilot AI balanced review requested due to automatic review settings October 2, 2026 17:04
@mbani01

mbani01 commented Oct 2, 2026

Copy link
Copy Markdown
Contributor Author

Review Feedback Addressed

Commit: 362bc8a

Changes Made

  • syncGitActivityContributors.ts: the 1st/15th full reconcile now refuses to delete when more than 20% of the existing git_activity rows were left untouched by the run, which is what a truncated-but-non-empty Tinybird snapshot looks like. The run throws with the counts, nothing is deleted, the watermark is not advanced. (per copilot[bot])
  • syncGitActivityContributors.test.ts: covers the guard passing on normal churn and refusing on an excessive drop.

Threads Resolved

1 of 1 unresolved thread addressed in this iteration.

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.

Copilot review overview

🔵 Needs a closer look

The initial 7M-row reconciliation and production Tinybird access require final human operational validation.

Review effort: Balanced
Findings: None

Resolved since last review (1)

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