Refolk
FrameworkEngineering and open source

The Publisher-Change Verdict: Upgrade, Hold, or Block a Flagged Release

Take one flagged release, pull its publisher and maintainer history, score five dimensions, and record an Upgrade, Hold, or Block verdict a second engineer would repeat.

22 min readLast reviewed October 27, 2026Read as Markdown

Key takeaways

  • Valid provenance does not clear a release: 84 malicious TanStack versions shipped in under six minutes with valid SLSA Build Level 3 provenance, because the attacker controlled the source account and the real pipeline signed the result.
  • A flagged release gets a score of 0, 1, or 2 on each of five dimensions: publish-path continuity, account identity continuity, handover trail, contribution tenure of the new identity, and change content.
  • Block and pin whenever change content scores 0, or when publish path and account identity both score 0. Upgrade only when no dimension scores 0, change content scores 2, and the total is at least 8 of 10.
  • In the documented axios and Tensorlake compromises, scanners flagged the malicious release 6 to 11 minutes after publish, while axios stayed live for about 3 hours, so a 1-day cooldown outlasts the install-time window in those cases.
  • PyPI keeps no ownership history and no API names the uploader, so you can only detect a publisher change on PyPI by comparing against ownership.roles snapshots you stored yourself.
  • Refolk's index holds only 2 US profiles with supply-chain or open-source security engineer titles, against 40 with maintainer or OSPO titles. The verdict usually lands on a generalist engineer, so it needs a written rubric.

This is the decision standard for one specific moment. A package you already depend on ships a release from a different account, or without the provenance its earlier versions carried, or with a changed maintainer list, and someone has to decide today whether to take it. It is for the engineering manager, technical founder, developer-relations lead, or sourcer who ends up holding that call. It gives you five scored dimensions, a rule that turns the scores into Upgrade, Hold, or Block and pin, and a record format a second engineer can check line by line.

What does the publisher-change verdict decide?

The publisher-change verdict decides whether the person behind a flagged release is the legitimate maintainer. That answer determines whether you upgrade, hold the release behind a cooldown until named checks clear, or block it and pin the last good version. The verdict treats the release as a question about a person's identity, not about package hygiene.

A release is flagged when any of these is true compared with the last version you trusted:

  • The publishing account (_npmUser on npm) is different.
  • The previous version carried a provenance attestation and this one does not.
  • The npm maintainers[] list or the PyPI ownership.roles list has changed.
  • The PyPI ownership.organization has changed. This is how a project ownership transfer looks from outside.

The three verdicts mean specific things:

  • Upgrade. Take the release on your normal schedule, including the standard cooldown.
  • Hold. Keep the cooldown in force and deny any exemption until a named list of checks clears. Every Hold names its checks and the person who clears them.
  • Block and pin. Pin the last good version in your lockfile and refuse the flagged one until the maintainers publish an explanation you can verify.

Why provenance no longer settles it

Provenance is a signed attestation that binds a published tarball to the CI workflow that built it. It looked like the obvious shortcut: if the release came through the real pipeline, it came from the real maintainers. Worm-style compromises broke that shortcut. An attacker who controls a maintainer's source account can push to the branch, and the legitimate workflow then builds and signs the result.

84
Malicious TanStack versions published with valid SLSA Build Level 3 provenance in under six minutes
The 84 versions covered 42 packages, and every signature checked out because the attacker pushed through the real pipeline.

What a provenance signature actually vouches for

  1. Person
    The human behind the account; provenance says nothing about this layer
  2. Source account and branch
    Whoever can push or merge to the default branch
  3. CI workflow
    The trusted publisher identity named in the attestation
  4. Tarball
    The published file the signature is bound to
Provenance binds the tarball to the workflow, so whoever controls the source branch inherits the signature.

So the verdict has to look past the signature to the account that pushed the code, and past the account to the person.

Which registry fields show a publisher change?

On npm, the registry document records three things for each version: who published it, the maintainer list at publication time, and any provenance attestation. On PyPI you get the current ownership roles and a separate provenance endpoint, but no uploader and no history. Read each field for what it proves and for how it can mislead you.

