Context
rankedUsesDefaultGoalSpec (packages/loopover-miner/lib/opportunity-ranker.js:90-98) uses ranked.some((issue) => !specRepos.some((repo) => ... === target)) — it returns true the moment any ranked repo lacks a matching per-tenant goal spec, even if other repos in the same ranked batch did have one supplied and applied. discover-cli.js (lines 169-172) then prints this as a single, blanket CLI note:
note: ranked with the built-in default goal spec (no per-tenant .loopover-miner.yml supplied)
Verified empirically: ranking two candidates on acme/widgets (given a supplied goalSpecContentByRepo["acme/widgets"]) and acme/gadgets (no config) together via rankCandidateIssuesWithSummary returns usedDefaultGoalSpec: true — so the printed note claims "no per-tenant .loopover-miner.yml supplied" for the whole run, even though one of the two repos genuinely had one supplied and used. This is a real, reachable scenario: goalSpecContentByRepo/goalSpecsByRepo are documented as per-repo maps precisely because a single discover invocation fans out across every repo the miner has been pointed at, and mixed-config portfolios (some repos configured, some not) are the expected steady state, not an edge case. None of the existing tests in test/unit/miner-opportunity-ranker.test.ts (lines 80-165) exercise a multi-repo candidate batch with partial goal-spec coverage — every existing case is single-repo, so this gap isn't caught today.
Requirements
rankCandidateIssuesWithSummary's summary must distinguish "every ranked repo used the default" from "some ranked repos used the default and some used a supplied spec" (e.g. by returning which ranked repos fell back, or a count instead of a single boolean collapsing the whole batch).
discover-cli.js's printed note must not claim a blanket "no per-tenant .loopover-miner.yml supplied" when a subset of the ranked repos actually had one supplied and applied — the note text (or its trigger condition) must reflect partial vs. total fallback accurately.
- The existing all-default and all-custom single-repo behaviors (already tested) must be preserved.
Deliverables
Test Coverage Requirements
packages/loopover-miner/lib/opportunity-ranker.js and discover-cli.js are both under Codecov's 99% patch-coverage gate. Pure/deterministic logic — full branch coverage achievable with the mixed-repo regression test plus the existing all-default/all-custom cases continuing to pass.
Expected Outcome
An operator running discover across a multi-repo portfolio with partial .loopover-miner.yml coverage sees an accurate note reflecting exactly which repos used the built-in default rubric, instead of a misleading blanket claim that no per-tenant configuration was used at all.
Links & Resources
packages/loopover-miner/lib/opportunity-ranker.js:90-118
packages/loopover-miner/lib/discover-cli.js:169-172,376-408
test/unit/miner-opportunity-ranker.test.ts:80-165
Context
rankedUsesDefaultGoalSpec(packages/loopover-miner/lib/opportunity-ranker.js:90-98) usesranked.some((issue) => !specRepos.some((repo) => ... === target))— it returnstruethe moment any ranked repo lacks a matching per-tenant goal spec, even if other repos in the same ranked batch did have one supplied and applied.discover-cli.js(lines 169-172) then prints this as a single, blanket CLI note:Verified empirically: ranking two candidates on
acme/widgets(given a suppliedgoalSpecContentByRepo["acme/widgets"]) andacme/gadgets(no config) together viarankCandidateIssuesWithSummaryreturnsusedDefaultGoalSpec: true— so the printed note claims "no per-tenant.loopover-miner.ymlsupplied" for the whole run, even though one of the two repos genuinely had one supplied and used. This is a real, reachable scenario:goalSpecContentByRepo/goalSpecsByRepoare documented as per-repo maps precisely because a singlediscoverinvocation fans out across every repo the miner has been pointed at, and mixed-config portfolios (some repos configured, some not) are the expected steady state, not an edge case. None of the existing tests intest/unit/miner-opportunity-ranker.test.ts(lines 80-165) exercise a multi-repo candidate batch with partial goal-spec coverage — every existing case is single-repo, so this gap isn't caught today.Requirements
rankCandidateIssuesWithSummary's summary must distinguish "every ranked repo used the default" from "some ranked repos used the default and some used a supplied spec" (e.g. by returning which ranked repos fell back, or a count instead of a single boolean collapsing the whole batch).discover-cli.js's printed note must not claim a blanket "no per-tenant.loopover-miner.ymlsupplied" when a subset of the ranked repos actually had one supplied and applied — the note text (or its trigger condition) must reflect partial vs. total fallback accurately.Deliverables
opportunity-ranker.js's summary reports per-repo (or count-based) goal-spec-fallback detail instead of one blanket booleandiscover-cli.js's CLI note text is accurate for a mixed-repo run (states which/how-many repos fell back, not a blanket claim)Test Coverage Requirements
packages/loopover-miner/lib/opportunity-ranker.jsanddiscover-cli.jsare both under Codecov's 99% patch-coverage gate. Pure/deterministic logic — full branch coverage achievable with the mixed-repo regression test plus the existing all-default/all-custom cases continuing to pass.Expected Outcome
An operator running
discoveracross a multi-repo portfolio with partial.loopover-miner.ymlcoverage sees an accurate note reflecting exactly which repos used the built-in default rubric, instead of a misleading blanket claim that no per-tenant configuration was used at all.Links & Resources
packages/loopover-miner/lib/opportunity-ranker.js:90-118packages/loopover-miner/lib/discover-cli.js:169-172,376-408test/unit/miner-opportunity-ranker.test.ts:80-165