Goal
Give the malware_or_abuse_surface risk flag a stated reason in directContentRequestChangesReasons, so a flagged direct PR actually tells the contributor why.
Why this matters
A contributor whose direct content PR trips this flag currently sees a "changes requested" verdict with zero explanation — a real, silent gap in the risk scorer's own feedback mechanism.
Current behavior
packages/registry/src/submission-risk.js:
malware_or_abuse_surface is raised as a "high" severity flag (lines ~1331-1341), not "critical".
directContentRequestChangesReasons builds human-readable "why this PR needs changes" text from a flagReasons map for named flags (lines ~1716-1738), plus a fallback loop that only catches unmapped flags with severity "critical" (lines ~1743-1749).
malware_or_abuse_surface is in neither: it's absent from flagReasons, and its "high" severity means the fallback skips it too — so it silently produces zero reason text. Its sibling "critical"-severity flag malicious_data_theft_capability gets an explicit, specific reason.
Desired behavior
malware_or_abuse_surface gets an explicit entry in flagReasons (preferred, for a specific message), or the fallback is extended to also catch unmapped "high"-severity flags generally. Either way, a PR that trips this flag now surfaces a real reason.
Scope
packages/registry/src/submission-risk.js (flagReasons map and/or the fallback loop)
- focused tests
Out of scope
- Other flags that already have reasons
- The scoring/severity logic that decides when
malware_or_abuse_surface fires (already correct)
Acceptance criteria
- PR includes
Closes #<issue>.
- A submission that trips
malware_or_abuse_surface now produces non-empty reason text in directContentRequestChangesReasons's output.
- Existing reasons for other flags are unchanged.
Quality evidence required in the PR
- No visual impact; include the exact before/after reason text for a fixture submission that trips this flag.
Validation
pnpm build
pnpm exec vitest run tests/submission-risk.test.ts
git diff --check
Goal
Give the
malware_or_abuse_surfacerisk flag a stated reason indirectContentRequestChangesReasons, so a flagged direct PR actually tells the contributor why.Why this matters
A contributor whose direct content PR trips this flag currently sees a "changes requested" verdict with zero explanation — a real, silent gap in the risk scorer's own feedback mechanism.
Current behavior
packages/registry/src/submission-risk.js:malware_or_abuse_surfaceis raised as a"high"severity flag (lines ~1331-1341), not"critical".directContentRequestChangesReasonsbuilds human-readable "why this PR needs changes" text from aflagReasonsmap for named flags (lines ~1716-1738), plus a fallback loop that only catches unmapped flags with severity"critical"(lines ~1743-1749).malware_or_abuse_surfaceis in neither: it's absent fromflagReasons, and its"high"severity means the fallback skips it too — so it silently produces zero reason text. Its sibling"critical"-severity flagmalicious_data_theft_capabilitygets an explicit, specific reason.Desired behavior
malware_or_abuse_surfacegets an explicit entry inflagReasons(preferred, for a specific message), or the fallback is extended to also catch unmapped"high"-severity flags generally. Either way, a PR that trips this flag now surfaces a real reason.Scope
packages/registry/src/submission-risk.js(flagReasonsmap and/or the fallback loop)Out of scope
malware_or_abuse_surfacefires (already correct)Acceptance criteria
Closes #<issue>.malware_or_abuse_surfacenow produces non-empty reason text indirectContentRequestChangesReasons's output.Quality evidence required in the PR
Validation
pnpm build
pnpm exec vitest run tests/submission-risk.test.ts
git diff --check