> **See also:** [ROADMAP.md](../ROADMAP.md)

## v1.0.0 — Stability Contract

**User promise:** *"The product is now boring and dependable."*

**Goal:** First officially supported release. Semantic versioning locks in.
API, catalog schema, and GUC names are considered stable. Focus is
distribution and trust: getting pg_trickle onto package registries, shipping
signed artifacts and SBOMs with provenance, and proving PostgreSQL 19
forward-compatibility.

### The real 1.0 gate

Packaging and signing are necessary but not sufficient. The gate that actually
decides whether 1.0 ships is:

> **No known correctness issues, and boring upgrades.**

After the v0.93.0 feature freeze, the project accepts only bug fixes,
documentation, tests, compatibility work and simplification. The pre-1.0 period
is spent on **bugs → benchmarks → compatibility → upgrades → docs → real-world
workloads → simplification** — deliberately not on inventing new feature
releases to fill the space.

That period is a **release-candidate series**, not a gap. `v1.0.0-rc.1` ships
when every gate below is believed met; each subsequent `rc.N` ships when a
blocker found by an rc user is fixed. 1.0.0 is tagged when an rc has been in the
field with no new blocker. Going straight from a feature freeze to a stability
contract with no candidate in users' hands is how a 1.0 acquires the bugs it
promised not to have.

| Gate | Condition |
|------|-----------|
| G1 | Zero open correctness defects. Every known DVM limitation is either fixed or documented in `docs/DVM_SUPPORT_MATRIX.md` with a proven FULL fallback and a reason code. |
| G2 | Upgrade from every supported prior version, on every supported PostgreSQL version, with an active workload — green, unattended, and documented. |
| G3 | `pg_upgrade` across a PostgreSQL major version with active stream tables and a non-empty change buffer — green. |
| G4 | 72-hour soak with schema changes, restarts and failure injection — zero correctness deviations, no unbounded growth. |
| G5 | Published benchmarks (write-path overhead, refresh throughput, TPC-H/Nexmark) enforced as blocking regression gates. |
| G6 | Documentation matches reality: every `#[pg_extern]` documented, every user-facing GUC justified, every claim in the README reproducible from a shipped test. |
| G7 | API, catalog schema and GUC surface frozen; a compatibility test asserts no breaking change versus v0.93.0. |
| G8 | At least one release candidate has been published and used, with no unresolved blocker reported against it. |

> **Note on effort estimates.** The hour figures below cover release
> engineering only. G1–G8 are not estimated in hours because they are
> conditions, not tasks: their cost is however long it takes for the soak, the
> upgrade matrix and the rc series to come back clean. Do not read the
> "~46–86 hours" total as the cost of reaching 1.0.

### PostgreSQL 19 Forward-Compatibility (A3) — **not a 1.0 blocker**

> **In plain terms:** When PostgreSQL 19 beta stabilises and pgrx ships PG 19
> support, this milestone audits every internal `pg_sys::*` API call for
> breaking changes, adds conditional compilation gates, and validates the WAL
> decoder against any pgoutput format changes introduced in PG 19.
>
> **This is explicitly removed from the 1.0 gate.** PG 19 GA and pgrx PG 19
> support are both outside this project's control; making them blocking means
> the stability contract for PG 18 users — which is finished work — is held
> hostage to someone else's schedule. PG 19 support ships in the first minor
> release after pgrx supports it, as v1.1.0 or a v1.0.x if it turns out to be
> additive.

| Item | Description | Effort | Ref |
|------|-------------|--------|-----|
| A3-1 | pgrx PG 19 support (the crate is already pinned at `=0.18.0`; this is a PG-target addition, not the version bump the earlier plan described) + `cargo pgrx init --pg19` | 2–4h | [PLAN_PG19_COMPAT.md](plans/infra/PLAN_PG19_COMPAT.md) §2 |
| A3-2 | `pg_sys::*` API audit: heap access, catalog structs, WAL decoder `LogicalDecodingContext` | 8–16h | [PLAN_PG19_COMPAT.md](plans/infra/PLAN_PG19_COMPAT.md) §3 |
| A3-3 | Conditional compilation (`#[cfg(feature = "pg19")]`) for changed APIs | 4–8h | [PLAN_PG19_COMPAT.md](plans/infra/PLAN_PG19_COMPAT.md) §4 |
| A3-4 | CI matrix expansion for PG 19 + full E2E suite run | 4–8h | [PLAN_PG19_COMPAT.md](plans/infra/PLAN_PG19_COMPAT.md) |

> **A3 subtotal: ~18–36 hours**

### Release engineering

> **In plain terms:** The 1.0 release is the official "we stand behind this
> API" declaration — from this point on the function names, catalog schema,
> and configuration settings won't change without a major version bump. The
> practical work is getting pg_trickle onto standard package registries
> (PGXN, apt, rpm) so it can be installed with the same commands as any
> other PostgreSQL extension, and hardening the CloudNativePG integration
> for Kubernetes deployments.

