Warm a receipt decision, change a merchant feature and policy threshold, then verify no stale route survives a regional switch.
Project: prove receipt prediction-cache identity across releases
Choose what the cache stores
Cache the final receipt route for a short bounded window, with tenant, request digest, feature revision, model digest and policy revision in the key. Record creation time, expiry and source decision ID. The same receipt bytes can produce a different route after merchant data or threshold changes, so bytes alone are insufficient. The cache identity must include every input that changes the final decision. Keep a separate idempotency record for a client retry of one logical request.
Force two invalidations
Warm a clear result, then advance the merchant feature revision while leaving model and policy unchanged. The old entry must miss and the next decision must use fresh features. Restore the feature revision in a new test and change only the review threshold; again the final route entry must miss. Keep the original model digest constant so the test isolates feature and policy behavior. The invalidation matrix states expected miss reasons before the test runs.
Switch regions and compare
Populate a standby-region cache with the old entry. Fail traffic over after the current region has the new approved feature watermark and policy revision. The standby must reject its old entry even if the raw request and tenant match. Recompute or route to manual review if its feature state is too old. Failover checks prevent a healthy standby endpoint from silently serving a stale cached route.
Publish the outcome
Report hit and miss counts, stale rejections, recompute latency, decision digests, expiry settings and any divergent routes. Compare a small fresh-recompute sample with cache hits. State the maximum feature age covered by the cache and who owns changing it. A result that saves model calls but reuses an old decision fails. Link the result to feature freshness and policy change control so both release processes exercise this cache test.
Implementation
def cache_release_check(warm_entry, current_identity, now_seconds):
if now_seconds >= warm_entry["expires_at"]:
return "recompute:expired"
for field in ("tenant", "request_digest", "feature_revision",
"model_digest", "policy_revision"):
if warm_entry[field] != current_identity[field]:
return "recompute:" + field
return "reuse"
warm = {"tenant": "merchant-47", "request_digest": "req-82",
"feature_revision": "f3", "model_digest": "risk-47",
"policy_revision": "p4", "expires_at": 1082}
identity = {key: value for key, value in warm.items() if key != "expires_at"}
assert cache_release_check(warm, identity, 1047) == "reuse"
assert cache_release_check(warm, {**identity, "feature_revision": "f4"},
1047) == "recompute:feature_revision"
Performance and operating cost
The identity comparison is O(f) time and O(1) extra space for f fields. Recompute misses increase inference load during a model or policy rollout; reserve capacity for that surge. Testing both regions consumes additional cache storage and traffic, but the cost is bounded compared with silently serving decisions under an outdated feature or policy.
Common Mistakes
- Reusing a final route after only the policy threshold changes.
- Testing invalidation only in the primary region.
- Making a cached score and a cached decision share one key format.
- Counting lower inference cost as a success despite route divergence.
Read next
- Prediction caches: key by every input that changes the decision
- Cache invalidation tests for model, feature and policy changes
- Project: keep receipt scoring safe during feature publication lag
- Project: release a receipt threshold with review evidence
- Region failover for inference: match model and feature state
