The old refresh trigger was the some→none transition of the
/api/graph/status poll — with parallel runs under the serialized
audit, run A's merge landed while B was still queued, but the feed
still held B, so nothing refreshed until B finished too: both runs'
nodes appeared in one batched reveal (owner's live-test finding,
2026-09-28). The ledgers were correct the whole time (each merge is
a synchronous append inside the gate; the serialization test pins
B's auditor seeing A's node) — only the reveal was batched.
Now: refetch the snapshot whenever a run DISAPPEARS from the feed
(finished / aborted / failed). A run leaves the registry only after
its merge + settle + usage persist complete, so disappearance
implies the graph change is already on disk; each run surfaces
within poll latency (~2s). Redundant fetches on aborted runs are
free — the deletion-refresh doctrine. The costs pill follows the
same disappearance rule (usage persists per run). Confirmed the
status pills already render the raw phase, so the 'waiting' stage
displays as Waiting with no change.