FieldRegistryWhat it provesHow it lies
_npmUsernpmAccount that published the versionUnder staged publishing, may name the approver
_npmUser.trustedPublishernpmPublish came through a configured CI identityA hijacked source account still publishes through real CI
maintainers[]npmMaintainer list and emails at publish timeA changed email can sit on the same account name
dist.attestations.provenancenpmAn attestation existsAlso present on token publishes with provenance
ownership.rolesPyPICurrent owners and maintainersCurrent state only; no history
Integrity API provenancePyPITrusted Publisher kind, repo, workflow, environmentUploader is never named

On npm, fetch https://registry.npmjs.org/<package> and compare the versions entries for the previous and flagged releases. Practitioners have an open complaint that npm has no field equivalent to provenance for trusted or staged publishing. So read trustedPublisher and _npmUser together, and never rely on dist.attestations alone.

On PyPI, the JSON API gives you ownership.roles and ownership.organization. The Integrity API at /integrity/{project}/{version}/{filename}/provenance returns the Trusted Publisher identity behind the PEP 740 attestations. The JSON API does not expose the trusted-publisher configuration, which appears only on the project's Publishing page. One practitioner audit found that no API names the account that uploaded a file.

A missing attestation on PyPI means something only if earlier versions had one. A single-PR audit put attestation of the latest release at 44% of the top 500 projects. I treat that figure as unverified, but it means absence is common and is not a signal by itself.

I have not verified the equivalent fields for crates.io, RubyGems, or Packagist. Check each registry's own documentation before you apply this table to them.

The five dimensions and how to score each

Score each dimension 0, 1, or 2. A 2 means the release is continuous with the trusted history. A 1 means something changed but evidence you can verify explains it. A 0 means something changed and nothing explains it, or the evidence contradicts it. Write one line of evidence beside every score so a reviewer can check it without redoing your work.

Dimension2: continuous1: changed, explained0: changed, unexplained
Publish pathSame trusted publisher, tag, PR-merged commitsPath changed; tag and file list matchNo tag, or commits bypassed PRs
Account identitySame account and maintainer emailsNew account tied to known maintainer or orgNew account or email, no link
Handover trailNone needed, or posted by an existing maintainerTrail exists, only from new accountsNone, or flooded by new accounts
New identity tenureNo new identity, or broad history and normal escalationThin history, no pressure patternPressure patterns or sudden elevation
Change contentMatches tagged source; no new scriptsNew dependency that source importsUnimported dependency, lifecycle script, .pth, blobs

Publish-path continuity

This dimension proves the release took the same route from source to registry as the versions you trusted. That means the same trusted publisher, a tag that exists before the publish, and commits that reached the default branch through pull requests. Legitimate releases leave a gap you can see: the Playwright release was tagged 22 minutes before the npm publish.

When it lies: valid provenance gives a false clear when a hijacked source account pushes through the real CI. In the Tensorlake case, malicious commits landed under a maintainer's name and none went through a pull request. A clean trustedPublisher with direct commits to the default branch scores 0, not 2.

Account identity continuity

This dimension proves the same account, with the same contact identity, published the release. In the axios compromise the maintainer email changed at the same time as the publish path. Also watch for several release lines published from a new path in quick succession. Axios 1.14.1 and 0.30.4 went out 39 minutes apart, and LiteLLM 1.82.7 and 1.82.8 about 13 minutes apart.

When it lies: under staged publishing, _npmUser may name the npm user who approved the release, not the one who built it. On PyPI a change of uploader is invisible. One practitioner reports buying a sole author's expired email domain. In that case the account looks unchanged even though someone else now controls it.

Handover trail

This dimension proves that someone who was already trusted announced a legitimate change. Documented precedents:

  • Corporate release-infrastructure change: @playwright/cli 0.1.19 dropped provenance and _npmUser moved to "microsoft1es". A GitHub issue in the Playwright repository documents the change.
  • Identity rotation after an incident: LiteLLM moved to new maintainer accounts and documented it in pinned issue #24518.
  • Temporary token publishing while OIDC is set up: one project recorded this in a repository issue.

When it lies: attackers can manufacture a trail. During the LiteLLM incident, attackers posted 88 bot comments from 73 unique accounts in a 102-second window. A trail only counts toward a 2 if a maintainer account that existed before the change posted it. For foundation transfers and acquisitions I found no publicly established pattern of documenting artifact. In those cases I would look for the announcement on the foundation's or acquirer's existing channels and score 1 until I found it.

