Skip to content

release: add behavioral feature-gate coverage - #192

Merged
NikolayS merged 18 commits into
NikolayS:mainfrom
samo-agent:agent/w4-features
Jul 28, 2026
Merged

release: add behavioral feature-gate coverage#192
NikolayS merged 18 commits into
NikolayS:mainfrom
samo-agent:agent/w4-features

Conversation

@samo-agent

@samo-agent samo-agent commented Jul 27, 2026

Copy link
Copy Markdown
Contributor

Summary

Fills the per-feature behavioral release-gate gap documented in #160 and absorbs the complete release-gate foundation developed in #188.

  • adds deterministic fixtures and exact assertions for every installed non-underscore public surface
  • covers readers, lifecycle/admin side effects, reader grants/revokes/default pg_monitor, documented reader edges, and pgss text enrichment/degradation
  • runs the canonical feature suite with both optional extensions, without pg_cron, without pg_stat_statements, and without either
  • includes release: add Docker release gate and normalize config upgrade #188's pg_cron Docker images, runner, shared SQL assertions, attnum-ordered schema snapshot, and ash.config ordinal normalization
  • retains release: return processed grains from rollups #194's processed-grain contract: empty minute grains count as processed, caught-up calls return zero, and physical rows remain independently asserted

Refs #160, #188, #191, and #194.

Final integration

Hand-rebased onto current main 2ccdf65 after #194. The two stacked #194 commits were dropped: the test patch was recognized as upstream, and the implementation duplicate differed only at the migration header where main carries the corrected, non-contradictory wording. Range-diff preserves every other PR commit.

Three full-workflow findings were fixed without changing product behavior or weakening an assertion:

  1. DROP/CREATE EXTENSION pg_stat_statements does not clear its preloaded shared state. After thousands of earlier workflow statements, the exact marker could be evicted. The feature driver now calls pg_stat_statements_reset() immediately after recreating the extension.
  2. H-CI-3 launched three synthetic pg_sleep(120) clients but retained neither backend identities nor client PIDs. The later lifecycle fixture correctly observed those three plus its own sleeper. H-CI-3 now tags only its workload, terminates those tagged backends, and reaps all three clients on success and failure. The exact active_count = 1 and decoded-row assertions are unchanged.
  3. PostgreSQL 19 beta 2 resolves text || jsonb in two ASSERT diagnostic expressions as JSON concatenation. Both coverage objects are now explicitly cast to text. The asserted bounds and minutes_with_data predicates are unchanged.

#188 absorption and assertion conservation

All original 42 #188-owned shared assertion sites remain and are reachable through the canonical runner. Their files now contain 44 sites after adding the current-main failure-counter and trigger-preservation checks.

