Stage short-lived `'use cache'` entries correctly in dev (#94645)
When the streaming dev render defers a short-lived `'use cache'` entry
to a later stage (a `revalidate` of zero or a short `expire` excludes it
from the static shell, a short `stale` time excludes it from the runtime
prefetch shell), it previously left the cache signal read open. At a
staged rendering task boundary that open read looked like a pending
cache read, so even a warm handler hit was counted as a cache miss,
lighting the cold-cache indicator and routing validation through the
background warm render. We now end the cache signal read as soon as such
an entry is deferred, the same as the prerender path already does, and
serve the buffered value through a plain stream instead of one tracked
by the cache signal, so a warm short-lived hit is no longer mistaken for
a miss. A deferred entry can still turn out to be stale and need
regenerating (for instance, a cache handler may return a past-`expire`
entry), so the regenerate path re-begins the read before generating,
keeping the signal balanced against the regeneration's own end of the
read rather than over-decrementing it.
The runtime-prefetch exclusion for a short stale time must only apply
when the render actually produces the runtime prefetch shell, which is a
property of the request rather than the cache entry. An initial HTML
load, a plain client navigation, and an HMR refresh all produce the
static shell, where a short-stale entry stays, mirroring the static
prerender. A client navigation into a runtime-prefetch route produces
the runtime prefetch shell, where it is excluded, mirroring the
`prerender-runtime` prerender. We thread the render's shell stage onto
the request store, and onto the warm validation render that mirrors it,
and gate the stale-based deferral on `shellStage === Runtime`. This
preserves the build-time asymmetry where a short stale time is omitted
from the runtime prefetch but not from the static shell.
A new `short-stale-cache` fixture and warmup test exercise this
asymmetry directly: a `'use cache'` entry with a short stale time but a
long expire resolves in the static stage on an initial load and on a
navigation without runtime prefetch, and only resolves dynamically on a
navigation into a runtime-prefetch route. The previously skipped
short-lived warmup case is re-enabled, and the cache-indicator
short-lived case now asserts the cold-cache badge on a cold load but not
on a warm reload. Those fixtures use a long `revalidate` so the entry
stays a fresh hit for the duration of the test, isolating them from the
in-memory handler dropping the entry at `revalidate`; that workaround
can be dropped once the cache handler serves stale entries in dev.