generated from coulomb/repo-seed
spec(SHARD-WP-0005 T5): cache freshness & invalidation protocol (§8.8)
Fixes C-2 (invalidation). Per-binding modes (event-driven push / validator poll / TTL), hybrid default, operational-envelope coupling (rate-limited shards must not poll-per-read), single-flight coalescing + batched bulk invalidation, freshness always represented in the provenance envelope. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -491,6 +491,39 @@ Its parameters (LSH band/row counts, shingle size, precision/recall) are tunable
|
||||
**false-negative rate of blocking** is a known, tracked limitation (§12) — blocking trades a
|
||||
small miss rate for tractability, and curator bindings are the escape hatch for misses.
|
||||
|
||||
### 8.8 Cache freshness & invalidation
|
||||
|
||||
Replication-projection caches remote shard content; cache invalidation is the actual hard part
|
||||
and was missing from the first draft (review C-2). The protocol is **per-binding, driven by the
|
||||
capability profile**, with one rule: **freshness is always represented, never assumed** — every
|
||||
cached page's provenance envelope carries `(observed-at, source-rev-if-known, staleness-state)`,
|
||||
so a consumer can always tell live from stale.
|
||||
|
||||
**Three invalidation modes, chosen by capability, not hard-coded:**
|
||||
|
||||
| Mode | When | Mechanism |
|
||||
|------|------|-----------|
|
||||
| **Event-driven (push)** | shard has `notify` | a change event invalidates exactly the affected entries and enqueues a delta refresh (§8.7); the preferred mode |
|
||||
| **Validator poll** | shard exposes ETag / Last-Modified / rev | conditional fetch (`If-None-Match`); cheap "still fresh?" checks without transferring bodies |
|
||||
| **TTL** | shard offers neither | time-bounded staleness; the floor mode (Oddmuse-class shards) |
|
||||
|
||||
Most real bindings are **hybrid**: event-driven for invalidation + a long TTL as a safety net
|
||||
for missed events + validator polls on read when an entry is past a soft age.
|
||||
|
||||
**Operational-envelope coupling.** The mode is constrained by axis-10: a **rate-limited** shard
|
||||
(Notion) *must* favour event-driven + long TTL and *must not* poll per-read — the freshness
|
||||
policy is capability-gated like everything else. A local file shard can watch the filesystem
|
||||
(near-instant invalidation, effectively event-driven for free).
|
||||
|
||||
**Thundering-herd / coalescing.** Concurrent reads of the same stale entry trigger a **single
|
||||
in-flight refresh** (single-flight); other readers await it or are served the stale-but-labelled
|
||||
value per policy. Bulk invalidations (a shard-wide event) are **batched and rate-shaped** to the
|
||||
shard's envelope rather than fired as N concurrent fetches.
|
||||
|
||||
**Staleness is a policy knob, not a correctness bug.** Whether a reader gets *stale-but-fast* or
|
||||
*blocks-for-fresh* is a §10 preset (per space or per request); either way the envelope tells the
|
||||
truth about what was served. This is union-without-erasure applied to time.
|
||||
|
||||
---
|
||||
|
||||
## 9. Cross-cut — Authorization (L5)
|
||||
|
||||
@@ -109,7 +109,7 @@ residual as open (→ T9).
|
||||
|
||||
```task
|
||||
id: SHARD-WP-0005-T4
|
||||
status: todo
|
||||
status: done
|
||||
priority: high
|
||||
state_hub_task_id: "eb885f03-2569-4ade-b3aa-174bc6062672"
|
||||
```
|
||||
|
||||
Reference in New Issue
Block a user