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