Refolk
FrameworkEngineering and open source

The Security Report Intake Read: Reproduce, Request PoC, Dedupe, or Decline

Score any inbound security report on five evidence dimensions and reach one of four defensible verdicts, with the reply, in under fifteen minutes.

24 min readLast reviewed November 13, 2026Read as Markdown

Key takeaways

  • Over one reporting window, the PHP security team published 15 CVEs and closed 106 reports, about 7.1 closures for every confirmed vulnerability.
  • curl's confirmed share of security reports fell below 5% and then recovered to 15 to 16% while submission volume roughly doubled, so the scarce resource is now reproduction capacity, not the ability to spot fabricated reports.
  • Close a report as out of scope only against a written SECURITY.md clause that names the attacker position it fails to reach, never on writing style or suspected AI use.
  • git log -L fails when the cited function does not exist at the named revision, but it also fails after a rename, so run git log -S on the old name before treating a missing function as fabrication.
  • Two reporters finding the same bug no longer confirm each other, because researchers who prompt the same model get the same answers, so match duplicates on root cause and not on wording.
  • Reporter track record from accepted GitHub advisory credits or HackerOne Signal, which stays blank until a reporter has more than 3 closed reports, should only break ties, and GitHub's trusted-reporter allow list exempts reporters from rate limits, not from validation.

A private vulnerability report has landed on a repo you maintain. The queue already holds more than you can reproduce this week, and you have about fifteen minutes to decide what this one gets. This guide gives maintainers, security leads and the people who triage for them a scored read: five evidence dimensions, four verdicts and a reply for each. It is built so that two maintainers grading the same report reach the same verdict, and so that nothing is closed on writing style.

What does the intake read decide?

The intake read decides where a single report goes next. There are four options: a reproduction slot, a single request for proof, a close as duplicate or already fixed, or a decline. It does not set severity, assign a CVE or judge the person who sent the report.

VerdictTriggerWhat you send
ReproduceRunnable PoC at a named revision, in scope, no prior matchAcknowledgement and a booked slot
Request PoCPlausible, but nothing runs as writtenOne request listing what is missing
Dedupe or already fixedSame root cause found in the queue, the advisories or git historyA pointer to the match
DeclineOutside the written threat model, or still no PoC after the one requestThe SECURITY.md clause, or the unanswered request

A PoC (proof of concept) is an input, script or command sequence that triggers the claimed behaviour. A named revision is the commit hash or tag the reporter says they tested against. Throughout this guide it is written as REV.

Why reproduction slots have to be rationed

Few reports turn out to be real vulnerabilities, and confirming each one is expensive. Here are the public numbers from two projects that published them:

Project and windowConfirmedClosedValid share
PHP, Jul 1 to Oct 14, 202615 CVEs10612.4% (derived)
curl, historicn/an/aabove 15%
curl, 2025n/an/abelow 5%
curl, April 2026n/an/a15 to 16%

The PHP share is 15 confirmed out of 121 resolved reports. PHP closed its 106 reports for three reasons: the report was not a vulnerability, it duplicated something already in the queue, or it did not reproduce. PHP did not publish how the 106 split across those reasons, and I found no public per-reason split for any project or platform. If you want that split for your own queue, record the closing reason on every report from now on.

7.1
Reports closed for every CVE the PHP security team published
Derived from 106 closures against 15 published CVEs in one reporting window; the split by closing reason was not published.

Each confirmation costs real time. One secondary source says curl's seven-member security team spends 30 minutes to three hours per report, with 3 to 4 team members involved in each one. That works out to roughly 1.5 to 12 person-hours per report, but treat the range as unverified. GitHub says validating even one poor-quality report can take hours. A Node.js triager describes the asymmetry this way: generating a report takes thirty seconds and reviewing it takes an hour. No project publishes a median time, and none separates the time spent confirming valid reports from the time spent rejecting invalid ones.

The problem has changed from fake reports to real minor findings

Periodcurl inbound volumePer week
Before AI-assisted reportingabout 1 per week1
July 2025about 2 per week2
Mid-20261 every 18 hours9.3 (derived)

curl's valid share fell below 5% at the height of the flood of AI-generated reports. It then recovered to 15 to 16% while volume ran at roughly double the already high rate of the year before. Log4j describes the same pattern: many reports describe real behaviour that is not hallucinated, but the vast majority do not meet its definition of a vulnerability under its threat model. That means the hard part is no longer spotting fabrication. It is deciding fast, and defensibly, which real findings deserve a slot. At 9.3 reports a week with a 15% valid rate, that is still roughly 8 closes a week, and each one needs a reason you can write down.

