Refolk
TeardownInvesting and deal sourcing

Separating a COSS Repo's Real Adoption From Bought Stars

You can take a startup's claimed GitHub star trajectory and reach a defensible organic-or-manufactured verdict corroborated by two adoption signals no campaign can buy.

16 min readLast reviewed September 21, 2026Read as Markdown

You have a commercial open-source deck leaning on GitHub star growth, and you need to decide whether the traction is real or manufactured before you wire money. This guide takes one repository from a suspiciously smooth star chart all the way to a defensible go or no-go, using only public data and the adoption signals a bought campaign cannot pay for. It is written for early-stage investors, platform and talent partners, and angels who need a verdict they can defend in a partner meeting, not a vibe.

I will carry a worked case throughout: a Series-Seed data-infrastructure repo that has crossed the published seed star median, with a star curve that looks a little too clean. I will show the real queries, the intermediate counts, the two forks where I nearly got it wrong, and the two signals that finally settled it.

Why star count is the first thing to distrust

The star count is the single metric on a COSS deck that is both public and free for the founder to inflate, which is exactly why it is the first thing to distrust. A commercial open-source (COSS) company is one whose business is built around an open-source project, and its GitHub star total is the vanity number investors have been trained to read as demand.

Here is the arithmetic that makes stars a purchase target. Across a sample of devtool companies, the median star value at Series Seed was 2,850 and at Series A was 4,980. Generating 2,850 stars costs roughly $85 to $285. Set that against a seed round of $1M to $10M and the return on the fake runs from 3,500x to 117,000x.

117,000x
Peak ROI on faking the seed star median against a $1M round
2,850 stars cost $85 to $285; the metric is gamed precisely because it is public and free to the account holder.

The scale is not fringe. By mid-2024, 16.66% of all repositories with 50 or more stars had been involved in fake-star campaigns, up from near zero before 2022. In July 2024 alone, 30,779 participating stargazers - just 1.88% of active GitHub users - starred repos that made up 15.84% of everything gaining 50-plus stars that month. When you open a deck at the seed median, you are looking at the exact number a campaign is built to hit.

The signal stack, outermost to un-fakeable

Detection works in layers, from the cheap outer checks that a campaign can partly evade to the inner signals a founder would have to build a real company to produce. Read the stack from the outside in and you spend your first hour cheaply and your judgment where it counts.

The COSS traction signal stack

  1. Star timeline
    Shape of the curve; spikes against releases. Cheapest to read, cheapest to fake.
  2. Stargazer profiles
    Ghost ratio, account age, lockstep clusters. Fakeable with aged accounts.
  3. Fork and download ratios
    Downstream usage per star. Partly fakeable, but forks-plus-downloads is harder.
  4. Contributor and PR breadth
    Independent people building on it. Very hard to fake at scale.
  5. Professional skill adoption
    Labor-market commitment to the tool. Effectively un-fakeable.
Each inner layer is harder and more expensive to fake than the one outside it.

The two outer layers tell you whether to suspect. The three inner layers tell you whether demand is real regardless of what the stars say. A repo can have a dirty history and a real business; a repo can have a clean chart and no one using it. You are not hunting for fakes for their own sake. You are deciding whether durable demand exists.

Reading the star timeline for the shape of a purchase

A bought campaign leaves a shape: a brand-new repo jumping by several hundred stars in a couple of days, usually timed to a release or an announcement, against an otherwise flat baseline. Organic growth is lumpier and tied to real events like a Hacker News front page or a conference talk, and it does not vanish afterward.

For my worked case I pulled the WatchEvent history from GHArchive through its BigQuery replica and bucketed it by month. WatchEvent is GitHub's internal name for a star. The curve showed two things: a genuine-looking ramp after a product launch, and one month eleven months later that added 1,900 stars against a trailing baseline of about 150 a month. That one month is the object of the next test.

The narrowing scale of fake-star campaigns

  1. Repos with 50+ stars flagged (mid-2024)
    16.66%

    share of all such repos touched by campaigns

  2. Repos in raw StarScout detection
    26,254

    before post-processing

  3. Repos surviving the spike rule
    18,617

    after post-processing

  4. Fake-star repos that ship a package
    1.23%

    the usage layer thins the field further

StarScout's raw catch narrows sharply once the anomalous-spike rule is applied.

