<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
    <title>Thingz Blog</title>
    <subtitle>Open source intelligence for teams that ship on trust.</subtitle>
    <link href="https://thingz.io/feed.xml" rel="self"/>
    <link href="https://thingz.io/blog/"/>
    <updated>2026-05-03T00:00:00+00:00</updated>
    <id>https://thingz.io/blog/</id>
    <author>
        <name>Thingz</name>
    </author>
    
    <entry>
        <title>Cross-Platform Identity: When the Same Private Key Signs Two Forges</title>
        <link href="https://thingz.io/blog/cross-platform-identity/"/>
        <updated>2026-05-03T00:00:00+00:00</updated>
        <id>https://thingz.io/blog/cross-platform-identity/</id>
        <content type="html">&lt;p&gt;Anyone can register a popular username like &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;torvalds&lt;/code&gt; on GitLab. Or Codeberg. Or Sourcehut. The
GitHub account belongs to who you think it does. The others are first-come, first-served.
Bios are free-text. The “linked accounts” section on a profile is whatever the
contributor typed in. None of these are proof of anything beyond what the contributor
chose to claim.&lt;/p&gt;

&lt;p&gt;The same problem applies in reverse. When &lt;a href=&quot;https://devtrace.thingz.io&quot;&gt;DevTrace&lt;/a&gt; is
asked whether a GitHub contributor also has a GitLab presence, name matching is a guess.
Profile-link extraction is a declaration. Neither is verifiable in the cryptographic
sense.&lt;/p&gt;

&lt;p&gt;There is one signal that is. If the same SSH public key appears on a contributor’s
GitHub account and on their GitLab, Codeberg, or Sourcehut account, then the same private
key signed operations on each platform. That private key is held by exactly one person
— or, at most, exactly one breach. Producing it on two systems means controlling it.&lt;/p&gt;

&lt;p&gt;This post walks through how DevTrace surfaces cross-VCS identity matches, what the
signal proves, and where its limits are.&lt;/p&gt;

&lt;h2 id=&quot;the-hierarchy-of-identity-claims&quot;&gt;The hierarchy of identity claims&lt;/h2&gt;

&lt;p&gt;Most open source identity tooling treats one of three signals as “verified”:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;strong&gt;Declared&lt;/strong&gt; — the contributor put a link to their GitLab profile in their GitHub
bio. Anyone can claim this. Worth treating as a hint, not a fact.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Asserted by a third party&lt;/strong&gt; — a Keybase proof, a verified email domain, an OIDC
issuer. Stronger, because the assertion depends on a system that has its own checks.
But the chain is only as strong as the attester, and most of the historically popular
attesters are out of scope or defunct.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Cryptographic&lt;/strong&gt; — the same private key signs on both platforms. This is the only
signal that requires the contributor to demonstrate control, not just claim it.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;DevTrace’s cross-VCS check sits in the third category. It is not a name match dressed up
as a fingerprint comparison. It is the actual fingerprint comparison.&lt;/p&gt;

&lt;h2 id=&quot;how-keys-endpoints-work&quot;&gt;How &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;.keys&lt;/code&gt; endpoints work&lt;/h2&gt;

&lt;p&gt;Every major code-hosting platform except Bitbucket exposes a public endpoint that
returns the SSH public keys a user has uploaded to their account. The keys are intended
for &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ssh&lt;/code&gt; and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;git&lt;/code&gt; clients to verify identities at the protocol level, but the
endpoints are unauthenticated and machine-readable:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;https://github.com/{user}.keys
https://gitlab.com/{user}.keys
https://codeberg.org/{user}.keys
https://meta.sr.ht/~{user}.keys
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Each returns one line per key in OpenSSH format:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIK... user@host
ssh-rsa AAAAB3NzaC1yc2EAAAA... id_rsa
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;DevTrace fetches each platform’s &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;.keys&lt;/code&gt; response for the contributor’s handle, computes
the SHA-256 fingerprint of every public key, and compares the sets. A match is a match
— the same &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;SHA256:...&lt;/code&gt; value appearing in two different platforms’ responses. No
platform involvement, no API key, no rate-limit dependency on a vendor’s terms.&lt;/p&gt;

&lt;p&gt;The result is cached weekly per platform, so the marginal cost of re-scoring a
contributor whose cross-VCS surface has not changed is a single cache lookup, not four
HTTP calls.&lt;/p&gt;

&lt;h2 id=&quot;why-fingerprint-matches-are-categorically-stronger&quot;&gt;Why fingerprint matches are categorically stronger&lt;/h2&gt;

&lt;p&gt;Three reasons, in order of importance.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The signal is not declared, it is demonstrated.&lt;/strong&gt; A bio link is a string the user
typed. A fingerprint match required the user to upload the same public key on each
platform. To do that, they held the corresponding private key when they did it.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Spoofing requires compromise, not registration.&lt;/strong&gt; To fake a GitHub–GitLab match, an
attacker would have to either obtain the target’s private key — equivalent to the
target reusing a compromised key — or upload their own key to both accounts, which
means they already control both accounts, which is a different problem entirely. There
is no cheap trick.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The check is reproducible by anyone.&lt;/strong&gt; The &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;.keys&lt;/code&gt; endpoints are public. A reviewer
who wants to verify the DevTrace match by hand can run &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;curl github.com/USER.keys&lt;/code&gt; and
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;curl gitlab.com/USER.keys&lt;/code&gt; and compare the SHA-256 fingerprints themselves. The signal
is not DevTrace’s claim. DevTrace just consolidates it into one place.&lt;/p&gt;

&lt;h2 id=&quot;what-a-strong-cross-vcs-profile-looks-like&quot;&gt;What a strong cross-VCS profile looks like&lt;/h2&gt;

&lt;p&gt;A typical long-tenured open source contributor — someone who has been writing code in
public for a decade — will often have keys on three or four forges. The kernel
mailing-list contributors, the longtime KDE developers, the people who maintain
infrastructure projects across multiple ecosystems. Their GitHub &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;.keys&lt;/code&gt; matches at least
one entry on GitLab and frequently on Codeberg as well.&lt;/p&gt;

&lt;p&gt;In the scorecard, this surfaces as a Cross-VCS section showing each platform with a
checkmark next to the matched fingerprint. Three matches is a strong signal. Two matches
is solid. One match is meaningful but circumstantial — the contributor has at least
proven control of the same key on two systems, which is more than a declaration but
less than a cross-ecosystem footprint.&lt;/p&gt;

