Skip to content

fix(signals): classify .mjs/.cjs/.mts/.cts as code and test files#2665

Merged
JSONbored merged 1 commit into
JSONbored:mainfrom
glorydavid03023:fix/code-file-module-extensions
Jul 3, 2026
Merged

fix(signals): classify .mjs/.cjs/.mts/.cts as code and test files#2665
JSONbored merged 1 commit into
JSONbored:mainfrom
glorydavid03023:fix/code-file-module-extensions

Conversation

@glorydavid03023

@glorydavid03023 glorydavid03023 commented Jul 3, 2026

Copy link
Copy Markdown
Contributor

Summary

isCodeFile omitted the Node/TypeScript ESM + CommonJS module extensions — .mjs / .cjs / .mts / .cts — even though the codebase's own src/review/rag.ts (JS_TS_RE = /\.(ts|tsx|js|jsx|mjs|cjs)$/i) already recognizes .mjs/.cjs as JS/TS. So a PR that changes only .mjs/.mts source was counted as having no code files, skewing:

  • the "code changed without matching tests" slop signal (signals/engine.ts),
  • codeFileCount / source-line inputs, and
  • the AI-review code-path grounding (services/ai-review.tslocal-branch isCodeFile).
isCodeFile("src/loader.mjs")  // before: false → after: true
isCodeFile("src/config.mts")  // before: false → after: true

Fix: add the four module extensions to isCodeFile in both src copies (signals/local-branch.ts and the private one in signals/engine.ts) and the MCP client copy — and, consistently, to the .test/.spec group in isTestPath (signals/test-evidence.ts) and the MCP isTestFile, so a foo.test.mts still classifies as a test rather than as source (verified). Pure classifiers — no schema or API change.

No issue because issue creation is restricted on this repo for outside accounts; this aligns the code/test-file classifiers with the module extensions the codebase already uses.

Scope

  • Conventional Commit title; focused; follows CONTRIBUTING; small self-evident fix (no linked issue).

Validation

  • git diff --check
  • npm run typecheck
  • npm run build:mcp (node --check clean)
  • npm run test:coverage (scoped: test-evidence.test.ts + local-branch-file-classifiers.test.ts + local-branch.test.ts — 75 pass; the changed regex lines add extension alternatives, not new branches, and are exercised by these tests and the engine slop tests — engine.ts isCodeFile statement confirmed hit.)
  • npm run test:workers / ui:* — N/A (no UI/worker change)
  • npm audit --audit-level=moderate
  • New/changed behavior has tests

If any required check was skipped, explain why:

  • Backend classifier change in src/signals/** plus the MCP client copy (plain JS, outside Codecov's src/**/*.ts include). typecheck + build:mcp clean; regression assertions added in the file-classifier, test-evidence, and MCP-lib tests (.mjs/.cjs/.mts/.cts are code; .test.mts/.spec.cjs are tests). I did not run the UI/workers steps (unrelated), and the local Windows tree has pre-existing unrelated failures (CRLF, missing CLI binaries, Node 24 vs pinned 22). CI runs the full matrix on a clean checkout.

Safety

  • No secrets/wallets/hotkeys/trust/reward/private terms exposed.
  • Public GitHub text stays sanitized and low-noise.
  • Auth/cookie/CORS/session negative-path tests. — N/A.
  • API/OpenAPI/MCP behavior updated/tested where needed. (Internal classifiers; covered by the added tests. No schema changed.)
  • UI changes use live API data. — N/A: no UI change.
  • UI Evidence. — N/A: no visible UI change.
  • Docs/changelog updated where needed. (None needed.)

Notes

  • The .test/.spec group is extended in lockstep with isCodeFile so a foo.test.mts is still a test, not source — a regression test pins this.
  • Both isCodeFile copies (local-branch.ts exported + engine.ts private) and the MCP client copy are updated together so the classifier can't drift by extension.

Update (addressing review): also extended the Cypress/Playwright .cy/.e2e test-file group to the module extensions (so checkout.cy.mts / flow.e2e.mjs stay tests, not source), and replaced engine.ts's stale private isTestFile (which lacked .cy/.e2e and __snapshots__) with a delegation to the canonical isTestPath, mirroring local-branch.ts — so all test/code classifiers are single-sourced and cannot drift by extension. Regression assertions added for the .cy.mts/.e2e.mjs cases; engine.ts delegation line confirmed covered.

@codecov

codecov Bot commented Jul 3, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 96.10%. Comparing base (cfbdc9f) to head (f3c6f0e).
⚠️ Report is 25 commits behind head on main.

