# The revision record — what the feed said first, against what it settled on

**Since:** 2026-10-31, over `reference_evaluations` (migration 219; the record begins 2026-10-28). **Logic:** `lib/determination/reference/revisions.ts`. **Reader:** `GET /api/v1/verification/revisions[?month=YYYY-MM]` (public), a section on `/track-record`. No table of its own: it is a reading of the evaluation rows.

## Why this is a new quantity

ComCat revises an earthquake's magnitude, epicenter and depth for hours after the first report and serves only the settled solution afterward; the operational sequence — what the feed said at 00:05, at 00:20, at 02:00 — is not published. A parametric term that settles on the first report carries that revision as unpriced risk, and nobody has been able to measure it, because nobody kept the sequence. The as-issued archive keeps every body the all-day feed served, and the reference catalog reads each one at receipt, so the sequence is now a table: one row per body per event, in receipt order, with the reading it carried.

This record is the error model of the operational feed that follows: per first-report magnitude band, how often the reading moved, by how much and in which direction, how fast it settled, how far the epicenter moved — and the number a structurer needs: of the first reports that landed near a threshold, how many ended on the other side of it.

## Definitions

- **First** is the first body of the event the archive received (`is_first_report`). An event whose first body predates the archive has no first report here and is counted only under `events_without_first_report`.
- **Latest** is the most recent body; **settled** is the latest body ComCat marked `reviewed`, when there is one. All three are the feed's preferred origin as served, to 0.01.
- **Band** is by the first-report magnitude — the number a first-report term settles on.
- **Thresholds** are the catalog's tiers (M6.0, 6.5, 7.0) and lower marks (2.5, 3.0, 4.0, 4.5, 5.0) that show the feed's behaviour before a large event arrives. A reading **crossed** a threshold when it ended on the other side of the mark from where it started; a first report is **near** a threshold when within 0.3 of it.
- **Hours to latest** runs from the first body's receipt to the latest's; **hours to settled** to the reviewed one.

## What it does not say

- The feed is polled every five minutes; a revision served and replaced within one interval is not seen. The record is a lower bound on how often the feed moved.
- Shares are of the record, not probabilities. The record is young and most of it is small earthquakes; the catalog's tiers have no events near them yet.
- USGS only. NHC advisories are successive forecasts, not revisions of one reading; their first-report question is different.
- Nothing here says a revision was wrong. ComCat's later solution is better; the point is what a first-report term would have paid before it existed.

## Citing a month

**Since:** migration 227 (written 2026-10-31). **Table:** `revision_extracts`. **Logic:** `lib/determination/reference/extract.ts`. **Worker:** `revision-extract`, the 8th of each month at 03:10Z. **Reader:** `GET /api/v1/verification/revisions/extract[?month=YYYY-MM[&format=csv]]`.

The figures above move as the feed revises, so they cannot be cited. A closed month is therefore **frozen** once, a week after it closes (`SETTLE_DAYS`, so the last events' late revisions are in): one CSV of every earthquake whose first report the archive received that month — `source_event_id, place, bodies, first_magnitude, latest_magnitude, settled_magnitude, delta, abs_delta, first_received_at, latest_received_at, hours_to_latest, hours_to_settled, reviewed, deleted, epicenter_km, depth_delta_km, crossed` — sorted by event id, RFC 4180, LF line ends, no metadata inside the file, so its hash is the data's. The table is append-only; a corrected method is a new `extract_version` and a new row beside the old.

The extract's id is `cre1-` + the SHA-256 of the CSV bytes. The daily determination-log digest seals that id beside the day's determination ids (the third `DIGEST_SOURCES` entry), so the month sits under a published Merkle root that is itself independently timestamped (`docs/digest-anchoring.md`). What a reader can show, with nothing from Calchis but the file: its hash equals the id (`sha256sum`), the id is under the root (`sealed.proof`), the root existed by the block's time (`sealed.anchor`).

The statement a citation names: `calchis-revision-extract/1 <YYYY-MM> <method_version> <extract_version> <sha256> <rows>`.

A **DOI** (Zenodo or similar) for a frozen extract is an outward publication of the same file with this document as the methods note; it is the operator's decision, and the file to deposit is the CSV at the URL, unchanged.

## Verifying

```sql
WITH e AS (
  SELECT source_event_id, magnitude, is_first_report, review_status, received_at,
         row_number() OVER (PARTITION BY source_event_id ORDER BY product_row_id) AS rn,
         count(*) OVER (PARTITION BY source_event_id) AS n
  FROM reference_evaluations WHERE product = 'usgs_comcat' AND unreadable_reason IS NULL)
SELECT f.source_event_id, f.magnitude AS first, l.magnitude AS latest, round(l.magnitude - f.magnitude, 2) AS delta,
       round(extract(epoch FROM (l.received_at - f.received_at))/3600, 2) AS hours
FROM e f JOIN e l ON l.source_event_id = f.source_event_id AND l.rn = l.n
WHERE f.rn = 1 AND f.is_first_report ORDER BY abs(l.magnitude - f.magnitude) DESC LIMIT 20;
```