&lt;p&gt;A contrasting profile shows zero matches. Either the contributor has no presence on
forges other than GitHub, has not uploaded a key to those forges, or rotated keys
recently enough that previous matches are gone. None of those is automatically
suspicious, but combined with a sparse profile, low repo diversity, and no community
footprint, the absence becomes part of the picture.&lt;/p&gt;

&lt;h2 id=&quot;what-this-signal-does-not-prove&quot;&gt;What this signal does not prove&lt;/h2&gt;

&lt;p&gt;A cross-VCS match is not a real-name identity check. It does not tell you whether the
person behind the keys is who they claim to be in the social sense — only that the
same person controls all the matched accounts. The Jia Tan account in the xz-utils
incident was a single coherent identity across the surface the attacker chose to
maintain. A cross-VCS match between Jia Tan on GitHub and a hypothetical Jia Tan on
GitLab would have been real, in the cryptographic sense. It would not have been correct,
in the social-engineering sense.&lt;/p&gt;

&lt;p&gt;Three other limits are worth naming explicitly:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;strong&gt;Bitbucket has no public &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;.keys&lt;/code&gt; endpoint.&lt;/strong&gt; Atlassian gates SSH key access behind an
authenticated API. DevTrace cannot include Bitbucket in the cross-VCS check today. If
the endpoint ever becomes public, it goes in.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;The handle is assumed to be the same.&lt;/strong&gt; DevTrace v1 fetches &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;.keys&lt;/code&gt; for the same
handle across platforms. A contributor who is &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;alice&lt;/code&gt; on GitHub and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;alice-h&lt;/code&gt; on
Codeberg will not show a match even if the underlying keys are identical. This is a
known limitation that handle-mapping will address in a later release.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;GPG fingerprint correlation is not yet included.&lt;/strong&gt; GitHub exposes signing keys at
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;github.com/USER.gpg&lt;/code&gt;. The same approach — fetch, SHA-256, compare — applies. It
is on the roadmap but not in the v1 cross-VCS surface.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;how-devtrace-exposes-the-signal&quot;&gt;How DevTrace exposes the signal&lt;/h2&gt;

&lt;p&gt;Cross-VCS identity is a Pro-tier capability. Every Pro scorecard for an authenticated
contributor includes the section automatically when the relevant handles exist. The
matches are cached weekly per platform, the call budget is bounded, and the
unauthenticated &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;.keys&lt;/code&gt; lookup does not depend on any platform’s API quota.&lt;/p&gt;

&lt;p&gt;For programmatic use, the same data is returned in the JSON response from
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;/api/v1/score/{username}&lt;/code&gt; on a Pro plan, in a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;cross_vcs&lt;/code&gt; field with one entry per
platform and the matched fingerprints listed alongside.&lt;/p&gt;

&lt;p&gt;The reason to surface this at all is straightforward. “Verified identity” in open
source has been treated as a marketing concept for too long. The strongest signal that
does not require a human in the loop already exists, in the public infrastructure of
every major forge. DevTrace consolidates it into the scorecard so that a reviewer
reading a PR can see “matched on three forges” alongside the rest of the trust signal
— without opening four tabs and computing fingerprints in a terminal.&lt;/p&gt;

&lt;h2 id=&quot;try-it&quot;&gt;Try it&lt;/h2&gt;

&lt;p&gt;DevTrace is free to score any public GitHub contributor at
&lt;a href=&quot;https://devtrace.thingz.io&quot;&gt;devtrace.thingz.io&lt;/a&gt;. The cross-VCS identity signal sits on
the Pro tier alongside the behavioral signals and synthetic-contributor flags — but
the rest of the scorecard, including the 25+ trust signals, AI risk narrative, and
enrichment surface, is available on every authenticated plan.&lt;/p&gt;

&lt;p&gt;If you are evaluating the projects those contributors maintain rather than just the
contributors themselves, &lt;a href=&quot;https://devpulse.thingz.io&quot;&gt;DevPulse&lt;/a&gt; tracks the project-level
signals that complement contributor trust. A project whose top maintainers verify across
multiple forges is a different proposition from one whose maintainers do not, and the
two views are most useful when read together: DevTrace tells you who, DevPulse tells you
how the project is holding up around them.&lt;/p&gt;
</content>
    </entry>
    
    <entry>
        <title>AI-Generated PRs and the New Shape of Contributor Risk</title>
        <link href="https://thingz.io/blog/ai-generated-prs-contributor-risk/"/>
        <updated>2026-04-30T00:00:00+00:00</updated>
        <id>https://thingz.io/blog/ai-generated-prs-contributor-risk/</id>
        <content type="html">&lt;p&gt;AI-generated code has a 2.7x higher vulnerability density than human-written code.
That figure — from
&lt;a href=&quot;https://www.coderabbit.ai/blog/state-of-ai-vs-human-code-generation-report&quot;&gt;CodeRabbit’s analysis of 470 real-world pull requests&lt;/a&gt;,
and consistent with Veracode’s 2025 GenAI Code Security Report across more than 100
LLMs — gets quoted a lot in supply chain conversations. It changes the threat
model on its own.&lt;/p&gt;

&lt;p&gt;But the code is the easier half of the problem. The harder half is the contributors.&lt;/p&gt;

&lt;p&gt;AI lowers the cost of manufacturing a convincing fake contributor history at scale.
Plausible commit messages. Reasonable-looking patches. Activity patterns that mimic
a real developer over months instead of hours. The same tools that make legitimate
developers more productive make social engineering campaigns cheaper to execute. A
campaign that took two years for xz-utils could, in principle, be parallelized across
a hundred targets by one person with a script and an API key.&lt;/p&gt;

&lt;p&gt;This is not an argument against AI-assisted development. AI in the PR pipeline is
normal and net positive. It is an argument that contributor vetting has to evolve
alongside the tools contributors are using — because the cheap, plentiful version
of “looks like a real developer” is now widely available.&lt;/p&gt;

&lt;h2 id=&quot;what-changed&quot;&gt;What changed&lt;/h2&gt;

