Skip to content

release: prepare 2.0 stamp - #200

Draft
NikolayS wants to merge 6 commits into
mainfrom
release/2.0
Draft

release: prepare 2.0 stamp#200
NikolayS wants to merge 6 commits into
mainfrom
release/2.0

Conversation

@NikolayS

@NikolayS NikolayS commented Jul 28, 2026

Copy link
Copy Markdown
Owner

Draft release stamp — do not merge or tag

This prepares the final pg_ash 2.0 payload identity. It intentionally does not tag, merge, publish a release, or dispatch the authoritative pre-tag suite. Those actions remain blocked on the owner-reviewed visual harness in #178 and a subsequent clean whole-suite run from the exact candidate commit.

Final identity follows the repository's two-part policy:

  • payload: 2.0
  • eventual tag: v2.0
  • not 2.0.0 / v2.0.0

What changes

  • Stamps all three checker-known ash.config.version sites and the installer header as exactly 2.0.
  • Leaves all five finalized 1.x migrations and all five root compatibility wrappers byte-identical.
  • Keeps the current-line cumulative sql/migrations/ash-1.5-to-2.0.sql, which remains provisional until the stable tag.
  • Makes installer replay and physical ash.config normalization one migration-owned transaction, fixing release blocker 1.5-to-2.0 migration can stamp 2.0 before config normalization fails #202: no failed upgrade can publish 2.0 while physically unconverged.
  • Adds exact immutable-v1.5 red/green coverage for the reported custom-trigger failure, a later dependent-view / DROP RESTRICT failure, and same-client transaction-marker rollback and direct-installer ownership.
  • Corrects the release-note reader contract: typed aggregate readers expose provenance; samples() is raw-only; chart() is presentation-only and emits its hour-grain planning notice.
  • Updates README and SECURITY identity surfaces and consolidates all final 2.0 release notes.

Promotion note

At base 87c22a3608cbcfeb422ae2ff15425bd462fbb990, devel/sql/ contains only its README: there is no development installer or migration to copy. The post-beta candidate had already accumulated in the released paths before #179's policy landed. This PR therefore performs the honest in-place finalization of that candidate. The five scripts declared immutable by docs/RELEASE_PROCESS.md remain unchanged; the current 1.5-to-2.0 migration is explicitly provisional until v2.0.

Adversarial release blocker #202

Red

PostgreSQL 17.10, using git archive v1.5 -- sql and the real archived v1.0→v1.5 chain:

custom-trigger precondition: 1.5|1.5|11
custom-trigger migration_exit=3
ERROR: cannot normalize ash.config: unsupported custom triggers are present
custom-trigger after failure: 2.0|2.0|11

dependent-view precondition: 1.5|1.5|11
dependent-view migration_exit=3
ERROR: cannot drop table ash.config_ordinal_legacy because other objects depend on it
dependent-view after failure: 2.0|2.0|11

The tuple is ash.config.version | ash.status() version | num_partitions attnum; fresh 2.0 has attnum=3.

Fix and rationale

sql/migrations/ash-1.5-to-2.0.sql now begins one transaction before including the installer. A transaction-local internal setting tells sql/ash-install.sql to suppress only its own boundaries; normalization then completes before the migration's sole final COMMIT. Direct installer invocation still owns its transaction and still commits a caller's existing outer transaction at its final COMMIT.

The normalization code already preflights the enumerable unsupported shapes: columns/types/nullability/row count, legacy-name collision, storage/security/replication/table properties, custom column properties, triggers, policies, rules, publications, extended statistics, labels, inheritance, inbound foreign keys, and invalid indexes. Preflight alone cannot prove later DDL or commit success: a permitted dependent view can block DROP RESTRICT, while replay, event-trigger, concurrent-DDL, role/dependency, permission, cancellation, deadlock/timeout, storage, OOM, or commit failures can occur later. One transaction enforces the invariant for every failure class rather than only the known catalog list.

The marker is transaction-local rather than a persistent psql variable. In one deterministic psql process, the regression sets the marker locally, rolls it back, then invokes the installer directly and forces a late failure after the stamp and most DDL. The exact v1.5 state and schema must remain unchanged, proving the marker cleared and direct transaction ownership returned.

Green