The post-processing rule that produced that narrowing is the same one you apply by hand. StarScout, the open-sourced detector from the CMU study, runs SQL over the GHArchive event dataset and keeps only repos with an anomalous monthly spike: more than 50 fake-suspect stars, over 50% of that month's stars fake, and over 10% fake all-time. My 1,900-star month cleared all three thresholds as a candidate. The ramp months did not.

Profiling the stargazers behind a spike

Once you have a candidate-campaign month, sample the accounts that starred and measure how many are hollow. Organic projects run roughly 1 to 2% ghost accounts - zero repos, zero followers, no bio - while inflated repos run near 30%. That gap is the clearest single reading you get from profiles.

I pulled about 150 stargazers from the candidate month via the REST API and measured account age, public repos, followers, and bio presence. The organic and manipulated fingerprints below are the baselines I compared against.

RepoMedian account age (days)Zero-follower %Ghost %Fork-to-star
Flask4,80110.01.30.235
LangChain2,96712not recorded0.155
AutoGPT4,02262.00.090
RepoMedian account age (days)Zero-follower %Ghost %Fork-to-star
RagaAI-Catalyst48476.228.00.224
openai-fm11666% suspicious36.02.794
FreeDomainover 1,00050 to 8028.00.017

My candidate month came back at 22% ghosts and 61% zero-follower, with a median account age of 690 days. That is squarely in manipulated territory, not organic. But notice the FreeDomain row: median age over 1,000 days. Premium campaigns buy aged accounts specifically to beat a young-account filter. Age alone would have cleared my case; age combined with zero repos, zero followers, and no bio did not.

The lockstep check

Ghost ratio tells you the accounts are hollow. The lockstep check tells you they moved together. Bin the stargazer creation dates into two-week windows and look for batch-created clusters, then check whether the same accounts starred the same set of repos inside short time windows. The CMU study uses CopyCatch, an algorithm built to detect fraudulent patterns in social networks, for exactly this. In my case, 340 of the accounts from the spike month were created inside the same fortnight and shared a starring fingerprint across four unrelated repos. That is lockstep, and it is not something organic interest produces.

The fork and download ratios, and where they lie

Fork-to-star and watcher-to-star ratios test whether stars come with the behavior of real users, but a padded fork count fakes the fork ratio outright. Some merchants sell stars and forks together - in one cluster, 7.49% of accounts engaged in both. So the ratio is a starting point, never a conclusion.

The organic baselines above sit around 0.09 to 0.24 forks per star. Flask ran 235 forks per 1,000 stars; FreeDomain, at 28% ghosts, ran only 17 per 1,000. My case showed 0.06 forks per star, low but not damning on its own. This was my first near-miss: a low fork ratio can mean a manufactured audience, or it can mean a tool people run without cloning. I did not let it decide anything.

The stronger cousin of the fork ratio is package adoption. Query ecosyste.ms - an open API across package registries holding 262 million repositories and 22 billion dependency links, rate-limited to 5,000 requests per hour by IP - or query npm and PyPI directly for downloads and dependent-repo counts. Of repos with fake-star campaigns, only 1.23% appeared in package registries at all, and of those 738 packages, 70.46% had zero dependent projects. Real funding, by contrast, brings an 8x jump in dependent projects and a 7x jump in package downloads.

Dependent-repo count is the cheapest disqualifier: campaigns buy attention, but they cannot buy other people's code depending on yours.

Sources disagree on when to run this. Security-first write-ups run the package check early as a fast disqualifier. The CMU method treats it as a post-hoc characteristic. My rule: run it early only if a package exists. My case shipped a PyPI package with 44,000 monthly downloads and 210 dependent public repos. That is real usage, and it directly contradicted the manipulated profile reading. Now I had a genuine conflict to resolve, which is where the durable-adoption layer earns its place.

The un-fakeable spine: professional skill adoption

The signal a $285 campaign can never replicate is labor-market commitment: the number of working professionals who list the tool as a skill and have built with it. Stars cost cents; a person putting a technology on their profile and shipping it in a job is a decision no vendor can sell you.

In Refolk's index of professional profiles, about 20,106 US professionals list Apache Airflow as a skill and about 17,649 list dbt. Set that scale against the cost of the seed star median and the asymmetry is total.

SignalApache Airflowdbt
US professionals listing skill (Refolk index)20,10617,649
Ratio to the other tool (derived)1.14x0.88x
Cost to fake seed star median (context)$85 to $285$85 to $285

For a repo at the seed star median with near-zero professional skill adoption, that mismatch is a red flag no clean chart can explain away. For my case, I sized the practitioner base directly rather than eyeballing stars.

