LAST_VALUE with an ORDER BY and no frame returns the current row rather than the last one, which is correct by the specification and is never what anybody wants.
-- returns the CURRENT row's value, every time
LAST_VALUE(status) OVER (PARTITION BY order_id ORDER BY changed_at)
-- what people mean
LAST_VALUE(status) OVER (
PARTITION BY order_id ORDER BY changed_at
ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING
)
-- or, more readably, FIRST_VALUE with the order reversed
The default frame with an ORDER BY runs from the start of the partition to the current row, so the last row in that frame is the current one — the function is doing exactly what it was asked. FIRST_VALUE with a descending order says the same thing in fewer words and is what I would write. This is the most reliably confusing thing about window functions and it produces a report that is plausible and wrong.