Using the established ^\s*assert\b source-site convention across the workflow and devel/tests/*.sql:

  • current main before: 858 inline + 0 shared = 858
  • this PR after: 848 inline + 145 shared = 993
  • 11 existing inline assertions moved into shared SQL; the other 847 remain inline
  • 1 new inline plus 134 other net-new shared sites yields +135 overall

No assertion was lost. At #188's original extraction point, its own before/after inventory was 594/594 workflow assertions.

RED/GREEN evidence

  • Ordinals: current main's dev-upgrade leaves ash.config.num_partitions at attnum=11; the new assertion exits 3. This head normalizes canonical attnums 1–22 (num_partitions=3) and passes preservation plus idempotent reapply checks.
  • rollup_minute() and rollup_hour() return per-database row counts, not processed grains #191: on exact head 08b5f6b, the four feature-bearing surfaces (features, degraded-no-cron, degraded-no-pgss, degraded-neither) all PASS on PG14 and PG17: 8/8, with no Expected FAIL: #191 remaining.
  • pgss isolation: after prefilling PG17 pgss to 4,910 entries/17 deallocations, the old no-reset step executes the marker then fails at features_readers.sql:1400; the reset passes the unchanged enrichment assertions.
  • H-CI-3 isolation: old head 041a450 fails every cron-on matrix job with four live sleepers. An isolated PG17 check of the fix removes all three tagged backends and tracked clients while leaving a differently tagged control active.
  • PG19 diagnostics: old head 61a7547 fails on PG19beta2 with invalid input syntax for type json at the unchanged B5 assertion; exact explicit casts make the canonical PG19beta2 fresh-install surface PASS.

Validation

On exact head 08b5f6b:

  • PG14/PG17 four-surface feature gate: 8/8 PASS; no Expected FAIL: #191
  • PG19beta2 canonical fresh-install surface: PASS
  • PG17 canonical upgrade chain: PASS
  • fresh install, full dev-upgrade, and actual v1.5-to-current snapshots: byte-identical
  • config row/default/owner/ACL/constraint/index/self-FK/trigger preservation and OID-stable reapply: PASS
  • release: add Docker release gate and normalize config upgrade #188 shared assertions: 42/42 retained; final inventory 993 static sites
  • bash -n devel/scripts/release_gate.sh: PASS
  • release-gate helper unit tests: 7/7 PASS
  • workflow parse, extracted Bash syntax, Python AST parse, and git diff --check: PASS
  • independent Codex and focused cleanup reviews: no merge-blocking finding

Final landing rebase

The merge candidate is hand-rebased onto current main at 9efad9c (after #198 and #199). Exact head: fcd37d7.

  • GitHub Actions has a 512,000-byte workflow-file limit. Combining release: add behavioral feature-gate coverage #192 with the new release: keep stale rollups honest without losing fast path #199 inline selector gate would have produced 513,005 bytes, so the unchanged 110-line/9-assert selector transaction was moved byte-for-byte to devel/tests/stale_rollup_source.sql; the workflow is now 508,364 bytes and invokes it in the same psql session.
  • The final assertion inventory is 848 inline + 187 shared = 1,035. All 42/42 original release: add Docker release gate and normalize config upgrade #188-owned shared assertions remain; those files now contain 44 sites after later additions. The release: keep compacted query attribution honest #198 query-attribution gate remains 30 assertions and the release: keep stale rollups honest without losing fast path #199 source-selector gate remains 9.
  • Exact PG14/PG17 hard gates passed features, degraded-no-cron, degraded-no-pgss, and degraded-neither: 8/8 PASS, with no Expected FAIL: #191 in source or output.
  • The first exact combined run correctly failed because release: keep compacted query attribution honest #198 added the dynamic reader helper ash._exact_query_uses_coarser(integer,integer,name), taking the direct reader-function count from 43 to 44. The final gate expects 44 and also names that helper explicitly for both the feature reader and pg_monitor, so an unrelated 44th grant cannot mask its loss.
  • A deterministic fractional-boundary fixture exposed a real ash.report bug: convert-then-floor rounded :59.9 endpoints into the following minute. The implementation now floors each bound before epoch conversion. Parent RED shifted both bounds by one minute and reported 4 expected/3 with data; final GREEN covers the exact four-minute range. This user-visible fix is recorded in RELEASE_NOTES.md; no assertion was weakened.
  • Fresh-install and upgrade-chain release gates pass on PG17; workflow YAML, shell syntax, helper tests (7/7), and git diff --check pass.

This section supersedes the historical base/head and assertion totals above; those remain as the audit trail for the earlier review point.

@samo-agent samo-agent changed the title test: add behavioral feature release-gate coverage release: add behavioral feature-gate coverage Jul 27, 2026
@samo-agent
samo-agent force-pushed the agent/w4-features branch 2 times, most recently from 26acfb0 to 2b02a08 Compare July 27, 2026 21:27
samo-agent added a commit to samo-agent/pg_ash that referenced this pull request Jul 27, 2026
samo-agent added a commit to samo-agent/pg_ash that referenced this pull request Jul 27, 2026
samo-agent added a commit to samo-agent/pg_ash that referenced this pull request Jul 27, 2026

@NikolayS NikolayS left a comment

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Codex review standing in for REV — audit verdict: PASS on exact head 041a450. Hand rebase onto main 2ccdf65 correctly dropped the two stacked #194 commits; the only stopped conflict was their obsolete migration-header wording, for which current main is the corrected superset. Range-diff preserves the other 12 commits. Ordinal RED/GREEN reproduced (main attnum 11 and assertion exit 3; head canonical 1–22 with preservation/reapply PASS). Both schema-equivalence paths are byte-identical. The mandated #191 feature gate is 8/8 PASS across four surfaces on PG14 and PG17. All 42 #188-owned shared assertions remain; source-site inventory is 858 before and 993 after (848 inline + 145 shared), with none lost. Old CI's pgss-marker failure was independently reproduced under saturated shared state and fixed narrowly by reset-after-create; enrichment assertions are byte-identical and pass. Codex static review found no blocker. APPROVED.

@NikolayS
NikolayS marked this pull request as ready for review July 27, 2026 22:49
Keep the Docker tag independent from the numeric package major so the same image definition supports PostgreSQL 14 through 19beta2.

Relates to NikolayS#160
Source cron, degraded-mode, and schema snapshots from shared SQL while preserving all 594 workflow assertions. Include attnum in schema snapshots so column-order divergence is visible.

Relates to NikolayS#160
Run every gate surface across bounded parallel PostgreSQL workers, reuse exact CI step bodies, emit validated TSV and human summaries, and guarantee ID-scoped container and volume teardown.

Relates to NikolayS#160
Rebuild the v1.5 upgrade table in canonical fresh-install order while preserving the singleton row, defaults, constraints, indexes, ownership, ACLs, and comments. Reject unsupported custom dependencies and catalog properties transactionally instead of dropping them.

Add an upgrade regression that seeds non-default values and custom catalog objects, verifies preservation, and proves migration reapplication keeps the replacement table OID.
The shared feature step runs after the full workflow has accumulated hundreds of pg_stat_statements entries. Dropping and recreating the extension does not clear the preloaded shared state, so the exact marker query can be missing even though the reader code is correct.

Reset pg_stat_statements immediately after recreating it. This preserves the exact ash.top()/ash.samples() enrichment assertions while making their fixture independent of prior workflow activity.
Tag H-CI-3's three synthetic pg_sleep clients, terminate only those tagged backends on every exit, and wait for their client processes. The prior step left all three sessions live for later workflow steps, so features_lifecycle.sql correctly observed four active sleepers instead of its single owned fixture. Keep the exact active_count = 1 and decoded-row assertions unchanged; restore the quiescent precondition they test.
PostgreSQL 19 beta 2 resolves text || jsonb as JSON concatenation, so both B5 ASSERT message expressions raise on the JSON token before reporting the contract. Cast the coverage object explicitly to text. The asserted bounds and minutes-with-data predicates are unchanged; this is a diagnostic typing fix, not a behavior change. The old exact head fails on PG19beta2, while the canonical fresh-install surface passes with these casts.
Combining NikolayS#192 with NikolayS#198 and NikolayS#199 makes test.yml 513,005 bytes, above GitHub Actions' 512,000-byte workflow limit. Move NikolayS#199's exact 110-line transaction fixture to devel/tests and invoke it with the same psql connection and ON_ERROR_STOP behavior. The payload is byte-identical after removing YAML indentation; all nine assertions remain. The combined inventory is 848 inline plus 184 shared, 1,032 total.
ash.ts_from_timestamptz() rounds fractional seconds while casting to int4. report() previously converted first and divided by 60 afterward, so an endpoint at :59.5 or later crossed into the next minute before the documented minute floor. Floor v_from/v_to in timestamp space first. Add a deterministic +59.9-second feature assertion: the old code shifts both bounds and reports three of four data-bearing minutes; the corrected code preserves the exact four-minute coverage. Record the public behavior change in RELEASE_NOTES.md. No assertion is weakened.
After NikolayS#198, grant_reader() correctly discovers 44 non-admin reader functions rather than the pre-NikolayS#198 count of 43. Update both the explicit-role and default pg_monitor feature contracts, and name _exact_query_uses_coarser(integer,integer,name) in a direct EXECUTE assertion so an unrelated 44th grant cannot mask a missing helper. The initial exact PG14/PG17 feature run failed 44-versus-43; all four feature-bearing surfaces now pass on both majors.

@NikolayS NikolayS left a comment

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Final exact-head verification on fcd37d71efbe5c2b86b2374b52a07d42194db4b8: APPROVE.

  • Hand-rebased onto exact current base 9efad9c. Range-diff maps all 15 original #192 commits patch-identically; only the documented selector extraction, report-boundary fix, and helper-grant assertions follow.
  • Exact-head CI is green across PG14–PG19beta2, docs, and cron-off: https://github.com/NikolayS/pg_ash/actions/runs/30315785772
  • Required hard gate is 8/8 PASS: PG14+PG17 × features/no-cron/no-pgss/neither, with zero Expected FAIL: #191.
  • Parent RED proves convert-before-floor shifted both :59.9 report bounds +1 minute and returned 3/4 covered minutes. Final GREEN floors before conversion, preserves all four minutes, and release-notes the behavior change; no assertion was weakened.
  • The #198 dynamic reader helper made the correct direct function-grant count 44. The final gate asserts both that exact count and named EXECUTE on _exact_query_uses_coarser(integer,integer,name) for the explicit reader and pg_monitor, while admin negative controls remain.
  • Assertion inventory is 848 inline + 187 shared = 1,035. All 42/42 original #188-owned shared sites execute on passing paths; those files now contain 44 sites.
  • #198 is preserved (30 query-attribution assertions); #199 is preserved byte-for-byte after extraction (9 source-discriminating assertions and the exact least(until, date_trunc(minute, now())) clamp).
  • Fresh/dev-upgrade/actual-v1.5 schemas are byte-identical; ordinal, reapply, and OID-stability checks pass.
  • Workflow size is 508,364 bytes, below GitHub Actions’ 512,000-byte limit. Shell/YAML/Python syntax, helper unit tests, conflict-marker scan, and diff check pass.

No merge blocker found.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants