feat(miner): implement generic ContributionProfile extraction - #6979
Merged
loopover-orb[bot] merged 1 commit intoJul 17, 2026
Merged
Conversation
…red#6796) Reads a repo's real published signals -- label taxonomy + CONTRIBUTING.md -- and produces a populated ContributionProfile per the JSONbored#6795 schema. Generic by design: it recognizes conventional OSS eligibility/exclusion vocabulary and matches over label name AND description (the JSONbored#6794 finding that rust encodes eligibility in descriptions), with no loopover-specific hardcoding. Never throws: any fetch/parse failure degrades the signal to absent/unknown, so an unreachable or docs-less repo yields a low-confidence profile rather than a false-positive guess. Confidence is honest per signal: recognized eligibility labels are explicit, conventional exclusion labels inferred, a tiny CONTRIBUTING.md is treated as a signpost (unknown) not the rules. Fetch is injectable; 100% branch coverage on fixtures for the loopover convention, a description-only convention, and a no-signals repo. Closes JSONbored#6796
Contributor
|
Superagent didn't find any vulnerabilities or security issues in this PR. |
Contributor
|
Important 🟪🟪🟪🟪🟪🟪🟪🟪🟪🟪🟪🟪 🔍 LoopOver is reviewing…AI analysis is in progress. This comment will update when the review is complete. 🟩 Safe / merged · 🟦 Advisory · 🟨 Held for review · 🟥 Blocked / closed · 🟪 Reviewing |
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## main #6979 +/- ##
==========================================
+ Coverage 89.24% 93.72% +4.47%
==========================================
Files 687 688 +1
Lines 68422 68491 +69
Branches 18737 18737
==========================================
+ Hits 61066 64192 +3126
+ Misses 5647 3302 -2345
+ Partials 1709 997 -712
Flags with carried forward coverage won't be shown. Click here to find out more.
|
This was referenced Jul 17, 2026
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 extraction half of the AMS contribution-profile chain (#6793): reads a repo's real published signals — its label taxonomy and
CONTRIBUTING.md— and produces a populatedContributionProfileper the #6795 schema I just landed. Depends only on #6795, which is merged.Generic by design — no loopover-specific hardcoding
The issue is explicit that classification must be "generic heuristics, not loopover-specific keyword matching." The extractor recognizes conventional OSS eligibility (
good first issue,help wanted,up for grabs,beginner,easy, …) and exclusion (blocked,wontfix,needs triage, …) vocabulary, and — the key #6794 finding — matches over label name AND description, preferring the name but falling back to the description. That's what lets it catch rust'sE-easy, which encodes "good first issue" only in the description.loopover's owngittensor:*labels are deliberately not special-cased — the #6794 inventory found they're the exception, not the shape to generalize from.Confidence is honest, never a false positive
Per the issue ("a repo with no discoverable signals should produce a low-confidence/empty profile, not a false-positive guess"):
explicit(a recognized convention is an explicit statement).inferred(conventional but unstated — AMS contribution-profile: inventory real-world eligibility signals across a diverse repo sample #6794 found no repo names exclusion in a label name).CONTRIBUTING.mdbelow 600 bytes → treated as a signpost, not the rules (unknown), because AMS contribution-profile: inventory real-world eligibility signals across a diverse repo sample #6794 found react's is 208 B and kubernetes' 525 B — just links to an external guide AMS can't read.absent.completenessis the weakest of the three spine signals, sodiscovertreats a partial profile conservatively.Never throws
Every fetch goes through a bounded, catch-wrapped helper; any transport/HTTP/parse failure degrades that signal to
absent/unknownrather than propagating. A malformed repo name returns the safe empty profile without any network call. Fetch is injectable (fetchImpl), following thelive-issue-snapshot.jspattern.Tests
18 cases against fixtures, covering exactly the three the issue names plus every branch:
help wantedlabel) → explicit eligibility..github/fallback, HTTP-error and thrown-transport degradation, JSON-parse failure, undecodable contents, unnamed-label provenance, a supplied token'sAuthorizationheader + a customapiBaseUrl, the default-now timestamp, and the weakest-completeness rule.Validation
.js(packages/loopover-miner/lib/**): 78/78 statements, 51/51 branches, 13/13 functions. The one genuinely-unreachable branch (the global-fetchproduction default, which every test injects around) carries a/* v8 ignore */pragma.npm run typecheck— 0 (after the standard engine rebuild) ·eslint— 0/0 ·prettier --check— clean ·node --check(added to the miner build list) — ok ·check-miner-packageunchanged · rebased on latestmain.Scope & safety
node --checklist. Wanted paths (packages/,test/).src/api/routes.ts,src/mcp/server.ts, the MCP CLI bin, or the stdio-tool count pin — by design, to avoid the base-conflict/count-pin contention.discoverbehavior change (that's AMS contribution-profile: wire eligibility filtering into discover #6798). No secrets; no changelog/site//CNAME/lovablechanges.Closes #6796