Skip to content

ci: detect a dead EXPORT, and make the 84 existing ones honest (#9852) - #9858

Merged
JSONbored merged 1 commit into
mainfrom
ci/dead-export-check-9852
Jul 29, 2026
Merged

ci: detect a dead EXPORT, and make the 84 existing ones honest (#9852)#9858
JSONbored merged 1 commit into
mainfrom
ci/dead-export-check-9852

Conversation

@JSONbored

@JSONbored JSONbored commented Jul 29, 2026

Copy link
Copy Markdown
Owner

Closes #9852.

#9856 has merged, so this is now a single commit on main and no longer stacked. That PR is what gives the two route-spec tables a consumer — without it this check correctly flags them, which is why the order mattered.

The gap

check-dead-source-files.ts catches a dead file, and its own header names what it does not catch:

no detection of a file that's imported but whose EXPORTS are all unused

That gap was populated: 84 src/** symbols were exported and referenced nowhere outside the file declaring them — not by another module, not by a script, not even by their own test.

Each was one of three things, and nothing told them apart:

  1. A missing wire-upmaintainability: processors.ts (16.2k lines, 437 touches) is the structural cause of this audit's drift and determinism gaps; plus a confirmed dead wire #9492's class one level down. An export with no caller is a feature built and never connected.
  2. A safety net with nothing behind itopenapi: the route auth-parity meta-test two files are exported FOR does not exist #9851 exactly: two route-spec tables exported "for the meta-test that asserts every entry's declared auth matches the middleware", test never written. That issue was found by this sweep.
  3. Dead surface that still has to be read, typechecked and maintained.

Coverage cannot catch any of them: the declaring file's own tests exercise the symbol directly and report green while it contributes nothing to the running system.

The fix is almost never deletion

82 of the 84 are used inside their own file — only the export keyword was untrue. Dropping it makes the surface honest, and tsc proves each one: if any had really been reachable from elsewhere, the build would say so. It is clean.

The two exceptions were decided by reading, not by rule:

  • DEFAULT_REVIEW_CONFIDENCE is deleted. Its doc claims it is "shared by the parser and the combiners so the fallback is identical everywhere" — nothing references it, and the constant declared immediately below it (gate: move every objectively-checkable criterion from LLM judgment to deterministic checks #8833) replaced the fallback it describes. Stale, and the comment actively misleads a reader.
  • impactMapQueryCache is allowlisted, with the reason. check-schema-drift.ts parses this file's sqliteTable declarations rather than importing the symbol, and the table's reads are raw SQL — deleting the declaration would blind that check to the table.

The check

Mirrors its sibling's conventions deliberately: pure over injectable seams, wired into test:ci, and an exception must state why rather than being a bare name on a list (STAGED_AHEAD_OF_CONSUMERS is the precedent — "remove the entry once the seam gains its first real consumer").

Types are out of scope on purpose: an unused type costs nothing at runtime and noUnusedLocals already covers the local case. It is textual like its sibling, so a symbol reached only through a namespace import or a dynamic string is a false positive — which is what the allowlist is for.

Validation

  • npx vitest run --changed=origin/main: 25332 passed. (One ui-kit pack test fails on an unbuilt workspace and passes after npm run build --workspace @loopover/ui-kit — its own failure message says so; unrelated.)
  • 6 unit tests for the check itself: flagging, internalUses reporting, references from any root, the allowlist, types ignored, and that a substring is not mistaken for a reference.
  • tsc clean across all 52 changed files.

@loopover-orb

loopover-orb Bot commented Jul 29, 2026

Copy link
Copy Markdown
Contributor

Important

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

⏳ LoopOver is waiting…

LoopOver has seen this pull request and is waiting on CI checks to finish before reviewing it. This comment will update once the review runs.

🟩 Safe / merged · 🟦 Advisory · 🟨 Held for review · 🟥 Blocked / closed · 🟨 Waiting

@superagent-security

Copy link
Copy Markdown
Contributor

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

@cloudflare-workers-and-pages

cloudflare-workers-and-pages Bot commented Jul 29, 2026

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 51a4852 Commit Preview URL

Branch Preview URL
Jul 29 2026, 03:08 PM

@codecov

codecov Bot commented Jul 29, 2026

Copy link
Copy Markdown

Bundle Report

Bundle size has no change ✅

@codecov

codecov Bot commented Jul 29, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 91.65%. Comparing base (592dc59) to head (51a4852).
⚠️ Report is 4 commits behind head on main.
✅ All tests successful. No failed tests found.

Additional details and impacted files
@@            Coverage Diff             @@
##             main    #9858      +/-   ##
==========================================
- Coverage   91.65%   91.65%   -0.01%     
==========================================
  Files         916      916              
  Lines      112790   112789       -1     
  Branches    27097    27097              
==========================================
- Hits       103375   103374       -1     
  Misses       8126     8126              
  Partials     1289     1289              
Flag Coverage Δ
backend 95.68% <100.00%> (-0.01%) ⬇️

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

Files with missing lines Coverage Δ
src/api/proof-badge.ts 100.00% <100.00%> (ø)
src/auth/security.ts 99.09% <100.00%> (ø)
src/db/repositories.ts 96.86% <100.00%> (ø)
src/github/backfill.ts 96.00% <100.00%> (ø)
src/github/commands.ts 98.28% <ø> (ø)
src/github/webhook.ts 100.00% <ø> (ø)
src/notifications/ams-events.ts 100.00% <100.00%> (ø)
src/notifications/service.ts 100.00% <ø> (ø)
src/notifications/stranded-delivery-sweep.ts 100.00% <100.00%> (ø)
src/openapi/schemas.ts 100.00% <100.00%> (ø)
... and 39 more

@loopover-orb loopover-orb Bot added the manual-review Gittensor contributor context label Jul 29, 2026
Base automatically changed from feat/priority-label-author-eligibility to main July 29, 2026 15:03
`check-dead-source-files.ts` catches a dead FILE and its own header names what it does not catch:
"no detection of a file that's imported but whose EXPORTS are all unused". That gap was populated --
84 `src/**` symbols were exported and referenced nowhere outside the file declaring them, not by
another module, not by a script, not even by their own test.

Each was one of three things and nothing told them apart: a missing wire-up (#9492's class one level
down), a safety net with nothing behind it (#9851 exactly -- two route-spec tables exported "for the
meta-test", test never written), or dead surface that still has to be read and maintained. Coverage
cannot catch any of them, because the declaring file's own tests exercise the symbol directly and
report green while it contributes nothing to the running system.

The fix is almost never deletion. 82 of the 84 are used INSIDE their file, so only the `export`
keyword was untrue -- dropping it makes the surface honest, and tsc proves the safety of every one
(if any had really been reachable from elsewhere, the build would say so; it is clean).

The two exceptions, each decided by reading rather than by rule:

- `DEFAULT_REVIEW_CONFIDENCE` is deleted. Its doc claims it is "shared by the parser and the combiners
  so the fallback is identical everywhere" -- nothing references it, and the constant declared directly
  below it (#8833) replaced the fallback it describes. Stale, and its comment actively misleads.
- `impactMapQueryCache` is allowlisted with the reason: check-schema-drift.ts PARSES this file's
  sqliteTable declarations rather than importing the symbol, and the table's reads are raw SQL, so
  deleting the declaration would blind that check to the table.

The check is wired into test:ci and mirrors its sibling's conventions exactly: pure over injectable
seams, and an exception must state WHY rather than being a bare name on a list.
@JSONbored
JSONbored force-pushed the ci/dead-export-check-9852 branch from f8b3ef1 to 51a4852 Compare July 29, 2026 15:05
@JSONbored
JSONbored merged commit d392a0f into main Jul 29, 2026
4 of 5 checks passed
@JSONbored
JSONbored deleted the ci/dead-export-check-9852 branch July 29, 2026 15:06
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

manual-review Gittensor contributor context

Projects

None yet

Development

Successfully merging this pull request may close these issues.

ci: nothing detects a dead EXPORT — 87 src/ symbols have no consumer outside their own file

1 participant