What do platform intake controls filter, and what do they miss?

GitHub's private vulnerability reporting controls filter for completeness and volume, not validity. The structured form makes reporters fill in required fields, rate limits cap how many reports one account can file, and an allow list exempts trusted reporters from those caps. None of these controls tells you whether a report is true.

What each intake layer filters

  1. Per-account rate limits
    Cap how many reports one account files per day, to your repo and across GitHub
  2. Trusted-reporter allow list
    Exempts named reporters from both caps without validating their reports
  3. Structured report form
    Requires summary, details, PoC and impact, but 150 characters of prose still passes
  4. CWE and AI-use fields
    Classification and disclosure, both supplied by the reporter
  5. Human intake read
    The only layer that tests the report against the repository
Every platform layer filters for volume or completeness, and only the human intake read tests whether a report is true.

Here is what each control does and how it can mislead you:

  • Default form. Reporters must fill in a summary, details, a proof of concept of at least 150 characters, and an impact statement. Proves: the reporter wrote something in every box. Lies when: the PoC is 150 characters of description with no input you can run.
  • Custom form. You can define your own form by adding .github/VULNERABILITY_REPORT.yml to the default branch. Custom forms support min_length, and reports submitted through the REST API must match the custom form, whereas the default form is not enforced for the API. Lies when: the YAML is invalid, because GitHub then silently falls back to the default form. After every edit, file a test report from a second account to confirm the custom form is live.
  • Required CWE. You can require reporters to assign a CWE (a Common Weakness Enumeration category, such as out-of-bounds read) before they submit. Proves: the reporter picked a weakness class. Lies when: the class is a guess. It is still useful, because it lets you filter the advisory database later.
  • AI-use checkbox. Reporters can tick a box to disclose AI use. It is self-reported. Record the answer but do not score it.
  • Rate limits. These cap how many new reports one account can submit per day, both to your repository and across GitHub. GitHub has not published the thresholds. The limits work on volume, not validity.
  • Allow list. Repository admins can add trusted reporters, whose reports then count toward neither your repository's limit nor the reporter's global limit. It exempts them from throttling, not from your triage.

Two of these facts can change without notice: the rate-limit thresholds and the form schema. Re-check them in GitHub's private vulnerability reporting configuration docs whenever you change your setup, rather than relying on a number someone remembers.

Also check what your platform can do with an invalid report after you close it. curl moved its intake from HackerOne to GitHub and later went back, partly because GitHub could not label reports as AI slop, could not publish invalid reports, and sent whole reports over email. Publishing invalid reports discourages more of them. If your platform cannot do that, your intake read has to absorb the extra volume.

The five evidence dimensions and how to score them

Score every report from 0 to 2 on five dimensions: reproducer quality at a named revision, code-reference validity, threat-model fit, prior art and silent fixes, and reporter track record. The first four decide the verdict. The fifth only breaks ties, and it is recorded last so that it cannot colour the other four scores.

DimensionWhat a 2 provesHow it lies
Reproducer qualitySomeone ran a real input against real codeProse padded past 150 characters
Code-reference validityThe report concerns code that exists at REVReal code, impact that is not real
Threat-model fitThe attacker crosses a boundary you promise to defendA silent SECURITY.md makes everything look in scope
Prior art and silent fixNothing already covers this root causeFixes that pickaxe cannot see
Track recordThe reporter has accepted, credited findingsUnaccepted credits are invisible, new researchers look blank

D1: Reproducer quality against a named revision

The OpenSSF guide on handling external findings says to require evidence that a report may be a vulnerability, and in particular a sample input that demonstrates it. Score:

  • 0: no input, or only a description of one.
  • 1: an input or steps exist, but there is no named revision, or the input cannot run as written (missing files, pseudo-code, a build flag that is never stated).
  • 2: a concrete input or script, a named commit or tag, and the expected versus observed output.

At intake you are judging whether the PoC could run as written. Running it to confirm the bug happens in the reproduction slot.

D2: Code-reference validity

