fix(miner): carry assignees through normalizeCandidate in opportunity-ranker - #9343
Conversation
|
Superagent didn't find any vulnerabilities or security issues in this PR. |
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## main #9343 +/- ##
==========================================
+ Coverage 75.38% 75.40% +0.02%
==========================================
Files 275 276 +1
Lines 58023 58082 +59
Branches 6181 6205 +24
==========================================
+ Hits 43739 43798 +59
Misses 14014 14014
Partials 270 270
Flags with carried forward coverage won't be shown. Click here to find out more.
|
|
Tip ✅ LoopOver review result - approve/merge recommendedReview updated: 2026-07-27 13:39:01 UTC
Review summary Nits — 3 non-blocking
Decision drivers
Context & advisory signals — never blocks the verdict
Linked issue satisfactionAddressed Review context
Contributor next steps
Signal definitions
🧪 Chat with LoopOverAsk LoopOver a question about this PR directly in a comment — grounded only in the same cached, public-safe facts shown above, never a new claim.
Full command reference: https://loopover.ai/docs/loopover-commands 🧪 Experimental — new and may change. 🟩 Safe / merged · 🟦 Advisory · 🟨 Held for review · 🟥 Blocked / closed 💰 Earn for open-source contributions like this. Gittensor lets GitHub contributors earn for the work they already do — register to start earning →. Checked by LoopOver, a quiet PR intelligence layer for OSS maintainers.
|
What
RankedCandidateIssue = RawCandidateIssue & {...score fields}inpackages/loopover-miner/lib/opportunity-ranker.ts, andRawCandidateIssuecarriesassignees: string[](populated bynormalizeIssue/assigneeLoginsinopportunity-fanout.ts,#7040). But
normalizeCandidatere-copied every other field onto its return object —owner,repo,repoFullName,issueNumber,title,labels,commentsCount,createdAt,updatedAt,htmlUrl,aiPolicyAllowed,aiPolicySource— and silently droppedassignees. Sodiscover --json'sresult.ranked(andoptions.onResult's payload) omitted a field theRankedCandidateIssuetypepromises. The pre-ranking exclusion filter isn't affected — it runs on raw fan-out candidates — but
consumers of the ranked output lose the field.
Change
normalizeCandidatenow copiesassignees, validated exactly the way the siblinglabelsfield is(array-of-strings, defaulting to
[]when missing or malformed). No.trim()— the producer(
assigneeLogins) already emits clean GitHub logins filtered tolength > 0, so the check mirrorsthat (
typeof assignee === "string" && assignee.length > 0). No other field's normalization,RawCandidateIssue,RankedCandidateIssue, ornormalizeIssueis touched.Validation
Two new tests in
test/unit/miner-opportunity-ranker.test.ts:assigneesarray survivesrankCandidateIssueswithassigneespresent and correct in the ranked output;
undefined), non-array ("not-an-array"), and mixed-invalid ([42, "", "keep"])assigneesfields normalize to[]/["keep"]rather than throwing or propagating invalid values— exercising both sides of the
Array.isArrayguard and both operands of the filter predicate.npx vitest run test/unit/miner-opportunity-ranker.test.ts→ 22 pass. Every changed line and branchis covered.
Closes #9330