SIGN IN SIGN UP

feat(objectcache): carry a content checksum for conditional container-profile fetches (#941)

* feat(objectcache): carry a content checksum for conditional container-profile fetches

Lands the client half of the conditional container-profile fetch contract. It
is DORMANT: no in-tree ProfileClient implementer returns the sentinel, so no
conditional fetch has been or can be observed here, and there is no behavior or
byte-savings change. Green tests prove the contract compiles and that existing
behavior is unchanged — nothing more.

pkg/storage gains the shared vocabulary, deliberately out-of-band so
ProfileClient's signature is byte-identical and its checksum-unaware in-cluster
implementer changes by zero lines: a context key (WithKnownChecksum /
KnownChecksumFromContext) for the request, and ErrProfileUnchanged plus
ContainerProfileChecksumAnnotationKey for the response. The annotation key is a
string contract shared with an out-of-tree implementer and fails silently, not
loudly, if the two sides ever disagree.

CachedContainerProfile gains Checksum, populated at BOTH construction sites.
buildEntry matters as much as rebuildEntryFromSources: a profile that never
changes is built once and thereafter always fast-skips, so populating only the
rebuild path would leave the validator empty forever and make the optimization
silently inert for exactly the steady-state population it targets. On the
adoption path the value is corrected post-call from the pre-repoint learned CP,
mirroring the existing entry.RV = learnedRV fix, so the validator always
describes the object CPName points at.

refreshOneEntry offers the validator only under a five-conjunct guard — no
authored CP ref, no recorded authored RV, unchanged spec hash, a non-empty
stored checksum, and a cached state that has already reached Completed+Full.
The last conjunct is load-bearing: the lifecycle annotations sit outside the
content checksum, so a profile finishing its learning period presents an
unchanged checksum, and without it the entry would answer "unchanged" on that
tick and on every later one — freezing entry.State permanently. That state is
not internal bookkeeping; rulemanager gates HasFinalApplicationProfile on
Completed+Full and stamps FailOnProfile from it, so a frozen state would keep
alerting a finished profile as partial forever. Unlike the RV staleness below,
that staleness would never self-correct.

The validator is attached per call, never to the shared context, so the
authored-CP fetch can never receive the learned CP's checksum. The projection
spec is snapshotted once above the fetch and reused, which moves detection of a
spec swap landing mid-fetch to the next tick; that is self-healing.

One accepted, tested divergence remains: a checksum match proves content
identity, not ResourceVersion identity, so on the sentinel path e.RV may lag a
metadata-only write until the next unconditional fetch. That one is bounded and
self-correcting, which is why it is accepted where the state freeze is not.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01HnqMRD3r2kGYUBTxMHM5vi
Signed-off-by: Matthias Bertschy <matthias.bertschy@gmail.com>

* fix(containerprofilecache): harden conditional refresh

Validate conditional responses against the exact request, re-read projection state after fetch, and force periodic full bodies. Serialize ticker and nudge refreshes through a trailing-edge scheduler and expose bounded request/response metrics with regression coverage.

Co-Authored-By: Claude Code <noreply@anthropic.com>
Signed-off-by: Matthias Bertschy <matthias.bertschy@gmail.com>

---------

Signed-off-by: Matthias Bertschy <matthias.bertschy@gmail.com>
Co-authored-by: Claude Sonnet 5 <noreply@anthropic.com>
M
Matthias Bertschy committed
349c642e64197e279422f36ba68fbbe4a4ccf941
Parent: a327e76
Committed by GitHub <noreply@github.com> on 9/8/2026, 1:27:25 PM