Resolve every cited path and function at REV:

  • git rev-parse --verify REV^{commit} confirms the revision exists.
  • git show REV:path/to/file confirms the file exists at REV.
  • git log -L :function_name:path/to/file REV confirms the function exists. The git documentation says the walk starts from a single revision and the function name must exist in that starting revision, so a missing function makes the command fail.

Score 0 if cited code is absent at REV and no rename explains it, 1 if it resolves with drift (line numbers off, or a rename confirmed with git log -S), and 2 if every reference resolves exactly.

D3: Threat-model fit

Compare the attacker position the report claims with your SECURITY.md. The attacker position is what the attacker must already control for the exploit to work, such as the input, the configuration or the host. Score 0 if a written clause puts that position out of scope, 1 if SECURITY.md is silent or ambiguous, and 2 if the report crosses a boundary you have documented as defended. PHP notes that some of its reports came from very confident fuzzers running PHP in ways no production setup does. That is the classic 0.

D4: Prior art and silent fix

Score 0 if you found a match on the same root cause in the queue, your advisories, the global database or a fixing commit between REV and HEAD. Score 1 if the affected function changed after REV and you cannot yet tell whether the change fixes the issue. Score 2 if all four checks come back clean. The next section covers how to run them.

D5: Reporter track record

Score 2 for accepted advisory credits or a positive public Signal, 1 for no public history, and 0 for a public record that leans toward invalid reports. A new researcher scores 1, not 0. Having no history is not evidence against a reporter.

How do I check whether a report is a duplicate or already fixed?

Check four places in this order: the open queue, your repository's own advisories, the global advisory database filtered by CWE and package, and git history from the reporter's revision to HEAD. Match on root cause, not on wording or title.

  1. Open queue. Look for reports on the same function or the same weakness class. PHP uses AI to validate reports and to group reports that share a root cause, but a person makes every call.
  2. Your repository's advisories. Use GET /repos/OWNER/REPO/security-advisories. This catches issues you fixed and published yourself.
  3. Global advisories. The global advisory endpoint filters by ecosystem, CVE, severity, CWE and package. Filter by your package and the reporter's CWE.
  4. Silent fixes in git. A silent fix is a commit that removed the bug without being labelled as a security fix. Search from REV forward:
    • git log -S'vulnerable_string' REV..HEAD -- path/to/file (pickaxe). This shows commits that changed the number of times the string appears.
    • git log -G'regex' REV..HEAD -- path/to/file. This shows commits whose diff matches the regex, which catches a change to a bounds check that leaves the count unchanged.
    • git log -L :function_name:path/to/file REV..HEAD. This gives the full history of the function since REV.

Duplicates mean something different now. Three parties, Calif, Wiz and OpenAI, each independently reported the same out-of-memory root cause to PHP within about five weeks. That cluster was real. But researchers who prompt the same model get the same answers, so a second arrival does not confirm the first. Both reports can be wrong in the same way.

A duplicate is no longer corroboration. Two reporters prompting the same model can make the same mistake.

Two gaps you should know about. GitHub has said that automated duplicate and similarity checks against the Advisory Database are "on our radar", which means they have not shipped. Until they do, these four checks are manual. Re-check the GitHub community discussion on report quality to see whether that has changed. The OpenSSF guide also encourages reporters to deduplicate among themselves through Akrites. That helps upstream, but it is not a check you can run.

How much weight should reporter track record get?

Track record breaks ties and orders the queue. It is never a verdict. It can move a borderline report from Request PoC to Reproduce, but it cannot close a report, and it cannot rescue one that fails on evidence.

SourceHow to queryMinimum historyHow duplicates count
GitHub Advisory Databasecredit:USERNAMEnoneOnly credits the user accepted are public
HackerOne Signalprofile or APImore than 3 closed reportsexcluded
HackerOne Reputationprofilenone+2, 0 or -5 depending on timing

Here is what each source proves and how it misleads:

  • Accepted GitHub credits prove that a maintainer somewhere credited this account on a published advisory. Lies when: the reporter never accepted the credit, which makes it invisible to the public, or when the reporter is new and simply has none yet.
  • HackerOne Signal runs from -10 to 7 and excludes self-closed and duplicate reports. Lies when: the reporter has 3 or fewer closed reports, in which case it is blank, not low.
  • HackerOne Reputation rewards duplicates. A duplicate of a resolved report filed before that report went public earns +2. Under the milestones program, the first five duplicate reports for a vulnerability are also eligible for points. Lies when: a high score is built partly on duplicate filings, which is exactly the behaviour that fills your queue.
  • CVE credits: I could not verify a reliable way to query them, so do not score them.

