Skip to content

feat(orb): wire Sentry into the Cloudflare Worker (central ORB broker) - #6036

Merged
JSONbored merged 2 commits into
mainfrom
feat/worker-sentry-integration
Jul 15, 2026
Merged

feat(orb): wire Sentry into the Cloudflare Worker (central ORB broker)#6036
JSONbored merged 2 commits into
mainfrom
feat/worker-sentry-integration

Conversation

@JSONbored

Copy link
Copy Markdown
Owner

Summary

  • The actual central ORB broker server — the Cloudflare Worker at src/index.ts/src/api/routes.ts, handling every registration, token mint, and relay push/pull request — has had zero Sentry error tracking since it was built. initSentry() has only ever been called from src/server.ts (the self-host Node entrypoint); the Worker has no .onError( handler anywhere and no Workers-compatible Sentry SDK dependency. Every ORB fix shipped earlier this session was client-side (self-host); this is the corresponding server-side gap — and by request volume, the larger one.
  • @sentry/hono + @sentry/cloudflare (peer dep) auto-capture via Hono's onError by default, confirmed via the package's own README. nodejs_compat (needed for AsyncLocalStorage) was already enabled.
  • The real complication: self-host's server.ts imports THIS Worker's own exported {fetch, queue} object directly (import worker from "./index") and calls worker.fetch(request, env, ctx) for its own HTTP traffic — server.ts synthesizes a Worker-shaped env by spreading process.env specifically so it can reuse this handler byte-for-byte. Naming the new DSN var the same as self-host's own SENTRY_DSN would have silently activated the Cloudflare-only SDK inside a self-hoster's own Node process the moment they set their own Sentry DSN.
  • Fixed two ways: a distinctly-named WORKER_SENTRY_DSN/WORKER_SENTRY_ENVIRONMENT (no name collision to begin with), and gating the middleware's registration on isCloudflareWorkerRuntime() — checking navigator.userAgent === "Cloudflare-Workers", Cloudflare's own documented idiom — verified true in a real workerd isolate via test/workers/ and false under plain Node.
  • Registered as the first middleware in createApp() so it wraps every other middleware and route.

Scope

HTTP request handling only (every ORB endpoint). The queue() handler's own top-level safety net is a separate, smaller follow-up — it dispatches ALL background job types, not just ORB's, and @sentry/hono's onError integration doesn't cover it.

Test plan

  • test/unit/cloudflare-worker-runtime-detection.test.tsisCloudflareWorkerRuntime() is false under plain Node (self-host's real runtime).
  • test/workers/worker-runtime.test.ts (real workerd isolate via @cloudflare/vitest-pool-workers) — isCloudflareWorkerRuntime() is true; existing routes still serve correctly with the middleware wrapping them; a request still succeeds when WORKER_SENTRY_DSN is unset (registering the middleware must not itself break requests).
  • npm run test:coverage (unsharded) — full local gate green, no regressions.
  • npm run test:ci — green, re-verified after a rebase across 10 intervening commits.

@superagent-security

Copy link
Copy Markdown
Contributor

Superagent didn't find any vulnerabilities or security issues in this PR.

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

codecov Bot commented Jul 15, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 95.17%. Comparing base (d3bf13b) to head (9597167).
⚠️ Report is 25 commits behind head on main.
✅ All tests successful. No failed tests found.

Additional details and impacted files
@@           Coverage Diff           @@
##             main    #6036   +/-   ##
=======================================
  Coverage   95.16%   95.17%           
=======================================
  Files         593      592    -1     
  Lines       46955    46960    +5     
  Branches    15006    15007    +1     
=======================================
+ Hits        44685    44693    +8     
+ Misses       1512     1511    -1     
+ Partials      758      756    -2     
Flag Coverage Δ
shard-1 44.01% <100.00%> (+0.07%) ⬆️
shard-2 36.42% <100.00%> (-0.12%) ⬇️
shard-3 32.21% <100.00%> (+0.13%) ⬆️
shard-4 32.98% <100.00%> (-0.05%) ⬇️
shard-5 31.47% <100.00%> (+0.11%) ⬆️
shard-6 44.58% <100.00%> (-0.01%) ⬇️

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

Files with missing lines Coverage Δ
src/api/routes.ts 94.40% <100.00%> (+<0.01%) ⬆️

... and 5 files with indirect coverage changes

@codecov

codecov Bot commented Jul 15, 2026

Copy link
Copy Markdown

Bundle Report

Changes will decrease total bundle size by 267 bytes (-0.01%) ⬇️. This is within the configured threshold ✅

Detailed changes
Bundle name Size Change
loopover-ui 3.04MB -267 bytes (-0.01%) ⬇️

Affected Assets, Files, and Routes:

view changes for bundle: loopover-ui

Assets Changed:

Asset Name Size Change Total Size Change (%)
assets/tanstack-vendor-6XeVwX1N.js (New) 718.6kB 718.6kB 100.0% 🚀
openapi.json -188 bytes 487.89kB -0.04%
assets/maintainer-panel-BHVSXtkt.js (New) 75.5kB 75.5kB 100.0% 🚀
assets/ui-vendor-BARCU0sR.js (New) 65.83kB 65.83kB 100.0% 🚀
assets/owner-panel-oS3f_Oiv.js (New) 58.65kB 58.65kB 100.0% 🚀
assets/docs.self-hosting-configuration-DFxf4kcg.js (New) 48.42kB 48.42kB 100.0% 🚀
assets/app.analytics-CBfziuVx.js (New) 36.26kB 36.26kB 100.0% 🚀
assets/docs.self-hosting-release-checklist-CQg25LuC.js (New) 34.54kB 34.54kB 100.0% 🚀
assets/docs.tuning-BP-TPRco.js (New) 34.42kB 34.42kB 100.0% 🚀
assets/routes-Dzy5Y9K2.js (New) 34.04kB 34.04kB 100.0% 🚀
assets/app.runs-CDq7l85V.js (New) 27.11kB 27.11kB 100.0% 🚀
assets/app-BqGVrZiM.js (New) 25.83kB 25.83kB 100.0% 🚀
assets/app.operator-Bps0z0HE.js (New) 24.59kB 24.59kB 100.0% 🚀
assets/docs.self-hosting-security-ddq2pA0s.js (New) 21.3kB 21.3kB 100.0% 🚀
assets/docs.github-app-RwidpXDu.js (New) 19.49kB 19.49kB 100.0% 🚀
assets/miner-panel-C7gNwqoz.js (New) 19.23kB 19.23kB 100.0% 🚀
assets/docs.self-hosting-troubleshooting-C2V7cDG9.js (New) 18.47kB 18.47kB 100.0% 🚀
assets/api._op-D0KfhkO5.js (New) 17.89kB 17.89kB 100.0% 🚀
assets/docs.self-hosting-github-app-BkSiM80K.js (New) 17.32kB 17.32kB 100.0% 🚀
assets/docs.how-reviews-work-CPxb_JSr.js (New) 17.03kB 17.03kB 100.0% 🚀
assets/app.index-BHsJdTUk.js (New) 16.19kB 16.19kB 100.0% 🚀
assets/docs.maintainer-self-hosting-DuXCbaMq.js (New) 15.99kB 15.99kB 100.0% 🚀
assets/playground-panel-7arbW3zK.js (New) 14.43kB 14.43kB 100.0% 🚀
assets/docs.self-hosting-quickstart-DH2crgim.js (New) 14.15kB 14.15kB 100.0% 🚀
assets/docs.self-hosting-docs-audit-oENBSkpv.js (New) 12.14kB 12.14kB 100.0% 🚀
assets/docs.maintainer-install-trust-Y7OoKpE8.js (New) 10.51kB 10.51kB 100.0% 🚀
assets/docs.self-hosting-backup-scaling-Ch-F-0-I.js (New) 10.06kB 10.06kB 100.0% 🚀
assets/docs.beta-onboarding-B_k5ftac.js (New) 9.95kB 9.95kB 100.0% 🚀
assets/app.audit-CdeDbEXo.js (New) 9.35kB 9.35kB 100.0% 🚀
assets/extension-CDRYcl4f.js (New) 9.21kB 9.21kB 100.0% 🚀
assets/docs.self-hosting-rees-DhbgPnAn.js (New) 8.95kB 8.95kB 100.0% 🚀
assets/docs.self-hosting-ai-providers-NbB67tpz.js (New) 8.92kB 8.92kB 100.0% 🚀
assets/app.config-generator-D9ulVoRg.js (New) 8.13kB 8.13kB 100.0% 🚀
assets/maintainers-C0zLpgEr.js (New) 8.06kB 8.06kB 100.0% 🚀
assets/miners-TRJHVET6.js (New) 7.88kB 7.88kB 100.0% 🚀
assets/agents-CYVFicHf.js (New) 7.76kB 7.76kB 100.0% 🚀
assets/docs.privacy-security-DPNZ9ZY-.js (New) 7.21kB 7.21kB 100.0% 🚀
assets/docs.owner-checklist-kSFPakxm.js (New) 7.0kB 7.0kB 100.0% 🚀
assets/commands-panel-DY7eCgaT.js (New) 6.65kB 6.65kB 100.0% 🚀
assets/docs.self-hosting-releases-BBQKHeyd.js (New) 6.62kB 6.62kB 100.0% 🚀
assets/roadmap-DLdirpqS.js (New) 6.33kB 6.33kB 100.0% 🚀
assets/docs.self-hosting-rees-analyzers-Db12wPmw.js (New) 6.05kB 6.05kB 100.0% 🚀
assets/digest-panel-BV8j_XPi.js (New) 6.04kB 6.04kB 100.0% 🚀
assets/docs.loopover-commands-ZIw27ccX.js (New) 5.18kB 5.18kB 100.0% 🚀
assets/docs.scoreability-mV9gzD6d.js (New) 5.05kB 5.05kB 100.0% 🚀
assets/docs.troubleshooting-D7iMmOQl.js (New) 4.91kB 4.91kB 100.0% 🚀
assets/repos._owner._repo.quality-BYTM9QOq.js (New) 4.87kB 4.87kB 100.0% 🚀
assets/api.index-DL6w_BDT.js (New) 4.78kB 4.78kB 100.0% 🚀
assets/docs.index-BS7w19x-.js (New) 4.68kB 4.68kB 100.0% 🚀
assets/changelog-C5iQcUPy.js (New) 4.67kB 4.67kB 100.0% 🚀
assets/docs.maintainer-workflow-Ddesuoqk.js (New) 4.36kB 4.36kB 100.0% 🚀
assets/docs.self-hosting-rag-2dAwfzq-.js (New) 4.35kB 4.35kB 100.0% 🚀
assets/control-primitives-bYSkL7dA.js (New) 3.75kB 3.75kB 100.0% 🚀
assets/docs.ai-summaries-BWmrPCWk.js (New) 3.04kB 3.04kB 100.0% 🚀
assets/docs.branch-analysis-CsBK2jQH.js (New) 2.91kB 2.91kB 100.0% 🚀
assets/docs.mcp-clients-CKOlKXx6.js (New) 2.9kB 2.9kB 100.0% 🚀
assets/api-BTHmm6y9.js (New) 2.73kB 2.73kB 100.0% 🚀
assets/docs-DPY-qRd2.js (New) 2.67kB 2.67kB 100.0% 🚀
assets/docs.quickstart-BNpJsCqB.js (New) 2.1kB 2.1kB 100.0% 🚀
assets/alert-dialog-DHuilbc6.js (New) 2.07kB 2.07kB 100.0% 🚀
assets/docs.upstream-drift-CCTxaQ8x.js (New) 2.04kB 2.04kB 100.0% 🚀
assets/button-D3C6VlfD.js (New) 1.74kB 1.74kB 100.0% 🚀
assets/app.workbench-Be2991LA.js (New) 1.63kB 1.63kB 100.0% 🚀
assets/tooltip-Bnn6l0p3.js (New) 1.45kB 1.45kB 100.0% 🚀
assets/session-B5TAeaQy.js (New) 1.44kB 1.44kB 100.0% 🚀
assets/tabs-M1WUjDwT.js (New) 1.39kB 1.39kB 100.0% 🚀
assets/trend-chart-CqeASnnE.js (New) 1.22kB 1.22kB 100.0% 🚀
assets/app.repos-CYi_MVGM.js (New) 1.07kB 1.07kB 100.0% 🚀
assets/switch-BQ-Vjcnv.js (New) 982 bytes 982 bytes 100.0% 🚀
assets/analytics-card-shell-CWb3DrHj.js (New) 972 bytes 972 bytes 100.0% 🚀
assets/use-api-resource-Cz-W4okR.js (New) 934 bytes 934 bytes 100.0% 🚀
assets/input-Cm_hdzAg.js (New) 796 bytes 796 bytes 100.0% 🚀
assets/refresh-meta-j8YED58D.js (New) 796 bytes 796 bytes 100.0% 🚀
assets/file-cog-CreL162t.js (New) 758 bytes 758 bytes 100.0% 🚀
assets/app.maintainer-aEsrizm9.js (New) 501 bytes 501 bytes 100.0% 🚀
assets/sparkles-CrNapn_o.js (New) 494 bytes 494 bytes 100.0% 🚀
assets/app.owner-B-Sy3Amd.js (New) 473 bytes 473 bytes 100.0% 🚀
assets/app.commands-1nzjbRC5.js (New) 454 bytes 454 bytes 100.0% 🚀
assets/reveal-DRv5Z-br.js (New) 442 bytes 442 bytes 100.0% 🚀
assets/app.playground-CKSHzv7x.js (New) 441 bytes 441 bytes 100.0% 🚀
assets/index-BiiIVt-D.js (New) 438 bytes 438 bytes 100.0% 🚀
assets/eye-off-B5VO0IAe.js (New) 430 bytes 430 bytes 100.0% 🚀
assets/app.digest-BpBp0tod.js (New) 429 bytes 429 bytes 100.0% 🚀
assets/app.miner-CCpiDUrQ.js (New) 421 bytes 421 bytes 100.0% 🚀
assets/key-round-Bz_O4fmb.js (New) 355 bytes 355 bytes 100.0% 🚀
assets/bot-2qPZRg1m.js (New) 328 bytes 328 bytes 100.0% 🚀
assets/trash-2-DeQu90U8.js (New) 328 bytes 328 bytes 100.0% 🚀
assets/save-BO7liV8w.js (New) 327 bytes 327 bytes 100.0% 🚀
assets/git-pull-request-arrow-D0TJV5-2.js (New) 321 bytes 321 bytes 100.0% 🚀
assets/shield-check-CpqOPxJ2.js (New) 320 bytes 320 bytes 100.0% 🚀
assets/wrench-Co-5Ybz-.js (New) 303 bytes 303 bytes 100.0% 🚀
assets/bell-CHEY2rgL.js (New) 290 bytes 290 bytes 100.0% 🚀
assets/list-checks-DUzaFiRf.js (New) 279 bytes 279 bytes 100.0% 🚀
assets/shield-un3NWyjG.js (New) 272 bytes 272 bytes 100.0% 🚀
assets/workflow-KvygnHpS.js (New) 265 bytes 265 bytes 100.0% 🚀
assets/chart-column-BCwm3Ws5.js (New) 251 bytes 251 bytes 100.0% 🚀
assets/compass-BbaM2OCm.js (New) 251 bytes 251 bytes 100.0% 🚀
assets/skeleton-Dfs7lT55.js (New) 241 bytes 241 bytes 100.0% 🚀
assets/history-DWxLGN0v.js (New) 237 bytes 237 bytes 100.0% 🚀
assets/activity-Cnfgm8l9.js (New) 234 bytes 234 bytes 100.0% 🚀
assets/message-square-DjdK1hGC.js (New) 233 bytes 233 bytes 100.0% 🚀
assets/download-CY2SwAQO.js (New) 232 bytes 232 bytes 100.0% 🚀
assets/chevron-right-DYWIE2bz.js (New) 207 bytes 207 bytes 100.0% 🚀
assets/lock-CyB5UDhb.js (New) 206 bytes 206 bytes 100.0% 🚀
assets/rotate-cw-d27QKyLR.js (New) 201 bytes 201 bytes 100.0% 🚀
assets/play-JNLUBleS.js (New) 190 bytes 190 bytes 100.0% 🚀
assets/circle-check-DY154wHw.js (New) 178 bytes 178 bytes 100.0% 🚀
assets/search-DaBkBBIK.js (New) 174 bytes 174 bytes 100.0% 🚀
assets/circle-D6W9z0uE.js (New) 130 bytes 130 bytes 100.0% 🚀
assets/tanstack-vendor-2ShA11fZ.js (Deleted) -718.68kB 0 bytes -100.0% 🗑️
assets/maintainer-panel-DkiZlqqS.js (Deleted) -75.5kB 0 bytes -100.0% 🗑️
assets/ui-vendor-CE2rzz7f.js (Deleted) -65.83kB 0 bytes -100.0% 🗑️
assets/owner-panel-BYH36WMN.js (Deleted) -58.65kB 0 bytes -100.0% 🗑️
assets/docs.self-hosting-configuration-B_CVFjE7.js (Deleted) -48.42kB 0 bytes -100.0% 🗑️
assets/app.analytics-C2JK5KSL.js (Deleted) -36.26kB 0 bytes -100.0% 🗑️
assets/docs.self-hosting-release-checklist-CQDHGY9U.js (Deleted) -34.54kB 0 bytes -100.0% 🗑️
assets/docs.tuning-DMHrRMUl.js (Deleted) -34.42kB 0 bytes -100.0% 🗑️
assets/routes-jN48-GeQ.js (Deleted) -34.04kB 0 bytes -100.0% 🗑️
assets/app.runs-BjH6BQ-U.js (Deleted) -27.11kB 0 bytes -100.0% 🗑️
assets/app-C-2V-Ryj.js (Deleted) -25.83kB 0 bytes -100.0% 🗑️
assets/app.operator-DKGJgS5u.js (Deleted) -24.59kB 0 bytes -100.0% 🗑️
assets/docs.self-hosting-security-CGH3k1Ec.js (Deleted) -21.3kB 0 bytes -100.0% 🗑️
assets/docs.github-app-ryrG7ffY.js (Deleted) -19.49kB 0 bytes -100.0% 🗑️
assets/miner-panel-DDhUEcBq.js (Deleted) -19.23kB 0 bytes -100.0% 🗑️
assets/docs.self-hosting-troubleshooting-gx0i1hbS.js (Deleted) -18.47kB 0 bytes -100.0% 🗑️
assets/api._op-Cl1yWVV2.js (Deleted) -17.89kB 0 bytes -100.0% 🗑️
assets/docs.self-hosting-github-app-AW8Tpf1B.js (Deleted) -17.32kB 0 bytes -100.0% 🗑️
assets/docs.how-reviews-work-CcsNp0vC.js (Deleted) -17.03kB 0 bytes -100.0% 🗑️
assets/app.index-DFamDdhw.js (Deleted) -16.19kB 0 bytes -100.0% 🗑️
assets/docs.maintainer-self-hosting-CL90-8L_.js (Deleted) -15.99kB 0 bytes -100.0% 🗑️
assets/playground-panel-BUuPrK36.js (Deleted) -14.43kB 0 bytes -100.0% 🗑️
assets/docs.self-hosting-quickstart-DFA8JNw1.js (Deleted) -14.15kB 0 bytes -100.0% 🗑️
assets/docs.self-hosting-docs-audit-CkRPySKc.js (Deleted) -12.14kB 0 bytes -100.0% 🗑️
assets/docs.maintainer-install-trust-7SLYSFRj.js (Deleted) -10.51kB 0 bytes -100.0% 🗑️
assets/docs.self-hosting-backup-scaling-DeCBFVWI.js (Deleted) -10.06kB 0 bytes -100.0% 🗑️
assets/docs.beta-onboarding-DZqISd1v.js (Deleted) -9.95kB 0 bytes -100.0% 🗑️
assets/app.audit-g4S0oE02.js (Deleted) -9.35kB 0 bytes -100.0% 🗑️
assets/extension-BHY5yWvL.js (Deleted) -9.21kB 0 bytes -100.0% 🗑️
assets/docs.self-hosting-rees-Cl5v_pgs.js (Deleted) -8.95kB 0 bytes -100.0% 🗑️
assets/docs.self-hosting-ai-providers-BeqM2zgF.js (Deleted) -8.92kB 0 bytes -100.0% 🗑️
assets/app.config-generator-21fgSf4o.js (Deleted) -8.13kB 0 bytes -100.0% 🗑️
assets/maintainers-BvoqvFcj.js (Deleted) -8.06kB 0 bytes -100.0% 🗑️
assets/miners-Cs27Jakx.js (Deleted) -7.88kB 0 bytes -100.0% 🗑️
assets/agents-DtiXbfpi.js (Deleted) -7.76kB 0 bytes -100.0% 🗑️
assets/docs.privacy-security-CKvpwtl7.js (Deleted) -7.21kB 0 bytes -100.0% 🗑️
assets/docs.owner-checklist-CB1T0T6T.js (Deleted) -7.0kB 0 bytes -100.0% 🗑️
assets/commands-panel-C9mBHGx0.js (Deleted) -6.65kB 0 bytes -100.0% 🗑️
assets/docs.self-hosting-releases-H9PHRPyX.js (Deleted) -6.62kB 0 bytes -100.0% 🗑️
assets/roadmap-Db8vu4iN.js (Deleted) -6.33kB 0 bytes -100.0% 🗑️
assets/docs.self-hosting-rees-analyzers-DSaaTUR2.js (Deleted) -6.05kB 0 bytes -100.0% 🗑️
assets/digest-panel-ELQWCuKV.js (Deleted) -6.04kB 0 bytes -100.0% 🗑️
assets/docs.loopover-commands-ra4qZym8.js (Deleted) -5.18kB 0 bytes -100.0% 🗑️
assets/docs.scoreability-DMexuLOU.js (Deleted) -5.05kB 0 bytes -100.0% 🗑️
assets/docs.troubleshooting-BRUZL6Kw.js (Deleted) -4.91kB 0 bytes -100.0% 🗑️
assets/repos._owner._repo.quality-BJvxvgkD.js (Deleted) -4.87kB 0 bytes -100.0% 🗑️
assets/api.index-qjtInJnw.js (Deleted) -4.78kB 0 bytes -100.0% 🗑️
assets/docs.index-BLJACJMy.js (Deleted) -4.68kB 0 bytes -100.0% 🗑️
assets/changelog-DeS1Ti8x.js (Deleted) -4.67kB 0 bytes -100.0% 🗑️
assets/docs.maintainer-workflow-Dys6b5nO.js (Deleted) -4.36kB 0 bytes -100.0% 🗑️
assets/docs.self-hosting-rag-BfxEaxge.js (Deleted) -4.35kB 0 bytes -100.0% 🗑️
assets/control-primitives-BynrLU0B.js (Deleted) -3.75kB 0 bytes -100.0% 🗑️
assets/docs.ai-summaries-DT5CaCep.js (Deleted) -3.04kB 0 bytes -100.0% 🗑️
assets/docs.branch-analysis-BGV97oCi.js (Deleted) -2.91kB 0 bytes -100.0% 🗑️
assets/docs.mcp-clients-BrK67NcM.js (Deleted) -2.9kB 0 bytes -100.0% 🗑️
assets/api-BetKNRLZ.js (Deleted) -2.73kB 0 bytes -100.0% 🗑️
assets/docs-DOEud9RZ.js (Deleted) -2.67kB 0 bytes -100.0% 🗑️
assets/docs.quickstart-DmN4g4xg.js (Deleted) -2.1kB 0 bytes -100.0% 🗑️
assets/alert-dialog-CtEbNsd2.js (Deleted) -2.07kB 0 bytes -100.0% 🗑️
assets/docs.upstream-drift-DBKkiM7E.js (Deleted) -2.04kB 0 bytes -100.0% 🗑️
assets/button-lYtH04B0.js (Deleted) -1.74kB 0 bytes -100.0% 🗑️
assets/app.workbench-BYGTQaIJ.js (Deleted) -1.63kB 0 bytes -100.0% 🗑️
assets/tooltip-Vv1GSvGw.js (Deleted) -1.45kB 0 bytes -100.0% 🗑️
assets/session-Du1j0KUR.js (Deleted) -1.44kB 0 bytes -100.0% 🗑️
assets/tabs-CT9KI_fe.js (Deleted) -1.39kB 0 bytes -100.0% 🗑️
assets/trend-chart-CTrblxfo.js (Deleted) -1.22kB 0 bytes -100.0% 🗑️
assets/app.repos-DenqWv1C.js (Deleted) -1.07kB 0 bytes -100.0% 🗑️
assets/switch-Cl34Ufnx.js (Deleted) -982 bytes 0 bytes -100.0% 🗑️
assets/analytics-card-shell-BpQE1lUs.js (Deleted) -972 bytes 0 bytes -100.0% 🗑️
assets/use-api-resource-CfrVzC1y.js (Deleted) -934 bytes 0 bytes -100.0% 🗑️
assets/input-CIPRr6Wa.js (Deleted) -796 bytes 0 bytes -100.0% 🗑️
assets/refresh-meta-DW6B622K.js (Deleted) -796 bytes 0 bytes -100.0% 🗑️
assets/file-cog-B87Ih60a.js (Deleted) -758 bytes 0 bytes -100.0% 🗑️
assets/app.maintainer-BLDzMz9h.js (Deleted) -501 bytes 0 bytes -100.0% 🗑️
assets/sparkles-CmpkrtAo.js (Deleted) -494 bytes 0 bytes -100.0% 🗑️
assets/app.owner-DUQdw_Jj.js (Deleted) -473 bytes 0 bytes -100.0% 🗑️
assets/app.commands-Dc3j52bX.js (Deleted) -454 bytes 0 bytes -100.0% 🗑️
assets/reveal-Cf9aOShi.js (Deleted) -442 bytes 0 bytes -100.0% 🗑️
assets/app.playground-BlMB1bpd.js (Deleted) -441 bytes 0 bytes -100.0% 🗑️
assets/index-BI8QASaS.js (Deleted) -438 bytes 0 bytes -100.0% 🗑️
assets/eye-off-DyEOsu-P.js (Deleted) -430 bytes 0 bytes -100.0% 🗑️
assets/app.digest-DX2gPaiz.js (Deleted) -429 bytes 0 bytes -100.0% 🗑️
assets/app.miner-BXFesZu0.js (Deleted) -421 bytes 0 bytes -100.0% 🗑️
assets/key-round-DijjJ3Pv.js (Deleted) -355 bytes 0 bytes -100.0% 🗑️
assets/bot-CT4cbdHr.js (Deleted) -328 bytes 0 bytes -100.0% 🗑️
assets/trash-2-Dyz7ptVg.js (Deleted) -328 bytes 0 bytes -100.0% 🗑️
assets/save-VhVIeBNe.js (Deleted) -327 bytes 0 bytes -100.0% 🗑️
assets/git-pull-request-arrow-CUG1T-hU.js (Deleted) -321 bytes 0 bytes -100.0% 🗑️
assets/shield-check-By12r8tD.js (Deleted) -320 bytes 0 bytes -100.0% 🗑️
assets/wrench-B5O_LvuL.js (Deleted) -303 bytes 0 bytes -100.0% 🗑️
assets/bell-mw_qZjyb.js (Deleted) -290 bytes 0 bytes -100.0% 🗑️
assets/list-checks-aP43GST_.js (Deleted) -279 bytes 0 bytes -100.0% 🗑️
assets/shield-vZ3LqhL7.js (Deleted) -272 bytes 0 bytes -100.0% 🗑️
assets/workflow-Cv-G83sR.js (Deleted) -265 bytes 0 bytes -100.0% 🗑️
assets/chart-column-DCmEKyvS.js (Deleted) -251 bytes 0 bytes -100.0% 🗑️
assets/compass-DvdG7ziX.js (Deleted) -251 bytes 0 bytes -100.0% 🗑️
assets/skeleton-DqBGRQGk.js (Deleted) -241 bytes 0 bytes -100.0% 🗑️
assets/history-D-Sy7vlT.js (Deleted) -237 bytes 0 bytes -100.0% 🗑️
assets/activity-DOhfkhHg.js (Deleted) -234 bytes 0 bytes -100.0% 🗑️
assets/message-square-B8l8gzqs.js (Deleted) -233 bytes 0 bytes -100.0% 🗑️
assets/download-CX3bYneP.js (Deleted) -232 bytes 0 bytes -100.0% 🗑️
assets/chevron-right-C5Tckzz9.js (Deleted) -207 bytes 0 bytes -100.0% 🗑️
assets/lock-BaBWKd0H.js (Deleted) -206 bytes 0 bytes -100.0% 🗑️
assets/rotate-cw-D2QLvZg4.js (Deleted) -201 bytes 0 bytes -100.0% 🗑️
assets/play-DAg_HQwl.js (Deleted) -190 bytes 0 bytes -100.0% 🗑️
assets/circle-check-DZdBsQy6.js (Deleted) -178 bytes 0 bytes -100.0% 🗑️
assets/search-DztityCe.js (Deleted) -174 bytes 0 bytes -100.0% 🗑️
assets/circle-Bdn2SfHA.js (Deleted) -130 bytes 0 bytes -100.0% 🗑️

@loopover-orb loopover-orb Bot added the gittensor:feature Gittensor-scored feature linked to a feature issue — scores a 0.25x multiplier. label Jul 15, 2026
@loopover-orb

loopover-orb Bot commented Jul 15, 2026

Copy link
Copy Markdown
Contributor

Caution

🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥

🛑 LoopOver review result - fixes required

Review updated: 2026-07-15 07:26:59 UTC

6 files · 1 AI reviewer · 2 blockers · readiness 91/100 · CI failing · unstable

🛑 Suggested Action - Manual Review

Review summary
This wires @​sentry/hono's onError-capturing middleware into the Cloudflare Worker's createApp(), gated by a runtime check (isCloudflareWorkerRuntime, based on Cloudflare's documented navigator.userAgent idiom) and a distinctly-named WORKER_SENTRY_DSN so self-host's server.ts (which reuses this same worker.fetch handler with a synthesized env) never accidentally activates the Cloudflare-only SDK. The middleware is registered first/outermost per Sentry's own guidance so it wraps all downstream middleware and routes, and the change is backed by both a Node-runtime unit test and a real workerd-isolate regression test proving the gate flips correctly in each environment. The lockfile diff is churn from installing the two new peer packages (version bumps/dedup), not a manual edit, and looks consistent with the package.json additions.

Nits — 5 non-blocking
  • src/api/routes.ts: the sentry() call passes env.WORKER_SENTRY_DSN directly without checking it's non-empty before calling app.use — confirm @​sentry/hono/cloudflare no-ops gracefully when dsn is an empty string or undefined-at-runtime (env var unset in wrangler), since the isCloudflareWorkerRuntime gate alone doesn't guarantee DSN presence.
  • test/workers/worker-runtime.test.ts: the new 'still serves a normal response when WORKER_SENTRY_DSN is unset' test only checks status 200 — it doesn't assert Sentry actually stayed inert (e.g. no captured event), which is the more interesting invariant per the PR's own framing.
  • src/env.d.ts: WORKER_SENTRY_ENVIRONMENT has no documented default listed in the comment even though routes.ts defaults it to "production" via `??` — worth a one-line note for consistency with the rest of the file's doc style.
  • Consider a small integration test asserting that when WORKER_SENTRY_DSN is set under the real Workers isolate, a thrown handler error actually reaches Sentry's capture path (even via a spy), not just that the app boots.
  • src/api/routes.ts: double-check @​sentry/hono's onError wrapping doesn't swallow or alter the shape of existing custom error responses further down the middleware chain (e.g. CORS/rate-limit error bodies) since it's now the outermost handler.

Why this is blocked

  • No linked issue detected — If this PR is intended to solve an issue, link it explicitly in the PR body.
  • Maintainer requires a linked 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 — If this PR is intended to solve an issue, link it explicitly in the PR body.

2. Maintainer requires a linked issue — Link the relevant issue (for example `Closes #123`) before opening the PR.

CI checks failing

  • codecov/patch — 33.33% of diff hit (target 99.00%)
Signal Result Evidence
Code review ❌ 2 blockers 1 reviewer
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: 43 registered-repo PR(s), 35 merged, 367 issue(s).
Contributor context ✅ Confirmed Gittensor contributor JSONbored; Gittensor profile; 43 PR(s), 367 issue(s).
Gate result ❌ Blocking Repo-configured hard blocker found.
Improvement ✅ Minor risk: clean · value: minor · LLM: moderate
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: not available
  • Official Gittensor activity: 43 PR(s), 367 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://gittensory.aethereal.dev/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

The actual central ORB broker server -- the Cloudflare Worker at src/index.ts
/ src/api/routes.ts, handling every registration, token mint, and relay push/
pull request -- has had zero Sentry error tracking since it was built.
initSentry() has only ever been called from src/server.ts (the self-host Node
entrypoint); the Worker has no `.onError(` handler anywhere and no
Workers-compatible Sentry SDK dependency. Every ORB fix shipped earlier this
session was client-side (self-host); this is the corresponding server-side
gap, and by volume of traffic the larger one.

@sentry/hono + @sentry/cloudflare (peer dep) auto-capture via Hono's onError
by default, confirmed via the package's own README. nodejs_compat (needed for
AsyncLocalStorage) was already enabled.

The real complication: self-host's server.ts imports THIS Worker's own
exported `{fetch, queue}` object directly (`import worker from "./index"`)
and calls `worker.fetch(request, env, ctx)` for its own HTTP traffic --
server.ts synthesizes a Worker-shaped `env` by spreading `process.env`
specifically so it can reuse this handler byte-for-byte. Naming the new DSN
var the same as self-host's own SENTRY_DSN would have silently activated the
Cloudflare-only SDK inside a self-hoster's own Node process the moment they
set their own Sentry DSN. Fixed two ways: a distinctly-named
WORKER_SENTRY_DSN/WORKER_SENTRY_ENVIRONMENT (so there is no name collision to
begin with), AND gating the middleware's registration on
isCloudflareWorkerRuntime() -- checking navigator.userAgent === "Cloudflare-
Workers", Cloudflare's own documented idiom, verified true in a real workerd
isolate via test/workers and false under plain Node.

Registered as the first middleware in createApp() so it wraps every other
middleware and route. Scope: HTTP request handling only (every ORB endpoint).
The queue() handler's own top-level safety net is a separate, smaller
follow-up -- it dispatches ALL background job types, not just ORB's, and
@sentry/hono's onError integration doesn't cover it.
Codecov flagged the isCloudflareWorkerRuntime() TRUE branch as uncovered
patch: it only genuinely executes inside a real Workers isolate, and
test:coverage runs under plain Node (--pool=forks). The real coverage for
this branch is test/workers/worker-runtime.test.ts, which runs under
@cloudflare/vitest-pool-workers as a SEPARATE, non-coverage-instrumented step
in test:ci -- Codecov has no visibility into it.
@loopover-orb loopover-orb Bot added the manual-review Gittensor contributor context label Jul 15, 2026
@JSONbored
JSONbored force-pushed the feat/worker-sentry-integration branch from 85915e2 to 9597167 Compare July 15, 2026 07:28
@JSONbored
JSONbored merged commit 2d78493 into main Jul 15, 2026
5 checks passed
@JSONbored
JSONbored deleted the feat/worker-sentry-integration branch July 15, 2026 07:28
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

gittensor:feature Gittensor-scored feature linked to a feature issue — scores a 0.25x multiplier. manual-review Gittensor contributor context

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant