chore: make duplicate migration numbers impossible to ship unnoticed - #394
Merged
Conversation
`main` carries `migrate_v0.70_device_app_version.sql`, already applied to production. PR #393 independently added `migrate_v0.70_provider_accounts.sql`. Different schema, same number, neither author in a position to know. Two migrations sharing a number destroys the only record of what has actually run: "did v0.70 run?" becomes "which v0.70?". Postgres applies both without complaint, so the question only gets asked months later, during an incident. Three layers, because the first two are advice and advice gets missed: - `scripts/check_migration_numbers.sh` — fails on any duplicate, names both files, and prints the next free number. Verified both ways: passes on `main` (71 migrations), and reddens with exit 1 when the real #393 collision is reproduced locally. - Wired into swift-ci as its own job, next to the helper guards. The container-touch guard sat unwired for months and caught three real holes the first time anyone ran it — a guard nothing calls is not a guard. - Written into AGENTS.md (Codex et al.) and a new CLAUDE.md (Claude Code loads it automatically at session start; the repo only had AGENTS.md, so Claude sessions were starting blind). CLAUDE.md points at AGENTS.md as the single source of truth rather than forking the guidance. The rule as documented: never reuse a number, **including one only used on an unmerged branch** — parallel work is normal here, and two sessions each taking "the next number" is precisely the failure. If your branch collides with one that has landed on `main`, renumber yours; `main`'s has usually already run against production. The guard's own find/xargs pipelines use `-print0`/`-0`: the repo path contains a space, and the first version cheerfully reported a file named "cli". Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
The collision
maincarriesmigrate_v0.70_device_app_version.sql— already applied to production. PR #393 independently addedmigrate_v0.70_provider_accounts.sql. Different schema, same number, and neither author was in a position to know.Two migrations sharing a number destroys the only record of what has actually run: "did v0.70 run?" becomes "which v0.70?". Postgres applies both without complaint, so the question only gets asked months later, during an incident.
Three layers
Because the first two are advice, and advice gets missed.
scripts/check_migration_numbers.sh— fails on any duplicate, names both files, prints the next free number. Verified both directions: passes onmain(71 migrations), and reddens with exit 1 when the real Draft: isolated macOS onboarding and multi-account QA experience #393 collision is reproduced locally.AGENTS.md+ a newCLAUDE.md. Claude Code loadsCLAUDE.mdautomatically at session start and the repo only hadAGENTS.md, so every Claude session was starting blind.CLAUDE.mdpoints atAGENTS.mdas the single source of truth rather than forking the guidance.The rule
Note
The guard's
find/xargspipelines use-print0/-0— the repo path contains a space, and the first version cheerfully reported a duplicate file namedcli.🤖 Generated with Claude Code