> Plain-language companion for v0.77.0 implementation. ## v0.77.0 — Correctness Stop-the-Line & DVM Proof Infrastructure Status: ✅ Released. ### Context v0.77.0 is the first release of the Assessment-15 Hardening Arc (v0.77.0–v0.80.0). It implements a set of correctness hard gates that were identified during an independent audit of the differential view maintenance (DVM) engine. The release has zero user-visible API changes and no schema migrations. All changes are correctness fixes, safety assertions, and testing infrastructure. ### What changed **C-1: TRUNCATE LSN fix** The TRUNCATE CDC trigger was using `pg_current_wal_lsn()` (the WAL write position) instead of `pg_current_wal_insert_lsn()` (the WAL insert position). Inside a transaction, the insert position is always at or ahead of the write position. When a TRUNCATE and subsequent INSERTs were committed in the same transaction, the stale write-position LSN could cause the refresh engine to lose the post-TRUNCATE rows. Fixed. **C-2: Source-placeholder coverage assertion** The delta template resolver now verifies that every source OID it was given has both `__PGS_PREV_LSN_{oid}__` and `__PGS_NEW_LSN_{oid}__` placeholder tokens in the template. If a token is missing, it means the codegen silently dropped a source table from the delta SQL — which would cause the stream table to miss changes from that source. The resolver now returns an error that triggers a full reinitialisation. **C-3/DVM-1: q12-like CASE/IN-list drift → forced FULL fallback** TPC-H query 12 uses `SUM(CASE WHEN ... THEN 1 ELSE 0 END)` combined with `l_shipmode IN ('MAIL', 'SHIP')` in the WHERE clause. This pattern produces non-deterministic incremental results in the current DVM engine (the delta rule double-counts rows under certain orderings). v0.77.0 detects this pattern and forces a FULL refresh with reason code `CASE_IN_LIST_DVM_DRIFT_FULL_FALLBACK`. The root-cause fix (correct delta rule for CASE aggregates) is planned for v0.78.0. **DVM-2/P-1: q20-like correlated aggregate subquery → forced FULL fallback** TPC-H query 20 contains `ps_availqty > (SELECT 0.5 * SUM(l_quantity) FROM lineitem WHERE ...)`. In the DVM delta SQL, this inner aggregate subquery is re-evaluated for every changed row, giving O(delta × table) complexity. At SF=10 this produces delta SQL that takes 45+ minutes per cycle. v0.77.0 detects this pattern (comparison operator + aggregate subquery) and forces a FULL refresh with reason code `CORRELATED_SUBQUERY_DELTA_QUADRATIC`. The root-cause fix (pre-aggregation CTE rewrite) is planned for v0.78.0. **D-1: Per-source advisory lock in cleanup** When two stream tables share a source table, two concurrent refresh workers can both enter `drain_pending_cleanups` for the same source OID in the same tick. The min-frontier computation + DELETE/TRUNCATE must be atomic per source. v0.77.0 adds `pg_try_advisory_xact_lock(oid::bigint)` — a non-blocking, transaction-scoped lock — to guarantee exactly one worker owns the cleanup window per source OID per transaction. **DVM-3: `pg_trickle.validate_delta_invariants` GUC** New boolean GUC, default `false`. When enabled, after every successful DIFFERENTIAL refresh the extension compares the stream table's row count against a full recomputation of the defining query. A mismatch emits a WARNING. Intended for CI pipelines and debugging; the performance impact is significant (runs the full query after every differential). **C-4: Semgrep CI rule (formalised)** The existing `rust.panic-in-sql-path` semgrep rule in `.semgrep/pg_trickle.yml` already blocks `.unwrap()`, `.expect()`, and `panic!()` in non-test code on every PR. v0.77.0 formally annotates it as the C-4 Assessment-15 hard gate. **T-1: DVM algebra property generators** Added 12 property-based unit tests in `src/refresh/tests.rs` covering `classify_case_in_list_aggregate_drift` and `classify_correlated_aggregate_subquery_in_where`. Tests verify canonical true-positive patterns (q12, q20), variant patterns (lowercase, `>=`, `<`), and false-positive guards (benign aggregates, simple scans). **T-4: TRUNCATE LSN E2E regression tests** Added two E2E tests in `tests/e2e_cdc_tests.rs` verifying the C-1 fix: 1. TRUNCATE + INSERT in the same transaction: only post-TRUNCATE rows survive. 2. TRUNCATE then INSERT in separate transactions: same correctness guarantee. **D-2: IMMEDIATE mode SAVEPOINT/rollback E2E tests** Added three E2E tests in `tests/e2e_v077_tests.rs` verifying that IMMEDIATE mode stream tables correctly handle transaction rollbacks: 1. Rolling back a SAVEPOINT leaves no ghost rows. 2. Partial SAVEPOINT rollback: committed rows visible, rolled-back rows absent. 3. Nested SAVEPOINTs: rolling back to outer SAVEPOINT discards all inner work. ### Upgrade notes No action required. The upgrade SQL (`pg_trickle--0.76.0--0.77.0.sql`) is a no-op — there are no catalog changes. The binary upgrade is safe to apply with zero downtime using `ALTER EXTENSION pg_trickle UPDATE`.