⚠️ Definition of Done: this issue must be completed in full, in a single PR. Do not split this
work across multiple PRs, and do not defer any Deliverable below to a follow-up issue. A PR that
satisfies only some of the Deliverables, stubs a required test, or leaves a checkbox
partially-done does NOT resolve this issue and will be closed.
Context
packages/loopover-engine/src/signals/predicted-gate-engine.ts's buildCollisionReport builds two
different kinds of clusters over the same clusters map:
- Linked-issue clusters (lines 126-136): for every open issue that has at least one open PR
linking it, an issue-${issue.number} cluster is added. This loop iterates over all
openIssues/pullRequestsByLinkedIssue — it is not bounded by any sampling cap.
- Pairwise term-overlap clusters (lines 138-204): built only from
boundedCollisionIssues
(capped at MAX_COLLISION_PAIRWISE_ISSUES = 80) and boundedCollisionPullRequests (capped at
MAX_COLLISION_PAIRWISE_PULL_REQUESTS = 120). The itemTerms map (lines 141-143) is seeded
only from this bounded items array.
buildPreflightResult (lines 375-393) later reads collisionReport.clusters — which includes items
from BOTH the unbounded linked-issue clusters and the bounded pairwise clusters — and looks up each
cluster item's terms via itemTerms.get(itemKey(item)) at line 386, falling back to
collisionTerms(item) on a miss:
let terms = itemTerms.get(itemKey(item));
/* v8 ignore next -- Defensive only: collision item terms are cached for every cluster item. */
if (terms === undefined) terms = collisionTerms(item);
That v8 ignore comment's claim — "every cluster item is cached in itemTerms" — is only true for
items from the bounded pairwise clusters. An item that appears only in an unbounded linked-issue
cluster (i.e. an open issue with an open linking PR, where the repo has more than 80 open issues
that qualify, or more than 120 open PRs that qualify, so the item fell outside the pairwise sampling
window) was never seeded into itemTerms, and this fallback branch IS genuinely reachable for it.
Confirmed via grep -rn "MAX_COLLISION_PAIRWISE" test/ — the constant is never referenced by any
test, and neither twin has a test exercising the >80/>120 sampling boundary in combination with the
linked-issue cluster path. Because the line is v8 ignored, Codecov's patch-coverage gate will never
force a future edit here to add a real test — the ignore comment is actively hiding a live gap in
this logic, not documenting an already-covered one.
Note: the very similar-looking v8 ignore comments on lines 167 and 170 (inside
buildCollisionReport itself, in the pairwise nested loop) are correctly ignored — left/right
there are drawn from the exact same bounded items array that seeds itemTerms, so that fallback is
genuinely unreachable. Do not remove those two ignores; this issue is scoped to the buildPreflightResult
fallback at line 386-388 only.
Requirements
- Remove the
/* v8 ignore next */ comment immediately above the if (terms === undefined) terms = collisionTerms(item); line inside buildPreflightResult (currently line 387).
- Do not change the fallback's actual logic (
collisionTerms(item) remains the correct recovery
when a cache miss occurs) — this issue is about proving the branch is real and testing it, not
altering behavior.
- Do not modify the two
v8 ignore comments at lines 167/170 inside buildCollisionReport — those
remain correctly unreachable per the analysis above.
Deliverables
Both Deliverables are required in this one PR — there is no narrower scope for this issue.
Test Coverage Requirements
packages/loopover-engine/src/** is measured by Codecov via two separate uploads whose hits are
unioned — root test/** AND packages/loopover-engine/test/**. Add the new test to
test/unit/predicted-gate-engine.test.ts (root-level, matching this file's existing test location).
Target 100% branch coverage of the un-ignored line — the test must genuinely exercise the
cache-miss path (verify this by confirming the test fails if the v8 ignore removal is reverted
without adding the sampling-boundary scenario, i.e. the test must actually trigger a >80 open-issue
or >120 open-PR scenario, not merely call buildPreflightResult with a small dataset).
Expected Outcome
The itemTerms cache-miss fallback inside buildPreflightResult is proven correct by a real test
instead of being hidden from the coverage gate by an inaccurate v8 ignore claim, so a future
regression in this fallback (or in the sampling-boundary interaction it exists to handle) will be
caught by CI.
Links & Resources
packages/loopover-engine/src/signals/predicted-gate-engine.ts (lines 107-218
buildCollisionReport, lines 375-393 buildPreflightResult)
test/unit/predicted-gate-engine.test.ts
- Milestone: Miner Wave 4.6 — AMS Hardening Round 3
Context
packages/loopover-engine/src/signals/predicted-gate-engine.ts'sbuildCollisionReportbuilds twodifferent kinds of clusters over the same
clustersmap:linking it, an
issue-${issue.number}cluster is added. This loop iterates over allopenIssues/pullRequestsByLinkedIssue— it is not bounded by any sampling cap.boundedCollisionIssues(capped at
MAX_COLLISION_PAIRWISE_ISSUES = 80) andboundedCollisionPullRequests(capped atMAX_COLLISION_PAIRWISE_PULL_REQUESTS = 120). TheitemTermsmap (lines 141-143) is seededonly from this bounded
itemsarray.buildPreflightResult(lines 375-393) later readscollisionReport.clusters— which includes itemsfrom BOTH the unbounded linked-issue clusters and the bounded pairwise clusters — and looks up each
cluster item's terms via
itemTerms.get(itemKey(item))at line 386, falling back tocollisionTerms(item)on a miss:That
v8 ignorecomment's claim — "every cluster item is cached in itemTerms" — is only true foritems from the bounded pairwise clusters. An item that appears only in an unbounded linked-issue
cluster (i.e. an open issue with an open linking PR, where the repo has more than 80 open issues
that qualify, or more than 120 open PRs that qualify, so the item fell outside the pairwise sampling
window) was never seeded into
itemTerms, and this fallback branch IS genuinely reachable for it.Confirmed via
grep -rn "MAX_COLLISION_PAIRWISE" test/— the constant is never referenced by anytest, and neither twin has a test exercising the >80/>120 sampling boundary in combination with the
linked-issue cluster path. Because the line is
v8 ignored, Codecov's patch-coverage gate will neverforce a future edit here to add a real test — the ignore comment is actively hiding a live gap in
this logic, not documenting an already-covered one.
Note: the very similar-looking
v8 ignorecomments on lines 167 and 170 (insidebuildCollisionReportitself, in the pairwise nested loop) are correctly ignored —left/rightthere are drawn from the exact same bounded
itemsarray that seedsitemTerms, so that fallback isgenuinely unreachable. Do not remove those two ignores; this issue is scoped to the
buildPreflightResultfallback at line 386-388 only.
Requirements
/* v8 ignore next */comment immediately above theif (terms === undefined) terms = collisionTerms(item);line insidebuildPreflightResult(currently line 387).collisionTerms(item)remains the correct recoverywhen a cache miss occurs) — this issue is about proving the branch is real and testing it, not
altering behavior.
v8 ignorecomments at lines 167/170 insidebuildCollisionReport— thoseremain correctly unreachable per the analysis above.
Deliverables
v8 ignorecomment gating the cache-miss fallback insidebuildPreflightResultisremoved.
buildCollisionReportproduces a linked-issue cluster(an open issue with an open, linking PR) for an item that falls outside the bounded pairwise
sampling window (i.e. the repo has more open issues than
MAX_COLLISION_PAIRWISE_ISSUES, ormore open PRs than
MAX_COLLISION_PAIRWISE_PULL_REQUESTS, such that the linked-issue item isexcluded from
boundedCollisionIssues/boundedCollisionPullRequests), then callsbuildPreflightResultwith that data and asserts the previously-uncovered fallback branchexecutes and produces a correct, non-throwing result (i.e. the planned-contribution
collision/duplicate detection still works correctly for that item).
Both Deliverables are required in this one PR — there is no narrower scope for this issue.
Test Coverage Requirements
packages/loopover-engine/src/**is measured by Codecov via two separate uploads whose hits areunioned — root
test/**ANDpackages/loopover-engine/test/**. Add the new test totest/unit/predicted-gate-engine.test.ts(root-level, matching this file's existing test location).Target 100% branch coverage of the un-ignored line — the test must genuinely exercise the
cache-miss path (verify this by confirming the test fails if the
v8 ignoreremoval is revertedwithout adding the sampling-boundary scenario, i.e. the test must actually trigger a >80 open-issue
or >120 open-PR scenario, not merely call
buildPreflightResultwith a small dataset).Expected Outcome
The
itemTermscache-miss fallback insidebuildPreflightResultis proven correct by a real testinstead of being hidden from the coverage gate by an inaccurate
v8 ignoreclaim, so a futureregression in this fallback (or in the sampling-boundary interaction it exists to handle) will be
caught by CI.
Links & Resources
packages/loopover-engine/src/signals/predicted-gate-engine.ts(lines 107-218buildCollisionReport, lines 375-393buildPreflightResult)test/unit/predicted-gate-engine.test.ts