Contribution tenure of the new identity

This dimension proves the new identity has a real history beyond this one package. Record account age, contributions across other projects, and how the person gained permissions. Then check for the patterns in the OpenSSF/OpenJS alert on social-engineering takeovers:

  • Friendly yet aggressive and persistent pursuit of the maintainer by unknown members
  • Requests for elevated rights from new people
  • Sock-puppet endorsements
  • Binary blobs in pull requests

When it lies: tenure can make an attacker look trustworthy. The xz attacker's work represented 2.6 years of sustained, patient engagement. No numeric tenure threshold such as "six months" is publicly established, so do not invent one. Tenure can lower a verdict but never raise it above what path and content allow.

Building the cross-project footprint takes the longest in the whole procedure, because the evidence is scattered across commits, profiles, and talks. Refolk lets you ask for the person in plain English and returns their footprint across GitHub, LinkedIn, and the open web. It also shows who currently holds merge rights on the repository, which tells you whose confirmation to seek.

Change content

This dimension proves what will actually execute on your machines. Diff the published files against the tagged source and look for:

  • New dependencies, and whether source actually imports them
  • Lifecycle scripts such as postinstall
  • .pth files in Python packages
  • Binary blobs and unexplained changes to the file list

When it lies: attackers pre-stage dependencies so they do not look new. A clean decoy, plain-crypto-js 4.2.0, was published about 18 hours before the malicious 4.2.1 that axios pulled in. The test is whether anything imports the dependency, not how old it is.

How do the scores become Upgrade, Hold, or Block?

Block and pin when change content scores 0, or when publish path and account identity both score 0. Upgrade only when no dimension scores 0, change content scores 2, and the total is at least 8 of 10. Everything else is a Hold, and every Hold lists the checks that would move each low score to 2.

The rule in order:

  1. Block and pin if change content = 0.
  2. Block and pin if publish path = 0 and account identity = 0.
  3. Upgrade if no dimension is 0, change content = 2, and the total is 8 or more.
  4. Hold in every other case, with named checks.

These thresholds are my rubric, not a published standard. Their job is to make two engineers reach the same answer. Tenure is deliberately weak: a high tenure score cannot pull a release out of Block.

Path continuity against change content

Content cleanContent risky
Explained infra change
Hold; find the tag, a matching file list, and a trail posted by an existing maintainer
Normal release
Upgrade after the standard cooldown
Token hijack
Block and pin; this is the axios pattern
Source-account worm
Block and pin despite valid provenance; this is the TanStack pattern
Path and identity brokenPath and identity continuous
Clean content can earn a broken publish path a Hold while checks run, but continuous provenance never excuses risky content.

The documented incidents land cleanly on this grid:

IncidentPublish pathProvenanceContent signal
axios 1.14.1OIDC replaced by CLI token; email changedLostPhantom dependency with postinstall
LiteLLM 1.82.7Stolen token, direct uploadUnverified.pth file (in 1.82.8)
TanStackReal pipelineValid SLSA L3Worm
Tensorlake 0.5.144Real workflow; direct commits, no PRValidWorm

Axios scores 0 on path, identity, and content, so it is a Block under either rule. Before its compromise, the legitimate 1.14.0 had been published through OIDC trusted publishing. LiteLLM's last legitimate CI-published version came eleven days before the malicious upload, so its path scores 0 and its content scores 0. TanStack and Tensorlake would pass an automated provenance check, but both score 0 on content, and Tensorlake also scores 0 on path because the commits bypassed review. The Playwright handover is the opposite case. It scores 1 on path and identity and 2 on content once you confirm the file list matches. That makes it a Hold that turns into an Upgrade when the issue is confirmed.

Step-by-step: scoring one flagged release

Work through seven checks in order, writing each result into the verdict record as you go, then have a second engineer review it. The time estimates below are rough and unsourced, but the full pass is roughly an hour and a half of focused work.

