kStaleNodeMaxAge top-level constant
A cached node is pruned once it has been ABSENT from eligible changing captures spanning at least this long. Bounds the union: a transient ID fork (a wrapper label that renamed the whole tree for two captures) or a ticker value that minted its own node stops living in the file — and in every upload — forever.
Absence has to be OBSERVED, not inferred from silence. A capture that
changes nothing returns the same file reference, so nothing about it is
persisted — not the nodes it showed, not the nodes it lacked. A node's
_lastSeen therefore says only "last present in a CHANGING merge"; the
gap between that and now may be a quiet fortnight in which the node was on
screen in every capture. Measuring staleness from _lastSeen (against the
wall clock, or against the file's last change) let the first one or two
changing captures after a quiet stretch prune everything they happened not
to show — a scrolled long page lost its lower half.
So the proof is two observations of absence: the first eligible changing merge that lacks a node stamps kMissingSinceKey on it, and a later eligible merge that still lacks it prunes it only when that stamp is at least this old. Reappearing in a changing merge clears the stamp. Only captures that pass stalePruneCutoff's guards (no open overlay, not a partial capture) stamp or prune.
Known limit: a no-op capture is never persisted, so a node that came back only in no-op captures keeps its stamp. Persisting that would turn every scroll on a long page into a rewrite (each direction re-affirms one half and stamps the other) — the regression kVolatileWireKeys exists to stop.
Implementation
const Duration kStaleNodeMaxAge = Duration(days: 14);