> **Plain-language companion:** [v0.38.0.md](v0.38.0.md) ## v0.38.0 — EC-01 Correctness Sprint (Hard Gate) **Status: Released.** This focused release closes EC-01 (join phantom rows) with unconditional PH-D1 cleanup, plan-time `RowIdSchema` verification, and a DIFF-vs-FULL join convergence property test. Derived from [plans/PLAN_OVERALL_ASSESSMENT_8.md](plans/PLAN_OVERALL_ASSESSMENT_8.md) §4.1 (Finding C1). > **Release Theme** > v0.38.0 is a correctness-only release. Operational truthfulness, SQLSTATE > rollout, generated docs, OpenTelemetry operator docs, and ecosystem coverage > remain in v0.39.0+ so EC-01 is not deferred behind unrelated work. --- ### Features (EC-01 Only) | ID | Title | Effort | Priority | |----|-------|--------|----------| | C38-1 | Unconditional PH-D1 cleanup plus join row-id convergence | L | P0 | | C38-2 | Plan-time `RowIdSchema` verification in DVM planner | M | P0 | **C38-1 — Unconditional PH-D1 cleanup plus join row-id convergence.** Non-deduplicated join deltas now run PH-D1 cross-cycle cleanup after every differential apply for keyed, non-partitioned stream tables. The cleanup wraps the defining query with the same row-id expression used by FULL refresh and removes stream-table row IDs that no longer exist in the current full result set. This makes the cleanup unconditional for the EC-01 class instead of gating it on join shape, refresh count, or previously detected residuals. The join delta row-id formula continues to use canonical left-first/right-second key hashing across Part 1a, Part 1b, Part 2, and correction terms. PH-D1 cleanup is the final convergence guard for historical phantoms whose row IDs are absent from the current delta. **Acceptance criteria:** - [x] Join deltas either return `is_deduplicated: true` or are cleaned by unconditional PH-D1 - [x] Q07 and Q15 are no longer in `IMMEDIATE_SKIP_ALLOWLIST` - [x] No phantom accumulation across random mixed-DML join property cycles **C38-2 — Plan-time `RowIdSchema` verification in DVM planner.** `RowIdSchema` is now exercised at DVM planning time. The planner infers row-id schemas for scans, transparent operators, projections, joins, aggregates, set operations, CTEs, recursive plans, lateral plans, and scalar subqueries before generating the delta SQL. Any incompatible row-id pipeline fails planning with a clear `RowIdSchema verification failed` error instead of reaching refresh time as silent drift. ### Test Coverage (EC-01 Only) | ID | Title | Effort | Priority | |----|-------|--------|----------| | T-C38-1 | EC-01 DIFF-vs-FULL property generator for joins | L | P0 | **T-C38-1 — EC-01 DIFF-vs-FULL property generator (Release Gate).** `tests/e2e_ec01_property_tests.rs` creates matching FULL and DIFFERENTIAL stream tables over a three-table join aggregate, then runs 100 deterministic mixed-DML cycles by default. Each cycle includes inserts, updates, left/right deletes, and co-deletes across join participants. After every refresh cycle, the test verifies both stream tables against the defining query and compares FULL vs DIFFERENTIAL with multiset equality. Divergence diagnostics include row counts, row IDs, changed action counts, and sample extra/missing rows. The test is part of the light-E2E allowlist so CI runs it on every PR. ### What's NOT in v0.38.0 - Operational truthfulness (backpressure, wake, docs) — v0.39.0 - SQLSTATE-first retry classification rollout — v0.39.0 - Generated `CONFIGURATION.md` / `UPGRADING.md` drift checks — v0.39.0+ - OpenTelemetry operator guide — v0.39.0 - pg_partman / TimescaleDB ecosystem coverage — v0.40.0+ - `history_prune_interval_seconds` wiring — v0.40.0 ### Recommended Implementation Order 1. ✅ C38-1 — PH-D1 cleanup and join convergence guard 2. ✅ C38-2 — plan-time `RowIdSchema` verification 3. ✅ T-C38-1 — EC-01 DIFF-vs-FULL property release gate 4. ✅ Release metadata, upgrade SQL, changelog, and roadmap status ### Implementation Status | ID | Title | Status | |----|-------|--------| | C38-1 | Unconditional PH-D1 cleanup plus join row-id convergence | ✅ Done | | C38-2 | Plan-time `RowIdSchema` verification in DVM planner | ✅ Done | | T-C38-1 | EC-01 DIFF-vs-FULL property generator for joins | ✅ Done | ### Exit Criteria - [x] C38-1: Non-deduplicated join outputs no longer accumulate phantom rows in random property workloads - [x] C38-2: Incompatible `RowIdSchema` pipelines fail planning with a clear reason - [x] T-C38-1: DIFF-vs-FULL property convergence test is present and CI-covered - [x] Q07 and Q15 removed from `IMMEDIATE_SKIP_ALLOWLIST` - [x] Extension upgrade path added (`0.37.0 -> 0.38.0`) - [x] CHANGELOG.md entry written - [x] ROADMAP.md v0.38.0 row marked ✅ Released - [x] `just check-version-sync` passes