Scoring one flagged release

  1. Diff the registry snapshot
    Compare the previous and flagged versions on _npmUser, trustedPublisher, dist.attestations, and maintainer emails, or PyPI roles against your stored snapshot. About 10 minutes; done when the diff table is in the record.
  2. Check the publish path against the repo
    Confirm a matching tag exists and note the gap between tag and publish. About 10 minutes.
  3. Check the commit path
    Confirm every commit reached the default branch through a pull request and look for a new committer. About 15 minutes.
  4. Look for a handover trail
    Find an announcement, pinned issue, org transfer, or PyPI ownership.organization change, and note who posted it. About 15 minutes.
  5. Check the new identity's tenure and footprint
    Record account age, cross-project contributions, permission timeline, and any OpenSSF pressure patterns. About 30 minutes.
  6. Review the change content
    Check new dependencies and whether they are imported, lifecycle scripts, .pth files, blobs, and file-list changes. About 20 minutes; never skipped.
  7. Record the verdict and get a second review
    Apply the verdict rule, name the checks for any Hold, and have a second engineer confirm the same verdict.

Sources disagree on ordering. pnpm's trustPolicy: no-downgrade runs the automated provenance check first and fails closed. That is a sound gate, because a downgrade stops the install before a human looks. Some security researchers argue that provenance must never clear a release on its own. Both positions fit this procedure: let the automated gate run first, and still do step 6 when steps 1 and 2 pass.

Publisher-change verdict record
Package:
Flagged version:              Previous trusted version:
Trigger: publisher changed / provenance lost / maintainers changed / PyPI ownership changed

1. Registry diff
Field                          | Previous | Flagged
_npmUser                       |          |
_npmUser.trustedPublisher      |          |
maintainers (emails)           |          |
dist.attestations.provenance   |          |
PyPI ownership.roles / org     |          |   (from stored snapshot)

2. Publish path   Tag exists: Y/N   Tag-to-publish gap:
3. Commit path    All commits via PR: Y/N   New committer on default branch: Y/N
   Publish path score (0/1/2):          Evidence:
   Account identity score (0/1/2):      Evidence:
4. Handover trail link:
   Posted by pre-existing maintainer account: Y/N
   Handover score (0/1/2):              Evidence:
5. New identity   Account age:   Cross-project footprint:   OpenSSF patterns seen:
   Tenure score (0/1/2):                Evidence:
6. Change content   New deps (imported in source? Y/N):   Lifecycle scripts:   .pth files:   File-list diff:
   Content score (0/1/2):               Evidence:

Total: __/10    Any zero: Y/N
Verdict: Upgrade / Hold / Block and pin
If Hold, named checks and owner:
-
Cooldown exemption: denied / granted by:
Scored by:                Reviewed by:

Write one record per flagged release. Paste the registry diff verbatim and score every dimension, even when the verdict is obvious.

How does the publisher-change verdict go wrong?

Most wrong verdicts come from trusting one signal for something it cannot prove. Provenance gets read as identity, a new dependency gets read as a fresh dependency, and issue chatter gets read as a handover. Each failure below names the signal, how it misleads, and the check that catches it.

  1. Valid provenance gives a false clear. A hijacked source account publishes through the real CI, as happened with TanStack and keyv. Check: were all commits merged through pull requests, and is there a new committer on the default branch?
  2. The _npmUser read misleads. Staged publishing records the approver, and token publishes can still carry attestations. Check: read trustedPublisher, not dist.attestations alone.
  3. Pre-staging defeats the "new dependency" check. plain-crypto-js had existed for about 18 hours before the malicious version. Check: is the dependency actually imported in source? A dependency nothing imports, especially one that carries a lifecycle script, scores 0.
  4. A trust downgrade is a false positive. Playwright's move to microsoft1es was legitimate even though provenance disappeared. Check: look for a matching tag and an identical file list before you Block. Hold instead.
  5. A PyPI uploader change is invisible. No API names the uploader. Check: look for attestation presence and diff against your stored ownership snapshot.
  6. Tenure clears an attacker. The xz attacker had 2.6 years of tenure. Check: look for sock-puppet pressure and read the timeline of permission escalation, not just the account's age.
  7. The handover trail is manufactured. LiteLLM issue threads were flooded with bot comments. Check: treat issue chatter as unverified unless a maintainer account that existed before the change posted it.
  8. The cooldown silently fails. npm older than 11.10 ignores min-release-age. A pnpm 10.x bug ignores the cooldown when shared-workspace-lockfile=false. Check: run the package manager's config get for the setting on the version your CI actually runs.