Additional details and impacted files
@@            Coverage Diff             @@
##             main    #2665      +/-   ##
==========================================
- Coverage   96.10%   96.10%   -0.01%     
==========================================
  Files         237      237              
  Lines       26540    26539       -1     
  Branches     9625     9624       -1     
==========================================
- Hits        25507    25506       -1     
  Misses        424      424              
  Partials      609      609              
Files with missing lines Coverage Δ
src/signals/engine.ts 97.71% <100.00%> (-0.01%) ⬇️
src/signals/local-branch.ts 97.20% <100.00%> (ø)
src/signals/test-evidence.ts 100.00% <ø> (ø)
🚀 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 commented Jul 3, 2026

Copy link
Copy Markdown

Warning

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

⏸️ Gittensory review result - manual review recommended

Review updated: 2026-07-03 02:36:23 UTC

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

⏸️ Suggested Action - Manual Review

Review summary
The change brings the source and test-file classifiers into better parity for Node and TypeScript module extensions, and the tests cover both source files and `.test`/`.spec`/e2e variants so the source-vs-test ordering remains correct. The `engine.ts` wrapper now delegates to the canonical `isTestPath`, which also fixes the existing drift around e2e and snapshot paths instead of adding another regex copy. I do not see a reachable correctness break in the provided diff.

Nits — 4 non-blocking
  • nit: `src/signals/engine.ts:5505` now keeps a private `isTestFile` wrapper whose only behavior is `return isTestPath(file);`, so future readers still have two names to trace for the same classifier.
  • nit: `test/unit/local-branch-file-classifiers.test.ts:116` includes `helper_test.ts` in the positive `isCodeFile` examples; that is existing behavior, but it remains visually surprising beside the surrounding test-classifier assertions.
  • In `src/signals/engine.ts:5505`, either inline `isTestPath(file)` at the single private call site or add a short reason why the wrapper name is kept for local readability.
  • In `test/unit/local-branch-file-classifiers.test.ts:116`, add a brief comment that TypeScript `*_test.ts` is intentionally treated as source if that convention is deliberate.
Signal Result Evidence
Code review ✅ No blockers 1 reviewer
Linked issue ✅ No-issue rationale PR body explains why no issue is linked.
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 (size label size:S; no linked issue context).
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: 224 registered-repo PR(s), 143 merged, 11 issue(s).
Contributor context ✅ Confirmed Gittensor contributor glorydavid03023; Gittensor profile; 224 PR(s), 11 issue(s).
Gate result ✅ Passing No configured blocker found.
Review context
  • Author: glorydavid03023
  • 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: 224 PR(s), 11 issue(s).
  • PR-specific overlap: none found.
Contributor next steps
  • Await review-lane availability.
  • Refresh registry data or choose a registered active repo.
  • Link the issue being solved, or explicitly explain why this is a no-issue PR.
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 added gittensor gittensor:bug Gittensor-scored bug fix — scores a 0.05x multiplier. labels Jul 3, 2026
isCodeFile omitted the Node/TypeScript ESM + CommonJS module extensions
(.mjs/.cjs/.mts/.cts), even though the codebase's own rag.ts JS_TS_RE already
recognizes .mjs/.cjs as JS/TS. A PR changing only `.mjs`/`.mts` source was
therefore counted as having no code files, skewing the "code changed without
tests" slop signal, the codeFileCount/source-line inputs, and the AI-review
code-path grounding.

Add the four module extensions to isCodeFile (both src copies — signals/
local-branch.ts and signals/engine.ts — plus the MCP client copy) and,
consistently, to BOTH test-file extension groups (`.test`/`.spec` AND the
Cypress/Playwright `.cy`/`.e2e` group) in isTestPath / the MCP isTestFile, so a
`foo.test.mts` or `checkout.cy.mts` still classifies as a test rather than as
source. engine.ts's private isTestFile — a stale partial copy that also lacked
`.cy`/`.e2e` and `__snapshots__` — now delegates to the canonical isTestPath
(mirroring local-branch.ts), so the classifiers can't drift again. Adds
regression assertions across the file-classifier, test-evidence, and MCP tests.

No issue because issue creation is restricted on this repo; this aligns the code/
test-file classifiers with the module extensions the codebase already uses, no
schema or API change.
@dosubot dosubot Bot added the lgtm label Jul 3, 2026
@JSONbored
JSONbored merged commit f60a852 into JSONbored:main Jul 3, 2026
10 checks passed
@github-actions github-actions Bot mentioned this pull request Jul 3, 2026
12 tasks
glorydavid03023 added a commit to glorydavid03023/gittensory that referenced this pull request Jul 3, 2026
… conventions

