Skip to content

fix(signals): recognize the fully-qualified owner/repo#N closing reference - #2860

Merged
loopover-orb[bot] merged 1 commit into
JSONbored:mainfrom
ultrahighsuper:feat/qualified-linked-issue-refs
Jul 4, 2026
Merged

fix(signals): recognize the fully-qualified owner/repo#N closing reference#2860
loopover-orb[bot] merged 1 commit into
JSONbored:mainfrom
ultrahighsuper:feat/qualified-linked-issue-refs

Conversation

@ultrahighsuper

Copy link
Copy Markdown
Contributor

extractLinkedIssueNumbers (the preflight linked-issue detector) matched only the bare KEYWORD #N closing form:

/\b(?:close[sd]?|fix(?:e[sd])?|resolve[sd]?)\s+#(\d+)\b/gi

The \s+# requires whitespace immediately before #, so GitHub's other documented auto-close syntax — the fully-qualified KEYWORD owner/repo#N (Fixes octo-org/octo-repo#100) — is silently dropped.

Why it matters

extractLinkedIssueNumbers feeds buildPreflightResult / buildLocalDiffPreflightResult, whose linked-issue output drives real gating/scoring:

  • missing_linked_issue preflight finding — a PR whose body says Fixes myorg/myrepo#42 is flagged as having no linked issue, and slop receives hasLinkedIssue: false, tripping the no_linked_issue_without_rationale slop finding. A legitimately-linked PR is penalized as slop.
  • Duplicate-cluster detection (itemSharesPlannedLinkedIssue) — two PRs linking the same issue via the qualified form aren't recognized as overlapping.
  • Bounty linkage — the linked bounty issue is missed.

The qualified owner/repo#N form is standard — Renovate/Dependabot emit it routinely, and contributors paste fully-qualified references.

Fix

Also match KEYWORD owner/repo#N, repo-scoped: include N only when owner/repo case-insensitively equals this repo. A cross-repo reference (other-org/other#5) closes an issue elsewhere and must not spoof a same-repo link — this is the correctness nuance that keeps it from over-linking. repoFullName is threaded from both call sites (already in scope). The bare #N form and the #1988 word-boundary invariant (unfixes … is not a keyword) are unchanged.

Body (repo = owner/direct) Before After
Closes #10 [10] [10]
Fixes owner/direct#42 [] [42]
Resolves Owner/Direct#42 (case) [] [42]
Fixes other-org/other#42 (cross-repo) [] []
unfixes owner/direct#42 (embedded kw) [] []

Scope note: a parallel, intentionally-independent copy lives in src/db/repositories.ts (extractLinkedIssueNumbersWithOverflow, per #1988); it is deliberately left out of scope because its consumers include a guarded code path — this PR targets the preflight/slop path only.

Tests

Adds a regression case covering the same-repo qualified ref (links + suppresses missing_linked_issue), case-insensitive owner/repo match, cross-repo exclusion (still fires missing_linked_issue), the unchanged bare form, and the embedded-keyword guard. Verified the new cases FAIL on current main and PASS with the fix; signals-coverage + slop suites stay green.

No linked issue: issue creation is unavailable for this account.

…rence

extractLinkedIssueNumbers only matched the bare `KEYWORD #N` closing form, so
GitHub`s other documented auto-close syntax -- the fully-qualified
`KEYWORD owner/repo#N` (routinely emitted by Renovate/Dependabot and by
contributors pasting a qualified reference) -- was silently dropped. A PR whose
body says `Fixes myorg/myrepo#42` was therefore scored as having NO linked
issue: it wrongly tripped the missing_linked_issue preflight finding and fed
slop a false hasLinkedIssue=false, penalizing a properly-linked PR.

Match the qualified form too, repo-scoped: count `owner/repo#N` only when
owner/repo case-insensitively equals this repo, so a cross-repo reference
(which closes an issue elsewhere) never spoofs a same-repo link. The bare form
and the JSONbored#1988 word-boundary invariant are unchanged.
@ultrahighsuper
ultrahighsuper requested a review from JSONbored as a code owner July 4, 2026 01:01
@codecov

codecov Bot commented Jul 4, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 96.01%. Comparing base (10bd76c) to head (d840309).
⚠️ Report is 4 commits behind head on main.

Additional details and impacted files
@@           Coverage Diff           @@
##             main    #2860   +/-   ##
=======================================
  Coverage   96.01%   96.01%           
