Skip to content

fix(db): commit the #542/#543 ledger repairs so cloud has no orphan stamps (#541 follow-up) - #555

Merged
guillermoscript merged 1 commit into
masterfrom
fix/ledger-orphans-541-followup
Jul 26, 2026
Merged

fix(db): commit the #542/#543 ledger repairs so cloud has no orphan stamps (#541 follow-up)#555
guillermoscript merged 1 commit into
masterfrom
fix/ledger-orphans-541-followup

Conversation

@guillermoscript

Copy link
Copy Markdown
Owner

Follow-up to #541. Closes the two orphan migration stamps introduced by #553 (#542) and #554 (#543).

What's wrong

Cloud carries 175 migration stamps; master has 173 migration files. The two extra:

20260726013256  repair_migration_ledger_542
20260726015858  repair_migration_ledger_543

Both were applied through the MCP apply_migration tool while #542 and #543 were being worked, but neither committed a matching file.

The irony is the point: each of those was itself a ledger repair. #542's realigned rls_exam_child_tables_tenant_gate (2026072601321620260726100000), #543's realigned write_side_entitlement_gates (2026072601555320260726110000). Both were correct. But because apply_migration stamps a fresh timestamp rather than the filename, each repair became an orphan the moment it ran — one orphan traded for another, and the ledger never converged.

Committing the file is what actually closes the loop. That's why #541's own repair shipped as 20260726005843_repair_migration_ledger_541.sql and did not recur.

What this does

Adds the two missing files. The SQL in each is reproduced verbatim from supabase_migrations.schema_migrations.statements for the corresponding version — only the explanatory headers are new.

Nothing is applied to cloud by this PR. The statements have already run there; this commit exists so the repo can account for them. Both are idempotent — on a fresh supabase db reset the UPDATEs match nothing, because the CLI stamps 20260726100000 / 20260726110000 from the filenames in the first place.

Verification

Diffing supabase/migrations/ against supabase_migrations.schema_migrations:

before after
repo files 173 175
cloud stamps 175 175
pending (repo, not cloud) 0 0
orphans (cloud, no file) 2 0
repo=175  cloud=175
pending (repo, not cloud): NONE
orphans (cloud, no file): NONE
CLEAN

This is exactly the condition npm run verify:cloud reports as "cloud carries no migration stamp that matches no repo file" — and it is how this was caught, hours after that check shipped in #552. The check earned its keep immediately.

Worth noting for next time

The apply_migration → orphan-stamp cycle has now happened three times in one day (#541's four, then #542's and #543's). docs/MIGRATIONS.md states the push-only rule, but the pooler is unreachable from this network, so supabase db push isn't actually available to these jobs — which is why everyone reaches for apply_migration.

The durable fix is either restoring pooler access, or making apply_migration usage always pair with committing a file under the stamp it assigned. Not in scope here; flagging it because the rule as written assumes a tool that doesn't currently work.

QA

npm run test:unit    # 411 passed
npm run typecheck    # clean
npm run build        # succeeds

Lint is unchanged — this PR adds only .sql files.

🤖 Generated with Claude Code

https://claude.ai/code/session_01HPFyHjqzSR6Ku1gyWjeQie

…tamps (#541 follow-up)

Cloud carried 175 migration stamps against 173 files on master. The two extra:

  20260726013256  repair_migration_ledger_542
  20260726015858  repair_migration_ledger_543

Both were applied through the MCP `apply_migration` tool while #542 and #543
were being worked, but neither committed a matching file. Each repair correctly
realigned its own migration's stamp — and then became an orphan itself, because
`apply_migration` stamps a FRESH timestamp rather than the filename. One orphan
traded for another; the ledger never actually converged.

Committing the files is what closes the loop, which is why #541's own repair
shipped as 20260726005843_repair_migration_ledger_541.sql.

The SQL in both files is reproduced verbatim from
`supabase_migrations.schema_migrations.statements` for the corresponding
version; only the explanatory headers were added. Nothing is re-applied to
cloud — the statements have already run there, and this commit exists so the
repo can account for them.

Both are idempotent: on a fresh `supabase db reset` the UPDATEs match nothing,
because the CLI stamps 20260726100000 / 20260726110000 from the filenames in
the first place.

Ledger after this commit: 175 files, 175 stamps, zero pending, zero orphans —
verified by diffing supabase/migrations/ against schema_migrations.

This is the condition `npm run verify:cloud` (#541) reports as "cloud carries no
migration stamp that matches no repo file", and is how it was caught, hours
after that check shipped.

Gates: test:unit 411 passed, typecheck clean, build succeeds.

Refs #540, #541, #542, #543

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01HPFyHjqzSR6Ku1gyWjeQie
@guillermoscript
guillermoscript marked this pull request as ready for review July 26, 2026 02:17
@guillermoscript
guillermoscript merged commit 138e68f into master Jul 26, 2026
2 checks passed
@guillermoscript
guillermoscript deleted the fix/ledger-orphans-541-followup branch July 26, 2026 02:19
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant