# v0.98.0: Risk containment and contract truth > **Status:** Released > **Scope:** Medium > **User promise:** *"Known correctness risks are fixed or unavailable in stable operation."* > **Blocked by:** [v0.97.0](v0.97.0.md) > **Series assessment:** [v0.98.x](v0.98.x.md) ## Theme Contain every known correctness and security risk in the v0.97.0 baseline. Keep trigger capture as the only stable capture path. Report Graph V1 and Delta V1 as experimental and disabled until their assigned implementation and conformance releases pass. This release does not implement durable WAL receipt, unified graph execution, or complete Graph V1 and Delta V1 conformance. Those remain v0.103.0, v0.100.0, and v0.104.0 work. v0.98.0 prevents the incomplete paths from running as stable behavior. ## Work ### STAB-1: Contain unsafe WAL capture - Make trigger capture the only stable and automatically selected CDC mode. - Reject new WAL-polling selection and automatic transitions before creating a slot, consuming WAL, or changing a stream-table frontier. Return a stable unavailable reason that names v0.103.0 as the required implementation. - Detect existing WAL-backed stream tables during upgrade. Provide a tested transition to trigger capture. If an online handoff cannot prove a complete boundary, require rebuild before the table can resume. - Add fault tests that demonstrate the current consume-before-commit risk and prove that the v0.98 guard cannot advance a slot or stream-table frontier. ### STAB-2: Fail-closed Graph V1 and Delta V1 admission - Make `integration_capabilities()` report Graph V1 and Delta V1 as `experimental` and `enabled = false` throughout v0.98.x. - Route every public Graph V1 and Delta V1 operation through one admission guard. Reject before locks, catalog mutation, cursor or frontier movement, payload generation, or user-table writes. - Preserve existing catalog state for a documented rollback or later upgrade, but do not let disabled consumers accumulate unbounded retained payload. - Document the compatibility effect for existing coordinators and consumers. - Add live PostgreSQL negative tests for every public entry point, hostile `search_path`, non-owner roles, existing registrations, concurrent calls, savepoints, restart, restore, and binary upgrade. The conservative rejection contains the known graph policy, effective-action, boundary, cleanup, acknowledgement, resnapshot, exactness, retention, recovery, and ownership defects. v0.100.0 repairs the common graph execution path. v0.104.0 repairs and independently qualifies the complete public V1 contracts. ### STAB-3: Make operational contracts truthful - Make `active_profile()` distinguish configured, recommended, and effective values. Report an effective value only when runtime admission uses it. - Give automatic configuration an unambiguous representation. Do not interpret an explicit value as the automatic sentinel. - Either implement the documented disk forecast with a measurement time and horizon, or rename the current fields as accounted footprint. Include every extension-managed relation in the accounted total. - Either update progress during each advertised operation, or narrow the view and documentation to the state it measures. Test initial population, FULL, rebuild, repair, cancellation, and timestamp movement for the retained contract. - Give each enabled stable failure, fallback, rejection, and suspension an identifier, SQLSTATE, detail, hint, and support-matrix entry. - Validate monitoring with extension-emitted rows and spans. Text-presence and synthetic-span checks remain package-structure tests, not behavioral proof. ### STAB-4: Reconcile documentation and release gates - Reconcile active documentation with runtime admission for capture modes, Graph V1, Delta V1, set operations, volatility, windows, recursion, DISTINCT aggregates, identity types, and removed integrations. - Keep one authoritative checklist for each active release. Do not mark an item complete without evidence for the exact source commit and artifact. - Change the release-evidence writer to derive overall status from structured suite results. It must reject an unknown status and must not hard-code `passed`. ### STAB-5: Freeze an executable qualification contract - Add `tests/release/v0.98-qualification.json` and a schema-validating release gate. This is a release-test contract, not the product capability manifest assigned to v0.99.0. - Record exact required suite commands, expected capability states, source versions, package and platform artifacts, performance metrics and numeric budgets, longevity duration, and numeric growth limits. The 72-hour soak is optional and outside the required v0.98.1 contract. - Include a blocker ledger with identifier, severity, affected stable capability, status, and verifying suite. Publication requires zero open P0 or P1 entries. - Reject duplicate identifiers, unknown states, missing commands, wildcard versions, and absent or nonnumeric thresholds. The v0.98.0 tag may contain no `TBD`, `null`, or disabled required gate. - Freeze `duration_days = 7` for longevity. Do not make the 72-hour soak a required v0.98.1 gate. v0.105.x must execute the soak for final v1.0 qualification. ## Exit criteria - [ ] Trigger capture passes the exact-result and transaction-atomicity tests and is the only stable or automatic capture mode. - [ ] WAL polling and automatic WAL transition reject before slot consumption or frontier movement, including after upgrade from v0.97.0. - [ ] Every Graph V1 and Delta V1 public operation rejects before side effects, and capability discovery reports both contracts disabled and experimental. - [ ] Operational diagnostics and monitoring report only behavior that live PostgreSQL tests observe. - [ ] Active documentation, generated catalogs, and the authoritative release checklists match runtime behavior. - [ ] `tests/release/v0.98-qualification.json` passes its schema and completeness gate, contains exact commands and numeric thresholds, and has zero open P0 or P1 blocker entries. - [ ] The release workflow cannot publish when a required structured result is missing, skipped, unavailable, stale, or failed. ## Scope control Do not add SQL features, query forms, integrations, optimizer classes, or controller actions. Do not implement the work assigned to v0.100.0, v0.103.0, or v0.104.0. Conservative rejection is the v0.98 safety mechanism.