diff --git a/Assets/Scripts/ServerShared/CultCache/CultCache.cs b/Assets/Scripts/ServerShared/CultCache/CultCache.cs index e8b494c62..0f143c586 100644 --- a/Assets/Scripts/ServerShared/CultCache/CultCache.cs +++ b/Assets/Scripts/ServerShared/CultCache/CultCache.cs @@ -38,7 +38,7 @@ public class CultCache if (type.GetCustomAttribute() != null) { _globals[type] = null; - Add(Activator.CreateInstance(type) as DatabaseEntry); + AddInternal(Activator.CreateInstance(type) as DatabaseEntry); } } } @@ -56,7 +56,7 @@ public class CultCache } store.EntryAdded.Subscribe(entry => { - Add(entry, store); + AddInternal(entry, store); }); } @@ -67,6 +67,14 @@ public class CultCache } public void Add(DatabaseEntry entry, CacheBackingStore source = null) + { + if (ReadOnly && source == null) + throw new InvalidOperationException("Legacy CultCache is read-only. Durable state belongs to the Verse state spine."); + + AddInternal(entry, source); + } + + private void AddInternal(DatabaseEntry entry, CacheBackingStore source = null) { lock(addLock) { @@ -102,9 +110,12 @@ public class CultCache public void AddAll(IEnumerable entries) { + if (ReadOnly) + throw new InvalidOperationException("Legacy CultCache is read-only. Durable state belongs to the Verse state spine."); + foreach (var entry in entries) { - Add(entry); + AddInternal(entry); } } @@ -144,6 +155,9 @@ public class CultCache public void Remove(DatabaseEntry entry, CacheBackingStore source = null) { + if (ReadOnly && source == null) + throw new InvalidOperationException("Legacy CultCache is read-only. Durable state belongs to the Verse state spine."); + _entries.Remove(entry.ID); var type = entry.GetType(); foreach (var parentType in type.GetParentTypes()) diff --git a/docs/aetheria-perfect-machine-map.md b/docs/aetheria-perfect-machine-map.md index 50f4c1211..e1ede4389 100644 --- a/docs/aetheria-perfect-machine-map.md +++ b/docs/aetheria-perfect-machine-map.md @@ -36,7 +36,9 @@ local CultCache, and legacy UI paths should be migration-only or deleted. MessagePack backing stores may hydrate in-memory domain objects for the current Unity runtime, but this path cannot push or delete legacy files. The legacy backing-store abstraction is pull-only; its write and realtime - watcher APIs have been deleted. + watcher APIs have been deleted. Public `Add`, `AddAll`, and `Remove` calls + against the read-only cache are rejected; only backing-store pull hydration + can populate it. - `DatabaseLink.Value` can resolve legacy links only after `LegacyCatalogBoundary` binds the read-only catalog cache. `CultCache` construction no longer grabs global `DatabaseLinkBase` authority.