Skip to content

fix(orb): canonicalize issue-body path tokens in checkContentLaneDeliverable (#9667) - #9926

Closed
kai392 wants to merge 1 commit into
JSONbored:mainfrom
kai392:fix/9667-canonicalize-issue-path-tokens
Closed

fix(orb): canonicalize issue-body path tokens in checkContentLaneDeliverable (#9667)#9926
kai392 wants to merge 1 commit into
JSONbored:mainfrom
kai392:fix/9667-canonicalize-issue-path-tokens

Conversation

@kai392

@kai392 kai392 commented Jul 29, 2026

Copy link
Copy Markdown
Contributor

What

checkContentLaneDeliverable compares an issue-body path against the spec's entryFilePattern/providerFilePattern, which globToRegExp compiles against a canonicalized (lowercased) path with no i flag — so they only match lowercase input. The changedFiles side already canonicalizes each path before testing; the issue-body side did not. An issue naming the path with any capitalization (Registry/Subnets/Foo.json) produced no mentionedPath, so with no issueTitleImpliesEntryPattern the check returned not-applicable and the deliverable gate silently did not run — the exact "test-only PR closes a content issue without delivering the content" gap the function exists to close. classifyRegistryPrScope in the same file already documents this canonicalization hazard; the issue-body side never got the treatment.

How

Canonicalize each token from extractPathTokens before matchesSpec, exactly as the changedFiles side does. .find still returns the original token, so the "missing" verdict's mentionedPath stays the path as written in the issue body (rendered verbatim into the public PR comment).

const mentionedPath = extractPathTokens(issueText).find((token) => matchesSpec(canonicalize(token)));

Tests (content-lane-registry-logic.test.ts)

  1. A mixed-case issue path (Registry/Subnets/Foo.json) with no matching changed file → { verdict: "missing", mentionedPath: "Registry/Subnets/Foo.json" } (original case preserved).
  2. The same mixed-case body → delivered when the PR changes registry/subnets/foo.json.
  3. All-lowercase behaviour (delivered + missing) unchanged.
  4. A path matching no spec pattern still returns not-applicable (no over-broadening).

The mixed-case cases fail against the current code.

Closes #9667

@kai392
kai392 requested a review from JSONbored as a code owner July 29, 2026 23:51
@loopover-orb

loopover-orb Bot commented Jul 29, 2026

Copy link
Copy Markdown
Contributor

Caution

🛑 LoopOver review result - reject/close recommended

Review updated: 2026-07-30 16:02:13 UTC

2 files · 1 AI reviewer · 1 blocker · CI green · clean

🛑 Suggested Action - Reject/Close

Review summary
This is a narrowly-scoped fix: `checkContentLaneDeliverable`'s issue-body token matching now canonicalizes each token before testing against `entryFilePattern`/`providerFilePattern`, mirroring the existing `changedFiles` handling and the same hazard already documented for `classifyRegistryPrScope`. The `.find` predicate correctly still returns the original (uncanonicalized) token so `mentionedPath` preserves the issue's literal casing for the public comment, and the four new tests (mixed-case missing/delivered, lowercase-unchanged, non-matching path still not-applicable) directly exercise the fixed and unfixed branches. The fix is well-targeted, low-risk, and closes issue #9667 as claimed.

Nits — 3 non-blocking
  • The inline comment at src/review/content-lane/registry-logic.ts:933-937 is quite long (5 lines) for a one-line fix; could be trimmed since the rationale is already covered by the analogous comment on `classifyRegistryPrScope`.
  • No test case for a mixed-case ISSUE TITLE path combined with `issueTitleImpliesEntryPattern` — though that signal doesn't use `extractPathTokens`/canonicalize at all, so it's arguably out of scope.
  • Consider referencing `classifyRegistryPrScope`'s comment directly (e.g., 'see classifyRegistryPrScope's comment above') instead of restating the full rationale, to avoid drift if one is updated without the other.

Why this is blocked

  • Linked issue's expected content was never delivered: This PR's linked issue names registry/subnets/foo.json, but the PR's changed files never touch it -- the issue's actual content deliverable does not appear to have been added. — Edit registry/subnets/foo.json to deliver the issue's actual ask, or link the correct issue.
📋 Copy for AI agents — paste into your coding agent
Fix the following blocker(s) from this PR review:

1. Linked issue's expected content was never delivered: This PR's linked issue names `registry/subnets/foo.json`, but the PR's changed files never touch it -- the issue's actual content deliverable does not appear to have been added. — Edit registry/subnets/foo.json to deliver the issue's actual ask, or link the correct issue.

Decision drivers

  • ❌ Code review — 1 blocker (1 reviewer)
  • ❌ Gate result — Blocking (Repo-configured hard blocker found.)
Context & advisory signals — never blocks the verdict
Signal Result Evidence
Linked issue ✅ Linked #9667
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 ✅ 25/25 PR body includes validation/test evidence.
Contributor workload ✅ 10/10 Author activity: 100 registered-repo PR(s), 52 merged, 9 issue(s).
Contributor context ✅ Confirmed Gittensor contributor kai392; Gittensor profile; 100 PR(s), 9 issue(s).
Improvement ✅ Minor risk: clean · value: minor
Linked issue satisfaction

Addressed
The diff canonicalizes each issue-body token before testing against matchesSpec while preserving the original token via .find, exactly mirroring classifyRegistryPrScope's approach, and adds all four required test cases (mixed-case missing/delivered, lowercase unchanged, non-matching path stays not-applicable).

Review context
  • Author: kai392
  • Role context: outside_contributor
  • Public audience mode: oss maintainer
  • Lane context: Repository is configured for direct PR review.
  • Public profile languages: Python, Cuda, JavaScript, Kotlin, MDX, Perl, Ruby, Rust
  • Official Gittensor activity: 100 PR(s), 9 issue(s).
  • PR-specific overlap: none found.
Contributor next steps
  • Keep the PR focused and include validation evidence before maintainer review.
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.
🧪 Chat with LoopOver

Ask LoopOver a question about this PR directly in a comment — grounded only in the same cached, public-safe facts shown above, never a new claim.

  • @loopover ask <question> answers contribution-quality Q&A with source citations and freshness.
  • @loopover chat <question> answers in natural prose from cached decision-pack facts via local inference (maintainer/collaborator; read-only).
  • A plain-language @loopover mention with a real question is routed to the closest matching read-only command automatically — no exact syntax required.

Full command reference: https://loopover.ai/docs/loopover-commands

🧪 Experimental — new and may change.

Decision record
  • action: hold · clause: content_lane_deliverable_missing
  • config: 766da59d49b7af88f1e8d9771ad15936012c91804c897868c39b03233f22909e · pack: oss-anti-slop · ci: passed
  • note: diverted by the randomized close-audit holdout (calibration: randomized ε-holdout on would-close PRs with propensity logging #8831) — the deterministic pipeline would otherwise have closed this PR
  • record: 26fbd7cfd70b13060ccd9d8c2f0afd0862eb653692570745a82392c248f5be29 (schema v5, head a013ff5)

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

  • Re-run LoopOver review

@superagent-security

Copy link
Copy Markdown
Contributor

Superagent did not find any vulnerabilities or security issues in this PR.

…verable (JSONbored#9667)

checkContentLaneDeliverable compares an issue-body path against the spec's
entryFilePattern/providerFilePattern, which globToRegExp compiles against a
CANONICALIZED (lowercased) path with no `i` flag -- so they only match
lowercase input. The changedFiles side already canonicalizes each path
before testing; the issue-body side did not. An issue naming the path with
any capitalization (`Registry/Subnets/Foo.json`) produced no mentionedPath,
so with no issueTitleImpliesEntryPattern the check returned "not-applicable"
and the deliverable gate silently did not run -- the exact "test-only PR
closes a content issue without delivering the content" gap the function
exists to close (classifyRegistryPrScope in the same file already documents
this canonicalization hazard).

- Canonicalize each token from extractPathTokens before matchesSpec, exactly
  as the changedFiles side does. `.find` still returns the ORIGINAL token, so
  the "missing" verdict's mentionedPath stays the path as written in the issue
  body (rendered verbatim into the public PR comment).

Tests: a mixed-case issue path is "missing" (original case preserved in
mentionedPath) and "delivered" when the real lowercase file is changed; the
all-lowercase behaviour is unchanged; a path matching no spec pattern still
returns not-applicable (no over-broadening). The mixed-case cases fail
against the current code.

Closes JSONbored#9667

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@loopover-orb loopover-orb Bot added the gittensor:bug Gittensor-scored bug fix — scores a 0.05x multiplier. label Jul 30, 2026
@loopover-orb loopover-orb Bot added the manual-review Gittensor contributor context label Jul 30, 2026
@codecov

codecov Bot commented Jul 30, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 79.61%. Comparing base (f051cd2) to head (a013ff5).

Additional details and impacted files
@@            Coverage Diff             @@
##             main    #9926      +/-   ##
==========================================
+ Coverage   79.52%   79.61%   +0.09%     
==========================================
  Files         281      282       +1     
  Lines       58577    58853     +276     
  Branches     6833     6951     +118     
==========================================
+ Hits        46581    46857     +276     
  Misses      11706    11706              
  Partials      290      290              
Flag Coverage Δ
backend 100.00% <100.00%> (?)

Flags with carried forward coverage won't be shown. Click here to find out more.

Files with missing lines Coverage Δ
src/review/content-lane/registry-logic.ts 100.00% <100.00%> (ø)

@JSONbored JSONbored closed this Jul 30, 2026
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. manual-review Gittensor contributor context

Projects

None yet

Development

Successfully merging this pull request may close these issues.

orb(content-lane): canonicalize issue-body path tokens in `checkContentLaneDeliverable

3 participants