The local score-preview scripts inline their own test/code classifiers (they ship
in the standalone Node bin package and can't import from src/). Both had drifted
from the canonical isTestPath/isCodeFile: the .mjs and .py test detectors missed
the pytest `test_*.py` prefix (JSONbored#2666), the Cypress/Playwright `*.cy.*`/`*.e2e.*`
convention and `__snapshots__` dirs (JSONbored#2665); the `.mjs` isCodeFile and the `.py`
metadata_fallback source-extension tuple both missed the `.mts/.cts/.mjs/.cjs`
module extensions.

So a miner's LOCAL preview classified a `.mts` source file as non-code and a
Cypress/pytest test as source — disagreeing with the gate's own source/test split
and skewing the previewed token scores. (JSONbored#2776 already re-synced these scripts'
C#/Swift/Groovy code extensions; this closes the older test-convention + module-
extension gaps.)

Bring both scripts' classifiers to parity with isTestPath/isCodeFile. Adds a
spawn-based regression running the real .mjs (and the .py metadata_fallback when
python is available) over module-ext/Cypress/pytest files.
glorydavid03023 added a commit to glorydavid03023/gittensory that referenced this pull request Jul 3, 2026
… conventions

The local score-preview scripts inline their own test/code classifiers (they ship
in the standalone Node bin package and can't import from src/). Both had drifted
from the canonical isTestPath/isCodeFile: the .mjs and .py test detectors missed
the pytest `test_*.py` prefix (JSONbored#2666), the Cypress/Playwright `*.cy.*`/`*.e2e.*`
convention and `__snapshots__` dirs (JSONbored#2665); the `.mjs` isCodeFile and the `.py`
metadata_fallback source-extension tuple both missed the `.mts/.cts/.mjs/.cjs`
module extensions.

So a miner's LOCAL preview classified a `.mts` source file as non-code and a
Cypress/pytest test as source — disagreeing with the gate's own source/test split
and skewing the previewed token scores. (JSONbored#2776 already re-synced these scripts'
C#/Swift/Groovy code extensions; this closes the older test-convention + module-
extension gaps.)

Bring both scripts' classifiers to parity with isTestPath/isCodeFile. Adds a
spawn-based regression running the real .mjs (and the .py metadata_fallback when
python is available) over module-ext/Cypress/pytest files.
glorydavid03023 added a commit to glorydavid03023/gittensory that referenced this pull request Jul 3, 2026
… conventions

The local score-preview scripts inline their own test/code classifiers (they ship
in the standalone Node bin package and can't import from src/). Both had drifted
from the canonical isTestPath/isCodeFile: the .mjs and .py test detectors missed
the pytest `test_*.py` prefix (JSONbored#2666), the Cypress/Playwright `*.cy.*`/`*.e2e.*`
convention and `__snapshots__` dirs (JSONbored#2665); the `.mjs` isCodeFile and the `.py`
metadata_fallback source-extension tuple both missed the `.mts/.cts/.mjs/.cjs`
module extensions.

So a miner's LOCAL preview classified a `.mts` source file as non-code and a
Cypress/pytest test as source — disagreeing with the gate's own source/test split
and skewing the previewed token scores. (JSONbored#2776 already re-synced these scripts'
C#/Swift/Groovy code extensions; this closes the older test-convention + module-
extension gaps.)

Bring both scripts' classifiers to parity with isTestPath/isCodeFile. Adds a
spawn-based regression running the real .mjs (and the .py metadata_fallback when
python is available) over module-ext/Cypress/pytest files.
loopover-orb Bot pushed a commit that referenced this pull request Jul 3, 2026
… conventions (#2822)

The local score-preview scripts inline their own test/code classifiers (they ship
in the standalone Node bin package and can't import from src/). Both had drifted
from the canonical isTestPath/isCodeFile: the .mjs and .py test detectors missed
the pytest `test_*.py` prefix (#2666), the Cypress/Playwright `*.cy.*`/`*.e2e.*`
convention and `__snapshots__` dirs (#2665); the `.mjs` isCodeFile and the `.py`
metadata_fallback source-extension tuple both missed the `.mts/.cts/.mjs/.cjs`
module extensions.

So a miner's LOCAL preview classified a `.mts` source file as non-code and a
Cypress/pytest test as source — disagreeing with the gate's own source/test split
and skewing the previewed token scores. (#2776 already re-synced these scripts'
C#/Swift/Groovy code extensions; this closes the older test-convention + module-
extension gaps.)

Bring both scripts' classifiers to parity with isTestPath/isCodeFile. Adds a
spawn-based regression running the real .mjs (and the .py metadata_fallback when
python is available) over module-ext/Cypress/pytest files.
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.

2 participants