From 8b47a2e8d9da0da5a8755d01bc44a66ff43e735e Mon Sep 17 00:00:00 2001 From: Meta Vens Date: Thu, 22 Oct 2026 15:57:01 +0200 Subject: [PATCH] Caching: PersistedSchemaId and MarkWritten are internal for 2.0; Mesh single-file write guard in the CHANGELOG C2a's StoredVersion owns the same identity and deletes both. No consumer outside CultLib uses them, so they do not ship public in 2.0.0 and C2a's release is not a major. Co-Authored-By: Claude Sonnet 5.5 --- .../Contracts/cultcache-store-composition.md | 7 ++++--- src/GameCult.Caching/CultCache.cs | 6 +++--- src/GameCult.Caching/GameCult.Caching.csproj | 1 + unity/org.gamecult.cultlib/CHANGELOG.md | 16 +++++----------- 4 files changed, 13 insertions(+), 17 deletions(-) diff --git a/src/GameCult.Caching/Contracts/cultcache-store-composition.md b/src/GameCult.Caching/Contracts/cultcache-store-composition.md index 93bcd5f5..e23d491f 100644 --- a/src/GameCult.Caching/Contracts/cultcache-store-composition.md +++ b/src/GameCult.Caching/Contracts/cultcache-store-composition.md @@ -227,13 +227,14 @@ against what is durably on disk at that moment: `(key, schemaId, storedAt)`. Any insert, delete or replace fails it. Record identity for conditions is `(schemaId, storedAt)`, where `schemaId` is -the id the record is persisted under (`CultStoredDocument.PersistedSchemaId`), +the id the record is persisted under (the internal `CultStoredDocument.PersistedSchemaId`), not the one this cache decodes it as. A value change mints a `storedAt` strictly later than the record it replaces; writers bump a minted timestamp by one tick when it is not later. An entry loaded under compatible schema drift keeps its persisted id until its store rewrites it; a store records each -record its completed write rewrote with the protected instance method -`CacheBackingStore.MarkWritten`, which refuses an entry that is not the one +record its completed write rewrote with the internal instance method +`CacheBackingStore.MarkWritten` (the shipped stores call it; it is not part of +the public API), which refuses an entry that is not the one the store holds in its own `Entries` at that key. That guards against a store marking by mistake an entry it never held; a store that writes another copy into its own `Entries` and then marks it is trusted to have rewritten that diff --git a/src/GameCult.Caching/CultCache.cs b/src/GameCult.Caching/CultCache.cs index bc95ace9..124bea21 100644 --- a/src/GameCult.Caching/CultCache.cs +++ b/src/GameCult.Caching/CultCache.cs @@ -394,9 +394,9 @@ namespace GameCult.Caching /// The schema id this record is durably stored under, as its backing store last read or wrote it. It differs from /// only for a record loaded under compatible schema drift that its /// store has not rewritten since; a store records its rewrite of an entry it holds with . - /// Conditional commit compares this id and with the disk. + /// Conditional commit compares this id and with the disk. Internal to the shipped stores. /// - public string PersistedSchemaId => _persisted.SchemaId; + internal string PersistedSchemaId => _persisted.SchemaId; // The complete document. For a variant, the resolved view: derived, never written back. public object Document => _document ?? @@ -3333,7 +3333,7 @@ namespace GameCult.Caching /// /// is not the entry this store holds in /// at its key: a store marks only its own rewrite. - protected void MarkWritten(CultStoredDocument entry) + internal void MarkWritten(CultStoredDocument entry) { if (entry == null) throw new ArgumentNullException(nameof(entry)); diff --git a/src/GameCult.Caching/GameCult.Caching.csproj b/src/GameCult.Caching/GameCult.Caching.csproj index 7bc41ccc..c3ec80ae 100644 --- a/src/GameCult.Caching/GameCult.Caching.csproj +++ b/src/GameCult.Caching/GameCult.Caching.csproj @@ -9,5 +9,6 @@ + \ No newline at end of file diff --git a/unity/org.gamecult.cultlib/CHANGELOG.md b/unity/org.gamecult.cultlib/CHANGELOG.md index 90b8e819..c5b33142 100644 --- a/unity/org.gamecult.cultlib/CHANGELOG.md +++ b/unity/org.gamecult.cultlib/CHANGELOG.md @@ -76,20 +76,14 @@ All notable changes to this package are documented in this file. reading it. A store with no variant stays `cultcache.store.v1`, byte-identical to 1.0.x. CultMesh single-file reads, the directory store and CultNet refuse a variant record by name; only the C# CultCache resolves variants. +- `CultMesh.WriteSingleFileDocument` and `WriteSingleFileDocumentPayload` read the + file they replace, under the store's `.lock`, and refuse (without touching + it) a file this runtime cannot read, a store stamped with a newer format version, + or one holding any record besides the key being written. They used to replace the + file whole. Write to a store that holds several records through a `CultCache`. ### Added -- `CultStoredDocument.PersistedSchemaId`: the schema id a record is durably - stored under, as its backing store last read or wrote it. It differs from - `Descriptor.SchemaId` only for a record loaded under compatible schema drift - that its store has not rewritten since. -- `CacheBackingStore.MarkWritten(CultStoredDocument)` (protected instance - method): a backing store records that its completed durable write stored a - record under its descriptor, so `PersistedSchemaId` follows the rewrite. It - throws `ArgumentException` for an entry that is not the one the store holds - in its own `Entries`. The single-file and directory stores mark every record - they rewrite; a custom store calls it for each record its own write rewrote. - - Variants: a record that stores only its difference from a base record, resolved in memory when the cache admits it (`cultcache.store.v2`; see the persistence-format contract). A plain write at a variant's key is refused, and `Flatten` replaces a