# v0.92.0 — Backup, Restore, Upgrade & CDC Recovery

> **Status:** Implemented
> **Scope:** Large
> **User promise:** *"Backups, upgrades, clones, and capture failures preserve correctness."*
> **Blocked by:** [v0.91.0](v0.91.0.md)
> **Split from:** the former v0.91.0 lifecycle release.

## Theme

Define and test the behavior of persistent stream-table state through backup,
restore, cloning, upgrade, promotion, and CDC failure. This release is a
mandatory v1.0 blocker.

Recovery means proving continuity or rebuilding from a known point. Recreating
a trigger or replication slot is not recovery unless pg_trickle can prove the
frontier remains valid.

## Items

### LC-3: Backup, restore, and promotion

Test each path independently:

- `pg_dump` and `pg_restore`
- `pg_basebackup` and physical restore
- point-in-time recovery
- physical replica promotion
- restore to a host without pg_trickle
- restore with a different extension version where supported

After restore or promotion, pg_trickle validates every frontier and persistent
operator state against the restored database. A frontier ahead of recoverable
source history triggers protected reinitialization or suspension. It never
resumes silently.

### LC-4: Clone isolation

Store an explicit database-instance identity for capture ownership. A database
created from a template, dump, physical copy, or logical copy must detect the
new identity before capture resumes. A clone cannot consume, overwrite, or
reuse capture infrastructure that belongs to the source database.

### LC-5: Upgrade preflight and quiescence

`pgtrickle.preflight_upgrade()` reports both human-readable details and stable
machine-readable statuses:

- `BLOCKER` for a condition that makes the upgrade unsafe
- `DRAIN_RECOMMENDED` for pending work that should finish first
- `WARNING` for a condition that needs review
- `SAFE` when no action is required

The function covers suspended tables, in-flight refreshes, capture health,
buffer backlog, catalog integrity, persistent state versions, and rebuild disk
headroom. `pgtrickle.quiesce()` and `pgtrickle.resume_all()` provide a scripted
upgrade boundary.

### LC-6: PostgreSQL and extension upgrades

CI tests PostgreSQL major upgrades with active stream tables and pending deltas.
Extension upgrade E2E tests cover every supported source version. Downgrades
remain unsupported and fail with the rollback runbook named in the error.

The v1.0 support matrix is bounded to source extension versions v0.40.0 through
the latest v0.98.x release, on PostgreSQL 18. Before LC-6 implementation starts,
commit a manifest with every supported source-version and PostgreSQL-major pair.
Older migration scripts remain chain-checked, but they do not receive full E2E
support. Later releases publish a new bounded matrix instead of automatically
carrying every historical source version forward.

### LC-7: CDC failure classification and recovery

Every detected capture failure enters one recovery class:

| Class | Required action |
|-------|-----------------|
| Self-repairable | Repair automatically only when continuity can be proved. |
| Reinitialization required | Rebuild the result and capture state from a known point before resuming. |
| Operator intervention required | Suspend with a stable reason code because automatic action could risk correctness or external state. |

Tests inject missing triggers, missing slots, unavailable WAL, restored sources,
corrupt or missing buffers, and interruption during repair. No repair may advance
an unproven frontier.

## Exit criteria

- [x] Every supported backup, restore, promotion, and clone path has automated
      E2E coverage
- [x] Clone isolation is proven with an explicit database-instance identity
- [x] PostgreSQL major-upgrade coverage includes active stream tables and
      pending deltas
- [x] The checked-in v1.0 support manifest contains only v0.40.0 through the
      latest v0.98.x release on PostgreSQL 18, and every listed pair passes E2E
- [x] Preflight, quiesce, and resume expose stable results suitable for scripted
      DBA workflows
- [x] Every injected CDC failure enters one documented recovery class
- [x] No injected failure can resume with an unproven frontier