Issue #202 custom-trigger precondition: 1.5|1.5|11
Issue #202 custom-trigger migration_exit=3
Issue #202 custom-trigger after failure: 1.5|1.5|11
Issue #202 custom-trigger rollback PASSED
Issue #202 dependent-view precondition: 1.5|1.5|11
Issue #202 dependent-view migration_exit=3
Issue #202 dependent-view after failure: 1.5|1.5|11
Issue #202 dependent-view rollback PASSED
Issue #202 same-client marker rollback: 1.5|1.5|11
Issue #202 same-client transaction-marker rollback PASSED
Issue #202 failed-normalization release-state atomicity PASSED

Each failure is checked from a fresh connection against both identity surfaces, the physical ordinal, a full before/after ash schema snapshot, and survival of the blocking customization.

Verification

Candidate: ba96f7858c0827b8afaf031cd3f832de37db256a

17/17 devel/scripts/test_release_stamp.py tests: PASS
7/7 devel/scripts/test_ci_step_script.py tests: PASS
exact docs guard: PASS
git diff --check: PASS
release stamp OK: v2.0 matches sql/ash-install.sql (ash.config.version=2.0)
PostgreSQL 14 upgrade-chain: PASS
PostgreSQL 15 upgrade-chain: PASS
PostgreSQL 16 upgrade-chain: PASS
PostgreSQL 17 upgrade-chain: PASS
PostgreSQL 18 upgrade-chain: PASS
PostgreSQL 19beta2 upgrade-chain: PASS
PostgreSQL 17 fresh-install / direct-installer atomicity surface: PASS

Payload hashes:

d8d2b744756e80df55a30db275fdf3d5b4ab63cfc438f065be7a523e3dc800ab  v2.0-beta1:sql/ash-install.sql
845a7306d825cadfd091a0b7d9a6d82458ccae65167b5fc52601e9ce4df3aec2  sql/ash-install.sql
f6cb220fafe84f8423fe61664acd7dda2ecee4648e870b80fcd4bd2204eb2221  sql/migrations/ash-1.5-to-2.0.sql
ec42eb2eb5c7c30ff67204445ca21018b368c9e94e56c5115044eb199539b5c8  sql/ash-1.5-to-2.0.sql

The ten frozen 1.x migration/wrapper hashes remain identical to base. The current-line migration hash changes intentionally for #202.

Real PostgreSQL beta1 → 2.0 rehearsal

Rerun after the atomicity fix in an owned disposable pg-ash-release-gate:17 container on a Docker-assigned localhost port. The tagged beta installer came directly from v2.0-beta1; upgrade and re-apply used the public root wrapper from candidate ba96f78.

BETA1_TO_2_0_SERVER=17.10 (Debian 17.10-1.pgdg13+1)
BETA_IDENTITY=2.0-beta1|2.0-beta1|42|00:00:07|true
FINAL_IDENTITY=2.0|2.0|42|00:00:07|true|3
WRAPPER_REAPPLY_CONFIG_OID_STABLE=true
READER_ADMIN_EXECUTE_REMOVED=true
READER_DYNAMIC_HELPER_EXECUTE=true
SCHEMA_EQUIVALENCE_FRESH_VS_BETA1_UPGRADE=PASS
BETA1_TO_2_0_REHEARSAL=PASS

The final tuple adds num_partitions attnum=3. The beta reader role was removed before the final schema snapshots after its _admin_funcs() narrowing and dynamic helper access were asserted, so the fresh-final and beta-upgraded snapshots compare semantically without role-specific ACL ordering noise.

Hosted checks for exact candidate ba96f78 are green: docs/release guards plus PostgreSQL 14, 15, 16, 17, 18, 19beta2, and the PostgreSQL 17 no-cron matrix. The regression builds immutable v1.5 once in an owned seed database and template-clones an isolated database for each case, avoiding earlier pg_cron workers and repeated historical installs.

Remaining owner gates

Until those are complete, this PR must remain draft and unmerged.

Run the installer replay and ash.config normalization in one migration-owned transaction so no failure can publish the 2.0 stamp on an unconverged schema. Cover the exact custom-trigger repro, a late dependent-view failure, and same-session installer retry ownership from immutable v1.5.

Correct the 2.0 reader provenance notes to distinguish aggregate readers from raw-only samples() and presentation-only chart().

Refs #202
Run the issue #202 fixture in a generated database so prior pg_cron workers in the full hosted workflow cannot hold migration locks. Drop the owned database on every exit.
Build the immutable v1.5 chain once, then clone it as a PostgreSQL template for each issue #202 failure case. This preserves exact preconditions while avoiding three full historical installs per CI job.
Prove the transaction-local marker clears and direct installer ownership returns in one deterministic psql process, then force a late installer error and require exact v1.5 state/schema rollback. This retains the discriminator without terminal-dependent CI behavior.
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