&lt;p&gt;Three things shifted in the last 24 months that matter for contributor risk:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The cost of plausible activity dropped.&lt;/strong&gt; Generating a year’s worth of believable
commit history — spread across multiple repos, with appropriate language, with
realistic PR descriptions — is no longer labor-intensive. It is a prompt and a loop.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The cost of plausible identity dropped.&lt;/strong&gt; Bios, READMEs, blog posts, and even
conversational issue replies can be produced at volume. The textual artifacts that
used to take time to fabricate now take minutes.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Detection got harder for humans.&lt;/strong&gt; Reviewers cannot reliably distinguish
AI-generated code from human-written code in a single PR. Pattern-matching at scale
across a contributor’s entire history is the only reliable place to look, and humans
do not do that pattern-matching by default.&lt;/p&gt;

&lt;p&gt;What still holds up: longitudinal behavioral signals. The thing AI is bad at faking
is the texture of how a real developer interacts with the open source ecosystem over
years — the rhythm of activity across timezones, the messy inconsistency of real
human attention, the fingerprints of being embedded in multiple unrelated communities.&lt;/p&gt;

&lt;p&gt;That is where &lt;a href=&quot;https://devtrace.thingz.io&quot;&gt;DevTrace&lt;/a&gt;’s AI sensing layer focuses.&lt;/p&gt;

&lt;h2 id=&quot;two-tiers-of-detection&quot;&gt;Two tiers of detection&lt;/h2&gt;

&lt;p&gt;DevTrace’s AI sensing operates in two tiers. Tier 1 is metadata — explicit and
implicit signatures that an AI tool was involved. Tier 2 is behavioral — patterns
that distinguish a real developer (with or without AI assistance) from a synthetic
account.&lt;/p&gt;

&lt;p&gt;The two tiers answer different questions. Tier 1 asks “was this PR produced with AI
help?” Tier 2 asks “is this contributor a real person?” Those questions are not the
same, and conflating them is how teams end up either flagging legitimate Copilot
users or missing actual synthetic accounts.&lt;/p&gt;

&lt;h2 id=&quot;tier-1-metadata-analysis&quot;&gt;Tier 1: metadata analysis&lt;/h2&gt;

&lt;p&gt;Tier 1 runs on every contributor scan. It looks at the artifacts that AI tooling
leaves behind in commits, PRs, and account configuration.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Bot detection.&lt;/strong&gt; GitHub exposes an account type field that distinguishes user
accounts from bot accounts. Known bots — Dependabot, Renovate, GitHub Apps — are
flagged automatically and excluded from contributor trust analysis. This is table
stakes, but it matters because dashboards that ignore bot status tend to inflate
contributor counts.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Commit trailers.&lt;/strong&gt; AI coding assistants increasingly add &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Co-authored-by:&lt;/code&gt; trailers
identifying themselves. Claude Code, Cursor agents, GitHub Copilot Workspace, and
several others use predictable trailer formats. DevTrace parses commit messages for
these trailers and tracks the proportion of a contributor’s commits that were
co-authored by an AI tool.&lt;/p&gt;

&lt;p&gt;This is informational, not punitive. A contributor whose commits are 80% co-authored
by Claude Code is not less trustworthy — they are just transparent about their
workflow. The signal becomes interesting when combined with other tier 2 signals.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Tool signatures.&lt;/strong&gt; Beyond trailers, AI tools leave fingerprints in commit message
formatting, branch naming conventions, and PR description structure. These signatures
are weak individually but useful as a population-level indicator: a contributor whose
PRs all match a single AI tool’s default output format is using that tool heavily,
which is a fact worth knowing.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;PR authenticity classification.&lt;/strong&gt; This combines the above into a per-PR
classification: human-authored, AI-assisted, or AI-generated. The classification is
probabilistic, not absolute. The point is to give reviewers context, not to gate
merges.&lt;/p&gt;

&lt;h2 id=&quot;tier-2-behavioral-analysis&quot;&gt;Tier 2: behavioral analysis&lt;/h2&gt;

&lt;p&gt;Tier 2 is the harder problem and the part that actually distinguishes real from
synthetic. These signals come from
&lt;a href=&quot;https://www.gharchive.org/&quot;&gt;GH Archive&lt;/a&gt; data, which gives DevTrace longitudinal
visibility into contributor activity across all of GitHub — not just the repo in
question.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Velocity anomaly ratio.&lt;/strong&gt; Real developers have rhythm. They commit in bursts during
focused work, go quiet during meetings, sleep, take weekends. Their velocity over a
30-day window has texture — peaks, valleys, patterns that correlate with
calendar days.&lt;/p&gt;

&lt;p&gt;A synthetic account often does not. Either the velocity is too smooth (an automated
loop producing one PR per day at consistent intervals) or it is too spiky in
suspicious ways (zero activity for weeks, then a flood of PRs across multiple repos
in 48 hours). DevTrace computes the ratio of actual velocity to expected velocity for
that account’s age and activity level. Ratios well outside the typical range are
flagged.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Active hour spread.&lt;/strong&gt; A real developer working a normal job tends to commit during
a recognizable subset of the 24-hour day — their working hours, plus or minus
their personal habits. The histogram of their commit timestamps has a shape: usually
two or three peaks (morning, afternoon, occasional evening) with quiet zones for
sleep and lunch.&lt;/p&gt;

&lt;p&gt;A synthetic account often has either a uniformly flat distribution (commits at every
hour, because the script does not sleep) or a too-narrow distribution (commits only
in a 2-hour window, because that is when the operator runs the script).&lt;/p&gt;

&lt;p&gt;This signal is noisier than it sounds — contributors travel, change jobs, work
across timezones with collaborators — so DevTrace uses it as one input among many.
But the failure modes (flat or narrow distributions) are distinctive enough to be
useful.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Burst-vanish score.&lt;/strong&gt; This is the signal most directly aimed at the xz-utils
playbook: an account that appears, builds visible activity rapidly, then either
vanishes or pivots to a single high-value target. DevTrace computes a burst-vanish
score that captures the ratio of active days to total account age, weighted by the
concentration of activity in specific time windows.&lt;/p&gt;

&lt;p&gt;A real developer with five years of patchy activity gets a low burst-vanish score.
An account that is six months old, was active for the last 60 days, has commits in
12 unrelated repos, and is now requesting commit access to a critical library — that
account gets a high score.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Synthetic contributor flag.&lt;/strong&gt; When tier 2 signals combine in ways consistent with a
manufactured account (low diversity, high burst-vanish, narrow active hour spread,
no review participation, sparse profile), DevTrace surfaces a synthetic contributor
flag. The flag is not a verdict. It is a “this contributor warrants closer review
before granting elevated trust” signal.&lt;/p&gt;

