# Results (measured)

Measured on 2026-11-12, PostgreSQL **16.15 (Homebrew)**, disposable single-node cluster
(`initdb --locale=C --encoding=UTF8`), unix socket only, port 54329, deleted on exit. One psql
session, serial statements. Full raw transcript: [results-transcript.txt](results-transcript.txt).
Reproduce with `bash run.sh` (see [run.sh](run.sh), [experiment.sql](experiment.sql)).

These are the recorded outputs, not predictions. Interpretation is in [FINDINGS.md](FINDINGS.md).

## Phase 0 — after backfill

```
 id | label | minutes | duration_minutes
----+-------+---------+------------------
  1 | a     |      60 |               60
  2 | b     |      30 |               30
  3 | c     |      45 |               45
drift_rows (IS DISTINCT FROM) = 0
```

## After the legacy writer acts (W1 update id=1 → minutes 90; W2 insert id=4 → minutes 120)

Raw state:

```
 id | label | minutes | duration_minutes
----+-------+---------+------------------
  1 | a     |      90 |               60      <- W1: minutes moved, new column stale
  2 | b     |      30 |               30
  3 | c     |      45 |               45
  4 | w2    |     120 |            (null)      <- W2: new column never written
```

## Strategy A (new-column-only) vs Strategy B (old-authoritative)

```
 id | label | authoritative (B=minutes) | a_sees (duration_minutes) | a_is_correct
----+-------+---------------------------+---------------------------+--------------
  1 | a     |            90             |            60             | f
  2 | b     |            30             |            30             | t
  3 | c     |            45             |            45             | t
  4 | w2    |           120             |          (null)           | f
```

Strategy A was wrong on **2 of 4** rows (the W1 row: 60 instead of 90; the W2 row: NULL instead of
120). Strategy B returned the correct value on **4 of 4**.

## Drift measurement — `IS DISTINCT FROM` vs plain `<>`

```
drift_rows_is_distinct = 2        (rows 1 and 4)
drift_rows_plain_neq   = 1        (row 1 only; row 4 NULL<>120 is UNKNOWN, so not counted)
```

Per-row flags:

```
 id | duration_minutes | flagged_by_is_distinct | flagged_by_plain_neq
----+------------------+------------------------+----------------------
  1 |        60        |           t            |          t
  4 |      (null)      |           t            |        (null)
```

## Strategy C in the wrong order — reconcile while the writer is still active

```
drift_after_reconcile_only       = 0      (momentarily clean)
-- then one more legacy write lands: W3 UPDATE id=2 SET minutes = 75
drift_reconcile_raced_writer     = 1      (row 2 re-diverged)
```

## Strategy C in the right order — retire the writer, then reconcile

```
drift_after_retire_then_reconcile = 0
```

A and B agree on every row afterward:

```
 id | label | b_value (minutes) | a_value (duration_minutes) | a_matches_b
----+-------+-------------------+----------------------------+-------------
  1 | a     |        90         |            90              | t
  2 | b     |        75         |            75              | t
  3 | c     |        45         |            45              | t
  4 | w2    |       120         |           120              | t
```

## Environment / disposal checks

- `postgres --version` → `postgresql (PostgreSQL) 16.15 (Homebrew)`.
- After the run: no `pg-rollback-lab.*` temp dir remained; `pgrep postgres` found nothing;
  `brew services list` showed `postgresql@16  none` (Homebrew's default cluster was never started).
