# v0.61.0 — DX, Documentation & Final Pre-1.0 Polish > **Full details:** [v0.61.0.md-full.md](v0.61.0.md-full.md) ## What's New v0.61.0 closes the remaining low-severity findings from the v0.57.0 overall assessment and delivers the developer-experience and documentation improvements needed before the v1.0 stable label. After this release every finding in Report 12 is resolved and the project is ready for the v1.0 release gate. ### DX-1: health_check() Detects Foreign-Owned Attachments (E-1) `pgtrickle.health_check()` gains an `attachment_owner_check` row. It lists all pg_tide outboxes and downstream publications attached to stream tables where the attachment was made by a role other than the stream table owner. This catches the residual exposure from the pre-v0.58.0 ownership-check gap and flags it clearly for operators performing post-upgrade audits. ### DX-2: SQL_REFERENCE.md Completeness Audit (E-2) `docs/SQL_REFERENCE.md` is reconciled against the full list of `#[pg_extern]` symbols in the compiled extension. Every function not intended for direct user use is annotated with `@internal` in the source and excluded from the reference. Functions in `src/api/metrics_ext.rs`, `src/api/self_monitoring.rs`, and `src/api/planner.rs` that are useful for operators are promoted to documented entries with signatures, return types, and worked examples. ### COR-7: ctid Invariant Comment in phd1.rs (C-7) The EC01-2 phantom-cleanup code in `src/refresh/phd1.rs` that relies on `ctid` stability gains an explicit `// INVARIANT:` comment documenting that the `ctid` is captured and consumed within the same snapshot and must not be split across subtransaction boundaries. ### COR-8: Snapshot Cache Key Secondary Equality Check (C-8) The 64-bit `DefaultHasher` snapshot cache now stores the rendered fingerprint string alongside the hash. On a cache hit, the string is compared before the cached CTE is reused. Hash collisions — astronomically rare but silent if they occur — now produce a cache miss rather than wrong SQL. ### COR-9: DiffContext cte_counter Reset per differentiate() (C-9) `DiffContext::cte_counter` is reset to 0 at the start of each `differentiate()` call. CTE names now start from `__pgt_cte_scan_1` in every differentiation, keeping generated SQL compact and deterministic. ### SEC-5: Outbox Name Collision Prevention (S-5) `outbox_table_name_for()` now appends an 8-character hex suffix derived from `blake3(st_name)` when truncation to 63 characters would otherwise occur. Two stream tables whose names differ only after the 56-character mark now produce distinct outbox names. ### QUAL-4: sublinks.rs Decomposition Plan (Q-4) `src/dvm/parser/sublinks.rs` (7 065 lines) is split into focused sub-modules: - `dvm/parser/sublinks/exists.rs` — EXISTS / NOT EXISTS extraction - `dvm/parser/sublinks/scalar.rs` — scalar sublink hoisting - `dvm/parser/sublinks/in_list.rs` — IN / NOT IN rewrite (including multi-column and NULL-safety fixes) - `dvm/parser/sublinks/having.rs` — HAVING-clause aggregate rewrites `dvm/parser/sublinks/mod.rs` re-exports all public functions. ### QUAL-5: Brittle split().nth() Test Pattern Fixed (Q-5) Tests in `src/dvm/operators/lateral_subquery.rs` that split generated SQL by a magic CTE-name string are rewritten to use `splitn(2, marker)` with an explicit assertion that the split produced two parts. A mismatch now fails loudly rather than silently passing with an empty assertion. ### DOC-1: Three Foundational ADRs (D-1) The ADR framework in `plans/adrs/PLAN_ADRS.md` transitions from PROPOSED to ACTIVE with the addition of three foundational Architecture Decision Records: - **ADR-001: Trigger-Based CDC over Logical Replication** — documents why row-level `AFTER` triggers were chosen over logical replication slots for the default CDC path (single-transaction atomicity, no slot management overhead, simpler failure modes) and when WAL-based CDC is appropriate. - **ADR-002: Z-Set / Multiset Formalism for IVM** — documents the choice of Z-sets (signed integer multiplicities) as the algebraic foundation for the differential engine, why true multisets were insufficient (negative multiplicities needed for deletes), and the implications for operator correctness. - **ADR-003: EC-01 Join-Correctness Invariant** — documents the R₀ snapshot-splitting fix and the cross-cycle phantom-reconciliation invariant, specifying the exact conditions under which `phd1.rs` must run and what invariants it guarantees. ### DOC-2: LIMITATIONS.md — Multi-Column NOT IN with NULLs (D-2) `docs/LIMITATIONS.md` gains a new subsection "Multi-column NOT IN with nullable columns" that explains when the rewrite falls back to subquery-based execution, why the fallback is necessary, and how users can avoid the performance impact (add `IS NOT NULL` predicates on each column). ### FEAT-1: SEARCH / CYCLE Clause — Clear UnsupportedFeature Error (F-2) Queries using SQL:2023 `SEARCH BREADTH FIRST` or `CYCLE` clauses in recursive CTEs now produce a clean `UnsupportedFeature` error with a descriptive message instead of being silently ignored or producing a cryptic parse error. ### FEAT-2: LATERAL + DIFFERENTIAL Interaction Documented (F-1) `docs/DVM_OPERATORS.md` and `docs/LIMITATIONS.md` gain new sections documenting the exact supported subset of LATERAL in DIFFERENTIAL mode: which LATERAL patterns are fully differentiable, which fall back to FULL refresh, and which produce a clear `UnsupportedFeature` error.