Skip to content

fix(build): build @loopover/contract in both deploy paths so a clean checkout can deploy - #9732

Merged
loopover-orb[bot] merged 1 commit into
mainfrom
fix/ui-build-contract-dependency
Jul 29, 2026
Merged

fix(build): build @loopover/contract in both deploy paths so a clean checkout can deploy#9732
loopover-orb[bot] merged 1 commit into
mainfrom
fix/ui-build-contract-dependency

Conversation

@JSONbored

Copy link
Copy Markdown
Owner

Summary

Workers Builds: loopover-ui has failed on every one of the last 25+ commits on main, and it is the deploy path — no GitHub Actions workflow runs wrangler deploy (ui-deploy.yml only validates). Production has been serving stale code as a result: #9574's fleetAccuracy.basis and #9594's anchor-payload auth exemption both landed on main on 2026-07-28, and neither is live (/v1/public/stats has no basis key; /anchor-payload still 401s).

The Cloudflare build command is npm run build:cloudflarenpm ci && npm run ui:build. 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. Nothing in that chain builds @loopover/contract@loopover/engine does not depend on it — so on a clean checkout:

Error [ERR_MODULE_NOT_FOUND]: Cannot find module
  '/opt/buildhome/repo/node_modules/@loopover/contract/dist/public-api.js'
  imported from /opt/buildhome/repo/src/openapi/schemas.ts

It passes in test:ci only by accident of ordering: npm run typecheck runs earlier, 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". Cloudflare runs ui:build on 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 .tsbuildinfo files removed, TURBO_FORCE=1 to defeat the shared worktree cache:

ui:build exit @loopover/contract/dist/public-api.js @loopover/engine/dist/parse-pull-request-target-key.js
origin/main 1 (ERR_MODULE_NOT_FOUND) absent absent
this branch 0 emitted emitted

