Skip to content

Active years are undercounted for organization contributions #90

Description

@martinbha

Summary

GitFut can undercount a developer's active years when their contribution history includes work outside personally owned repositories.

Current behavior

The GitHub client fetches one contributionsCollection for every calendar year and reduces those collections into a single lifetime contribution total. Once reduced, the annual boundaries are lost.

The scoring layer then reconstructs active_years from createdAt and pushedAt dates on repositories returned by:

repositories(ownerAffiliations: OWNER, isFork: false)

This repository-derived estimate excludes years where activity occurred only in organization-owned repositories. It can also miss private, issue, pull request, or review activity that is represented in annual contribution collections without a corresponding owned-repository date.

Impact

An incorrect active-year count changes the average lifetime pace used by the recent-spike signal. It can also affect PHY, legacy score, overall rating, style, and card finish.

Expected behavior

Active years should be counted from GitHub's annual contribution collections. The existing yearly query can request hasAnyContributions and count the years where GitHub returns true.

The calculation should use inclusive UTC calendar years because the source collections are calendar-year windows. For example, an account created late in 2021 can legitimately have activity in six annual collections from 2021 through 2026 even though fewer than five full years have elapsed.

Acceptance criteria

  • Annual lifetime queries request hasAnyContributions without adding API requests.
  • Lifetime totals and active-year counts are calculated before annual results are discarded.
  • Organization and private contribution years count when GitHub reports activity.
  • Owned-repository creation and push dates no longer determine active_years.
  • Failed batches retry as individual years.
  • An individually unavailable or omitted year becomes zero/inactive without failing the scout.
  • Cache versioning and the existing two-hour TTL remain unchanged.
  • The distribution sampler mirrors the production calculation.
  • Tests cover differing contribution and repository histories, non-contiguous activity, fallback failures, missing collections, inclusive calendar-year boundaries, and the recent-spike threshold.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions