Skip to content

v1.108.180 — unknown freshness stops collapsing into fresh

Choose a tag to compare

@jgravelle jgravelle released this 26 Jul 17:06

Item 4 of the #377 post-ship review by @mightydanp: unknown freshness must not collapse into fresh.

FreshnessProbe.repo_is_stale is a Boolean, and a Boolean has nowhere to put "I could not find out". It returned False when the SHAs matched and also when either of them was missing, and the verdict rendered False as channels.index: "fresh". An index whose freshness had never been established was claiming current-snapshot equivalence, and every absence gate downstream trusted a comparison that was never made.

Four states now, and only one of them is proof:

fresh        the indexed revision equals the live one
stale        they differ
unknown      the subject HAS a revision we could not read
not_tracked  the subject has no revision at all

unknown and not_tracked get opposite treatment, on purpose. unknown is a capability we have, failing — git absent, the source root moved, the index stored no SHA — so a zero-result scan is degraded and the absence claim is refused. not_tracked is a capability the subject does not support: a plain indexed folder has no revision and never will, so it is disclosed and the absence stays citable. That is the call jDataMunch made in v1.26.0 for freshness it cannot model. Refusing instead would strip absence evidence from every folder index over a limitation that is permanent, already stated, and unrelated to whether the target exists.

A subdirectory of a checkout is tracked by the checkout above it, so the trackability test walks up the way git does; otherwise every monorepo subdir index would understate to not_tracked.

Precedence is rebuilding > partial > stale > unknown / not_tracked > fresh: a known lag is worse than an unestablished one, and both beat proven currency. Disclosed on every state, refused only for the absence claim, with the refusal naming the failed capability.

Zero blast radius for a producer that passes nothing: build_verdict without freshness= keeps its exact previous behavior, and an unrecognized value is ignored rather than propagated. The channels.index enum is closed in the published schema, so both new values are published there.