&lt;h2 id=&quot;what-a-real-high-velocity-contributor-looks-like&quot;&gt;What a real high-velocity contributor looks like&lt;/h2&gt;

&lt;p&gt;The hardest population to score correctly is the legitimate high-velocity
contributor. These are real developers — often working full-time on open source,
or using AI assistants aggressively — who can produce more PRs in a week than a
typical contributor produces in a quarter.&lt;/p&gt;

&lt;p&gt;They share several characteristics that distinguish them from synthetic accounts:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;strong&gt;Long account history with consistent rhythm.&lt;/strong&gt; The high velocity is part of a
multi-year pattern, not a recent spike.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Activity across many repositories.&lt;/strong&gt; They review code, file issues, and comment
in unrelated communities. They are embedded.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Realistic active hour distribution.&lt;/strong&gt; A shape, with quiet zones, that holds up
over months.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Other signals of human presence.&lt;/strong&gt; Followers, profile, blog posts, conference
talks, real-world identity that can be cross-referenced.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Conversational depth.&lt;/strong&gt; Their issue comments and PR replies show familiarity
with project history, with the maintainers, with prior decisions. Synthetic
accounts struggle here because the context window is too small to fake.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;DevTrace’s behavioral category is specifically tuned to surface this distinction. A
contributor with 50 PRs in 30 days but a five-year account history, broad repo
diversity, consistent review participation, and a normal active-hour shape will score
well. The same 50 PRs from a 6-month-old account with no review participation, no
repo diversity, and a flat hourly distribution will score poorly — and trigger the
synthetic contributor flag.&lt;/p&gt;

&lt;h2 id=&quot;what-still-slips-through&quot;&gt;What still slips through&lt;/h2&gt;

&lt;p&gt;No detection layer catches everything. The honest list of what does not work yet:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Hybrid accounts.&lt;/strong&gt; A real developer with a mature account who decides to run a
malicious campaign is the hardest case. Their behavioral fingerprint looks normal
because it is normal. This is where DevTrace’s repo-context signals — code
provenance, commit signing, organizational role — carry more weight than the
behavioral category.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Slow-burn synthetic accounts.&lt;/strong&gt; A patient adversary willing to invest two years in
building authentic-looking history can defeat the burst-vanish signal by simply not
bursting. The xz-utils attack worked partly because the timeline was patient. The
trade-off is that this kind of attack does not scale — it is back to being
expensive, which is itself a deterrent.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Coordinated networks.&lt;/strong&gt; A cluster of synthetic accounts that interact with each
other to fake community signals (followers, code reviews, mutual mentions) can
defeat per-contributor analysis. Detecting these requires graph-level analysis that
DevTrace does not yet do at the public-tier level. It is on the roadmap.&lt;/p&gt;

&lt;p&gt;This is the same dynamic as any other detection problem. The cheap, common attacks
get caught. The expensive, patient attacks remain hard. The point is to raise the
floor.&lt;/p&gt;

&lt;h2 id=&quot;how-to-use-this-in-practice&quot;&gt;How to use this in practice&lt;/h2&gt;

&lt;p&gt;For most teams, the practical question is not “did AI write this code?” It is “is
this contributor someone whose elevated access I should trust?”&lt;/p&gt;

&lt;p&gt;A reasonable workflow:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;For first-time contributors:&lt;/strong&gt; run a DevTrace scan as part of PR review. The trust
score and any synthetic contributor flags surface in the GitHub Action output. Most
first-time contributors are fine. The point is to catch the cases that warrant a
second look before merging.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;For contributors requesting commit access:&lt;/strong&gt; run a deeper scan that includes the
behavioral signals. Anyone whose burst-vanish score is high or whose active hour
spread looks synthetic should not get commit access on the strength of a few good
PRs alone, regardless of how good those PRs are.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;For your own contributor base:&lt;/strong&gt; periodically audit the contributors with elevated
access against current trust scores. Account behavior changes. A contributor who
scored well three years ago may have changed accounts, gone dormant, or been
compromised. Trust is not a one-time check.&lt;/p&gt;

&lt;h2 id=&quot;what-this-is-not&quot;&gt;What this is not&lt;/h2&gt;

&lt;p&gt;DevTrace’s AI sensing is not a tool for penalizing AI-assisted development. The
proportion of legitimate PRs touched by AI tools is high and rising, and any
detection system that treats AI involvement as suspicious by default will produce
mostly false positives.&lt;/p&gt;

&lt;p&gt;It is also not a substitute for code review. The point is to surface contributors
whose pattern of behavior diverges from what real developers look like — so that
human reviewers know where to spend their attention. The reviewer still does the
review.&lt;/p&gt;

&lt;p&gt;The asymmetry that matters: synthetic contributor accounts are cheap to create and
expensive to vet manually. Behavioral signals are the only way to keep the vetting
cost from blowing up as the creation cost falls. That is the gap DevTrace is trying
to close.&lt;/p&gt;

&lt;h2 id=&quot;try-it&quot;&gt;Try it&lt;/h2&gt;

&lt;p&gt;DevTrace is free to use. Score any public GitHub contributor at
&lt;a href=&quot;https://devtrace.thingz.io&quot;&gt;devtrace.thingz.io&lt;/a&gt; — the AI sensing layer runs
automatically as part of the trust score. Tier 1 metadata signals are available on
the free tier. Tier 2 behavioral signals are available on higher plans. The
&lt;a href=&quot;https://github.com/thingzio/devtrace-action&quot;&gt;GitHub Action&lt;/a&gt; integrates the same
scoring into your PR workflow.&lt;/p&gt;

&lt;p&gt;If you are also watching the project-level side of this —
&lt;a href=&quot;https://devpulse.thingz.io&quot;&gt;DevPulse&lt;/a&gt; detects sudden shifts in project contribution
patterns that can signal automated activity at the repository level: contributor
mix changes, velocity spikes, review ratio drops. Project-level anomalies and
contributor-level anomalies are usually correlated. Looking at both at once is how
you tell the difference between “the project just got popular” and “something is
off.”&lt;/p&gt;
</content>
    </entry>
    
    <entry>
        <title>Bus Factor 1: The Metric Your Dependency Review Is Missing</title>
        <link href="https://thingz.io/blog/bus-factor-1/"/>
        <updated>2026-04-25T00:00:00+00:00</updated>
        <id>https://thingz.io/blog/bus-factor-1/</id>
        <content type="html">&lt;p&gt;Stars, forks, and last-commit-date. These are the three numbers most developers check
