Skip to content

ci: run the contract api-schemas drift check in CI, not only in the local gate - #10268

Closed
JSONbored wants to merge 2 commits into
mainfrom
claude/wire-contract-api-schemas-ci
Closed

ci: run the contract api-schemas drift check in CI, not only in the local gate#10268
JSONbored wants to merge 2 commits into
mainfrom
claude/wire-contract-api-schemas-ci

Conversation

@JSONbored

@JSONbored JSONbored commented Jul 31, 2026

Copy link
Copy Markdown
Owner

What

contract:api-schemas:check was reachable only from the local npm run test:ci aggregate — nothing in
CI ran it
. This wires it into ci.yml alongside the other generated-artifact drift checks.

Closes #10237

Two of the issue's four deliverables are already resolved on main

Verified before writing anything, since the issue's central claim is now stale:

What remains live is the issue's contributing factor 1, which is the reason both drifts went unnoticed
in the first place — and that is what this PR fixes.

The gating

The generator has three inputs, and only two were covered by existing filters:

input filter
src/openapi/schemas.ts backend
apps/loopover-ui/public/openapi.json ui
the contract package's own modules (scanned to emit imports) nothing watched packages/loopover-contract/**

So a contract-only PR would have skipped the very check it most needs. This adds a contract filter shaped
exactly like its engine / mcp / miner siblings.

The "must produce a file that compiles" deliverable

Satisfied structurally rather than with a new test, and the pairing is worth stating explicitly:

  • contract:api-schemas:check proves committed == generated;
  • typecheck:packages runs tsc -p packages/loopover-contract/tsconfig.json, whose include is src, so
    it compiles the generated file.

Together they prove the generated file compiles. Both now run in CI; previously the first held only if
someone happened to run the local gate.

Verification

  • npm run contract:api-schemas:check — passes on this base.
  • npm run contract:api-schemas — empty diff, confirming the generator is no longer destructive.
  • npm run actionlint — clean.

Noted separately, not fixed here

While measuring this I found contract:api-schemas:check is not the exception — 22 of the 42 drift and
wiring checks reachable from test:ci run in no workflow at all
(measured against main, this one
included), including checkers-wired:check,
dead-exports:check, typecheck-coverage:check and test-wiring:check. Fixing that wholesale is a
maintainer call about CI runtime and per-check gating, not something to smuggle into this PR, so it is
filed on its own.

…ocal gate

`contract:api-schemas:check` was reachable only from the `npm run test:ci`
aggregate, so nothing in CI ever ran it. That is the same local-only gap the
selfhost and miner env-reference steps already document on themselves, and it
has now let this artifact drift twice with zero CI signal: once when the
discovery-route schemas were added without teaching the generator, which left
`main` red for every PR that ran the full local gate, and again when #10160
added `linkedIssueMaintainerExempt` without regenerating.

The step is gated on the generator's three real inputs. Two were already
covered -- src/openapi/schemas.ts by `backend`, apps/loopover-ui/public/
openapi.json by `ui` -- but the generator also scans the contract package's own
modules to emit its imports, and no filter here watched
packages/loopover-contract/** at all, so a contract-only PR would have skipped
the check it most needs. Hence the new `contract` filter, shaped like its
`engine` / `mcp` / `miner` siblings.

This also completes the issue's "regenerating must produce a file that
compiles" guard without a new test, and the pairing is worth stating: the drift
check proves committed == generated, and `typecheck:packages` compiles
packages/loopover-contract/src/**, which includes the generated file. Together
they now prove in CI what previously only held if someone ran the local gate.

The other two deliverables are already resolved on main: #10225 taught the
generator to emit the discovery-route schemas, so regenerating is now a no-op
rather than destructive, and the `linkedIssueMaintainerExempt` regeneration
landed with it.

Closes #10237
@superagent-security

superagent-security Bot commented Jul 31, 2026

Copy link
Copy Markdown
Contributor

Superagent Supply Chain Scan

Superagent flagged 1 dependency introduced by this pull request.

High risk: actions/cache/save@55cc8345863c7cc4c66a329aec7e433d2d1c52a9

  • Change: added 55cc8345863c7cc4c66a329aec7e433d2d1c52a9
  • Dependency path: .github/workflows/ci.yml → jobs → validate-code → steps → 67 → actions/cache/save
  • Correlated risks: 3
  • Why flagged: Detects keylogging and input capture patterns. Location: cache-55cc8345863c7cc4c66a329aec7e433d2d1c52a9/dist/restore-only/index.js. Rules: threat-runtime-keylogging
  • Risk score: 4.9

View Superagent Supply Chain Scan

@loopover-orb

loopover-orb Bot commented Jul 31, 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.

@JSONbored

Copy link
Copy Markdown
Owner Author

Note on the red Superagent Supply Chain Scan — it is a pre-existing false positive, not something this
diff introduced.

It reports actions/cache/save@55cc8345863c7cc4c66a329aec7e433d2d1c52a9 as an added dependency with three
HIGH threat-runtime-keylogging hits in dist/restore-only/index.js. That pin is already on main at the
identical SHA (.github/workflows/ci.yml lines 600, 663, 728), and this PR's diff references
actions/cache zero times — it adds one run: step and one path filter. The scanner appears to
re-evaluate every action referenced by a changed workflow file and report them as new.

Precedent that it does not block: #10217 (ci(ui-kit): wire ui-kit's vitest suite into ui:test/CI) merged
with Superagent Supply Chain Scan = FAILURE and Security Scan = SUCCESS, the same pair as here.

Flagging rather than acting on it: silencing a supply-chain finding is not something to do from inside an
unrelated PR, and the heuristic matching actions/cache's bundled webpack dist is worth its own look if it
is going to fail every PR that edits a workflow.

@codecov

codecov Bot commented Jul 31, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 92.28%. Comparing base (12f3c6a) to head (1db8968).
✅ All tests successful. No failed tests found.

Additional details and impacted files
@@           Coverage Diff           @@
##             main   #10268   +/-   ##
=======================================
  Coverage   92.28%   92.28%           
=======================================
  Files         939      939           
  Lines      114775   114775           
  Branches    27715    27715           
=======================================
  Hits       105920   105920           
  Misses       7553     7553           
  Partials     1302     1302           
Flag Coverage Δ
backend 95.70% <ø> (ø)
control-plane 100.00% <ø> (ø)
rees 89.62% <ø> (ø)

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

@cloudflare-workers-and-pages

cloudflare-workers-and-pages Bot commented Jul 31, 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 Updated (UTC)
❌ Deployment failed
View logs
loopover-ui 1db8968 Jul 31 2026, 11:23 PM

@JSONbored
JSONbored force-pushed the claude/wire-contract-api-schemas-ci branch from d465fe6 to 1db8968 Compare July 31, 2026 23:22
@JSONbored

Copy link
Copy Markdown
Owner Author

Superseded by #10280, which contains this change verbatim (the Contract api-schemas drift check step, its conditional, and the contract path filter) plus the meta-checker that guards the whole wired-check list against drifting again. Closing rather than carrying both: this PR's only red check is a Superagent scanner false-positive on the unchanged official actions/cache v6.1.0 pin (rule threat-runtime-keylogging, fired for any PR touching ci.yml since 2026-07-31 ~15:28 UTC) that has no repo-side fix, while #10280's rescan already comes back neutral.

@JSONbored JSONbored closed this Jul 31, 2026
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.

contract: api-schemas.ts is half-generated — regenerating it deletes live discovery-route schemas, and the check is not wired into CI

1 participant