# v0.60.0 — Code Quality, Test Coverage & CI > **Full details:** [v0.60.0.md-full.md](v0.60.0.md-full.md) ## What's New v0.60.0 is the third release of the Assessment-Driven Hardening Arc, closing the code quality, test coverage, correctness, and CI/CD gaps identified in the v0.57.0 overall assessment ([plans/PLAN_OVERALL_ASSESSMENT_12.md](../plans/PLAN_OVERALL_ASSESSMENT_12.md)). ### QUAL-1: Scheduler Log Level Standardisation (Q-1) All `log!()` calls in `src/scheduler/dispatch.rs`, `pool.rs`, and `scheduler_loop.rs` that represent routine state transitions (start dispatch, acquire execution lock, worker registered) are upgraded to `info!()`. `warning!()` remains reserved for recoverable errors. `error!()` is used for events that require operator attention. Operators running at the default `log_min_messages = warning` now see warnings and above with no extra noise; operators at `log_min_messages = info` get clean, structured progress output. ### QUAL-2: refresh/codegen.rs Function Decomposition (Q-2) Three functions exceeding 200 lines (`build_bypass_capture_sql`, `capture_diff_to_table`, and the primary MERGE template builder) are extracted into a new `src/refresh/sql_fragments.rs` helper module containing named single-purpose builders: `build_cte_predicate()`, `build_merge_join_condition()`, `build_content_hash_column()`, and `build_delta_target_list()`. ### QUAL-3: src/cdc.rs Module Decomposition (Q-3) `src/cdc.rs` (3 383 lines) is split into four focused sub-modules, mirroring the v0.55.0 monitor decomposition: - `cdc/triggers.rs` — trigger creation, trigger SQL builders, column-name escaping, statement vs row mode logic - `cdc/buffer.rs` — change-buffer DDL, compaction, buffer naming helpers - `cdc/compact.rs` — compaction scheduling, lock-acquisition helpers, `CompactionResult` enum - `cdc/partition.rs` — partition-promotion detection, `should_promote_to_partitioned` `cdc/mod.rs` retains public SQL-callable functions and re-exports. ### TEST-1: Refresh Orchestrator and Merge Sub-Module Unit Tests (T-1) New `#[cfg(test)]` blocks cover the pure-logic paths in: - `src/refresh/orchestrator.rs` — cost-model state machine transitions (cold start → diff-preferred → full-preferred → diff-recovery), threshold boundary values, and the adaptive scoring formula. - `src/refresh/merge/columns.rs` and `conflict.rs` — column-list builders and conflict-resolution SQL generation. - `src/refresh/codegen.rs` — new `sql_fragments.rs` helpers each have table- driven unit tests. ### TEST-2: CDC Pure-Logic Unit Tests (T-2) `src/cdc/triggers.rs` and `src/cdc/buffer.rs` gain `#[cfg(test)]` blocks testing: `cb_col_name()` (reserved-name escaping), `buffer_base_name_for_oid()` (OID formatting), `build_changed_cols_bitmask_expr()` (column-bitmask SQL generation), and `should_promote_to_partitioned()` (partition-promotion classification). ### TEST-3: DDL Hook Classification Unit Tests (T-3) `src/hooks.rs` gains a `#[cfg(test)]` block with table-driven tests for each `DdlCommandKind` variant. Tests cover: ADD COLUMN on a tracked table, DROP COLUMN, ALTER COLUMN TYPE, RENAME TABLE, CREATE INDEX, and commands on untracked tables. ### TEST-4: Fixed Sleep Replacement (T-4) Remaining `tokio::time::sleep()` calls in `tests/e2e_quota_tests.rs`, `tests/e2e_bgworker_tests.rs`, and `tests/e2e_wal_cdc_tests.rs` are replaced with `wait_for_*` polling helpers from `tests/common/mod.rs`, continuing the programme started in v0.53.0. ### TEST-5: Differential Idempotence Proptest (T-5) A new `proptest!` block in `src/dvm/diff.rs` asserts that refreshing a stream table twice with the same source rows (written in randomised partition order) produces identical output. This validates the idempotence invariant of the differential engine under arbitrary ingest ordering. ### COR-5: WAL Decoder OID-Based Table Filter (C-5) The WAL decoder's change-routing filter is changed from string equality on qualified names to OID equality. On each poll cycle, the decoder resolves each tracked source table to its OID via `to_regclass()` and compares against the decoded row's relation OID (available in the `pg_logical_slot_changes` record). Text-name matching is retained only as a fallback when OID lookup fails. ### COR-6: Publication Rebuild Detects Partition-Attach (C-6) `check_if_publication_needs_rebuild()` now also detects when a source table transitions from a standalone table to a partition of another table (i.e., when `pg_inherits.inhrelid = source_oid` becomes true). When this transition is detected, the WAL publication is rebuilt with `publish_via_partition_root = true` and the stream table is marked for reinit. ### CI-1: Path-Filtered Full E2E on PRs (CI-1) `.github/workflows/ci.yml` gains a new `full-e2e-on-dvm-change` job that runs the full E2E test suite (stock test image, no TPC-H) when a PR modifies any file under `src/dvm/`, `src/refresh/`, or `src/cdc/`. This reduces the worst-case detection window for DVM regressions from ~24 hours to within the PR merge gate. ### CI-2: Dockerfile.e2e Non-Root User (CI-2) `tests/Dockerfile.e2e` adds `USER postgres` before the final `CMD`, so test containers run as the `postgres` system user instead of root. ### CI-3: Codecov Threshold for Safety-Critical Modules (CI-3) `codecov.yml` adds per-path coverage thresholds for modules previously excluded from the patch gate: `src/cdc/**` (50%), `src/hooks.rs` (40%), `src/wal_decoder.rs` (40%).