before adopting a dependency. None of them answer the question that actually matters:
what happens if one person stops contributing?&lt;/p&gt;

&lt;p&gt;Bus factor — the number of contributors who account for 50% or more of recent
work — is the single strongest predictor of project fragility. A project with 10,000
stars and a bus factor of 1 is one resignation, one burnout, one job change away from
becoming unmaintained.&lt;/p&gt;

&lt;p&gt;This is not hypothetical. It is the pattern behind most of the open source failures
that make the news.&lt;/p&gt;

&lt;h2 id=&quot;the-metric-nobody-checks&quot;&gt;The metric nobody checks&lt;/h2&gt;

&lt;p&gt;When engineering teams evaluate a new dependency, the review process typically looks
like this: check the star count (social proof), check the last commit date (is it
alive?), maybe glance at the issue tracker (is anyone responding?). Some teams go
further and check the license, the test coverage, or the SBOM.&lt;/p&gt;

&lt;p&gt;Almost nobody checks how many people are actually doing the work.&lt;/p&gt;

&lt;p&gt;The problem is that GitHub’s default metrics create a misleading picture. A repository
can show 200 contributors in its history while only 1 of them has committed anything
in the last 90 days. The contributor list is a cumulative count. It tells you who has
ever touched the project, not who is keeping it alive right now.&lt;/p&gt;

&lt;p&gt;Bus factor corrects this by measuring concentration of recent work. The computation
is straightforward: rank contributors by their share of recent activity, then count
how many you need before you cross 50% of total contributions. If the answer is 1,
your dependency has a single point of failure.&lt;/p&gt;

&lt;h2 id=&quot;how-devpulse-computes-bus-factor&quot;&gt;How DevPulse computes bus factor&lt;/h2&gt;

&lt;p&gt;&lt;a href=&quot;https://devpulse.thingz.io&quot;&gt;DevPulse&lt;/a&gt; computes bus factor from actual contribution
events — pull requests, reviews, issues, and comments — over a configurable time
window (default: 90 days). The query ranks each contributor by event count, computes
a running cumulative sum, and returns the number of contributors whose cumulative
total first exceeds 50% of all activity.&lt;/p&gt;

&lt;p&gt;This is not an approximation or a heuristic. It is a direct measurement: how many
people would need to leave before more than half the project’s recent work output
disappears?&lt;/p&gt;

&lt;p&gt;DevPulse also computes a parallel metric called pony factor, which applies the same
50% threshold at the organization level. A bus factor of 3 sounds reasonable until
you realize all three contributors work at the same company. If that company
deprioritizes the project, the effect is the same as losing one person.&lt;/p&gt;

&lt;p&gt;Both numbers appear on the Health tab alongside an overall health grade that combines
them with demand, throughput, and responsiveness scores.&lt;/p&gt;

&lt;h2 id=&quot;what-bus-factor-1-actually-looks-like&quot;&gt;What bus factor 1 actually looks like&lt;/h2&gt;

&lt;p&gt;A project transitioning from healthy to fragile rarely announces itself. The pattern
is slow and the symptoms are easy to miss if you are not watching the right metrics.
Here is what to look for:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Contributor retention drops first.&lt;/strong&gt; Before a project becomes a one-person show,
it loses its returning contributors. DevPulse tracks new versus returning contributors
over time. A healthy project converts newcomers into repeat contributors. When
returning contributor count trends downward while new contributor count stays flat,
the community is not retaining people.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Time to first response climbs.&lt;/strong&gt; When fewer people are doing the work, incoming
issues and PRs wait longer for attention. DevPulse measures the hours until a PR gets
its first review and until an issue gets its first comment. This is the most direct
signal for contributor experience — slow responses drive external contributors
away, which accelerates the retention problem.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;PR review ratio deteriorates.&lt;/strong&gt; Healthy projects maintain a review culture where
PRs get reviewed before merge. When the reviewer pool shrinks, either PRs go
unreviewed or the remaining maintainer becomes the bottleneck. DevPulse tracks
reviews per PR over time. A declining ratio often precedes the bus factor dropping
to 1.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Lead time inflates.&lt;/strong&gt; Days from PR creation to merge stretch out. External
contributors submit work, wait, and eventually stop contributing. DevPulse’s velocity
charts show this clearly: lead time and first-response time trend upward together.&lt;/p&gt;

&lt;p&gt;The pattern reinforces itself. Fewer maintainers leads to slower responses, which
leads to fewer contributors, which leads to fewer maintainers. By the time bus factor
hits 1, the project has usually been in decline for months.&lt;/p&gt;

&lt;h2 id=&quot;stars-hide-fragility&quot;&gt;Stars hide fragility&lt;/h2&gt;

&lt;p&gt;It is tempting to treat star count as a health indicator. It is not. Stars are a
measure of historical interest, not current maintenance capacity.&lt;/p&gt;

&lt;p&gt;Consider the dynamics: a project gets popular, accumulates stars over years, and
becomes a transitive dependency for thousands of other projects. The original
maintainer gets a new job, starts a family, or simply burns out. Stars keep
accumulating because people keep discovering the project through blog posts,
tutorials, and Stack Overflow answers that were written when the project was actively
maintained.&lt;/p&gt;

&lt;p&gt;The star count says 15,000. The bus factor says 1. The last response to an external
PR was 4 months ago. The project is technically alive (there was a commit last month)
but functionally unmaintained for anyone outside the single remaining contributor.&lt;/p&gt;

&lt;p&gt;Forks tell a similar misleading story. A rising fork count without rising PRs often
means people are forking to work around issues they cannot get addressed upstream.
DevPulse tracks forks alongside activity events specifically to surface this
divergence.&lt;/p&gt;

&lt;h2 id=&quot;the-xz-utils-connection&quot;&gt;The xz-utils connection&lt;/h2&gt;

