Skip to content

feat(regate-sweep): add opt-in oldest-first ordering mode to selectRegateCandidates#3867

Merged
loopover-orb[bot] merged 1 commit into
mainfrom
feat/regate-sweep-oldest-first-order
Jul 6, 2026
Merged

feat(regate-sweep): add opt-in oldest-first ordering mode to selectRegateCandidates#3867
loopover-orb[bot] merged 1 commit into
mainfrom
feat/regate-sweep-oldest-first-order

Conversation

@JSONbored

Copy link
Copy Markdown
Owner

Summary

  • Fixes feat(regate-sweep): add opt-in oldest-first ordering mode to selectRegateCandidates #3815. The scheduled re-gate sweep's default staleness-based ordering (lastRegatedAt ascending) is deliberately non-deterministic from an operator's perspective — after a repo's first sweep pass, PR selection order is driven by "which PR was re-gated longest ago," not creation order. During today's backlog recovery this looked effectively random to the operator, who wants deterministic oldest-first draining going forward.
  • Adds an opt-in regateSweepOrderMode per-repo setting ("staleness" default | "oldest-first"), wired end-to-end per this repo's own config-as-code convention: repository_settings DB column + migration (0116_regate_sweep_order_mode.sql), resolver default (getRepositorySettings/upsertRepositorySettings), .gittensory.yml schema entry (both the generic settings: override list and the manifest parser, documented in config/examples/gittensory.full.yml + .gittensory.yml.example), and the OpenAPI schemas + regen.
  • selectRegateCandidates (src/settings/agent-sweep.ts) takes a new orderMode param. "oldest-first" sorts candidates by createdAt ascending, but — since createdAt never changes — it preserves an equivalent, timing-independent convergence guarantee to the staleness sort (full backlog coverage in ceil(open/max) sweeps, even under dry-run/pause) by deferring whichever PR(s) hold the current candidate pool's single most-recent lastRegatedAt value (i.e. whichever PR(s) the immediately preceding sweep dispatched — every candidate in one dispatch shares the exact same stamp, see markPullRequestsRegated). This is a relative comparison within the pool on every call, not a fixed time window, so it holds regardless of how far apart consecutive sweeps actually run. A starvation guard falls back to the full pool when every eligible PR ties on the same lastRegatedAt (a small backlog whose entire open-PR count fits in one sweep).
  • sweepRepoRegate (src/queue/processors.ts) threads the resolved setting through, so the fanned-out per-PR job dispatch (and its delaySeconds stagger) follows the chosen order.

Heads-up for the maintainer: config/examples/gittensory.full.yml is very close to the hard-coded 64KB manifest-size cap (MAX_FOCUS_MANIFEST_BYTES) this same file is parsed against in tests — after this PR's addition it sits at ~65,522 of 65,536 bytes (14 bytes of headroom). This is a pre-existing structural squeeze from organic growth across many PRs, not something this PR fully addresses; any future field added to this reference file will likely need to either trim existing comments elsewhere in the file or raise the cap.

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 an issue, or this is small enough that the summary explains why an issue is not needed.

Validation

  • git diff --check
  • npm run actionlint
  • npm run typecheck
  • npm run test:coverage locally; codecov/patch requires ≥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:workers
  • npm run build:mcp
  • npm run test:mcp-pack
  • npm run ui:openapi:check
  • npm run ui:lint
  • npm run ui:typecheck
  • npm run ui:build
  • npm audit --audit-level=moderate
  • New or changed behavior has unit/integration tests for new branches, fallback paths, and sanitizer boundaries

All run via npm run test:ci (full local gate, green) plus a standalone npm audit --audit-level=moderate (0 vulnerabilities). Also ran npm run db:migrations:check, npm run db:schema-drift:check, and npm run ui:openapi:settings-parity (the new field is fully in sync across the DB, Drizzle schema, and both hand-authored Zod schemas). New test coverage: test/unit/agent-sweep.test.ts (basic oldest-first order, most-recent-dispatch deferral, the starvation guard, repair-priority interaction, and a ceil(open/max)-sweeps convergence regression test spaced 5 minutes apart — well past any fixed window, proving the guarantee is timing-independent) and test/unit/queue.test.ts (an end-to-end regression asserting the fanned-out per-PR delaySeconds sequence is strictly increasing in creation order).

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.
  • Public docs/changelogs are updated where needed; changelogs are only edited for release-prep PRs.

Backend/config-only change: no auth/CORS/session surface, no interactive app UI, default-off behavior (existing repos see zero change until they opt in).

UI Evidence

N/A — no app UI surface changed; the only "docs" touched are the .gittensory.yml reference examples.