Running the equivalent search against my target project returned a practitioner base in the low four figures with public commits - modest, but real, and consistent with a Series-Seed tool eleven months past launch. It also gave me an independent second signal: I could name individual engineers, outside the founding team, building on the project in production. When you need to reach that base without hand-scraping GitHub and cross-referencing employers, Refolk resolves the query in plain English and hands back the people.

The step-by-step procedure

Run these eight steps in order. Steps 1 through 5 decide whether to suspect manipulation; steps 6 and 7 decide whether demand is real regardless. The verdict at step 8 must rest on the inner layers, never on any single outer heuristic.

From a suspicious star chart to a documented verdict

  1. Pull the raw star timeline
    Query GHArchive via BigQuery or the GitHub API for the repo's WatchEvent history and build per-day and per-month counts. Done when you can see whether spikes align with releases or announcements.
  2. Flag anomalous months
    Label a spike month candidate-campaign if it holds over 50 fake-suspect stars, over 50% of that month's stars, and over 10% of all-time stars. Done when every spike is labeled.
  3. Sample stargazer profiles
    Pull about 150 stargazers via the API and measure account age, public repos, followers, and bio presence. Done when you have a ghost percentage and a median account age.
  4. Run low-activity and lockstep checks
    Bin creation dates into two-week windows to find batch-created clusters and check shared starring fingerprints. Done when synchronous clustered starring is confirmed or ruled out.
  5. Compute fork and watcher ratios
    One API call gives forks and watchers; divide by stars and compare to the 0.09 to 0.24 organic baseline. Done when the ratios are placed against the baseline.
  6. Cross-check package adoption
    Query ecosyste.ms, npm, or PyPI for downloads and dependent-repo counts, but only if the repo ships a package. Done when you know whether stars are matched by usage.
  7. Corroborate durable adoption
    Track contributor growth over time, independent PR activity, and professional skill adoption. Done when you can state whether adoption tracks or contradicts the star curve.
  8. Reach a verdict and document wrong turns
    Write the go or no-go citing at least two independent signals a campaign cannot fake, and note the dead ends. Done when the verdict rests on no single heuristic.

How this goes wrong

Every heuristic here has a failure mode, and the ones that catch practitioners are the false positives, where a clean signal misleads. This section is the part of the standard worth the most, because a wrong no-go on a real company is as expensive as a wrong yes on a fake one.

Failure modeHow it fools youThe corroborating check
Fork ratio aloneMerchants sell forks with stars; 7.49% of one cluster did bothCross-reference fork ratio with downloads and issue activity
Young-account filterPremium campaigns use accounts over 1,000 days oldRequire age plus zero-repo plus zero-follower plus no bio
StarScout false positiveAd-hoc heuristics and the 50-star threshold misfireRequire two or more independent signals before concluding fraud
Popular-repo contaminationA genuine repo gets a thin adversarial fake fractionApply the over-50%-in-a-month spike rule, not total fake count
Package check misappliedPenalizes a CLI or app with no registry presenceOnly run downloads-versus-stars when a package exists

Two more deserve their own note. First, the clean-current-profile-dirty-history trap: enforcement is asymmetric. GitHub deletes 90.42% of flagged repos but only 57.07% of flagged accounts, so the account infrastructure survives to re-star and the historical clustering persists in GHArchive even after cleanup. Always reconstruct the spike from the archive.

Second, do not over-read the promotion effect. The research finding that a 1% rise in fake stars in one month associates with a 0.07% rise in real stars the next month, then inverts to a 0.04% net drag from two months on, is a fitted regression the authors explicitly call non-causal. It is one signal, not proof of purchase. Fake stars are a decaying asset, which is why a sustained multi-quarter climb is harder to buy than a spike, but treat the correlation as corroboration, never as a smoking gun.

Resolving the worked case

My target had a manipulated spike and real underlying demand at the same time, which is the most common and most confusing outcome. Here is how the signals stacked: one candidate-campaign month at 22% ghosts, 61% zero-follower, and a 340-account lockstep cluster; a low fork ratio that meant little on its own; but 44,000 monthly PyPI downloads, 210 dependent public repos, contributor growth consistent with a real ramp, and a live professional skill base with public commits outside the founding team.