&lt;p&gt;The xz-utils incident (CVE-2024-3094) is primarily discussed as a social engineering
attack, and it was. But the precondition for the attack was a project health problem:
a critical compression library, depended on by most Linux distributions, maintained
by a single burned-out developer.&lt;/p&gt;

&lt;p&gt;The attacker did not need to compromise a large team. They needed to earn the trust
of one overwhelmed person. The bus factor was already 1 before the attack began. The
social engineering succeeded in part because the maintainer needed help and someone
showed up offering it.&lt;/p&gt;

&lt;p&gt;This is where project-level health metrics and contributor-level trust scoring are
complementary. DevPulse would have shown the fragility: bus factor 1, no meaningful
contributor retention, a single-person bottleneck. &lt;a href=&quot;https://devtrace.thingz.io&quot;&gt;DevTrace&lt;/a&gt;
would have provided the per-contributor analysis of the new person stepping in. Neither
tool alone tells the full story. Together, they surface the combination of conditions
that makes a project vulnerable.&lt;/p&gt;

&lt;h2 id=&quot;how-to-use-bus-factor-in-dependency-decisions&quot;&gt;How to use bus factor in dependency decisions&lt;/h2&gt;

&lt;p&gt;Bus factor is most useful as a triage metric — a fast way to separate dependencies
that need deeper investigation from those that are reasonably healthy.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Before adopting a dependency:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Open the project on DevPulse and check the Health tab. Bus factor and pony factor
tell you the concentration risk. But do not stop there. Check contributor retention
(are people sticking around?), time to first response (are external contributors
getting attention?), and PR review ratio (is there a review culture?). A bus factor
of 3 with strong retention and fast response times is a healthy project. A bus factor
of 3 where all three contributors are from the same org and retention is declining
is a project heading toward fragility.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;For dependencies you already use:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;DevPulse tracks metrics over time, so you can watch for trends. Set up your portfolio
to include your critical dependencies and check the Health Scorecard periodically. The
scorecard grades three categories — Demand (community interest and growth),
Throughput (how efficiently work moves), and Responsiveness (how quickly the team
reacts) — each on an A through F scale. A project whose responsiveness grade drops
from B to D over two quarters is telling you something, even if the star count keeps
climbing.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;At the organizational level:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;For OSPO leads and engineering managers, the portfolio view shows bus factor across
all tracked repositories in one table. Sort by bus factor to identify which
dependencies carry the most key-person risk. Cross-reference with your dependency
graph to understand blast radius: a bus-factor-1 library that appears in 3 services
is a different risk than one that appears in 300.&lt;/p&gt;

&lt;h2 id=&quot;what-the-metric-is-not&quot;&gt;What the metric is not&lt;/h2&gt;

&lt;p&gt;Bus factor measures concentration of recent work. It does not measure code quality,
security posture, or whether the project’s architecture is sound. A project with a
bus factor of 5 can still have unreviewed PRs, no test suite, and known
vulnerabilities.&lt;/p&gt;

&lt;p&gt;Bus factor also does not account for contribution quality. A maintainer who reviews
every PR and triages every issue contributes more to project health than someone who
commits frequently but only touches CI configuration. DevPulse weights all event
types equally in the bus factor computation because distinguishing “important” from
“routine” contributions requires judgment that a metric cannot automate.&lt;/p&gt;

&lt;p&gt;Treat bus factor as one input to your risk assessment, not the assessment itself. It
answers a specific question — how concentrated is the work? — and that question
matters more than most teams realize. But it is not the only question.&lt;/p&gt;

&lt;h2 id=&quot;check-your-dependencies&quot;&gt;Check your dependencies&lt;/h2&gt;

&lt;p&gt;DevPulse is free to use. Track any public GitHub repository at
&lt;a href=&quot;https://devpulse.thingz.io&quot;&gt;devpulse.thingz.io&lt;/a&gt; and see bus factor, pony factor,
contributor retention, velocity, and 30 other metrics across the Health, Activity,
Velocity, Quality, and Community dashboards.&lt;/p&gt;

&lt;p&gt;If you are also evaluating the contributors behind the bus factor number —
&lt;a href=&quot;https://devtrace.thingz.io&quot;&gt;DevTrace&lt;/a&gt; scores individual contributors across 23
signals covering identity, engagement, community standing, and behavioral patterns.
The two tools are complementary: DevPulse tells you the project has a bus factor of 1,
DevTrace helps you evaluate the one person it depends on.&lt;/p&gt;
</content>
    </entry>
    
    <entry>
        <title>Anatomy of a Trust Score: What 23 Signals Tell You About an Open Source Contributor</title>
        <link href="https://thingz.io/blog/anatomy-of-a-trust-score/"/>
        <updated>2026-04-22T00:00:00+00:00</updated>
        <id>https://thingz.io/blog/anatomy-of-a-trust-score/</id>
        <content type="html">&lt;p&gt;In early 2024, a contributor named Jia Tan planted a backdoor in xz-utils. It was
not a smash-and-grab. It was a two-year campaign: legitimate patches, earned trust,
commit access, then a carefully obfuscated payload that shipped to production
distributions before anyone noticed.&lt;/p&gt;

&lt;p&gt;Every tool in the open source security ecosystem — SCA scanners, container scanners,
SBOM generators — detected the vulnerability after the fact. None of them evaluated
the contributor before it happened.&lt;/p&gt;

&lt;p&gt;This is the problem &lt;a href=&quot;https://devtrace.thingz.io&quot;&gt;DevTrace&lt;/a&gt; tries to address. Not by
claiming it would have prevented xz-utils (we honestly do not know), but by asking a
different question: instead of scanning the package, what if you scored the person?&lt;/p&gt;

&lt;h2 id=&quot;what-a-trust-score-actually-measures&quot;&gt;What a trust score actually measures&lt;/h2&gt;

&lt;p&gt;DevTrace computes a numerical trust score between 0.0 and 1.0, mapped to a letter
grade (A+ through F). The score is built from 23 individual signals grouped into five
categories:&lt;/p&gt;

