"Append-only means a correction REMOVES what it invalidates; it never leaves it beside the replacement."
The apparent contradiction
The storage invariant says snapshots are append-only: metric history rows carry their series, date, value, source and fetch time, and are never rewritten. Then the same invariant says a correction deletes. Read quickly, those two sentences fight.
They do not, and resolving the tension is the most useful thing in this lesson, because plenty of teams get one half and lose the other.
What append-only is actually protecting
Append-only exists to stop silent in-place mutation of history. The failure it prevents is a value that used to be one thing and is now another, with nothing anywhere recording that it changed. That is the thing that makes a historical series untrustworthy: not that it was ever wrong, but that you can no longer tell whether what you are looking at is what was recorded.
So the rule is: you do not edit a row's value in place. New readings arrive as new rows. History accumulates rather than being revised.
What it is not
Append-only is not a rule that says every row ever written must remain forever, regardless of whether it is true. That reading turns the invariant into a machine for preserving known falsehoods — and in a store whose read model takes the newest row per series, a preserved falsehood is not an inert historical artifact. It is the answer the product gives.
Which is precisely what happened. The forward-dated rows were not "history we should keep for the record"; they described sessions that never occurred, and they sat at the front of the read model. Keeping them would have meant choosing an abstract purity over the product being correct.
What the repair looks like in practice
The repair for this incident was a named, dated script — not an interactive session with the database. That distinction matters more than it looks.
A script has three properties an ad-hoc fix does not: it states in code exactly which rows are being removed and on what criterion, it can be read by someone else before it runs, and it stays in the repository afterward as the record of what was done. When a later reader asks "why does this series have a gap in early August", the answer is a file with a name and a date, sitting in version control.