The allow list belongs here, and it is narrower than it looks. Adding someone exempts their reports from rate limits. It does not change how you grade those reports. If you score track record inside the evidence dimensions, two maintainers will disagree depending on whether they recognise the name. Keep it in its own column.

The slow part is working out who a reporter actually is. The GitHub handle, the HackerOne handle and the name on a conference talk are often three different strings. Refolk resolves people across GitHub, LinkedIn and the open web from a plain-English description. I use it to connect a handle to a public body of credited work, and to draw up a shortlist of researchers worth adding to an allow list before their reports arrive.

From five scores to one verdict

Apply the rules below in order and stop at the first one that fires. Write down the number of the rule you used. That number, plus the evidence line behind each score, is what lets a second maintainer reach the same verdict without discussing it.

  1. D4 = 0: Dedupe or already fixed. Point to the match.
  2. D3 = 0: Decline as outside the threat model. Quote the clause.
  3. D1 = 2, D2 at least 1, D3 at least 1, D4 at least 1: Reproduce. If D4 = 1, attach the commit you could not rule out.
  4. Anything else, with no PoC request sent yet: Request PoC once, listing every D2 mismatch. Tiebreak: if D1 = 1, D2 = 2 and D5 = 2, you may book the slot instead.
  5. Anything else, after the one request: Decline as non-reproducing. Quote the request.

Whenever a report scores D3 = 1, open an issue to add the missing SECURITY.md clause, whatever the verdict.

Evidence against trust boundary

Crosses the trust boundaryOutside the trust boundary
Request PoC once
Plausible and in scope, so ask once for a runnable input at a named revision
Reproduce
Book a slot once the prior-art check comes back clean
Decline
Quote the SECURITY.md clause, with no PoC request needed
Decline, real behaviour
Quote the clause, and open a hardening issue if the behaviour is worth changing
Reproducer evidence weakReproducer evidence strong
Once prior art is ruled out, reproducer strength and trust-boundary fit decide most verdicts, and an out-of-scope report is declined however good its PoC is.
Intake scoring card
Report: GHSA-xxxx-xxxx-xxxx / reporter handle
Named revision (REV):
REV exists (git rev-parse --verify): yes / no

D1 Reproducer quality (0/1/2):
  Evidence: input type; runnable as written at REV? yes / no
D2 Code references (0/1/2):
  Evidence: git show / git log -L result; mismatches:
D3 Threat-model fit (0/1/2):
  Evidence: SECURITY.md clause quoted, or "SECURITY.md silent"
D4 Prior art and silent fix (0/1/2):
  Queue:
  Repo advisories:
  Global advisories (CWE, package):
  git log -S / -G / -L, REV..HEAD:
D5 Track record (0/1/2, tiebreaker only):
  credit: search:
  Signal (or "blank, 3 or fewer closed reports"):
AI-use box: yes / no / unanswered (recorded, not scored)

PoC already requested on this report: yes / no
Verdict: Reproduce / Request PoC / Dedupe or already fixed / Decline
Rule fired (1 to 5):
Graded by:

Paste into the private advisory thread and fill in every line; a score without its evidence line does not count.

The fifteen-minute intake procedure

Run the checks from cheapest to most expensive, and record track record last so it cannot anchor the evidence scores. The form gate takes about 2 minutes and the revision anchor about 3 to 5. Those are working budgets, not measured medians, and the remaining steps share whatever is left of the fifteen minutes.

Security report intake read

  1. Run the form gate
    Confirm summary, details, PoC and impact are present, the PoC is a real input rather than padded prose, a CWE is assigned and the AI-use box is answered. Done when every field passes or a PoC request is queued.
  2. Anchor to the named revision
    Confirm the commit or tag exists, then resolve each path with git show REV:path and each function with git log -L :func:file REV. Done when everything resolves or the mismatches are listed.
  3. Test threat-model fit
    Compare the claimed attacker position with SECURITY.md. Done when you have recorded crosses, outside with the clause quoted, or silent.
  4. Search prior art and silent fixes
    Check the open queue, your repository's advisories, the global advisories by CWE and package, and git log -S and -G from REV to HEAD. Done when a root-cause match is found or all four are clean.
  5. Record reporter track record
    Run a credit:USERNAME search and note public Signal if it exists. Done when the value is on the card, never as a verdict.
  6. Apply the verdict and send the reply
    Apply rules 1 to 5 in order, record the rule number and send the matching template. A PoC request is sent only once.
  7. Book the reproduction slot
    Queue Reproduce verdicts with REV, the PoC and any possible match attached, for a build configured like the project's CI with AddressSanitizer and UndefinedBehaviorSanitizer. Done when the slot has an owner and a date.