…gateCandidates (#3815)

The scheduled re-gate sweep's default staleness-based ordering
(lastRegatedAt ascending) is deliberately non-deterministic from an
operator's perspective: after a repo's first sweep pass, PR selection
order is driven by "which PR was re-gated longest ago," not creation
order, which looked effectively random to an operator watching a
backlog-recovery drain.

Adds an opt-in `regateSweepOrderMode` per-repo setting ("staleness"
default | "oldest-first"), wired end-to-end: DB column + migration,
resolver default, `.gittensory.yml` schema entry (settings: block and
the friendly-alias parser), and OpenAPI regen. selectRegateCandidates
now takes an `orderMode` param; "oldest-first" sorts by createdAt
ascending but preserves an equivalent, timing-independent convergence
guarantee to the staleness sort by deferring whichever PR(s) hold the
current pool's single most-recent lastRegatedAt value (the immediately
preceding sweep's dispatch), with a starvation guard for backlogs small
enough to fully clear in one sweep. sweepRepoRegate threads the
resolved setting through, so the fanned-out per-PR delaySeconds stagger
follows the chosen order.
@superagent-security

Copy link
Copy Markdown
Contributor

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

@cloudflare-workers-and-pages

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
gittensory-ui f9a5c64 Commit Preview URL

Branch Preview URL
Jul 06 2026, 08:36 PM

@codecov

codecov Bot commented Jul 6, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 93.49%. Comparing base (6a0fb60) to head (f9a5c64).
⚠️ Report is 2 commits behind head on main.
✅ All tests successful. No failed tests found.

Additional details and impacted files
@@           Coverage Diff           @@
##             main    #3867   +/-   ##
=======================================
  Coverage   93.49%   93.49%           
=======================================
  Files         333      333           
  Lines       33206    33228   +22     
  Branches    12144    12159   +15     
=======================================
+ Hits        31045    31067   +22     
  Misses       1530     1530           
  Partials      631      631           
Files with missing lines Coverage Δ
src/api/routes.ts 94.93% <ø> (ø)
src/db/repositories.ts 96.59% <100.00%> (+<0.01%) ⬆️
src/db/schema.ts 71.18% <ø> (ø)
src/openapi/schemas.ts 100.00% <ø> (ø)
src/queue/processors.ts 94.51% <ø> (ø)
src/settings/agent-sweep.ts 100.00% <100.00%> (ø)
src/signals/focus-manifest.ts 99.13% <100.00%> (+<0.01%) ⬆️
src/signals/settings-preview.ts 98.54% <ø> (ø)
🚀 New features to boost your workflow:
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

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

loopover-orb Bot commented Jul 6, 2026

Copy link
Copy Markdown

Tip

🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩

✅ Gittensory review result - approve/merge recommended

Review updated: 2026-07-06 20:46:18 UTC

27 files · 1 AI reviewer · no blockers · readiness 100/100 · CI green · clean

✅ Suggested Action - Approve/Merge

  • safe to merge

Review summary
Adds an opt-in `oldest-first` ordering mode to the re-gate sweep's `selectRegateCandidates`, wired end-to-end (schema, migration 0116, resolver defaults, .gittensory.yml overlay, OpenAPI, focus-manifest, settings-preview, processors.ts call site) with extensive regression tests covering the starvation guard, priority-repair bypass, and multi-sweep convergence. The most-recent-dispatch deferral logic (excluding whichever PR(s) hold the pool's single freshest lastRegatedAt, with a starvation fallback when the whole pool ties) is correctly derived and matches its test suite exactly. All required touchpoints for this repo's config-as-code convention appear present and consistent with sibling fields (default handling, required-vs-optional schema entries, focus-manifest overlay).

Nits — 6 non-blocking
  • src/settings/agent-sweep.ts: the new `creationOrder` helper duplicates the exact same `Date.parse(pr.createdAt) ?? 0` logic that already exists inline in the preexisting `regateProgress`-adjacent code just above it — worth extracting a single shared `parseCreatedAt` helper instead of copy-pasting the parse+fallback.
  • The doc comment above `selectRegateCandidates` is quite long (multiple paragraphs); consider trimming to the essential invariant and moving the detailed convergence-proof narrative into the test file where the REGRESSION test already documents it.
  • migrations/0116_regate_sweep_order_mode.sql: I can't verify from this diff alone that 0116 is the next contiguous migration number (no gap) — worth double-checking against the latest existing migration file.
  • Consider a short constant or named export for the `feat(regate-sweep): add opt-in oldest-first ordering mode to selectRegateCandidates #3815`-referenced convergence guarantee comment block so future readers can jump straight to the rationale without re-deriving it from prose.
  • The `isMostRecentlyDispatched` priority-bypass check re-tests `priorityBypassesFreshness && priorityPullNumbers.has(pr.number)` — this mirrors the same guard used for the freshness filter; a small shared predicate would reduce the risk of the two drifting out of sync if one is updated later.
  • 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.
Signal Result Evidence
Code review ✅ No blockers 1 reviewer
Linked issue ✅ Linked #3815
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 (1 linked issue).
Validation posture ✅ 25/25 PR body includes validation/test evidence.
Contributor workload ✅ 10/10 Author activity: 51 registered-repo PR(s), 43 merged, 372 issue(s).
Contributor context ✅ Confirmed Gittensor contributor JSONbored; Gittensor profile; 51 PR(s), 372 issue(s).
Gate result ✅ Passing No configured blocker found.
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: Python, TypeScript, JavaScript, Ruby, Go, Kotlin, MDX, Shell
  • Official Gittensor activity: 51 PR(s), 372 issue(s).
  • PR-specific overlap: none found.
Contributor next steps
  • Treat this as maintainer-lane context rather than normal contributor-lane activity.
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.

🟩 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.

  • Re-run Gittensory review

@loopover-orb loopover-orb Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

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

@loopover-orb
loopover-orb Bot merged commit b14a258 into main Jul 6, 2026
13 checks passed
@loopover-orb
loopover-orb Bot deleted the feat/regate-sweep-oldest-first-order branch July 6, 2026 20:46
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.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

feat(regate-sweep): add opt-in oldest-first ordering mode to selectRegateCandidates

1 participant