Worth recording, because it masked the reproduction twice: packages/loopover-engine's build does not clear its own .tsbuildinfo the way @loopover/contract's does, so deleting dist/ alone leaves tsc a silent no-op; and turbo's shared worktree cache replays a stale dist unless 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 --check
  • npm run ui:build from a clean tree (the actual regression)
  • npm run ui:openapi:check — no OpenAPI drift
  • npm run test:coverage / test:workers / build:mcp / test:mcp-pack — not run; this changes one npm script and no src/** line, so there is nothing for codecov/patch to measure. Left to CI.

Scope

  • The PR title follows type(scope): short summary Conventional Commit format, for example fix(api): restore profile access checks.
  • This PR is focused and does not mix unrelated backend, UI, MCP, docs, dependency, and deploy changes.
  • This follows CONTRIBUTING.md and does not reintroduce GitHub Pages, VitePress, site/, or CNAME.
  • I linked a currently open issue this PR resolves (e.g. Closes #123) — a linked open issue is required for every contributor PR.

Safety

  • No secrets, wallet details, hotkeys, coldkeys, user PATs, private keys, raw trust scores, private rankings, or private maintainer evidence are exposed.
  • Public GitHub text stays sanitized, low-noise, and does not imply compensation guarantees or optimization tactics.
  • Auth, cookie, CORS, GitHub App, Cloudflare, or session changes include negative-path tests.
  • API/OpenAPI/MCP behavior is updated and tested where needed.
  • UI changes use live API data or real empty/error/loading states, not production mock/demo fallbacks.
  • Visible UI changes include a UI Evidence section 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.
  • Public docs/changelogs are updated where needed; changelogs are only edited for release-prep PRs.

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 Builds check for this reason, and none of them will reach production until deploys work again. Workers Builds: loopover-api also fails on these commits; whether it shares this root cause is unconfirmed — its log has not been read.

@loopover-orb

loopover-orb Bot commented Jul 29, 2026

Copy link
Copy Markdown
Contributor

Tip

✅ LoopOver review result - approve/merge recommended

Review updated: 2026-07-29 05:58:06 UTC

1 file · 1 AI reviewer · no blockers · readiness 83/100 · CI green · clean

✅ Suggested Action - Approve/Merge

  • safe to merge

Review summary
This is a one-line-per-script fix adding an explicit `--filter=@​loopover/contract` to the turbo build invocations in `ui:build` and `deploy:api`, so that a clean checkout builds `@​loopover/contract`'s `dist/public-api.js` before `scripts/write-ui-openapi.ts` imports it. The change is narrow, targeted, and matches the described root cause (the root `//#typecheck` task already had this edge per turbo.json but `ui:build`'s own turbo invocation did not), closing issue #9731. The diff is small, low-risk, and directly addresses the deploy-path breakage described.

Nits — 3 non-blocking
  • Confirm that `turbo run build --filter=@​loopover/engine --filter=@​loopover/contract` builds both packages (turbo filters are typically additive/OR'd) rather than intersecting to nothing — worth a sanity check in CI logs since this is the crux of the fix.
  • package.json: consider extracting the shared `--filter=@​loopover/engine --filter=@​loopover/contract` turbo invocation into a single script (e.g. `build:core`) reused by both `deploy:api` and `ui:build` to avoid future drift between the two paths.
  • PR author also opened the linked issue — Link an issue that was opened by a different contributor, or provide a rationale for why this self-authored issue represents genuine discovery work.

Decision drivers

  • ✅ Code review — No blockers (1 reviewer)
  • ✅ Gate result — Passing (No configured blocker found.)
Context & advisory signals — never blocks the verdict
Signal Result Evidence
Linked issue ✅ Linked #9731
Related work ✅ No active overlap found No same-issue or scoped active PR overlap found.
Change scope ❌ 8/20 High review scope from cached public metadata (1 linked issue).
Validation posture ✅ 25/25 PR body includes validation/test evidence.
Contributor workload ✅ 10/10 Author activity: 14 registered-repo PR(s), 13 merged, 359 issue(s).
Contributor context ✅ Confirmed Gittensor contributor JSONbored; Gittensor profile; 14 PR(s), 359 issue(s).
Improvement ℹ️ Insufficient signal risk: clean · value: insufficient-signal · LLM: moderate
Linked issue satisfaction

Addressed
The diff adds the explicit --filter=@​loopover/contract edge to ui:build's turbo invocation, exactly matching the fix the issue prescribes for the deploy-path build failure, and also proactively applies the same fix to deploy:api for the related API deploy path.

Review context
  • Author: JSONbored
  • Role context: owner (maintainer lane)
  • Public audience mode: oss maintainer
  • Lane context: Repository is registered but has no active allocation in the current snapshot.
  • Public profile languages: Python, TypeScript, Ruby, Go, MDX, Shell, Solidity, JavaScript
  • Official Gittensor activity: 14 PR(s), 359 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 4 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 <question> answers contribution-quality Q&A with source citations and freshness.
  • @loopover chat <question> 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.

🟩 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

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 5a4e62f Commit Preview URL

Branch Preview URL
Jul 29 2026, 05:38 AM

@JSONbored JSONbored self-assigned this Jul 29, 2026
@codecov

codecov Bot commented Jul 29, 2026

Copy link
Copy Markdown

Bundle Report

Bundle 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.
@JSONbored
JSONbored force-pushed the fix/ui-build-contract-dependency branch from bd3c0d9 to 5a4e62f Compare July 29, 2026 05:35
@JSONbored JSONbored changed the title fix(build): build @loopover/contract in ui:build so a clean checkout can deploy fix(build): build @loopover/contract in both deploy paths so a clean checkout can deploy Jul 29, 2026
@JSONbored

Copy link
Copy Markdown
Owner Author

Updated: this now fixes both workers, not just the UI.

The loopover-api build log shows the same root cause in a second script. 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"
    The module "./dist/index.js" was not found on the file system

Same fix, same reasoning — deploy:api now expresses the contract build edge through turbo exactly as ui:build does.

Reproduced and verified locally against a clean tree (dists + .tsbuildinfo removed, TURBO_FORCE=1):

ui:build wrangler deploy --dry-run
engine only (today's main) exit 1, ERR_MODULE_NOT_FOUND exit 1, 8 unresolved @loopover/contract imports
engine + contract (this PR) exit 0 exit 0, 0 unresolved

The 8 matches the Cloudflare log's "Build failed with 8 errors" exactly. Workers Builds: loopover-ui already went green on the previous push of this branch; the API worker's build should follow on this one.

@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 90.24%. Comparing base (94fecf1) to head (5a4e62f).
⚠️ Report is 5 commits behind head on main.
✅ All tests successful. No failed tests found.

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           
Flag Coverage Δ
backend 95.52% <ø> (ø)

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

@loopover-orb loopover-orb Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LoopOver approves — the gate is satisfied and CI is green.

@loopover-orb
loopover-orb Bot merged commit 08e311d into main Jul 29, 2026
9 checks passed
@loopover-orb
loopover-orb Bot deleted the fix/ui-build-contract-dependency branch July 29, 2026 05:58
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Production is serving stale code: ui:build cannot complete on a clean checkout, so Workers Builds (the deploy path) fails

1 participant