ci: run every local-gate drift check in CI, and guard the two lists against drifting again - #10280
ci: run every local-gate drift check in CI, and guard the two lists against drifting again#10280JSONbored wants to merge 1 commit into
Conversation
|
Caution 🛑 LoopOver review result - fixes requiredReview updated: 2026-07-31 23:48:39 UTC
Review summary Nits — 7 non-blocking
CI checks failing
Decision drivers
Context & advisory signals — never blocks the verdict
Linked issue satisfactionAddressed Review context
Contributor next steps
Signal definitions
🧪 Chat with LoopOverAsk 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.
Full command reference: https://loopover.ai/docs/loopover-commands 🧪 Experimental — new and may change. Decision record
🟩 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.
|
|
Superagent didn't find any vulnerabilities or security issues in this PR. |
Deploying with
|
| Status | Name | Latest Commit | Updated (UTC) |
|---|---|---|---|
| ❌ Deployment failed View logs |
loopover-ui | 82e1971 | Aug 01 2026, 01:10 AM |
16b3d44 to
ac51e71
Compare
|
Rebased onto #10266 added That is the 23rd instance of this class, introduced during the work to fix the class, by me, and caught Also refreshed: the rebase pulled in Full suite re-verified after the rebase: 26,745 passed / 0 failed. |
ac51e71 to
993f327
Compare
|
CI caught a real ordering bug in this PR, which is worth recording because it is the same class the PR is
That check resolves a bare Reproduced properly by deleting Fix: Pinned by a test that asserts all three properties (not in the unconditional block, condition identical to While fixing that I also found the placement test's slice ran past the step boundary into the rest of the Re-verified: 26,746 passed / 0 failed, typecheck and actionlint clean, guard reports all 46 local-gate Separately: |
993f327 to
25bdcae
Compare
Bundle ReportBundle size has no change ✅ |
25bdcae to
d7788f1
Compare
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## main #10280 +/- ##
=======================================
Coverage 92.31% 92.31%
=======================================
Files 939 939
Lines 114816 114816
Branches 27729 27729
=======================================
Hits 105989 105989
Misses 7527 7527
Partials 1300 1300
Flags with carried forward coverage won't be shown. Click here to find out more. |
d7788f1 to
32a638d
Compare
Superagent Supply Chain ScanSuperagent flagged 1 dependency introduced by this pull request. High risk:
|
32a638d to
a603424
Compare
…gainst drifting again `npm run test:ci` (the documented local gate) and ci.yml (what actually blocks a merge) are two independently hand-maintained lists, and they had drifted: 22 of the 42 drift checks reachable from test:ci ran in no workflow at all. On a repo whose gate auto-merges on green CI, such a check is a convention rather than a gate, and worse, its presence reads as coverage. Three of the missing ones make that concrete: checkers-wired:check is the #9860 meta-guard that detects unwired checkers and was itself unwired; db:migrations:immutable:check guards the invariant whose violation breaks boot for every upgraded Orb; test-wiring and typecheck-coverage exist to stop coverage silently narrowing. Wired as ONE ungated block rather than 19 individually gated steps. Per-check path gating is where the fidelity bugs actually live -- the sibling PR had to add an entire `contract` filter because nothing here watched packages/loopover-contract/** -- and 19 hand-chosen gates would be exactly the hand-maintained list #9860 rejects. These are sub-second file-reading scripts, so running them unconditionally costs less than choosing 19 gates correctly. Three checks are deliberately NOT in that block. They need git history that validate-code's checkout does not have, and measuring them there showed they degrade in two different and equally bad ways: db:migrations:immutable:check exits 1 with "no orb-v* tags visible", so it would fail every PR, while release-commit-parsing:check returns [] and passes, and releasable-commit-types:check prints "cannot resolve; skipping" and exits 0. The last two would have been permanently green while verifying nothing -- the very failure this change exists to remove, reproduced at the CI layer and then read as coverage. They run in a new drift-checks-history job with fetch-depth: 0 and tags, which asserts up front that the history is actually present rather than trusting it. The aggregator gains a dependency on that job, since a job nothing depends on cannot fail a PR. check-ci-drift-checks-wired.ts is the guard that stops this reopening. It is the sibling of check-checkers-wired.ts on the other axis: that one asks whether a checker runs anywhere (test:ci counts), this one asks whether CI runs it, which is the question that decides whether a merge is gated. Both sides are computed, never listed, so the roster cannot drift the way ci.yml drifted from test:ci in the first place. Includes the contract api-schemas wiring from the sibling branch, because this guard cannot pass without it. Closes #10269
17005bf to
82e1971
Compare
What
npm run test:ci(the documented local gate) andci.yml(what actually blocks a merge) are twoindependently hand-maintained lists, and they had drifted: 22 of the 42 drift checks reachable from
test:ciran in no workflow at all. This wires all of them and adds the guard that stops it reopening.Closes #10269
Closes #10237
Implements B + D from the issue's options, with one correction found by measuring (below).
Why it matters, concretely
checkers-wired:checkis the Generate or guard the remaining hand-maintained lists — three shipped red-main incidents traced to one class #9860 meta-guard that fails when ascripts/check-*.tsruns nowhere.It was itself not run by CI. The mechanism for detecting unwired checkers was unwired.
db:migrations:immutable:checkguards the rule whose violation breaks boot for every upgraded Orb.test-wiring:check/typecheck-coverage:checkexist to stop coverage and typecheck silentlynarrowing — invisible precisely because they did not run.
One ungated block, not 19 gated steps
Per-check path gating is where the fidelity bugs actually live: the sibling PR #10268 had to add an entire
contractpath filter because nothing inci.ymlwatchedpackages/loopover-contract/**. Nineteenhand-chosen gates would be exactly the hand-maintained list #9860 exists to reject. These are all
sub-second file-reading scripts, so running them unconditionally costs far less than choosing 19 gates
correctly.
The correction to my own recommendation
I recommended "one ungated job, no gating to get wrong". Measuring showed that is wrong for three checks,
which need git history
validate-code's checkout does not have (it is shallow on purpose). They degradein two different, equally bad ways:
db:migrations:immutable:check"no orb-v* tags visible"→ fails every PRrelease-commit-parsing:check[]and passesreleasable-commit-types:check"cannot resolve …; skipping", exits 0The last two are the important ones: wired naively they would be permanently green while verifying
nothing — the exact "guards nothing while looking like a guard" failure this PR exists to remove,
reproduced at the CI layer and then read as coverage. That would have been worse than leaving them unwired.
So they run in a new
drift-checks-historyjob withfetch-depth: 0+fetch-tags, which asserts thehistory is actually present before running them rather than trusting it. The
validateaggregator gains adependency on that job, since a job nothing depends on cannot fail a PR.
The guard (D)
scripts/check-ci-drift-checks-wired.tsischeck-checkers-wired.ts's sibling on the other axis. That oneasks "does this checker run anywhere?" — satisfied by the local gate alone. This one asks the question
that decides merge safety: "does CI run it?" Both sides are computed, never listed, so the roster
cannot drift the way
ci.ymldrifted fromtest:ci.ALLOWED_LOCAL_ONLYexists and is deliberatelyempty.
It found a scoping bug in itself during review: the repo names audits
-audit, not:audit, so my firstpattern matched neither
ui:version-auditnortest:miner-deployment-docs-audit— silently excluding themwhile appearing to cover them. Fixed and pinned by a test.
Relationship to #10268
This branch includes #10268's commit, because the new guard cannot pass without it —
contract:api-schemas:checkwas one of the 22. The hunks are in different regions ofci.ymland areidentical, so whichever lands first, the other merges cleanly.
If #10268 merges first, its hunk is already here and this PR is unaffected. If this one merges
first, #10268's diff becomes empty and the gate will auto-close it as an empty PR — which would leave
#10237 open even though its work had shipped. That is why
Closes #10237is listed above as its own line(a combined "Closes #A and #B" only closes the first). Either order now closes both issues correctly.
Verification
npm run ci-drift-checks-wired:check→ all 45 local-gate drift check(s) also run in a workflow.actionlint,typecheck(root + packages + ui),checkers-wired:checkclean.ci-skip-draft-prs.test.tsenumerates the aggregator'sneeds, so adding the job without aggregating it failed. Updated, and the new job is also asserted tohonour the draft gate.
unconditional block, removing the aggregator dependency, and removing the word-boundary guard from the
checker's matcher each fail a test; the restored tree passes.
codecov/patchdoes not grade this diff (scripts/**is codecov-ignored; workflows are not source).Tests written to the same standard regardless: 22 across the two files.