feat(security): add a finder-credit policy — timing gate and no placeholders - #1127
Merged
Merged
Conversation
…holders The framework had no answer to "does this report earn a `finder` credit at all?". `bot-credits-policy.md` decides what *category* a credited party belongs to, but nothing decided whether the credit is earned, and nothing said how to represent the absence of a finder. Adds `tools/cve-tool-vulnogram/finder-credit-policy.md` as its sibling, carrying two rules. Rule 1 — timing. A report earns no finder credit when a public fix PR for the same issue was already *opened* before the report arrived. The bar is opened, not merged: an open PR's diff, title, and touched code path are readable by anyone, so a later report is not telling the project something it did not already know. Two authoritative timestamps decide it (`gh pr view --json createdAt` and the inbound `Date:` header), never the reporter's prose. Four exceptions: the original finder, a genuinely different prong, a credit already offered in writing, and a credit already published. The written-offer exception is the load-bearing one. Withdrawing a credit a reporter has read costs the project far more than one credit line, and the reporter did nothing to deserve it — so the gate is applied at intake, before any offer is made, and an offer made in error is the project's to absorb. Rule 2 — no placeholders. Where there is no named finder, omit the `finder` credit rather than writing `anonymous`. An empty field makes the generator emit no `finder` entry, which is the correct record: a `credits[]` carrying only the remediation developer is normal and complete. A literal `anonymous` occupies the space where a reader looks for attribution and answers nothing. Rule 2 governs only the `finder` row — a tool that made the discovery is still credited `type: "tool"`. Wires the policy into the two skills that actually write the field (`security-issue-import` at intake, `security-issue-sync` at reconciliation) and cross-references it from `bot-credits-policy.md`. `security-cve-allocate` and `security-issue-deduplicate` are named in the policy's own applies-to list but not edited here — neither writes `credits[]` directly. Generated-by: Claude Code (Claude Opus 5)
potiuk
added a commit
that referenced
this pull request
Aug 29, 2026
…anonymous (#1131) Reconciles #1124 with #1127, as promised in #1127's description. #1124 made `anonymous` the fallback for a scanner-sourced finding whose scanner declares no public credit name. #1127 then landed the finder-credit policy, whose Rule 2 says the opposite: where there is no named finder, omit the `finder` credit rather than writing a placeholder. Both are on `main`, so the framework currently contradicts itself in three places. Rule 2 wins. It is grounded in an ASF CVE reviewer's feedback on a published batch — "I'm not sure how helpful it is to credit 'anonymous' as finder, just leave it out" — and a `credits[]` carrying only the remediation developer is a complete record, whereas a literal `anonymous` occupies the space a reader scans for attribution and answers nothing. Nothing else about #1124 changes: the scanner's public credit name is still written when declared, still emitted with `type: "tool"`, and the confidential product token still never reaches a public surface. Only the no-name-declared branch changes, from writing a placeholder to omitting the row. Grep confirms no `anonymous` fallback remains under skills/, projects/, or tools/. Generated-by: Claude Code (Claude Opus 5)
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
The framework has no answer to "does this report earn a
findercredit at all?".bot-credits-policy.mddecides what category a credited party belongs to; nothing decides whether the credit is earned, and nothing says how to represent the absence of a finder.Adds
tools/cve-tool-vulnogram/finder-credit-policy.mdas its sibling, with two rules.Rule 1 — timing. No finder credit when a public fix PR for the same issue was already opened before the report arrived. The bar is opened, not merged: an open PR's diff, title and touched code path are readable by anyone, so a later report is not telling the project something it did not already know. Two authoritative timestamps decide it (
gh pr view --json createdAt, the inboundDate:header) — never the reporter's prose. Four exceptions: the original finder, a genuinely different prong, a credit already offered in writing, a credit already published.Rule 2 — no placeholders. Where there is no named finder, omit the
findercredit rather than writinganonymous. An empty field makes the generator emit nofinderentry, which is the correct record — acredits[]carrying only the remediation developer is normal and complete. Rule 2 governs only thefinderrow; a tool that made the discovery is still creditedtype: "tool".Motivation
Both rules come from a downstream adopter that hit the failure modes directly. Rule 1's written-offer exception is the load-bearing one: that adopter credited a duplicate reporter, then had to retract it once the rule was drawn. Applying the gate at intake — before any offer is made — is what stops the retraction being necessary.
Rule 2 comes from an ASF CVE reviewer's feedback on a published batch: "I'm not sure how helpful it is to credit 'anonymous' as finder, just leave it out."
Relationship to #1124
#1124 (open) makes
anonymousthe fallback when a scanner declares no public credit name. Rule 2 supersedes that fallback — the right end state is to omit thefinderrow, not write a placeholder. Rather than growing #1124's scope after review, I'll rebase this branch once #1124 merges and change that one fallback phrase to match. Flagging it so a reviewer seeing both doesn't read it as a contradiction.Scope
Wired into the two skills that actually write the field —
security-issue-import(intake) andsecurity-issue-sync(reconciliation) — and cross-referenced frombot-credits-policy.md.security-cve-allocateandsecurity-issue-deduplicateappear in the policy's applies-to list but aren't edited: neither writescredits[]directly.Test plan
prek run --filespasses on all four files —markdownlint,typos,check-placeholders,skill-and-tool-validate, doctoc, SPDX stamping, and the in-hook lychee. The new doc uses only<upstream>/<N>placeholders (no project identity), whichcheck-placeholdersverifies. The worked example is fully anonymised.🤖 Generated with Claude Code