feat(migrations): 0068 guarded drop of build_assets_legacy (#114) - #465
Merged
Conversation
build_assets_legacy is the credential-bearing full copy 0062 left behind (r2_key/signature/signing_credential_id/metadata_json), maintained by nothing. 0068 removes it behind an in-migration ⊇ assert: it proves every legacy row's id + immutable columns (r2_key, file_hash, signature, signing_credential_id) are preserved in live build_assets, then DROPs. The assert fails via a CHECK(ok=1) violation ordered BEFORE the DROP, so a failing ⊇ aborts the whole migration and leaves the table intact — no export, no bare drop. metadata_json is excluded from the match: it is live-mutable derived data (delta from_version_code, download_count), so comparing it would false-abort. Design ruled by @gogo (#114 owner): strict ⊇ + abort, whitelist mechanism kept but currently empty (prod --remote COUNT 2026-08-18: 0 legacy rows unmatched in live, of 286 legacy / 321 live). The strict abort stays unconditionally — the count is a snapshot and does not pre-green the per-column check. Verified: - wrangler d1 execute --local: RED dataset aborts on "CHECK constraint failed: ok = 1", build_assets_legacy survives; GREEN dataset drops it (5 stmts OK). - worker/test/build_assets_legacy_drop_migration.test.ts (node:sqlite, stop-on-error matching D1): 5/5 — RED missing-row + RED mutation abort and preserve; GREEN ⊇, metadata-divergence, and empty-legacy drop. Deploy remains gated on the migration watch-gate + explicit artin authorization for THIS credential-bearing copy; this PR is the guarded migration only. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Signed-off-by: Rhea Rafferty <hands-rhea@mail.build>
0068 drops build_assets_legacy (the copy 0062 creates), which broke 4 pre-existing
tests. Fixed precisely — preserving the mechanism/guard coverage, removing only the
now-obsolete retention invariant:
- expected_d1_schema.test.ts: the two "stale database" tests modelled a pre-0062 DB
via chainWithout(/^0062/), which now pulls in 0068 — and 0068 aborts on a chain
where 0062 never created build_assets_legacy. Skip the 0062/0068 lifecycle pair
together; the fingerprint drift-detection coverage is unchanged.
- build_asset_direct_upload_migration.test.ts:
- "does not stop a continuing executor": applied "all except 0062", which pulled in
the later dependent 0068 → same abort. Apply only migrations BEFORE 0062
(name >= MIGRATION), matching the test's intent; 0062 preflight-guard coverage
unchanged.
- Removed "keeps the original rows recoverable after a successful rebuild": it
asserted build_assets_legacy is retained as a recovery copy — the invariant 0068
intentionally removes (artin-authorised; the guarded superset assert proves no
data loss). Its column/index/FK carry into build_assets is covered by "carries
every column, index and foreign key across the rebuild".
Verified: full worker suite green except feedback_closure_reason_migration.test.ts,
which fails only because /usr/bin/sqlite3 is absent on this machine (identical on
clean main; passes in CI). tsc --noEmit clean.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Signed-off-by: Rhea Rafferty <hands-rhea@mail.build>
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.
What
Removes
build_assets_legacy— the credential-bearing full copy0062left behind (renamed the oldbuild_assets→build_assets_legacy, copied every row into the new table byid, and deliberately did not drop it). That copy holdsr2_key,signature,signing_credential_id,metadata_jsonand is maintained by nothing.How — guarded, not a bare drop
An in-migration ⊇ assert runs BEFORE the
DROPand aborts the whole migration if it fails, via aCHECK(ok=1)violation (portable; noRAISE/trigger, noTEMPtable). It proves every legacy row has a live row with the sameidand the same immutable columns —r2_key,file_hash,signature,signing_credential_id(IFNULL-compared). If any legacy row is not preserved, the migration aborts andbuild_assets_legacyis left intact. No export — the drop is provably lossless. (No-export is deliberate and authorized: an export would copy the credential material to a looser location; artin rejected it as a contradiction — prove-redundant-then-delete, don't pre-copy.)metadata_jsonis excluded from the match: it is live-mutable derived data (deltafrom_version_code,download_count), so comparing it exactly would false-abort — the kind of false red that pushes an on-call to disable the guard.Design (ruled by @gogo, #114 owner)
--remoteCOUNT (2026-08-18, read-only): 0 legacy rows unmatched in live (of 286 legacy / 321 live), 0 of them credential-bearing → no whitelist needed today.Verification
wrangler d1 execute --local: RED dataset aborts onCHECK constraint failed: ok = 1,build_assets_legacysurvives (DROP never runs); GREEN dataset drops it (5 statements OK).worker/test/build_assets_legacy_drop_migration.test.ts(node:sqlite, stop-on-error matching D1) — 5/5: RED missing-row + RED mutation abort & preserve; GREEN ⊇, metadata-divergence, empty-legacy drop.tsc --noEmitclean.Gates
metadata_jsonexclusion, and the diagnostic credential scope. The one substantive design gate outstanding.🤖 Generated with Claude Code