The verdict was a conditional go, not a no-go. The founder almost certainly bought a spike to clear the seed median, which is a governance flag I raised directly. But the durable-adoption layer contradicted the manipulated profile reading on two independent axes - dependents and skill adoption - and those are the signals a campaign cannot afford. Post-funding, real COSS projects average 27% more contributors, 8x dependents, and 7x downloads, and this repo already showed the downstream footprint of genuine use. The star chart lied; the usage did not.

Had the package downloads come back near zero and the skill base near zero, the same profile reading would have been a clean no-go. The lesson is that the outer layers tell you whether to suspect, and only the inner layers tell you whether to invest.

Before you call it done

Run this checklist before you write the verdict. If you cannot tick the last two items, you have a suspicion, not a decision.

Verdict readiness

  • Star timeline reconstructed from GHArchive, with each spike labeled candidate-campaign or organic
  • About 150 stargazers sampled, with ghost percentage and median account age recorded against the baseline
  • Lockstep and low-activity checks run, with any two-week batch clusters identified
  • Fork and watcher ratios compared to the 0.09 to 0.24 organic baseline
  • Package downloads and dependent-repo counts pulled, or the package check formally waived because no package ships
  • Professional skill adoption sized against the star claim
  • At least two independent signals a campaign cannot fake are cited in the verdict
  • Wrong turns and near-misses documented so the next reviewer can retrace the reasoning

Keeping the method current

The star-fraud market moves, so re-check the mechanism rather than memorizing today's thresholds. Star prices, from $0.03 disposable accounts to $0.90 aged premium ones, and the exact spike-rule cutoffs will drift, but the structure holds: cheap outer signals to suspect, expensive inner signals to invest. When you re-run this in six months, refresh the organic baselines from a handful of known-clean projects, confirm ecosyste.ms and the GitHub API rate limits, and re-pull the professional skill counts, because labor-market adoption is the one number that both moves with real demand and stays out of reach of a $285 campaign.

Questions practitioners ask

How many stargazer profiles do I need to sample to trust the ghost ratio?

About 150 per repo is the working sample size used in the public profile studies, and it is enough to separate an organic 1 to 2% ghost ratio from an inflated ratio near 28 to 30%. Pull them through the GitHub REST API and measure account age, public repos, followers, and bio presence. If your ghost percentage lands in the ambiguous 5 to 15% band, widen the sample and lean harder on adoption signals rather than profile counts alone.

Can a young-account filter catch bought stars on its own?

No. Premium campaigns use aged accounts, and many empty-shell accounts are over 1,000 days old precisely to pass a simple young-account filter. Age alone is not a signal. Combine age with zero repos, zero followers, and no bio to define a ghost, and never conclude manipulation from account age by itself.

What if the repo has no npm or PyPI package to check downloads against?

Then skip the package test entirely. Not every repo ships a package, and penalizing a CLI, an application, or a library with no registry presence produces a false positive. Only apply the downloads-versus-stars check when a package genuinely exists, and lean on contributor growth, independent PRs, and professional skill adoption instead.

Is a smooth multi-quarter star climb harder to fake than a spike?

Yes, and durability is itself the signal. The promotion effect from fake stars is a decaying asset that inverts to a net drag after about two months, so a single spike is cheap while a sustained multi-quarter climb corroborated by rising contributors and downloads is expensive to manufacture. Treat a smooth curve backed by adoption as a positive, not a suspicion.

How much does it actually cost to hit the seed star median?

Roughly $85 to $285 to generate 2,850 stars, which is the median seed value across a sample of devtool companies. Against seed rounds of $1M to $10M, that is a 3,500x to 117,000x return on the fake, which is exactly why a public, free-to-inflate metric gets gamed. The Series A median of 4,980 would cost about $990 to $4,500.

Try it on the search you came here for

Stop building boolean strings. Just describe the person.

Type one sentence. I plan the search, read GitHub, public LinkedIn and Crunchbase records, and the open web as it is right now, and hand back a ranked list with the reason next to every name.

  1. 01Describe them

    One plain sentence. Role, city, stack, stage, whatever matters to you.

  2. 02I read the web live

    GitHub, public LinkedIn and Crunchbase records, the open web. Not a database that went stale last quarter.

  3. 03You read the shortlist

    Ranked, with the reasoning under every name. Open a profile, ask a follow-up, narrow it down.

  • No boolean, no filters, no seat to buy. One box.
  • Read at search time, so a profile updated yesterday counts today.
  • Every step visible as it runs, every name with its reason.

500 free credits on sign-up. No card, no demo call. See real searches.

Read next