Skip to content

feat(gate): re-check migration-file collisions against live main before merge #2550

Description

@JSONbored

Parent: #1936

Problem

scripts/check-migrations.mjs (wired into CI via npm run db:migrations:check) validates migration-number contiguity/duplicates by reading migrations/ off disk in the checked-out branch. CI checks out github.event.pull_request.head.sha — the contributor's own branch tip — not a fresh merge against the current tip of main. Two PRs can each independently add a new, non-overlapping migration file (e.g. 0090_a.sql and 0090_b.sql); each individually passes check-migrations.mjs (no duplicate visible in its own branch), each gets mergeable_state: clean from GitHub (two distinct file additions, no textual conflict), and the gate's own live pre-merge recheck (refreshLiveMergeState/refreshLiveCiAggregate in runAgentMaintenancePlanAndExecute, src/queue/processors.ts) only re-fetches GitHub's mergeable_state and CI-check status — neither is content-aware, so neither catches this.

This is not hypothetical: it has now happened 4 times in this repo's history (0015/0017, 0074, 0075/0076, and most recently 0090 — PR #2479 and PR #2527 each independently claimed migration number 0090, merged cleanly, and required a reactive one-off patch, PR #2532, to grandfather the duplicate). No systemic fix exists — only the reactive patch.

Requirements

  • Add a live, content-aware recheck step to the gate's pre-merge pass (not just the CI/review-gate pass) for any PR touching migrations/**: re-run migration-collision-detection logic against a FRESH merge of the PR's head with the current live tip of main, immediately before the actual merge call.
  • If a live collision is detected (that wasn't visible at CI time because it originated from another PR merged since), downgrade the disposition to a HELD state with a clear "rebase needed — a sibling migration landed on main since your last CI run" comment, never merge blind.
  • Config-driven, off-by-default per the house pattern (e.g. gate.premergeContentRecheck), gated by the same autonomy/dry-run/kill-switch stack every other agent-driven mutation already uses.
  • Must not add meaningful latency to the common case (no migrations/** changes in the PR ⇒ skip entirely).

Deliverables

Acceptance criteria

  • A PR that would introduce a migration-number collision with the LIVE tip of main (not just its own branch snapshot) is held with a clear rebase-needed message, never merged.
  • A PR with no migrations/** changes sees zero behavior change and zero added latency.
  • The existing scripts/check-migrations.mjs CI check is unaffected — this is additive, not a replacement.

Expected outcome

The exact bug class that hit this repo 4 times (most recently #2479/#2527#90 collision, patched reactively via #2532) can no longer reach main silently — it is caught live, at the moment it would actually happen, instead of requiring a maintainer to notice db:migrations:check failing on main itself after the fact.

Metadata

Metadata

Assignees

Labels

maintainer-onlyOwner-only work — yields no Gittensor points.roadmapOn the Wave-2 agent-layer roadmap board (project 9)

Projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions