diff --git a/src/GameCult.Caching/Contracts/cultcache-store-composition.md b/src/GameCult.Caching/Contracts/cultcache-store-composition.md index 030668a1..e0521079 100644 --- a/src/GameCult.Caching/Contracts/cultcache-store-composition.md +++ b/src/GameCult.Caching/Contracts/cultcache-store-composition.md @@ -239,13 +239,14 @@ no serialization; a CultMath encoding, if added, uses this shape. |---|---|---|---|---| | One home store, no mirrors | implemented | implemented (exact type ids; `add_backing_store` returns `Err` on a second generic store or a claimed type; an empty type list is the generic store) | implemented (exact type ids; `addBackingStore` throws on a second generic store or a claimed type; no types is the generic store) | implemented (exact type ids; `add_backing_store`/`add_generic_store` raise on a claimed type or a second generic store; an empty type list is the generic store) | | Zero stores is in memory | implemented | implemented | implemented | implemented | -| Home cannot move after admission | implemented | implemented (`add_backing_store` returns `Err` and attaches nothing) | implemented (`addBackingStore` throws and attaches nothing) | implemented (`add_backing_store`/`add_generic_store` raise and attach nothing) | -| Refused at load when not home | implemented | implemented (`pull_all_backing_stores` returns `Err` naming key and both stores; admits nothing) | implemented (`pullAllBackingStores` throws naming key and both stores; admits nothing) | implemented (`pull_all_backing_stores` raises naming key and both stores; admits nothing) | +| Home cannot move after admission | implemented | implemented (`add_backing_store` returns `Err` and attaches nothing) | implemented (`addBackingStore` rejects and attaches nothing; it runs in the cache's serial queue, so it cannot move a write that is in flight) | implemented (`add_backing_store`/`add_generic_store` raise and attach nothing) | +| Refused at load when not home | implemented | implemented (`pull_all_backing_stores` returns `Err` naming key and both stores; `load_soa` returns `Err` for a type with no home once a store is attached; both admit nothing and leave the prior view intact) | implemented (`pullAllBackingStores` throws naming key and both stores; admits nothing) | implemented (`pull_all_backing_stores` raises naming key and both stores; admits nothing) | +| Refused write changes neither store nor cache | implemented | implemented (`put`, `put_envelope`, `put_raw_envelope`, `put_prepared_batch` and `delete` validate before the store call and apply infallibly after it; there are no user accessors) | implemented (home, `__global__` key and name and index accessors run before the store call; overwrite and delete use lookup values stored at admission; attach, pull, registration, writes and deletes run through one per-cache promise queue) | implemented for one caller at a time (same validation order and stored lookup keys as TypeScript; the cache takes no lock, so concurrent threads are not serialized) | | Attach hydrates; loading never writes | implemented | attach does not read (call `pull_all_backing_stores`); pull loads without writing | attach does not read (call `pullAllBackingStores`); pull loads without writing | attach does not read (call `pull_all_backing_stores`); pull loads without writing | | Runtime type decides schema | implemented | n/a (explicit type ids) | n/a | n/a | | Assignable lookups and watches | implemented | exact type ids | exact type ids | exact type ids | -| Globals never invented, singleton | implemented | no globals | single `__global__`; a write with a new key replaces it; refused only on pull; invents nothing | single `__global__`, invents nothing | -| Explicit batch commit | implemented | `put_prepared_batch`, one store, all-or-nothing | not implemented | `put_envelopes`, one type per call, not all-or-nothing | +| Globals never invented, singleton | implemented | no globals | single `__global__`; a write under any other key is refused before any store is touched; replacing writes `__global__` in place; a second persisted global is refused on pull; invents nothing | single `__global__`; `put`, `put_envelope` and `put_envelopes` refuse any other key before any store is touched; a second persisted global is refused on pull; invents nothing | +| Explicit batch commit | implemented | `put_prepared_batch`: staged records must share one home; that store receives one `push_all` of its own held records plus the batch; empty key or `stored_at` refused first; all-or-nothing | not implemented | `put_envelopes`, one type per call; every record validated before one `push_all`, applied only after the store accepts; atomicity on disk is the store's `push_all` | | Conditional commit | implemented | store-level `compare_exchange` family | not implemented | not implemented | | Per-assembly options, value-type arrays | contract | n/a | n/a | n/a |