⚠️ 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-miner/lib/self-review-context.ts has two sibling functions that extract
closing-keyword references from an issue/PR body: extractLinkedPrNumbers and
extractLinkedIssueNumbers.
extractLinkedIssueNumbers was hardened (per its own comment, referencing #7527) to exclude
matches that fall inside an inline Markdown code span (`...`), because a quoted example like
`Closes #123` — e.g. a PR template teaching the closing-keyword convention to contributors —
must not be read as a real link:
const inlineCodeSpanRanges = [...body.matchAll(/`[^`\n]*`/g)].map((match: any) => ({
start: match.index,
end: match.index + match[0].length,
}));
...
if (inlineCodeSpanRanges.some((range) => matchStart < range.end && matchEnd > range.start)) continue;
The comment explicitly notes this must be a byte-range exclusion, not a string-strip, because
stripping the span would let the surrounding text combine into a fake match.
extractLinkedPrNumbers, defined a few lines earlier in the same file and matching the same
keyword+reference shape (/\b(?:close[sd]?|fix(?:e[sd])?|resolve[sd]?)\s+(?:PR|pull request)\s+#(\d+)\b/gi), has zero code-span protection:
function extractLinkedPrNumbers(body: any) {
const numbers = [];
for (const match of body.matchAll(LINKED_PR_PATTERN)) {
const number = Number(match[1]);
if (Number.isInteger(number) && number > 0) numbers.push(number);
}
return numbers;
}
An issue body that quotes an example like `Closes PR #99` (e.g. explaining the linking
convention, exactly the same shape of false positive #7527 fixed for the issue-number sibling)
will have that example misread as a real linked PR by extractLinkedPrNumbers. This value feeds
IssueRecord.linkedPrs, which is consumed by issue-quality/feasibility logic elsewhere in this
package — a false positive here can make the miner wrongly treat an open issue as already linked to
a PR and skip attempting it.
test/unit/miner-self-review-context.test.ts has explicit REGRESSION (#7527) tests for
extractLinkedIssueNumbers's code-span exclusion (around lines 1071 and 1078) but no equivalent
test exists for extractLinkedPrNumbers.
Requirements
- Apply the same inline-code-span byte-range exclusion
extractLinkedIssueNumbers already uses to
extractLinkedPrNumbers — reuse the same exclusion technique (byte-range check against inline
code span matches), not a string-strip, for the same reason #7527's comment already documents.
- Do not change
extractLinkedIssueNumbers's existing behavior — this issue is scoped to bringing
extractLinkedPrNumbers up to the same standard, not modifying the function it's mirroring.
- Consider factoring the inline-code-span-range computation into a small shared helper used by both
functions, to prevent this same class of drift from happening again if either function is
modified in the future — this is encouraged but not required if you instead duplicate the
exclusion logic consistently with the existing style in this file; either approach satisfies this
issue as long as extractLinkedPrNumbers gets the actual exclusion behavior.
Deliverables
Both new tests and the code fix are required in this single PR.
Test Coverage Requirements
This repo's Codecov patch gate is 99%+ (branch-counted) on packages/loopover-miner/lib/**. Add
the new regression tests to test/unit/miner-self-review-context.test.ts (this package's tests
live in the shared root test/ directory, not packages/loopover-miner/test/**), next to the
existing #7527 tests for extractLinkedIssueNumbers. The new exclusion branch in
extractLinkedPrNumbers must be exercised by both the exclusion test and the still-matches test.
Expected Outcome
extractLinkedPrNumbers and extractLinkedIssueNumbers share the same protection against a
backtick-quoted closing-keyword example being misread as a real link. A quoted example in an issue
body's Markdown no longer causes the miner to wrongly treat that issue as already linked to a PR.
Links & Resources
packages/loopover-miner/lib/self-review-context.ts — extractLinkedPrNumbers (~lines 265-273)
and extractLinkedIssueNumbers (~lines 282-306), the function to mirror.
test/unit/miner-self-review-context.test.ts — the existing REGRESSION (#7527) tests (~lines
1071, 1078) to mirror for the new tests.
Context
packages/loopover-miner/lib/self-review-context.tshas two sibling functions that extractclosing-keyword references from an issue/PR body:
extractLinkedPrNumbersandextractLinkedIssueNumbers.extractLinkedIssueNumberswas hardened (per its own comment, referencing#7527) to excludematches that fall inside an inline Markdown code span (
`...`), because a quoted example like`Closes #123`— e.g. a PR template teaching the closing-keyword convention to contributors —must not be read as a real link:
The comment explicitly notes this must be a byte-range exclusion, not a string-strip, because
stripping the span would let the surrounding text combine into a fake match.
extractLinkedPrNumbers, defined a few lines earlier in the same file and matching the samekeyword+reference shape (
/\b(?:close[sd]?|fix(?:e[sd])?|resolve[sd]?)\s+(?:PR|pull request)\s+#(\d+)\b/gi), has zero code-span protection:An issue body that quotes an example like
`Closes PR #99`(e.g. explaining the linkingconvention, exactly the same shape of false positive
#7527fixed for the issue-number sibling)will have that example misread as a real linked PR by
extractLinkedPrNumbers. This value feedsIssueRecord.linkedPrs, which is consumed by issue-quality/feasibility logic elsewhere in thispackage — a false positive here can make the miner wrongly treat an open issue as already linked to
a PR and skip attempting it.
test/unit/miner-self-review-context.test.tshas explicitREGRESSION (#7527)tests forextractLinkedIssueNumbers's code-span exclusion (around lines 1071 and 1078) but no equivalenttest exists for
extractLinkedPrNumbers.Requirements
extractLinkedIssueNumbersalready uses toextractLinkedPrNumbers— reuse the same exclusion technique (byte-range check against inlinecode span matches), not a string-strip, for the same reason
#7527's comment already documents.extractLinkedIssueNumbers's existing behavior — this issue is scoped to bringingextractLinkedPrNumbersup to the same standard, not modifying the function it's mirroring.functions, to prevent this same class of drift from happening again if either function is
modified in the future — this is encouraged but not required if you instead duplicate the
exclusion logic consistently with the existing style in this file; either approach satisfies this
issue as long as
extractLinkedPrNumbersgets the actual exclusion behavior.Deliverables
extractLinkedPrNumbersexcludes matches whose byte range overlaps an inline code span,matching
extractLinkedIssueNumbers's existing#7527behavior.REGRESSION (#7527)tests forextractLinkedIssueNumbers) asserting that a body containing a backtick-quoted example like`Closes PR #99`is NOT counted as a linked PR byextractLinkedPrNumbers.Closes PR #99in thebody IS still counted — guarding against a regression where the new exclusion is too broad.
Both new tests and the code fix are required in this single PR.
Test Coverage Requirements
This repo's Codecov patch gate is 99%+ (branch-counted) on
packages/loopover-miner/lib/**. Addthe new regression tests to
test/unit/miner-self-review-context.test.ts(this package's testslive in the shared root
test/directory, notpackages/loopover-miner/test/**), next to theexisting
#7527tests forextractLinkedIssueNumbers. The new exclusion branch inextractLinkedPrNumbersmust be exercised by both the exclusion test and the still-matches test.Expected Outcome
extractLinkedPrNumbersandextractLinkedIssueNumbersshare the same protection against abacktick-quoted closing-keyword example being misread as a real link. A quoted example in an issue
body's Markdown no longer causes the miner to wrongly treat that issue as already linked to a PR.
Links & Resources
packages/loopover-miner/lib/self-review-context.ts—extractLinkedPrNumbers(~lines 265-273)and
extractLinkedIssueNumbers(~lines 282-306), the function to mirror.test/unit/miner-self-review-context.test.ts— the existingREGRESSION (#7527)tests (~lines1071, 1078) to mirror for the new tests.