Provenance tells you which workflow built the tarball. It does not tell you who pushed to the branch.

How do you run a Hold: cooldowns and exemption approval

A Hold works because of the cooldown. A cooldown is a minimum release age your package manager enforces before it will install a new version. The Hold verdict amounts to refusing the per-package exemption until named checks clear, so you need to know your tool's setting, its unit, and its exemption key.

ToolSetting and unitDefaultPer-package exemption
npmmin-release-age, days, CLI 11.10.0+OffDisputed
pnpmminimumReleaseAge, minutes, 10.16+1440 from v11minimumReleaseAgeExclude
YarnnpmMinimalAgeGate, minutes or duration, Berry 4.10.0+1 day; version disputednpmPreapprovedPackages
BunminimumReleaseAge, secondsUnverifiedminimumReleaseAgeExcludes

Sources conflict on several cells. For npm, one source gives min-release-age-exclude and --min-release-age=0, and another says npm has no exclusion yet and points to CLI issue #8994. For Yarn, sources disagree on which version introduced the 1-day default and on the unit, and one reports that suffixed duration strings are ignored on some versions. Renovate 42's config:best-practices preset reportedly sets a 3-day default. I did not verify uv exclude-newer, pip uploaded-prior-to, or Dependabot cooldown. Before you rely on any of these, confirm the value on your installed version.

Where a 1-day cooldown sits against documented timelines

  1. Publish
    The malicious version goes live on the registry
  2. First flag
    6 to 11 minutes in the axios and Tensorlake cases
  3. Removal
    About 3 hours live for axios; about 4h50m to deletion for LiteLLM
  4. Cooldown ends
    1 day after publish, after removal in these cases
  5. Not covered
    Upstream CI credential theft that began days earlier
In documented compromises, scanners flagged releases within minutes and registries removed them within hours, so a 1-day cooldown outlasts the install-time window.

The cooldown has limits. It covers the install-time window in these cases. It does not cover theft of upstream CI credentials, and in the LiteLLM case credential collection started five days before the malicious publish. A cooldown buys time for scanners and registries to act. It does not replace the verdict.

The exemption approval process I use:

  • Grant an exemption only for a release that has scored Upgrade in a reviewed record.
  • Record the approver's name in the record, next to the exemption key used.
  • For a Hold, deny the exemption and list the checks and their owner.
  • Remove the exemption once the release has aged past the cooldown, so it does not quietly cover later versions.

When a Hold turns on a handover question, ask a maintainer you already know to confirm it.

Confirmation request to a pre-existing maintainer
Hi <name>,

I work on a team that depends on <package>, and my tooling flagged <flagged version>. It was published by <account or path>, while <previous version> came through <previous publisher or workflow>.

Before I take it, can you confirm two things?
1. Did you, or a maintainer you added, publish this release?
2. Is the change in publish path or maintainers expected, and is it documented anywhere?

I am holding the upgrade until I hear back. If this was not you, the release may come from a compromised account, and you may want to check your tokens and CI credentials.

Thanks,
<your name>, <team>

Send this through a channel that existed before the flagged release, never to a contact listed in the new release or its issue thread.

Who should own the verdict?

The verdict should belong to a named engineer working from the written rubric, with a second engineer reviewing. Few organisations have a dedicated supply-chain security person, so the owner will usually be a generalist.

2
US profiles in Refolk's index with supply-chain or open-source security engineer titles
The two are at Google and AWS. The same title search in Germany returns zero.
SegmentCountryProfiles
Supply-chain or OSS security engineer titlesUS2
Same titlesGermany0
Open source maintainer or OSPO titlesUS40

In Refolk's index of professional profiles, US maintainer and OSPO titles outnumber supply-chain security titles 20 to 1. The top employer among the 40 is Akuity, with 2, and the SF Bay Area accounts for 6 of 25 sampled profiles. These are exact-title matches, so they are a floor, not the size of the market. Plenty of people do this work under other titles. Still, the inference is that few people hold this as a titled job. Expect the verdict to land on whoever is on call, and design for that: the rubric, the record, and the second review exist so that a generalist and a specialist reach the same answer.

If you want a specialist to review your rubric, or you are hiring for the role, the titled pool is too small to wait for. Searching on the work itself, such as contributions to Sigstore, pnpm, or the npm CLI, finds people that title searches miss. Refolk runs that kind of search in plain English across GitHub and professional profiles.

