Skip to content

ci(guards): make every scripts/check-*.ts prove it actually runs - #9945

Merged
JSONbored merged 1 commit into
mainfrom
chore/wire-checkers-guard-9860
Jul 30, 2026
Merged

ci(guards): make every scripts/check-*.ts prove it actually runs#9945
JSONbored merged 1 commit into
mainfrom
chore/wire-checkers-guard-9860

Conversation

@JSONbored

Copy link
Copy Markdown
Owner

Refs #9860 (item 3). One item, per that issue's own "not one big PR".

What writing this found

test:ci called npm run publishable-deps:checkand no such npm script existed.

Two consequences, both live on main today:

  1. npm run test:ci, the documented one-command local gate and CLAUDE.md's own non-negotiable feat(scoring): add situational score projections #3, dies with Missing script. Anyone following the contributor skill hits it.
  2. scripts/check-publishable-deps.ts has never run, despite being correct and passing when invoked directly.

That is precisely #9860's thesis — a hand-maintained ~50-command chain that nobody re-derives — so the missing script is defined here and the class is now guarded.

The guard

A checker wired into nothing guards nothing while looking exactly like a guard. That is worse than not writing it, because its presence in the tree reads as coverage.

Per #9860's bar (compute the fact, don't remember it), check-checkers-wired.ts holds no list of wired checkers. It resolves where each one actually runs, from the three places a checker can legitimately live:

home how it's detected
local gate transitively reachable from test:ci (through aggregate scripts, and through npm lifecycle hooks)
scheduled referenced by a workflow — by npm script name, or by the file path directly
shared module imported by a sibling script, so not an entry point at all

Anything in none of the three fails, with the specific fix in the message. It also verifies test:ci references no npm script that does not exist — the exact hole that hid the missing one above.

ALLOWED_UNWIRED has two entries, each with a reason: check-changelog.ts (needs a release-please branch the local gate never produces) and check-roadmap-issue-drift.ts (reads live GitHub issues, so it needs a token and network). Everything else is detected, never listed.

Two false positives fixed while building it

Both would have reported correctly-wired checkers as dead, and a checker that cries wolf gets muted:

  • npm lifecycle hookscheck-node-version.ts is wired as pretest/preui:test. Nothing ever says npm run pretest; npm runs it around test.
  • --workspace invocationsnpm run build --workspace @loopover/engine resolves against the workspace, so reading it as a root reference both misses the target and reports a phantom missing root build.

Starting point was 11 apparently-unwired checkers; after resolving real homes, 5 were genuinely suspect and exactly 1 (check-publishable-deps.ts) was truly dead.

Validation

  • 15 new tests. The resolution functions are pure, so every home kind and both false-positive classes are covered directly, plus a cycle-termination case.
  • Three of them run the resolution over the real tree, so this suite fails the same way CI does rather than only exercising fixtures — including one anti-vacuity assertion (the repo really does have >20 checkers and a known one really does resolve).
  • checkers-wired:check, publishable-deps:check, import-specifiers:check, dead-source-files:check, turbo-inputs:check, coverage-boltons:check, docs:drift-check, typecheck all pass.

dead-exports:check fails on this branch for a pre-existing reason on main, not from this change — two unreferenced exports my merged #9938 introduced. Fixed separately in #9944, which should land first.

Refs #9860 (item 3).

Found by writing the checker: `test:ci` called `npm run publishable-deps:check`
and no such npm script existed. So the documented one-command local gate --
CLAUDE.md's own non-negotiable -- died with "Missing script", and
check-publishable-deps.ts had never run despite being correct and passing. Both
are fixed here: the script is defined, and the guard below catches the class.

A checker that is wired into nothing guards nothing while looking exactly like a
guard, which is worse than not writing it, because its presence in the tree reads
as coverage.

Per #9860's bar, this computes the fact rather than remembering it. It does not
hold a list of wired checkers; it resolves where each one runs, from the three
places a checker can legitimately live: transitively reachable from test:ci,
referenced by a workflow, or imported by a sibling script as a shared module.
Anything in none of the three fails with the specific fix. Two entries are
allowlisted with reasons -- both need a token and a network the local gate does
not assume.

It also verifies test:ci references no npm script that does not exist, which is
the specific hole that hid the missing one above.

Two false positives were fixed while building it, both of which would have
reported correctly-wired checkers as dead: npm lifecycle hooks (a checker wired
as `pretest` is never named by any `npm run`), and `--workspace` invocations
(which resolve against the workspace, not the root).
@loopover-orb

loopover-orb Bot commented Jul 30, 2026

Copy link
Copy Markdown
Contributor

Warning

⏸️ LoopOver review result - manual review recommended

Review updated: 2026-07-30 19:40:04 UTC

3 files · 1 AI reviewer · 2 blockers · CI green · unknown

⏸️ Suggested Action - Manual Review

