# PostgreSQL old snapshots across heap replacement

Controlled native research for Hesela scope #5083, 2026-11-13.
Native evidence and reproduction method. Publication status is tracked separately
in the repository; this packet makes no deployment or external-review claim.

## Result

A PostgreSQL 16.15 Repeatable Read reader, whose snapshot was established on
another table, saw zero rows after a committed integer-to-bigint heap rewrite,
although fresh reads still returned both original rows. After TRUNCATE plus
ordinary reload it also saw zero rows. Changing the reload to COPY FREEZE
made the same kind of old snapshot see the replacement row while it retained
the old marker from the other table.

These are reproductions and a connected explanation of documented operation
exceptions, not a newly discovered defect. See synthesis.md, results-table.md,
summary.json and the full SQL/result events in capture-1.json/capture-2.json.

## Reproduce

Requirements: Linux, an unprivileged account, Python 3 standard library, libpq,
and PostgreSQL 16.15 server binaries. No Python dependencies or existing server.
From this directory:

    python3 -B probe.py --bindir /path/to/postgresql/bin --output replay.json
    python3 -B verify.py capture-1.json capture-2.json replay.json
    python3 -B -m unittest -v test_evidence.py test_review.py
    python3 -B -O -m unittest -v test_evidence.py
    python3 -B derive.py --check

The verifier intentionally restricts version scope to 16.15. Other releases
need a separately reviewed capture/protocol, not removal of the version check.
The recorded package is Ubuntu 16.15-0ubuntu0.24.04.1. It is not asserted to be
the newest release or a byte-identical upstream source rebuild. The official
REL_16_15 tag resolves to the commit recorded in sources.json.

The harness never accepts a DSN or a preexisting database directory. Each run
creates a fresh checksum-enabled cluster with private Unix socket and no TCP.
fsync, synchronous_commit and full_page_writes are checked as on. Each case
uses a fresh schema; all fixture tables are synthetic. Approximately 100 MiB
of temporary storage is needed. Statements time out after 5 seconds and lock
requests after 200 ms. The latter is a bounded failure control, not a latency
benchmark. Connections close before the owned cluster is stopped and removed.
An unstopped cluster is retained rather than deleting its data.

The provider used in this workspace was:
 /srv/cgpt-workspace/artifacts/aio-pg-page-contract-20261018/pg/usr/lib/postgresql/16/bin
It was reused read-only, not installed or modified. Captures contain binary,
runner and fixture hashes plus SQLSTATEs, table-lock witnesses, heap identities,
native events, engine version, settings, timestamps and shutdown confirmation.

## Evidence and sources

Two final runs on the same host/build each execute twelve prescribed cases.
The second uses Python -O. This establishes repeatability, not independent
replication or a population estimate. No confidence interval is appropriate.

verify.py checks the raw event bindings, schedules, version, exact results,
lock/heap witnesses and script identities. The 18 unittest methods include
16 evidence mutations; each starts by accepting the untouched capture.
These checks detect drift and selected corruptions, not malicious fabrication.
derive.py generates summary.json and results-table.md without hand-entered results.

sources.json contains six primary-source receipts pinned to PostgreSQL commit
7d3e000c5961a544302072058a1184e9a588837b. fetch_sources.py can fetch another
receipt and a new private source directory; it refuses existing destinations.
Upstream documents/source are linked, not included in the review packet.
The libpq adapter follows the existing Hesela read-committed-native harness;
it introduces no third-party library or new license for repository content.

## Integration

Deepen the existing storage-consistency-ordering analysis and the existing
repeatable-read-isolation note (#5074); insertion.md supplies proposed prose.
Do not add a competing analysis or change a stable definition. Existing
snapshot-horizon work examines row-version cleanup, while this packet covers
heap replacement and frozen import. Existing Read Committed work examines
conflict arbitration. Those are complementary boundaries, not substitutes.

External review, paired site integration, public evidence downloads,
metadata/full-text-export coverage, build and browser acceptance remain.
No production or SEO-effect claim follows from these research checks.

## Offline packet

Run `python3 -B pack.py --export /new/packet-directory` to generate sixteen
assets, including a deterministic ZIP and SHA-256 manifest. Add `--check` to
compare an existing export byte-for-byte. The ZIP contains the method, synthesis,
two original captures, derived results, source receipts and executable tests.
Extract it into an empty directory and run the commands above without a checkout.
Hash matching detects changed bytes; it is not an authenticity signature.