Practitioners order these steps differently, and the differences are worth knowing:

  • OpenSSF puts the evidence requirement first, before any triage.
  • PHP runs automated validation and grouping first, with a person making each call afterwards.
  • curl bans submitters of AI slop outright, which turns reporter history into a gate.
  • GitHub's allow list applies reporter trust at intake, but only to rate limits.

This guide follows the OpenSSF order for evidence and keeps reporter trust out of the gate. A ban works for a project with curl's profile. For most projects, it mostly loses the 15% of reports that are real.

How the intake read goes wrong

Every check in this read has a known way of giving a wrong answer. Most of them make a real report look fake, or a fake report look real. Learn these before trusting any single score.

  1. The function-exists check passes accurate reports with false impact. It catches hallucinations, but current reports cite real code. False positive: the code is real and the claimed impact is not. Check: D1 must be 2, meaning an input that runs, before a report earns a slot. D2 alone never does.
  2. git log -L fails after a rename. A renamed function makes the command fail at REV, which looks exactly like fabrication. Check: run git log -S on the old name before scoring D2 as 0.
  3. Pickaxe misses fixes that keep the count the same. -S only shows commits that changed how often a string appears. A silent fix that tightens a bounds check without changing that count is invisible to it. Check: use -G with a regex, or -L on the function.
  4. The PoC minimum length can be met with prose. 150 characters is easy to write without any input you can run. Check: ask whether the PoC could run against REV as written. Character count tells you nothing.
  5. Real behaviour gets reported as a vulnerability. Log4j sees this in most of its invalid reports. Check: decline only against a written SECURITY.md clause. If no clause exists, the gap is in your documentation, not in the report, and closing on tone or style is how real findings get lost.
  6. Track record misleads in both directions. Credits the reporter never accepted are invisible. New researchers have no history. Duplicates inflate HackerOne reputation, and Signal stays blank until a reporter has more than 3 closed reports. Check: track record is a tiebreaker only, in its own column.
  7. Independent duplicates can share the same error. Researchers who prompt the same model get the same answers, so a second report of the same bug does not confirm the first. Check: dedupe on root cause, and grade each report's evidence separately. The PHP three-party case shows clusters can still be real.
  8. Platform controls can look like validation. Rate limits address volume, not validity, and the AI-disclosure box is self-reported. Check: nothing upstream of the intake read changes any of the five scores.

Two more problems come from the people grading, not the tools. The first is a reporter who sends a second, stronger report after a PoC request. That is a new submission and should be graded fresh, not as a second request. The second is a maintainer who has seen the reporter's name before. That is why D5 goes on the card last.

Replies for each verdict, and keeping the read current

Every verdict gets a fixed reply that states what you checked, so the reporter knows exactly what would change the outcome. Fixed replies also stop the slow drift in which different maintainers close the same kind of report in different ways.

Intake replies for the four verdicts
REPRODUCE
Thanks for the report. The cited code resolves at <REV>, the claimed attacker position falls within the project's threat model (SECURITY.md, <clause>), and I found no prior report or fix covering this root cause. It is queued for reproduction on a build configured like the project's CI. I will update this advisory with the result.

REQUEST POC (sent once)
Thanks for the report. Before it can be scheduled for reproduction I need:
- the exact commit or tag you tested against
- an input or script that runs as written against that revision
- the output you expected and the output you observed
These references did not resolve at the revision given: <list mismatches, or "none">.
This is the only request I will send on this report. If the reply does not include a runnable input at a named revision, the report will be closed as non-reproducing.

DEDUPE OR ALREADY FIXED
Thanks for the report. It shares a root cause with <existing report, advisory ID, or commit hash>, so I am closing it as <duplicate / already fixed in that commit>. If you believe the root cause is different, reply with an input that still triggers the issue at <HEAD commit>.