Review summary
Adds check-checkers-wired.ts, a self-computing guard that verifies every scripts/check-*.ts is actually reachable from test:ci, a workflow, or a sibling import, plus a real fix (adding the previously-undefined publishable-deps:check script that test:ci was calling). The implementation avoids the hand-maintained-list anti-pattern it's meant to prevent by resolving wiring dynamically, and is well-covered by unit tests plus a live check against the real repo tree. The console.error/console statements flagged by the external brief are expected CLI-diagnostic output for a script tool, not debug leftovers, and the magic numbers (9860, 50) are issue references/rough-count comments, not logic constants — neither is a real defect.

Nits — 5 non-blocking
  • scripts/check-checkers-wired.ts: the regex-based NPM_RUN_REFERENCE matching for `npm run <name>` won't catch scripts invoked via other package managers (yarn/pnpm) or via `npm run-script`, though this repo consistently uses npm so it's low risk.
  • scripts/check-checkers-wired.ts:132 resolveCheckerHome nests to depth 5; consider extracting the workflow-ref resolution into a small named helper for readability.
  • The `imported` detection in resolveCheckerHome matches on substring inclusion of `./{base}"` etc., which could produce false positives if a script's file path text appears in an unrelated string/comment rather than an actual import statement.
  • ALLOWED_UNWIRED reasons are good, but consider also asserting (in the real-repository test suite) that every ALLOWED_UNWIRED key still exists as a file in scripts/, so a renamed/removed checker doesn't leave a stale allowlist entry unnoticed.
  • Consider parsing workflow YAML more structurely (e.g. via a YAML parser) instead of substring search on raw workflowText, to reduce false positives/negatives in workflow-ref detection.

Concerns raised — review before merging

  • No linked issue detected: No closing reference or linked issue number was found in the PR metadata/body. — If this PR is intended to solve an issue, link it explicitly in the PR body.
  • Maintainer requires a linked issue: This repo's maintainer focus manifest requires every PR to reference a tracked issue. — Link the relevant issue (for example Closes #123) before opening the PR.
📋 Copy for AI agents — paste into your coding agent
Fix the following blocker(s) from this PR review:

1. No linked issue detected: No closing reference or linked issue number was found in the PR metadata/body. — If this PR is intended to solve an issue, link it explicitly in the PR body.

2. Maintainer requires a linked issue: This repo's maintainer focus manifest requires every PR to reference a tracked issue. — Link the relevant issue (for example `Closes #123`) before opening the PR.

Decision drivers

  • ❌ Code review — 2 blockers (1 reviewer)
  • ❌ Gate result — Blocking (Repo-configured hard blocker found.)
Context & advisory signals — never blocks the verdict
Signal Result Evidence
Linked issue ⚠️ Missing No linked issue or no-issue rationale found.
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 (no linked issue context).
Validation posture ✅ 25/25 PR body includes validation/test evidence.
Contributor workload ✅ 10/10 Author activity: 9 registered-repo PR(s), 8 merged, 280 issue(s).
Contributor context ✅ Confirmed Gittensor contributor JSONbored; Gittensor profile; 9 PR(s), 280 issue(s).
Improvement ✅ Minor risk: clean · value: minor
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: 9 PR(s), 280 issue(s).
  • PR-specific overlap: none found.
Contributor next steps
  • Start here: Treat this as maintainer-lane context rather than normal contributor-lane activity.
  • Then work through the remaining 2 steps in the Signals table above.
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.

Decision record
  • action: hold · clause: missing_linked_issue
  • config: a80e52782f0bf2b75d47c9fd6c045da4eaf6d3c597888d337dd524075695d1e7 · pack: oss-anti-slop · ci: passed
  • record: 3e8b1dcf5cf26b3faaf614e1b579e0aab8fd6e2fab9ad2bcd1f8535f095a9537 (schema v6, head c39228f)

🟩 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 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 c39228f Commit Preview URL

Branch Preview URL
Jul 30 2026, 07:16 PM

@codecov

codecov Bot commented Jul 30, 2026

Copy link
Copy Markdown

Bundle Report

Bundle size has no change ✅

@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 91.87%. Comparing base (bae7b2f) to head (c39228f).
⚠️ Report is 3 commits behind head on main.
✅ All tests successful. No failed tests found.

Additional details and impacted files
@@           Coverage Diff           @@
##             main    #9945   +/-   ##
=======================================
  Coverage   91.87%   91.87%           
=======================================
  Files         928      928           
  Lines      113657   113657           
  Branches    27406    27406           
=======================================
  Hits       104427   104427           
  Misses       7931     7931           
  Partials     1299     1299           
Flag Coverage Δ
backend 95.67% <ø> (ø)

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

@loopover-orb loopover-orb Bot added the manual-review Gittensor contributor context label Jul 30, 2026
@JSONbored
JSONbored merged commit 48928a0 into main Jul 30, 2026
11 checks passed
@JSONbored
JSONbored deleted the chore/wire-checkers-guard-9860 branch July 30, 2026 19:39
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.

1 participant