Capability surfaces

Caching, post-enforcement.

Two-layer canonical model: foundational cache (raw KV with leases) and entity read cache (typed result projections). Post-enforcement ONLY — every cached read has already passed access evaluation, masking, decryption, and consistency gating. Anti-pattern #60 is absolute: no pre-enforcement entity cache, ever. Protected fields ride AEAD-wrapped envelopes with AAD bound to context.

The two layers

Foundational + entity read. One canonical bus.

Foundational cache

Raw KV with capability declarations. Two providers shipped: Redis (production, reuses canonical RedisConnectionHardening) and InMemory (opt-in, dev / test only — bootstrap NEVER falls back to InMemory implicitly).

Entity read cache

Typed result projections. Internal to EntityCore. Consumed by ReadCoordinator (hit/store) and WriteCoordinator (invalidate). Every cached read has already passed access evaluation.

AEAD-wrapped protected payloads

Opted-in protected entities ride a CachedPayloadEnvelope with AAD bound to tenant ‖ project ‖ entity ‖ keyFormat ‖ keyVersion. No plaintext fallback — missing key ring → store skipped + invariant metric.

EntityReadCacheGate

Centralized gate. Refuses transaction-scoped reads, non-ReadCommitted consistency, session-scoped reads, internal child reads, protected entities without opt-in. One canonical bypass authority.

4-tier generation composition

platgen + ggen + pgen + egen. O(1) namespace invalidation. Survives dormant providers via durable per-project sequences. The cache key encodes truth-affecting inputs only.

Real singleflight fill

TryAcquireFillLeaseAsync coordinates. Losers poll on capped exponential backoff and consume the winner's value. Lease-less providers degrade honestly to per-caller fill — never a dishonest contract.

Project-scoped bindings

CacheProviderBinding per project. Ancestry inheritance closer-ancestor-wins. Branchable, sandbox-able, scope-chain inherited like every other plane.

Cross-instance coherence

ICacheInvalidationBus. 21 distributed scopes. 13 caches subscribe — runtime compilers, surface compilers, schema cache, webhook endpoint cache, quota enforcement, plus the entity read cache itself.

Genesis-time root seeder

RootCacheBindingSeeder seeds the root project's Redis binding at deployment genesis. Operator opts out via Vadyl:Bootstrap:SeedRootCacheBinding=false. No host-global default cache.

Two-layer
Canonical model

Foundational + entity read

Post-only
Enforcement

Anti-pattern #60 absolute

AEAD
Protected payloads

AAD-bound to context

Real
Singleflight

Lease-coordinated, not best-effort

Caching that cannot leak.

Post-enforcement only. AEAD-wrapped where it matters. Real singleflight. Project-scoped with ancestry inheritance. Coherent across instances through the canonical bus.