&lt;table&gt;
  &lt;thead&gt;
    &lt;tr&gt;
      &lt;th&gt;Category&lt;/th&gt;
      &lt;th&gt;What it captures&lt;/th&gt;
    &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
    &lt;tr&gt;
      &lt;td&gt;Code Provenance&lt;/td&gt;
      &lt;td&gt;Are commits cryptographically signed? How mature is the account?&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;Identity&lt;/td&gt;
      &lt;td&gt;How old is the account? What is their role in the project? Is the profile populated?&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;Engagement&lt;/td&gt;
      &lt;td&gt;How much of the work in this repo is theirs? How recently? Are their PRs getting merged?&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;Community&lt;/td&gt;
      &lt;td&gt;Do other developers follow this person? Do they maintain their own projects?&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;Behavioral&lt;/td&gt;
      &lt;td&gt;Is their activity consistent over time? Do they review code? Do they contribute across repos?&lt;/td&gt;
    &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;

&lt;p&gt;None of these categories alone tells you much. A brand-new account is not inherently
suspicious. A sparse profile does not mean bad intent. But the categories interact.
A new account with no profile, no code reviews, commits only to one repo, and a
sudden burst of merged PRs — that pattern is worth looking at more closely.&lt;/p&gt;

&lt;h2 id=&quot;the-23-signals&quot;&gt;The 23 signals&lt;/h2&gt;

&lt;p&gt;Here is what actually feeds the model, organized by category.&lt;/p&gt;

&lt;h3 id=&quot;code-provenance&quot;&gt;Code Provenance&lt;/h3&gt;

&lt;p&gt;This category only applies when DevTrace has repository context (i.e., you are
scoring a contributor in the context of a specific repo).&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;strong&gt;Verified commit ratio&lt;/strong&gt; — what fraction of this contributor’s commits are
cryptographically signed. Signing does not prove good intent, but it ties commits
to a verifiable identity. The xz-utils attacker’s commits were not signed.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Account maturity&lt;/strong&gt; — how old the account is, applied as a maturity factor on
the verification signal. A two-year-old account with signed commits carries more
weight than a two-week-old one.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3 id=&quot;identity&quot;&gt;Identity&lt;/h3&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;strong&gt;Account age&lt;/strong&gt; — days since account creation, mapped through a logarithmic curve
that saturates around two years. This means the difference between 30 days and 180
days matters more than the difference between 3 years and 5 years.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Author association&lt;/strong&gt; — the contributor’s relationship to the repository: owner,
member, collaborator, prior contributor, or first-time contributor. Each maps to a
different trust level.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Org membership&lt;/strong&gt; — whether the contributor belongs to the repository’s
organization, and whether they are in a trusted role.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Profile completeness&lt;/strong&gt; — five boolean signals: bio, company, location, website,
and public email. Each present field adds to the score. This is a weak signal
individually (anyone can fill in a profile), but its absence in combination with
other red flags becomes meaningful.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3 id=&quot;engagement&quot;&gt;Engagement&lt;/h3&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;strong&gt;Commit proportion&lt;/strong&gt; — what fraction of the repo’s total commits belong to this
contributor, adjusted for the number of contributors (a 10% share in a 3-person
project means something different than 10% in a 200-person project).&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Commit recency&lt;/strong&gt; — days since last commit, modeled as exponential decay with a
half-life that adjusts based on project size. Larger projects tolerate longer gaps.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;PR acceptance rate&lt;/strong&gt; — the ratio of merged PRs to total closed PRs. A high merge
rate with a reasonable sample size suggests the contributor’s work is consistently
accepted by reviewers.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3 id=&quot;community&quot;&gt;Community&lt;/h3&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;strong&gt;Follower ratio&lt;/strong&gt; — followers divided by following, capped at a saturation point.
This is a rough proxy for whether other developers know and trust this person.
Not a strong signal by itself, but a useful data point.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Public repositories&lt;/strong&gt; — how many repos the contributor maintains. More original
repos (not forks) suggest someone who builds and ships their own work, not just
drive-by patches.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3 id=&quot;behavioral&quot;&gt;Behavioral&lt;/h3&gt;

&lt;p&gt;This is where things get interesting. These signals come from
&lt;a href=&quot;https://www.gharchive.org/&quot;&gt;GH Archive&lt;/a&gt; data, which gives DevTrace a longitudinal
view of contributor activity across all of GitHub — not just the repo in question.&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;strong&gt;Consistency score&lt;/strong&gt; — how regular is this contributor’s activity over time?
Steady, sustained contribution patterns score higher than erratic bursts followed
by silence.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Review participation&lt;/strong&gt; — how many code reviews has this contributor performed
in the last 30 days? Contributors who review others’ code tend to be embedded in a
project’s community, not just passing through.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Repo diversity&lt;/strong&gt; — how many distinct repositories has this contributor been active
in over the last 90 days? Broader engagement suggests a real developer with real
interests, not a single-purpose account.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Burst rate&lt;/strong&gt; — recent PR activity relative to account age. A six-month-old
account that suddenly opens PRs across 15 repos is not the same as a five-year-old
account doing the same thing.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Fork ratio&lt;/strong&gt; — what fraction of the contributor’s public repos are forks versus
original work? Accounts that consist almost entirely of forks may not have a
meaningful development history of their own.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Plus one hard gate: if an account is &lt;strong&gt;suspended&lt;/strong&gt; by GitHub, the score is
automatically zero regardless of other signals.&lt;/p&gt;

&lt;h2 id=&quot;how-the-math-works&quot;&gt;How the math works&lt;/h2&gt;

&lt;p&gt;Each signal is normalized to a 0-to-1 range using one of three functions depending
on the signal type:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;strong&gt;Logarithmic curve&lt;/strong&gt; for signals with diminishing returns (account age, repo count).
The first year of account age matters a lot; the tenth year barely moves the needle.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Exponential decay&lt;/strong&gt; for freshness signals (commit recency). Recent activity scores
high; stale activity fades.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Linear ratio&lt;/strong&gt; for bounded signals (consistency, review count, diversity). Capped
at a saturation ceiling so outliers do not distort the score.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The normalized signal values are multiplied by their category weights and summed. When
a contributor is scored without repository context (no specific repo provided), the
repo-dependent weights — code provenance, commit proportion, recency, and author
association — are excluded and the remaining weights are rescaled so they still sum
to 1.0.&lt;/p&gt;

&lt;p&gt;The final number maps to a letter grade. A 0.73 is a B. A 0.57 is a C. Below 0.37
is an F.&lt;/p&gt;

&lt;h2 id=&quot;what-this-looks-like-on-the-xz-utils-timeline&quot;&gt;What this looks like on the xz-utils timeline&lt;/h2&gt;