| Item | Description | Effort | Ref |
|------|-------------|--------|-----|
| R1 | Semantic versioning policy + compatibility guarantees | 2–3h | [PLAN_VERSIONING.md](plans/infra/PLAN_VERSIONING.md) |
| R2 | apt / rpm packaging (Debian/Ubuntu `.deb` + RHEL `.rpm` via PGDG) | 8–12h | [PLAN_PACKAGING.md](plans/infra/PLAN_PACKAGING.md) |
| R2b | PGXN `release_status` → `"stable"` (flip one field; PGXN testing release ships in v0.7.0) | 30min | [PLAN_PACKAGING.md](plans/infra/PLAN_PACKAGING.md) |
| R3 | ~~Docker Hub official image~~ → CNPG extension image | ✅ Done | [PLAN_CLOUDNATIVEPG.md](plans/ecosystem/PLAN_CLOUDNATIVEPG.md) |
| R4 | ~~CNPG operator hardening (K8s 1.33+ native ImageVolume)~~ ➡️ Pulled to v0.15.0 | 4–6h | [PLAN_CLOUDNATIVEPG.md](plans/ecosystem/PLAN_CLOUDNATIVEPG.md) |
| R5 | **Docker Hub official image.** Publish `pgtrickle/pg_trickle:1.0.0-pg18` and `:latest` to Docker Hub. Sync Dockerfile.hub version tag with release. Automate via GitHub Actions release workflow. | 2–4h | — |
| R6 | **Version sync automation.** Ensure `just check-version-sync` covers all version references (Cargo.toml, extension control files, Dockerfile.hub, dbt_project.yml, CNPG manifests). Add to CI as a blocking check. | 2–3h | — |
| SAST-SEMGREP | **Elevate Semgrep to blocking in CI.** CodeQL and cargo-deny already block; Semgrep is advisory-only. Flip to blocking for consistent safety gating. Before flipping, verify zero findings across all current rules. | 1–2h | [PLAN_SAST.md](plans/testing/PLAN_SAST.md) |
| OTL-1 | **OpenTelemetry tracing spans.** Add `pgtrickle.refresh`, `pgtrickle.cdc_capture`, and `pgtrickle.snapshot` spans via the OTel SDK so every pg_trickle operation is visible to OTel collectors. Minimum viable: trace_id propagation through the refresh pipeline; attribute set = `stream_table`, `refresh_mode`, `rows_processed`. | 4–8h | [PLAN_OVERALL_ASSESSMENT_3.md](plans/PLAN_OVERALL_ASSESSMENT_3.md) §9.6 |
| SIGN-1 | **Cosign-sign GHCR release images.** Add `cosign sign` step to the GitHub Actions release workflow for `trickle-labs/pg-trickle`, `trickle-labs/pgtrickle-relay`, and `pg_trickle-ext` GHCR images. Attach Rekor transparency log entry. Document `cosign verify` command in `SECURITY.md`. | 2–4h | [PLAN_OVERALL_ASSESSMENT_3.md](plans/PLAN_OVERALL_ASSESSMENT_3.md) §9.11 |
| SIGN-2 | **Publish SBOMs for extension and release artifacts.** Generate CycloneDX or SPDX SBOMs for the extension tarball, relay binary, and release images; attach them to GitHub releases and document how operators verify them. | 2–4h | [PLAN_OVERALL_ASSESSMENT_8.md](plans/PLAN_OVERALL_ASSESSMENT_8.md) §10 |
| SIGN-3 | **Attach provenance attestations to release workflows.** Emit SLSA-style provenance or equivalent signed attestations for published binaries and images so operators can verify how each artifact was built. | 2–4h | [PLAN_OVERALL_ASSESSMENT_8.md](plans/PLAN_OVERALL_ASSESSMENT_8.md) §10 |
| MDB-1 | **Promote G17-MDB multi-database soak test to `ci.yml`.** The `stability-tests.yml` G17-MDB job runs multi-database scenarios in isolation. Move it to `ci.yml` under the "Push to main" trigger alongside the existing soak test. Gate it on a 30-min wall-clock budget for PR CI; use the full 2-hour run on schedule. | 2–3h | [PLAN_OVERALL_ASSESSMENT_3.md](plans/PLAN_OVERALL_ASSESSMENT_3.md) §9.10 |

> **v1.0.0 total: ~46–86 hours** (incl. PG 19 compat ~18–36h + release engineering ~18–30h + OTel/signing/SBOM/provenance/MDB ~12–20h)

**Exit criteria:**
- [ ] G1–G8: the stability-contract gates above are all met
- [ ] At least one `v1.0.0-rc.N` published, with no unresolved blocker
- [ ] Published on PGXN (stable) and apt/rpm via PGDG
- [ ] Docker Hub image published (`pgtrickle/pg_trickle:1.0.0-pg18` and `:latest`)
- [x] CNPG extension image published to GHCR (`pg_trickle-ext`)
- [x] CNPG cluster-example.yaml validated (Image Volume approach)
- [ ] `just check-version-sync` passes and blocks CI on mismatch
- [ ] SAST-SEMGREP: Semgrep elevated to blocking in CI; zero findings verified
- [ ] OTL-1: OTel refresh/CDC/snapshot spans emitted; visible in Jaeger test run
- [ ] SIGN-1: All GHCR release images cosign-signed; `cosign verify trickle-labs/pg-trickle:1.0.0` passes
- [ ] SIGN-2: SBOMs are published for release tarballs, relay, and release images
- [ ] SIGN-3: Provenance attestations are published and verification is documented
- [ ] MDB-1: G17-MDB soak test runs in `ci.yml` on push to main; green
- [ ] Upgrade path from v0.30.0 tested
- [ ] Semantic versioning policy in effect
- [ ] A3 / PG 19: tracked, but **not** blocking this release

---

