# v0.91.0 — Schema & Query Evolution > **Status:** Planned > **Scope:** Large > **User promise:** *"Production schema and query changes fail safely."* > **Blocked by:** [v0.88.0](v0.88.0.md) > **Split:** backup, restore, cloning, upgrades, and CDC recovery moved to > [v0.92.0](v0.92.0.md). ## Theme Give every defining-query and source-schema change one deterministic outcome: continue correctly, rebuild safely, or suspend explicitly. No change may leave a stream table in an ambiguous degraded state. This release is part of the mandatory v1.0 lifecycle critical path. It stays narrow so schema-state design and recovery-state design are reviewed and gated separately. Incremental-window breadth in v0.89.0 and controller automation in v0.90.0 may proceed in parallel; neither blocks this release. ## Items ### LC-1: Safe defining-query replacement `pgtrickle.alter_stream_table_query()` classifies a proposed change as: - **compatible** only when pg_trickle proves that the materialized result, frontier, row identities, and auxiliary state remain valid - **rebuildable** when shadow state can be populated and swapped atomically - **rejected** when pg_trickle cannot preserve the stream table contract If compatibility cannot be proved, the change is rebuildable. An unnecessary rebuild is safer than reusing invalid state. `pgtrickle.explain_alter()` reports the classification, proof or rejection reason, affected state, and estimated rebuild cost before any mutation. A rebuild uses shadow state and a brief atomic swap. Interrupted rebuilds resume or roll back without exposing a partial result. ### LC-2: Source-schema evolution DDL event handling must cover: - transactional DDL and rollback - additive and destructive column changes - table, schema, and column rename chains - schema moves and ownership changes - dropped and recreated objects that reuse a name but have a new OID - dependency OID changes - refresh concurrent with DDL - an extension upgrade near source DDL An additive change may continue automatically only when the defining query and stored state remain valid. A destructive or ambiguous change suspends the stream table with a stable reason code, a `health_check()` entry, and an actionable repair command. No path serves silently stale or structurally invalid output. ## Exit criteria - [ ] Every supported query and DDL change has a deterministic classification - [ ] Compatible plan swaps are proven against the exact state oracle. An unproven change is rebuildable or rejected - [ ] Rebuilds use shadow state and atomic replacement. Interruption tests cover every state transition - [ ] No destructive DDL can produce silently stale or structurally invalid output - [ ] Rename chains, schema moves, recreated objects, dependency OID changes, and extension-upgrade overlap have deterministic tests - [ ] Concurrent DDL and refresh histories end by continuing correctly, rebuilding safely, or suspending explicitly