&lt;p&gt;I want to be careful here. DevTrace did not exist during the xz-utils incident, and
I am not going to fabricate numbers. But I can walk through which signals would have
surfaced concerns based on what we know publicly about the “Jia Tan” account.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Identity signals that would have flagged:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The Jia Tan GitHub account was created specifically for the xz-utils campaign. At the
time commit access was granted, the account was roughly two years old — which
actually clears the account age signal. This is exactly why no single signal is
dispositive. But the profile was sparse: no company, no website, no other visible
community presence. The profile completeness signal would have scored low.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Engagement signals that would have flagged:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The account’s PR activity was concentrated in a single project. The commit proportion
in xz-utils would have been high relative to the small contributor base, which is not
inherently bad — but in combination with limited activity elsewhere, it paints a
picture of a single-purpose account.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Community signals that would have flagged:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The account had minimal followers and no meaningful following network. No public repos
of their own beyond the target project. The follower ratio and public repo count
signals would both have been low.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Behavioral signals that would have flagged:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;This is where the model is most relevant. The Jia Tan account showed a pattern that
DevTrace’s behavioral category is specifically designed to detect:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;strong&gt;Low repo diversity&lt;/strong&gt; — activity concentrated in one or two repositories&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;No review participation outside the target project&lt;/strong&gt; — a contributor embedded in
a real community typically reviews code across multiple projects&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Low consistency&lt;/strong&gt; — the activity pattern was purpose-driven, not the organic
rhythm of someone who codes across different projects over years&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;What would NOT have flagged:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Account age would have looked reasonable (two years is past the logarithmic inflection
point). The PR acceptance rate would have been high — the patches were legitimate and
useful. This is the hard part: social engineering works precisely because the work is
real. No scoring model catches everything.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The aggregate picture:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;No single signal would have raised an alarm. But the composite score — a
single-project account with a sparse profile, no community footprint, no code review
activity outside the target repo, and low diversity — would have landed well below
the scores of typical long-term maintainers. Not an automatic rejection, but a strong
signal that this contributor deserved more scrutiny before being granted commit access.&lt;/p&gt;

&lt;p&gt;That is the point. DevTrace does not make access control decisions. It provides data
so that maintainers can make better-informed ones.&lt;/p&gt;

&lt;h2 id=&quot;ai-sensing-the-newer-layer&quot;&gt;AI sensing: the newer layer&lt;/h2&gt;

&lt;p&gt;On top of the 23 core signals, DevTrace includes an AI sensing layer that looks for
signs of AI-generated or AI-assisted contributions. This is a separate concern from
trust scoring, but it is increasingly relevant.&lt;/p&gt;

&lt;p&gt;The first tier is metadata analysis: checking for co-authored-by trailers from known
AI tools, bot-associated PRs, and known tool signatures. The second tier, available
on higher plans, computes behavioral heuristics — velocity anomaly ratios, active
hour spread, and a burst-vanish score that flags contributors who appear in a sudden
burst of activity and then disappear.&lt;/p&gt;

&lt;p&gt;These are not about penalizing AI-assisted development. Copilot-assisted PRs are
normal. The concern is synthetic contributor accounts — manufactured identities with
fabricated histories. AI lowers the cost of creating these, and the behavioral
heuristics are designed to distinguish a real developer who uses AI tools from an
account that only exists because of them.&lt;/p&gt;

&lt;h2 id=&quot;nist-ssdf-mapping&quot;&gt;NIST SSDF mapping&lt;/h2&gt;

&lt;p&gt;For teams that need to demonstrate compliance with NIST SP 800-218 (the Secure
Software Development Framework), DevTrace maps its signals to eight SSDF practices
across three practice groups. These include code access controls, release integrity
verification, contributor identity provenance, code review participation, activity
consistency, anomaly detection, and contributor maturity assessment.&lt;/p&gt;

&lt;p&gt;The mapping is intentionally conservative — DevTrace describes where its signals
are “relevant to” a practice, never that they “satisfy” it. Compliance is a judgment
call for your organization, not something a tool can declare on your behalf. But
having the data organized against the framework saves time when the auditors come
around.&lt;/p&gt;

&lt;p&gt;Full methodology is documented at &lt;a href=&quot;https://devtrace.thingz.io/compliance&quot;&gt;devtrace.thingz.io/compliance&lt;/a&gt;.&lt;/p&gt;

&lt;h2 id=&quot;what-the-score-is-not&quot;&gt;What the score is not&lt;/h2&gt;

&lt;p&gt;A trust score is not a background check. It does not tell you whether someone is
trustworthy as a person. It tells you whether their observable behavior on a platform
matches the patterns of established, embedded contributors — or whether it
diverges in ways that warrant closer attention.&lt;/p&gt;

&lt;p&gt;A low score does not mean “reject this contributor.” A high score does not mean
“trust without review.” The score is one input to a decision, not the decision itself.&lt;/p&gt;

&lt;p&gt;We got into this because we watched the xz-utils story unfold and realized that
the open source ecosystem had robust tooling for scanning code and packages, but
almost nothing for evaluating the people who write them. DevTrace is our attempt to
close that gap. It is an imperfect attempt — 23 signals cannot fully capture the
complexity of human behavior — but it is a starting point.&lt;/p&gt;

&lt;h2 id=&quot;try-it&quot;&gt;Try it&lt;/h2&gt;

&lt;p&gt;DevTrace is free to use. Score any public GitHub contributor at
&lt;a href=&quot;https://devtrace.thingz.io&quot;&gt;devtrace.thingz.io&lt;/a&gt;. If you want contributor scoring
integrated into your PR workflow, there is a
&lt;a href=&quot;https://github.com/thingzio/devtrace-action&quot;&gt;GitHub Action&lt;/a&gt; that runs on every pull
request.&lt;/p&gt;

&lt;p&gt;If you are also thinking about the project-level side of this —
&lt;a href=&quot;https://devpulse.thingz.io&quot;&gt;DevPulse&lt;/a&gt; tracks the health metrics (bus factor,
contributor retention, review ratios) that often precede the kind of maintainer
burnout that made xz-utils vulnerable in the first place. The two tools are
complementary: DevPulse evaluates the project, DevTrace evaluates the people.&lt;/p&gt;
</content>
    </entry>
    
</feed>
