fix(queue): isolate per-repo failures in the scheduled regate sweep fan-out - #3827
Conversation
…an-out (#3807) fanOutAgentRegateSweepJobs had two unguarded per-repo failure paths that could abort the entire tick for every managed repo: an uncaught throw in the per-repo settings/draining-check loop, and a single rejected env.JOBS.send() rejecting the whole Promise.all over every repo's dispatch (which also skipped the trailing audit event, so the failure never even showed up in the logs). Isolate both: a failing repo's settings/draining check is logged and skipped (picked up again next tick) instead of aborting the loop, and each dispatch send is caught individually so one repo's send failure can't block another repo's dispatch or the fan-out's own audit event.
|
Superagent didn't find any vulnerabilities or security issues in this PR. |
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## main #3827 +/- ##
=======================================
Coverage 93.41% 93.41%
=======================================
Files 325 325
Lines 32844 32850 +6
Branches 12030 12030
=======================================
+ Hits 30680 30686 +6
Misses 1530 1530
Partials 634 634
🚀 New features to boost your workflow:
|
|
Tip 🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩 ✅ Gittensory review result - approve/merge recommendedReview updated: 2026-07-06 13:28:26 UTC
✅ Suggested Action - Approve/Merge
Review summary Nits — 6 non-blocking
Review context
Contributor next steps
Signal definitions
🟩 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 Gittensory, a quiet PR intelligence layer for OSS maintainers.
|
Summary
fanOutAgentRegateSweepJobshad two unguarded failure paths that could silently abort the ENTIRE scheduled sweep tick for EVERY managed repo, not just the one that failed:resolveRepositorySettings,getLatestRegatedAt) had no try/catch — a transient D1 read error for a single repo threw out of theforloop before any repo reached the dispatch stage.env.JOBS.send(...)in a singlePromise.all— one repo's send rejecting (a transient queue-send error) rejected the wholePromise.all, which both aborted the sends still in flight for OTHER repos and skipped the trailingrecordAuditEventcall that records this fan-out's own outcome, making the failure invisible in the audit log.sweep_fanout_repo_check_failed) and skipped, and the loop continues to the next repo (that repo is picked up again on the next cron tick, since it never got a convergence marker)..catch(...): a failing repo's dispatch is logged (sweep_fanout_dispatch_failed) and swallowed, so thePromise.allnever rejects on a per-repo send failure — every other repo's dispatch still completes, and the fan-out's own audit event is always recorded.skippedErroredcount alongside the existingskippedDrainingcount in the fan-out's audit-event metadata, so a repeated settings-check failure for one repo is now directly observable instead of silent.Closes #3807. This was the leading hypothesis from today's incident audit for why the scheduled sweep stalled for hours across every managed repo simultaneously.
Scope
type(scope): short summaryConventional Commit format, for examplefix(api): restore profile access checks.CONTRIBUTING.mdand does not reintroduce GitHub Pages, VitePress,site/, orCNAME.Validation
git diff --checknpm run actionlintnpm run typechecknpm run test:coveragelocally;codecov/patchrequires ≥99% coverage of the lines AND branches you changed (aim for 100% on your diff so CI variance does not fail near the threshold). Global coverage is a non-blocking trend with a loose 90% backstop, not the gate.npm run test:workersnpm run build:mcpnpm run test:mcp-packnpm run ui:openapi:checknpm run ui:lintnpm run ui:typechecknpm run ui:buildnpm audit --audit-level=moderateSafety
UI Evidencesection below. (N/A — no visible UI change.)