How do you keep the verdict current?

Keep the verdict current by storing snapshots, re-checking the registry protections whose behaviour changes, and re-running the checklist on every flagged release. The registry metadata stays stable, but the protections around it change, and so do the tools' defaults.

What to re-check, and how:

  • npm's account-change hold. npm places high-impact accounts in read-only mode for 72 hours after an email change or use of a 2FA recovery code. npm has not restated the "high-impact" threshold. One analysis infers it matches npm's 2FA policy: more than 1M weekly downloads or 500 dependents. Long-lived tokens never trigger the hold, and the axios versions were published with one. Check npm's current documentation for the threshold before you count on it.
  • Staged publishing. It is opt-in. When a package uses it, read _npmUser as a possible approver.
  • Tool defaults and exemption syntax. Re-run config get after every package manager upgrade, and watch npm CLI issue #8994 for the exclusion syntax.
  • Ownership snapshots. Save PyPI ownership.roles and ownership.organization, and the npm maintainers[] list, at every adoption and upgrade. Without them, a PyPI ownership transfer is invisible.
  • Precedents. When a legitimate handover is documented, link it in your records. When a new compromise pattern appears, add its signal to the failure-mode list.

Before you call the verdict done

  • The registry diff for the previous and flagged versions is pasted into the record.
  • Each of the five dimensions has a 0, 1, or 2 with one line of checkable evidence.
  • Change content was reviewed even though provenance was present.
  • Every new dependency was checked for an actual import in source.
  • Any handover evidence cited was posted by an account that existed before the flagged release.
  • For PyPI, ownership roles were compared against a stored snapshot, not memory.
  • The cooldown setting was confirmed with config get on the package manager version CI runs.
  • Any Hold lists named checks, an owner, and an exemption decision.
  • A second engineer read the record and reached the same verdict.

Questions practitioners ask

How do I tell if an npm package was hijacked?

Compare the flagged version with the last trusted version in the registry document. Check whether _npmUser changed, whether trusted publishing gave way to a direct token publish, whether maintainer emails changed, and whether a new dependency with a postinstall script appeared. In the axios compromise all four happened together. Then confirm the release has a matching tag and that its commits went through pull requests. Worm-style hijacks publish through the real pipeline and keep valid provenance.

A new maintainer was added to a dependency. Is it safe to upgrade?

Not until you have scored the new identity and the change content. Look for a handover note posted by a maintainer account that existed before the change. Check the new account's age and its contributions to other projects, and look for the OpenSSF/OpenJS warning signs: persistent pressure on the maintainer, sudden requests for elevated rights, and sock-puppet endorsements. Tenure alone proves nothing, because the xz attacker spent 2.6 years building trust. Hold until the content review is clean.

What should I do when a package is published without provenance?

Hold it and find out why the publish path changed. Missing provenance is only a signal if earlier versions had it. Then look for a matching repository tag published before the release, a file list identical to the source, and an explanation from an existing maintainer. Playwright's move to a corporate release account dropped provenance legitimately, so a downgrade alone is not grounds to Block.

How should a dependency cooldown exception approval process work?

Grant an exemption only for a release that has scored Upgrade under the written rubric, and record who approved it. Use the package manager's per-package exemption key: minimumReleaseAgeExclude in pnpm, npmPreapprovedPackages in Yarn. npm's exclusion syntax is disputed, so confirm it on your installed version. If the release scored Hold, deny the exemption until the named checks clear. Remove the exemption once the release has aged past the cooldown.

Is a PyPI project ownership transfer a risk?

It can be, and you cannot see it unless you saved the earlier state. PyPI only exposes current ownership.roles and ownership.organization, keeps no history, and no API names the account that uploaded a file. Store a snapshot of the roles each time you adopt or upgrade a project, diff against it, and check whether the new release carries a Trusted Publisher attestation from the same repository and workflow as before.

Does valid provenance mean a release is safe?

No. Provenance proves which CI workflow built the tarball, not who pushed the code that workflow built. In the TanStack compromise, 84 malicious versions carried valid SLSA Build Level 3 provenance because the attacker controlled a source account. Valid provenance can earn the publish path a 2, but the change content review still has to happen.

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