Files
ModelForge/docs/architecture/adr/0042-immutable-verified-backup-sets.md

1.8 KiB

ADR-0042: Immutable verified backup sets

Status

Accepted in M15 on 2026-08-27.

Decision

Make BackupSet immutable recovery identity, sealed by immutable_at once written, carrying the ModelForge version and commit, the canonical repository and reference, the Alembic revision, the PostgreSQL server identity and tool version, the destination, the hashed manifest and payload, the included and excluded asset classes and the encryption identity.

Treat verification, not creation, as the gate. Only VERIFIED is restore eligible, and verification checks the manifest hash, manifest-to-journal agreement, the presence of a database payload, every object's size and hash at an allowlisted path, decryption against the recorded plaintext hash, and archive readability. Anything else fails closed with a typed code.

Protect the last known-good backups from retention unconditionally, and reconcile any backup interrupted mid-write to FAILED.

Consequences

A backup cannot look usable because a file exists. A single flipped byte in a 5.4 MB encrypted payload, a one-integer edit to a manifest entry, a wrong encryption key and a mid-write interruption were each caught in live rehearsal with HASH_MISMATCH, MANIFEST_HASH_MISMATCH, DECRYPTION_FAILED and MANIFEST_INCOMPLETE, and none of them could become a restore plan.

Immutability across several flushes required loosening the immutability guard to permit exactly the sealing flush — a backup is planned, written and only then stamped — while still rejecting every later change to identity fields.

The platform can never retain zero recovery points because a timer expired, and a backup can never contain a record of itself as complete, so a restored plane consistently reports the backup it came from as not restore eligible.