fix(build): build @loopover/contract in both deploy paths so a clean checkout can deploy - #9732
Conversation
|
Tip ✅ LoopOver review result - approve/merge recommendedReview updated: 2026-07-29 05:58:06 UTC
Review summary Nits — 3 non-blocking
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. 🟩 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 | Preview URL | Updated (UTC) |
|---|---|---|---|---|
| ✅ Deployment successful! View logs |
loopover-ui | 5a4e62f | Commit Preview URL Branch Preview URL |
Jul 29 2026, 05:38 AM |
Bundle ReportBundle size has no change ✅ |
…checkout can deploy Cloudflare Workers Builds is the deploy path for BOTH workers — no GitHub Actions workflow runs `wrangler deploy` (ui-deploy.yml only validates) — and both have failed on every recent commit. Production has consequently been serving stale code: #9574's `fleetAccuracy.basis` and #9594's anchor-payload auth exemption both landed on main and neither is live. One root cause, two scripts: nothing builds `@loopover/contract` before something needs its `dist/`. `@loopover/engine` does not depend on it, so building engine alone leaves it unemitted. loopover-ui — `npm run ui:build` runs `turbo run build --filter=@loopover/engine`, then `ui:openapi`, whose `scripts/write-ui-openapi.ts` reaches `src/openapi/schemas.ts` and imports `@loopover/contract/dist/public-api.js`: Error [ERR_MODULE_NOT_FOUND]: Cannot find module '/opt/buildhome/repo/node_modules/@loopover/contract/dist/public-api.js' loopover-api — `npm run deploy:api` builds only `@loopover/engine`, then `wrangler deploy` bundles `src/index.ts`, which reaches `@loopover/contract` from src/mcp/*, src/openapi/schemas.ts and src/orb/broker-client.ts: ✘ [ERROR] Build failed with 8 errors: ✘ [ERROR] Could not resolve "@loopover/contract" Both pass in `test:ci` only by accident of ordering: `npm run typecheck` runs first, and the `//#typecheck` turbo task already carries an explicit `@loopover/contract#build` edge — added for exactly this failure mode, and documented in turbo.json as "the root package.json dependency does NOT create a build edge for a root task". Neither deploy command runs a typecheck ahead of itself, so the incidental ordering never applies. Adding the same edge to each deploy path's own turbo invocation, which is the level that actually owns the dependency. `deploy:api` also moves from a bare `npm --workspace ... run build` to turbo so both paths express it identically. Verified against a genuinely clean tree (package dists and .tsbuildinfo files removed, TURBO_FORCE=1 to defeat the shared worktree cache — the first two reproduction attempts were masked by a stale tsbuildinfo and then by a turbo cache replay). ui:build: exit 1 -> exit 0. wrangler deploy --dry-run: 8 unresolved "@loopover/contract" imports -> 0, exit 0.
bd3c0d9 to
5a4e62f
Compare
|
Updated: this now fixes both workers, not just the UI. The Same fix, same reasoning — Reproduced and verified locally against a clean tree (dists +
The 8 matches the Cloudflare log's "Build failed with 8 errors" exactly. |
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## main #9732 +/- ##
=======================================
Coverage 90.24% 90.24%
=======================================
Files 900 900
Lines 112914 112914
Branches 26776 26776
=======================================
Hits 101896 101896
Misses 9687 9687
Partials 1331 1331
Flags with carried forward coverage won't be shown. Click here to find out more. |
Summary
Workers Builds: loopover-uihas failed on every one of the last 25+ commits onmain, and it is the deploy path — no GitHub Actions workflow runswrangler deploy(ui-deploy.ymlonly validates). Production has been serving stale code as a result:#9574'sfleetAccuracy.basisand#9594's anchor-payload auth exemption both landed onmainon 2026-07-28, and neither is live (/v1/public/statshas nobasiskey;/anchor-payloadstill 401s).The Cloudflare build command is
npm run build:cloudflare→npm ci && npm run ui:build.ui:buildrunsturbo run build --filter=@loopover/engine, thenui:openapi, whosescripts/write-ui-openapi.tsreachessrc/openapi/schemas.tsand imports@loopover/contract/dist/public-api.js. Nothing in that chain builds@loopover/contract—@loopover/enginedoes not depend on it — so on a clean checkout:It passes in
test:cionly by accident of ordering:npm run typecheckruns earlier, and the//#typecheckturbo task already carries an explicit@loopover/contract#buildedge — added for exactly this failure mode, and documented inturbo.jsonas "the root package.json dependency does NOT create a build edge for a root (//#) task". Cloudflare runsui:buildon its own, so that ordering never applies.This adds the same edge to
ui:build's own turbo invocation, which is the level that actually owns the dependency. One line.Closes #9731
Validation
Verified against a genuinely clean tree — package
dist/directories and.tsbuildinfofiles removed,TURBO_FORCE=1to defeat the shared worktree cache:ui:buildexit@loopover/contract/dist/public-api.js@loopover/engine/dist/parse-pull-request-target-key.jsorigin/mainERR_MODULE_NOT_FOUND)Worth recording, because it masked the reproduction twice:
packages/loopover-engine's build does not clear its own.tsbuildinfothe way@loopover/contract's does, so deletingdist/alone leavestsca silent no-op; and turbo's shared worktree cache replays a staledistunless forced. Neither applies to a fresh Cloudflare clone, but both produce a convincing false result locally. Flagged on #9731 rather than fixed here.git diff --checknpm run ui:buildfrom a clean tree (the actual regression)npm run ui:openapi:check— no OpenAPI driftnpm run test:coverage/test:workers/build:mcp/test:mcp-pack— not run; this changes one npm script and nosrc/**line, so there is nothing forcodecov/patchto measure. Left to CI.Scope
type(scope): short summaryConventional Commit format, for examplefix(api): restore profile access checks.CONTRIBUTING.mdand does not reintroduce GitHub Pages, VitePress,site/, orCNAME.Closes #123) — a linked open issue is required for every contributor PR.Safety
UI Evidencesection below with JPG/JPEG or PNG screenshots arranged as organized, captioned, clickable thumbnails. SVG screenshots are not used as review evidence. Review-only screenshots or recordings are not committed to the repository.No runtime code changes — one npm script gains a build dependency it already had implicitly. No rendered output changes, hence no UI Evidence table. No secrets involved; this touches no credential path.
Notes
Merge this one first. The other four open PRs (#9675, #9718, #9720, #9721) all carry the same red
Workers Buildscheck for this reason, and none of them will reach production until deploys work again.Workers Builds: loopover-apialso fails on these commits; whether it shares this root cause is unconfirmed — its log has not been read.