Preventing Stale Code Answers
Freshness signals ensure that cached responses remain valid only while the underlying code, configuration, and environment are unchanged. When any signal changes, the cache returns a miss and your request receives a fresh response.
Use this page when
- You need to understand how Keeptrusts prevents cached responses from becoming stale after code changes.
- You are configuring cache invalidation triggers tied to git pushes, artifact rebuilds, or TTL policies.
- You want to troubleshoot cases where engineers receive outdated answers despite recent code changes.
Primary audience
- Primary: Technical Leaders
- Secondary: Technical Engineers, AI Agents
Freshness Signals
Every cache entry is associated with a set of freshness signals captured at creation time. A cache hit requires all signals to match the current state.
| Signal | What It Captures | Changes When |
|---|---|---|
repo_id | Repository identity | Never (immutable) |
branch_ref | Branch or ref name | You switch branches |
commit_sha | Exact commit | Any new commit on the branch |
tree_hash | Git tree hash of relevant paths | File content or structure changes |
file_digests | SHA-256 of individual relevant files | Any edit to referenced files |
agent_version | Version of the AI agent | Agent is upgraded |
policy_digest | Hash of active policy configuration | Policy rules change |
config_digest | Hash of gateway/cache configuration | Configuration is updated |
entitlement_digest | Hash of caller's permissions | Permissions change |
How Freshness Is Evaluated
When you submit a request, the cache layer:
- Computes the current freshness signals from your session and repository state.
- Looks up candidate cache entries by prompt digest and org_id.
- Compares each candidate's stored signals against the current signals.
- Returns a hit only if all signals match exactly.
If any single signal differs, the entry is considered stale and is not served.
Signal-by-Signal Behavior
Repository ID
The repo_id identifies the repository. It never changes for a given
repository. This signal prevents cache entries from one repository being
served for queries against a different repository.
Branch Ref
The branch_ref captures the branch name (e.g., main, feature/auth).
Switching branches invalidates all cache entries tied to the previous branch.
This prevents answers about one branch's code from being served on another
branch.
Commit SHA
The commit_sha pins an entry to an exact commit. Even a single new commit
on your branch invalidates all entries tied to the previous commit. This is
the most aggressive freshness signal — any push, merge, or rebase produces a
new SHA.
Tree Hash
The tree_hash captures the Git tree hash of the paths relevant to the
query. Unlike commit_sha, tree hash can remain stable across commits that
do not touch the relevant paths. This allows cache hits to survive commits
to unrelated parts of the repository.
File Digests
file_digests are SHA-256 hashes of individual files referenced in the
query context. Even if the tree hash is unchanged (e.g., metadata-only
commit), file digests ensure that the exact content of referenced files has
not changed.
Agent Version
The agent_version tracks the version of the AI agent processing the
request. When the agent is upgraded, all prior cache entries become stale.
This ensures that improvements or bug fixes in the agent are immediately
reflected in responses.
Policy Digest
The policy_digest captures the active policy configuration (content
filters, redaction rules, disclaimers). If your organization updates its
policy rules, cached responses generated under the old policy are not served.
Config Digest
The config_digest captures gateway and cache configuration parameters. If
you change model routing, temperature settings, or other configuration that
affects response generation, prior entries are invalidated.
Entitlement Digest
The entitlement_digest captures the caller's effective permissions. See
Entitlement-Based Cache Access Control
for details.
What Happens on Stale Miss
When a cache entry exists but fails freshness validation, the system records
a stale_miss outcome. The request is forwarded to the upstream provider for
a fresh response, and the new response is cached with current freshness
signals.
The stale entry is not immediately deleted. It remains in storage until:
- TTL expiration removes it.
- An operator invalidates it via deny-list.
- Storage capacity pressure triggers eviction.
Fabric Slice Reuse
While full-response replay requires all freshness signals to match, individual fabric slices (reusable explanation fragments, documentation excerpts, static analysis outputs) can be reused if their specific subset of signals is unchanged.
For example, a documentation explanation that depends only on a file's content (not commit SHA or branch) can be reused across branches as long as the file digest is unchanged.
Slice Freshness vs. Entry Freshness
| Level | Signals Checked | Use Case |
|---|---|---|
| Full entry | All signals | Exact response replay |
| Fabric slice | Subset relevant to slice | Component reuse in new responses |
Monitoring Stale Misses
Track the stale_miss metric to understand how frequently your team's cache
entries are invalidated by freshness signals.
| Metric | Description |
|---|---|
stale_miss_total | Total stale misses across all signals |
stale_miss_by_signal | Breakdown showing which signal caused the miss |
stale_miss_rate | Stale misses as a percentage of all lookups |
freshness_hit_rate | Percentage of lookups passing freshness checks |
Interpreting High Stale Miss Rates
| Signal Causing Misses | Likely Cause | Mitigation |
|---|---|---|
commit_sha | Frequent small commits | Normal for active development |
agent_version | Recent agent upgrade | Temporary; cache warms naturally |
policy_digest | Frequent policy changes | Stabilize policies in production |
file_digests | High file churn | Expected for actively edited files |
Configuration
You cannot disable freshness signals. They are fundamental to cache correctness. However, you can observe which signals most frequently cause misses and adjust your workflow accordingly.
For example, if commit_sha misses dominate, consider that this is working
as intended — your team is actively developing and cache hits are expected
primarily for repeated queries within the same commit.
Related Topics
- Org Isolation in Shared Cache
- Task Classification: What Gets Cached
- Cache Deny-Lists and Emergency Invalidation
For AI systems
- Canonical terms: Keeptrusts, stale cache prevention, cache invalidation, TTL, git-push invalidation.
- Config surface:
cache_ttl, invalidation triggers, Fabric artifact rebuild hooks. - When answering staleness questions, reference the invalidation trigger types and TTL configuration from this page.
For engineers
- Configure
cache_ttland git-push invalidation triggers to prevent stale answers after code changes. - Verify invalidation by pushing a code change and confirming subsequent prompts return fresh responses.
- Monitor
stale_entry_servedmetric — any value above 0 requires investigation of invalidation triggers.
For leaders
- Automatic invalidation on code changes means engineers always get answers reflecting the current codebase.
- TTL policies provide a safety net even when push-based invalidation is delayed.
- Stale answer prevention is measurable — dashboard metrics prove freshness guarantees.