fix(miner): carry real assignees through the discovery-index supplement so the repo-owner exclusion applies#7488
Conversation
…nt so the repo-owner exclusion applies discover-cli's supplementWithDiscoveryIndex stubbed assignees: [] on every hosted discovery-index candidate, so contribution-profile-filter's always-on repo-owner exclusion (JSONbored#7040) -- which reads candidate.assignees -- could never fire for an index-sourced candidate, silently no-opping the safeguard for that entire source. Add an optional assignees field to DiscoveryIndexCandidate (normalized like labels, kept optional so 'never served' is distinguishable from 'served empty') and copy the real value through in supplementWithDiscoveryIndex, falling back to [] only when the served response genuinely omitted it. isAssignedToRepoOwner's logic is unchanged; the direct fan-out path already carried real assignees. Additive and backward-compatible. Adds contract + end-to-end discover-cli regression tests. Closes JSONbored#7442
|
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 #7488 +/- ##
=======================================
Coverage 91.41% 91.41%
=======================================
Files 717 717
Lines 73032 73035 +3
Branches 21636 21637 +1
=======================================
+ Hits 66762 66765 +3
Misses 5227 5227
Partials 1043 1043
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-20 12:45:05 UTC
Review summary Nits — 5 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.
|
Summary
Fixes #7442. #7040 added an always-on safeguard —
contribution-profile-filter.ts'sisAssignedToRepoOwnerexcludes any discover candidate assigned to its own repo's owner, "unconditionally, for EVERY candidate." Butdiscover-cli.ts'ssupplementWithDiscoveryIndex(the hosted discovery-index path, #7168) unconditionally stubbedassignees: []on every index-sourced candidate, becauseassigneeswasn't part of the hosted contract.isAssignedToRepoOwnerreadscandidate.assignees ?? []— an always-empty array means it could never detect an owner-assignment for a discovery-index candidate, so the exclusion silently no-oped for that entire source (while the label-based rules kept working, sincelabelsis carried through).discover-cli.tsrunsfilterCandidatesByProfilesover the index-supplemented rows in both the dry-run and real-run paths.Fix
packages/loopover-engine/src/discovery-index-contract.ts): added an optionalassignees?: readonly string[]field toDiscoveryIndexCandidateand normalized it innormalizeDiscoveryIndexCandidatewith the exact same string-filtering/trimming aslabels. Kept optional (unlikelabels) so a client can distinguish "assignees were never served" (older server build → field omitted) from "served, and empty" — the former must fall back to[]at the merge site, not silently skip the filter. The request side carries no candidate data, so only the candidate normalizer changes.packages/loopover-miner/lib/discover-cli.ts):supplementWithDiscoveryIndexnow copies the real assignees through ([...(candidate.assignees ?? [])]), falling back to[]only when the served response genuinely omitted the field.isAssignedToRepoOwner's own logic is untouched — the fix is getting real assignee data to it. The direct GitHub fan-out path is unchanged (it already carried realassignees).The change is additive and backward-compatible: an older discovery-index server that doesn't populate
assigneesstill yields[](fail-open, exactly as today). Making the exclusion take live effect for index candidates needs the hostedpackages/discovery-indexserver to start emittingassigneesin its query response — a mechanical maintainer-side fast-follow (thelabelsfield already proves this exact plumbing end-to-end), out of scope for this miner-side/contract PR per the issue's own scoping note.Tests
normalizeDiscoveryIndexCandidatenormalizesassigneeslikelabels(drops non-strings/blanks), keeps an explicitly-served[], and omits the field entirely when the response never carries it.discover-cli(end-to-end via realrunDiscoverwith an injectedqueryDiscoveryIndex): a discovery-index candidate assigned to its own repo owner is now excluded byfilterCandidatesByProfiles(only the direct fan-out issue survives); and a response that omitsassigneesfalls back to[]and still runs the filter (candidate kept, not skipped), proving the fail-safe.Every changed line + branch in both files is covered (verified via
--coverage), socodecov/patchholds; all existingdiscovery-index-contractandminer-discover-clitests pass unchanged.Validation
git diff --checknpm run typecheck(roottsc --noEmit) andnpm run build:miner(recompileddiscover-cli.js, no drift) greennpm run test:coverageon the affected suite: 100% of changed lines + branches covered;npm run test:miner-pack(no.tsleak) andnpm run miner:env-reference:checkcleanSafety
assigneesis public GitHub login data, already carried on the direct fan-out path.site//CNAME/lovablechanges.Closes #7442