DECLINE
Thanks for the report. The behaviour you describe requires <attacker position>, which SECURITY.md places outside the project's threat model: "<quoted clause>". I am closing it on that basis. If you can show the same effect without that position, please file a new report with a runnable input at a named revision.
[Non-reproducing variant: the PoC request sent on <date> did not receive a runnable input at a named revision, so I am closing this report as non-reproducing.]

Replace the angle-bracket fields with values from the scoring card; keep the structure so the reporter knows exactly what was checked.

Keep the read current in three ways:

  • Re-check platform mechanics, not numbers. The rate-limit thresholds are undisclosed, and automated duplicate checking had not shipped. When GitHub's changelog or configuration docs change, re-test your custom form from a second account and re-check whether D4 can be partly automated.
  • Watch the OpenSSF draft. The Vulnerability Disclosures Working Group is drafting guidance that covers threat models, SECURITY.md, submission requirements and triage signals. Its full signal list, reply templates and time-box values were not published when I last checked, so compare them with this card when they are.
  • Calibrate with a second grader. Double-grade a sample of reports regularly and compare cards dimension by dimension. Disagreements on D3 mean a SECURITY.md clause needs rewriting. Disagreements on D2 usually mean someone skipped the rename check. If your team is too small to grade twice, a peer on another project's security team is the best outside calibrator. Refolk can find maintainers on the PHP, curl or Node.js security teams who publish advisories, along with product security engineers who triage for open-source projects.

Before you send the verdict

  • The named revision exists and is written on the card
  • Every cited path and function was resolved at REV, or each mismatch is listed
  • A missing function was checked for a rename with git log -S before D2 was scored 0
  • Prior art was checked in the queue, the repository's advisories, the global advisories and git history from REV to HEAD
  • An empty pickaxe result was followed by -G or -L before D4 was scored 2
  • A Decline quotes a numbered SECURITY.md clause or the single PoC request already sent
  • Track record was recorded after D1 to D4 and was used, at most, as a tiebreaker
  • The rule number that produced the verdict is on the card
  • Any report scored D3 = 1 has an open issue to add the missing SECURITY.md clause

Questions practitioners ask

How do I handle AI-generated security reports?

Handle them the same way as any other report: score the evidence, not the prose. Since reporting models became technically accurate, hallucinated function names have stopped working as a tell, and many AI-assisted reports describe real behaviour. Check whether the PoC runs at a named revision, whether the code references resolve, whether the impact crosses your documented trust boundary, and whether the issue is already fixed. The AI-use checkbox is self-reported, so record it but never close a report because of it.

How do I check if a vulnerability report is already fixed?

Run git log -S with the vulnerable string from the reporter's revision to HEAD, restricted to the affected file. Pickaxe misses a fix that changes a bounds check without changing how often the string appears, so follow it with git log -G using a regex, or git log -L on the function. Then check your repository's own advisories endpoint and the global advisory database filtered by CWE and package. A fixing commit between REV and HEAD means Already fixed.

What does GitHub's trusted reporter allow list actually do?

It exempts named reporters from the per-account rate limits on private vulnerability reports. Their reports count toward neither your repository's daily limit nor their global limit. It does not mark their reports as valid, change the form they must fill in, or skip triage. Score an allow-listed reporter's report on the same five dimensions as anyone else's. GitHub has not published the numerical limits, so check the configuration docs instead of assuming a value.

What should SECURITY.md say so that out-of-scope closes hold up?

SECURITY.md should name the attacker positions the project defends against and the ones it does not, each as a numbered clause you can quote in a reply. Cover the cases you see most often: trusted configuration, local access you already assume, and runtime setups no production deployment uses. When a report lands in a gap the document does not cover, score threat-model fit as 1, proceed on the evidence, and open an issue to add the missing clause.

How many times should I ask a reporter for a proof of concept?

Ask once. List exactly what is missing in that single request: a named commit or tag, an input that runs, and the expected and observed output. If the reply still does not include something that runs at a named revision, close the report as non-reproducing and quote the request you sent. Repeated requests use up triage time, which is the scarcest resource in the queue, and they teach reporters that a weak report gets more of your attention.

Should two maintainers grade every report?

No, but they should both grade a sample regularly. Double-grade a handful of reports, compare the scoring cards dimension by dimension, and read every disagreement as a sign that a scoring definition or a SECURITY.md clause is ambiguous. Fix the definition, not the person. Disagreements usually cluster on threat-model fit and on how to score a renamed function, which are also the two places reports are most often closed wrongly.

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