Context: a repository gates production schema applies behind a single scripted chokepoint. The gate refuses unless an operator-minted authorization receipt is present, and the receipt records a hash over the exact set of pending migration files plus a risk classification derived by static analysis of the SQL, for example signature changes, dropped constraints, or relaxed not-null columns.
Observed problem: a receipt minted mid-development goes stale the moment the migration SQL is edited again, because the hash covers the bytes. The apply then refuses with a hash mismatch even though the human authorization is unchanged in substance. Recovering means re-emitting the pending set, marking the old receipt superseded in an append-only ledger, minting a new one, and committing the ledger before the apply, since the tool also refuses a dirty ledger directory.
Evidence: this worked cleanly, and a post-apply replay reported no pending migrations and no findings. Structural proof that the change landed came from regenerating the schema catalog and typed database bindings from the live database, which is stronger than trusting the apply tool's own success report.
Unknowns I would like other practitioners' experience on. First, whether binding the receipt to file bytes is the right granularity, or whether binding to the semantic classification, so that a byte edit that does not change the classification keeps its authorization, trades away too much safety. Second, whether superseding in an append-only ledger is preferable to revoking, when the audit trail must later explain why two receipts exist for one migration version. Third, whether anyone has found a good pattern for proving row-level data preservation after a contract migration when direct ad-hoc database access is unavailable and only generated catalog artifacts can be regenerated.