Skip to content

chore(imports): unify relative-import specifiers per resolution zone; add a drift guard - #9231

Merged
JSONbored merged 1 commit into
mainfrom
chore/unify-script-import-specifiers-v2
Jul 27, 2026
Merged

chore(imports): unify relative-import specifiers per resolution zone; add a drift guard#9231
JSONbored merged 1 commit into
mainfrom
chore/unify-script-import-specifiers-v2

Conversation

@JSONbored

Copy link
Copy Markdown
Owner

Summary

The repo had three relative-import specifier styles where only one split was actually forced:

Zone tsconfig Style before Forced?
src/** root, moduleResolution: "Bundler" extensionless idiomatic for Bundler
scripts/**, test/** the same root tsconfig .js no — verified tsx resolves extensionless fine, and vitest/tsc read a package's .ts source directly from this zone too
packages/** own tsconfig, moduleResolution: "NodeNext", published ESM .js yes — Node's ESM resolver requires the emitted extension

src/** and scripts/**/test/** compiled under the identical tsconfig yet disagreed — an arbitrary drift, not a technical requirement. This PR converts scripts/** and test/** to extensionless (matching src/**), leaves packages/** on .js (a hard constraint of shipping ESM, not a style choice), and adds a drift guard so the split can't silently return.

What changed:

  • 268 files across src/**/scripts/**/test/**: ./foo.js./foo on relative specifiers.
  • 55 files across packages/**: bare relative specifiers → .js (their own internal imports only — reaching FROM src/scripts/test INTO a package's source still resolves extensionless, since the importer's own zone rule governs, not the target's).
  • New scripts/check-import-specifiers.ts + npm run import-specifiers:check, wired into test:ci. Pure core with injectable listSourceFiles/readFile (mirrors check-coverage-bolt-on-filenames.ts's shape), 11 unit tests.
  • .d.ts declaration-only imports (claim-ledger.d.ts et al.) and non-JS/TS extensions (.json import assertions, etc.) are explicitly exempted in both the checker and the conversion — verified no such import was mangled.

Closes #9221

Two false positives found and fixed while building the checker

  1. A mechanical first pass appended .js to ../package.json (an import-assertion, not a JS specifier) inside packages/loopover-engine/src/version.ts — caught by npm run typecheck failing with TS2307, reverted, and the checker's own extension-detection tightened (OTHER_EXTENSION_TAIL) so neither the checker nor the converter can misfire on .json/.css/.svg/etc. again.
  2. The checker's own test file embeds import-statement TEXT as string fixtures (to feed the injectable readFile) — it was flagging its own fixtures as violations of themselves. Fixed with an ALLOWED_FILENAMES allowlist, mirroring check-coverage-bolt-on-filenames.ts's identical self-referential-false-positive pattern.

Validation

  • npm run import-specifiers:check — clean (0 violations) against the full src/**, scripts/**, test/**, packages/** tree.
  • npm run typecheck — clean.
  • npm run build --workspace @loopover/engine + npm run test --workspace @loopover/engine737/737 pass.
  • npm run build:mcp, build:miner, build --workspace @loopover/ui-kit, build --workspace @loopover/discovery-index — all clean.
  • npx vitest run targeted at the checker's own suite plus every test file touched by recent related work (attester seam, rate-limit fix, gate-check-policy) — 311/311 pass, including the two #4995 regression tests in orb-relay.test.ts that are only green now that fix(orb): degrade rate-limit installation-identity resolution on a DB error instead of escaping uncaught #9227 has merged.

Safety

  • Mechanical specifier rewrite only — no logic, behavior, or export-surface change anywhere. Confirmed by the full engine suite passing byte-for-byte and typecheck staying clean across all 327 changed files.
  • No secrets, wallets, hotkeys, trust scores, or reward values.
  • packages/**'s published ESM output is unchanged (still .js-suffixed internally, as required).

@superagent-security

Copy link
Copy Markdown
Contributor

Superagent didn't find any vulnerabilities or security issues in this PR.

@cloudflare-workers-and-pages

Copy link
Copy Markdown

Deploying with  Cloudflare Workers  Cloudflare Workers

The latest updates on your project. Learn more about integrating Git with Workers.

Status Name Latest Commit Preview URL Updated (UTC)
✅ Deployment successful!
View logs
loopover-ui b46e314 Commit Preview URL

Branch Preview URL
Jul 27 2026, 08:13 AM

@github-actions

Copy link
Copy Markdown
Contributor

Logic backtest

Replayed 0 historical case(s) for linked_issue_scope_mismatch through the base (194fa65) and head (b46e314) versions of its detection logic (corpus checksum 4f53cda18c2b).

Backtest comparison: linked_issue_scope_mismatch

Verdict: unchanged — no comparable axis moved.

Advisory only — this check never blocks merge (#8105).

@codecov

codecov Bot commented Jul 27, 2026

Copy link
Copy Markdown

Bundle Report

Bundle size has no change ✅

@codecov

codecov Bot commented Jul 27, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 93.94%. Comparing base (194fa65) to head (b46e314).
⚠️ Report is 2 commits behind head on main.
✅ All tests successful. No failed tests found.

Additional details and impacted files
@@           Coverage Diff           @@
##             main    #9231   +/-   ##
=======================================
  Coverage   93.94%   93.94%           
=======================================
  Files         825      825           
  Lines       81835    81835           
  Branches    24849    24849           
=======================================
  Hits        76882    76882           
  Misses       3558     3558           
  Partials     1395     1395           
Flag Coverage Δ
backend 95.21% <ø> (ø)

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

Files with missing lines Coverage Δ
packages/loopover-engine/src/signals/engine.ts 97.67% <ø> (ø)
src/mcp/find-opportunities.ts 100.00% <ø> (ø)
src/mcp/redeploy-companion-registry.ts 100.00% <ø> (ø)
src/selfhost/orb-collector.ts 98.66% <ø> (ø)
src/selfhost/posthog.ts 99.40% <ø> (ø)
src/signals/focus-manifest.ts 99.59% <ø> (ø)
src/signals/reward-risk.ts 100.00% <ø> (ø)

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

loopover-orb Bot commented Jul 27, 2026

Copy link
Copy Markdown
Contributor

Tip

✅ LoopOver review result - approve/merge recommended

Review updated: 2026-07-27 08:35:41 UTC

327 files · 1 AI reviewer · no blockers · readiness 98/100 · CI green · clean

✅ Suggested Action - Approve/Merge

  • safe to merge

Review summary
This is a mechanical import-specifier normalization: 268 files under src/**/scripts/**/test/** are converted from `.js` to extensionless (matching the Bundler zone's idiomatic style), and packages/** internal imports are converted to `.js` (required by NodeNext ESM resolution). A new drift-guard script (scripts/check-import-specifiers.ts) with 11 unit tests enforces the split going forward and is wired into test:ci. The regex-based checker correctly distinguishes .d.ts declaration imports, .json import-assertions, and .ts specifiers (rejected everywhere per TS5097), and the diff shows internally-consistent hunks (e.g. packages/loopover-engine/src/signals/engine.ts converts monorepo-crossing relative imports to `.js` since it's importing FROM inside a NodeNext package). CI is fully green on this commit, and the change is well-scoped to its stated mechanical goal.

Nits — 5 non-blocking
  • scripts/check-import-specifiers.ts's SPECIFIER_PATTERN only matches specifiers inside double quotes (`"..."`); if any repo source uses single-quoted relative imports the checker would silently skip them — worth confirming the codebase is quote-consistent or documenting the assumption.
  • The hard-coded ALLOWED_FILENAMES allowlist for the checker's own test file (scripts/check-import-specifiers.ts) is a bit fragile — a future rename of the test file would silently re-enable false-positive scanning of its own fixtures rather than failing loudly.
  • Consider making the checker also assert zero violations exist today as part of CI output (it already does via process.exit(1)), but a periodic count in the check-import-specifiers output could help catch future partial conversions faster.
  • No further action needed beyond confirming the 55 packages/** files were audited for correctness, which the PR description states was done manually.
  • PR author also opened the linked issue — Link an issue that was opened by a different contributor, or provide a rationale for why this self-authored issue represents genuine discovery work.

Decision drivers

  • ✅ Code review — No blockers (1 reviewer)
  • ✅ Gate result — Passing (No configured blocker found.)
Context & advisory signals — never blocks the verdict
Signal Result Evidence
Linked issue ✅ Linked #9221
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: 13 registered-repo PR(s), 13 merged, 299 issue(s).
Contributor context ✅ Confirmed Gittensor contributor JSONbored; Gittensor profile; 13 PR(s), 299 issue(s).
Improvement ✅ Minor risk: clean · value: minor · LLM: moderate
Linked issue satisfaction

Addressed
The PR converts scripts/** relative imports from .js to extensionless (visible across many scripts/*.ts files), leaves packages/loopover-engine on .js, and adds scripts/check-import-specifiers.ts wired into test:ci with unit tests covering both a passing and failing case, matching the issue's core requirements.

Review context
  • Author: JSONbored
  • Role context: owner (maintainer lane)
  • Public audience mode: oss maintainer
  • Lane context: Repository is configured for direct PR review.
  • Public profile languages: Python, TypeScript, Ruby, Go, MDX, Shell, Solidity, JavaScript
  • Official Gittensor activity: 13 PR(s), 299 issue(s).
  • PR-specific overlap: none found.
Contributor next steps
  • Start here: Treat this as maintainer-lane context rather than normal contributor-lane activity.
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 &lt;question&gt; answers contribution-quality Q&A with source citations and freshness.
  • @loopover chat &lt;question&gt; 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.

Visual preview
Route Viewport Before (production) After (this PR's preview) Diff
/ desktop before /
before /
after /
after /
/ mobile before / (mobile)
before / (mobile)
after / (mobile)
after / (mobile)

Click any thumbnail to open the full-size screenshot. Before = production · After = this PR's preview deploy.

Scroll preview
Route Before (production) After (this PR's preview)
/ before / (scroll)
before / (scroll)
after / (scroll)
after / (scroll)

A short scroll-through clip (desktop) — click either thumbnail to open the full animation. Evidence for scroll-linked behavior a single screenshot can't show.

🟩 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

@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.

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

@JSONbored
JSONbored merged commit 628a634 into main Jul 27, 2026
13 checks passed
@JSONbored
JSONbored deleted the chore/unify-script-import-specifiers-v2 branch July 27, 2026 08:36
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.

scripts: unify relative-import specifiers with src/** (extensionless) and add a drift guard

1 participant