# v0.72.0 — Frontier Durability & Catalog Correctness > **Full details:** [v0.72.0.md-full.md](v0.72.0.md-full.md) ## What's New v0.72.0 is the "Frontier Durability & Catalog Correctness" hardening release. It resolves four correctness-critical findings from Assessment 14 ( PLAN_OVERALL_ASSESSMENT_14.md) that represented real data-loss or catalog- corruption risk in production deployments. ### COR-001/REL-001/ARCH-001: Dead DUR-1 Tentative-Frontier Code Removed The codebase contained a two-phase tentative-frontier design (DUR-1) with three functions — `prepare_frontier`, `finalize_frontier_and_complete_refresh` (DUR-1 variant), and `reconcile_tentative_frontiers` — that had no call sites in production code and contained invalid SQL in the recovery path. The scheduler hot-path used the single-phase `store_frontier` but treated failure as log-only, providing no durability guarantee. Fix: the three dead DUR-1 functions are removed. The canonical path (`store_frontier` / `store_frontier_and_complete_refresh`) is now the only mechanism for advancing the frontier. All six scheduler refresh paths propagate frontier-store failures using `?`, making them fatal. A frontier-store failure aborts the entire refresh transaction, preventing partial commits. See [ADR-004](../plans/adrs/ADR-004.md) for the full rationale. ### COR-002/API-001: Outbox `stream_table_oid` Stores the Correct OID `pgtrickle.pgt_outbox_config.stream_table_oid` was being populated with `pgt_id::oid` — an internal sequential counter cast to an OID type — instead of `pgt_relid`, the actual `pg_class.oid` for the underlying table. This made all outbox joins against `pg_class` silently wrong, and meant that outbox consumers could not resolve the table from the stored OID. Fix: all five write/read paths in `src/api/outbox.rs` now use `pgt_relid` directly. The migration SQL updates any existing rows. ### COR-003: WAL Transition Handoff is Now Atomic `complete_wal_transition` previously dropped the CDC trigger before updating the catalog mode to `WAL`, creating a race window where concurrent writes could be missed: the trigger was gone but the WAL reader had not yet taken over. Fix: the update order is reversed and wrapped in a `pg_advisory_lock` — catalog mode is updated to `WAL` first; the trigger is dropped second; the advisory lock ensures only one concurrent call can execute the handoff for a given stream table. ### COR-004: Replication Slot Creation Guarded Against XID Assignment `create_replication_slot_pristine` would attempt to create a replication slot in a transaction that already had an XID assigned (e.g. after any catalog write), which causes PostgreSQL to error with "replication slot cannot be created in a transaction that has performed writes". This was surfaced in rare test environments and could occur in production during concurrent DDL. Fix: the function now checks `GetCurrentTransactionIdIfAny()` before calling the slot-creation primitive and returns an actionable `PgTrickleError` if the caller is in a dirty transaction. ## Breaking Changes None for users. Operators who inspect `pgt_outbox_config.stream_table_oid` directly should note that the migration SQL corrects existing rows to hold the real `pg_class` OID rather than the internal `pgt_id` counter.