=======================================
  Files         259      259           
  Lines       28279    28282    +3     
  Branches    10288    10289    +1     
=======================================
+ Hits        27151    27154    +3     
  Misses        491      491           
  Partials      637      637           
Files with missing lines Coverage Δ
src/signals/engine.ts 97.35% <100.00%> (+<0.01%) ⬆️
🚀 New features to boost your workflow:
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@loopover-orb loopover-orb Bot added the gittensor:bug Gittensor-scored bug fix — scores a 0.05x multiplier. label Jul 4, 2026
@loopover-orb

loopover-orb Bot commented Jul 4, 2026

Copy link
Copy Markdown
Contributor

Warning

🟨🟨🟨🟨🟨🟨🟨🟨🟨🟨🟨🟨

⏸️ Gittensory review result - manual review recommended

Review updated: 2026-07-04 01:32:33 UTC

2 files · 1 AI reviewer · no blockers · readiness 80/100 · CI green · clean

⏸️ Suggested Action - Manual Review

Review summary
The change correctly threads repo identity into preflight linked-issue extraction and adds same-repo recognition for GitHub's fully-qualified `KEYWORD owner/repo#N` syntax while preserving bare `#N` behavior. The repo-scoped comparison prevents cross-repo references from being treated as local issue links, and the added test covers same-repo, case-insensitive, cross-repo, bare, and embedded-keyword cases. I do not see a reachable correctness break in the visible diff.

Nits — 5 non-blocking
  • nit: `src/signals/engine.ts:5302` lowercases `repoFullName` without trimming, while nearby repo-name matching code such as `isConvergenceRepoAllowed` trims before comparing; consider matching that convention so incidental whitespace at a boundary cannot suppress qualified links.
  • nit: `src/signals/engine.ts:5297` and `src/signals/engine.ts:5303` duplicate the closing-keyword regex, which makes future keyword fixes easy to apply to only one form by mistake.
  • In `src/signals/engine.ts:5302`, use `const target = repoFullName.trim().toLowerCase();` to align with existing full-name comparison conventions.
  • In `src/signals/engine.ts:5297`, consider hoisting the shared closing-keyword fragment or regexes near `extractLinkedIssueNumbers` so the bare and qualified paths cannot drift.
  • In `test/unit/signals-coverage.test.ts:284`, add one assertion for a mixed body containing both `Closes #N` and `Fixes owner/direct#N` to lock in dedupe/sort behavior across the two extraction paths.
Signal Result Evidence
Code review ✅ No blockers 1 reviewer
Linked issue ✅ Linked #10
Related work ✅ No active overlap found No same-issue or scoped active PR overlap found.
Change scope ✅ 20/20 Low review scope from cached public metadata (1 linked issue).
Validation posture ❌ 5/25 Preflight is holding this PR: the review lane is unavailable, so it is not ready for automated review.
Contributor workload ✅ 10/10 Author activity: 73 registered-repo PR(s), 48 merged, 9 issue(s).
Contributor context ✅ Confirmed Gittensor contributor ultrahighsuper; Gittensor profile; 73 PR(s), 9 issue(s).
Gate result ✅ Passing No configured blocker found.
Review context
  • Author: ultrahighsuper
  • Role context: outside_contributor
  • Public audience mode: oss maintainer
  • Lane context: Repository registration is not available in the local Gittensory cache.
  • Public profile languages: not available
  • Official Gittensor activity: 73 PR(s), 9 issue(s).
  • PR-specific overlap: none found.
Contributor next steps
  • Await review-lane availability.
  • Refresh registry data or choose a registered active repo.
Signal definitions
  • Related work = same linked issue, overlapping active PRs, or title/path similarity.
  • Change scope = cached public metadata such as size labels, draft state, and review-burden hints.
  • Validation posture = whether the PR provides enough public validation/test evidence for maintainer review.
  • Contributor workload = public contributor activity and cleanup pressure, not a repo-wide quality failure.
  • Contributor context = public GitHub/Gittensor identity context; non-Gittensor status is not a blocker.

🟩 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 Gittensory, a quiet PR intelligence layer for OSS maintainers.

  • Re-run Gittensory review

@loopover-orb loopover-orb Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Gittensory approves — the gate is satisfied and CI is green.

@loopover-orb
loopover-orb Bot merged commit 2aadc4f into JSONbored:main Jul 4, 2026
9 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

gittensor:bug Gittensor-scored bug fix — scores a 0.05x multiplier.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant