Caching: a reference gained on an otherwise identical slot is compatible drift (1.0.x ref-list stores open); 2.0.1

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
This commit is contained in:
Meta Vens 2026-10-22 22:16:14 +02:00
commit 972e7b2ed4
3 changed files with 28 additions and 3 deletions

View file

@ -936,7 +936,22 @@ namespace GameCult.Caching
errors.Add($"slot {localMember.Slot} changed type '{persistedMember.TypeName}' -> '{localMember.TypeName}'");
}
if (localMember.IsReference != persistedMember.IsReference)
// 1.0.x persisted a CultRecordRef<T> collection as a plain value slot (not a reference, no target); the
// payload is the same array of keys. Gaining the reference classification on an otherwise identical slot
// is compatible drift. Losing it, or any other change of reference or target, is not.
var gainedReference = !persistedMember.IsReference
&& persistedMember.TargetSchemaName == null
&& localMember.IsReference
&& localMember.TargetSchemaName != null;
if (gainedReference)
{
warnings.Add(new CultSchemaMigrationWarning
{
Code = "gained_reference_semantics",
Message = $"Local slot {localMember.Slot} ('{localMember.Name}') is a reference to '{localMember.TargetSchemaName}'; the persisted schema stored it as a plain value with the same payload."
});
}
else if (localMember.IsReference != persistedMember.IsReference)
{
errors.Add($"slot {localMember.Slot} changed reference semantics");
}
@ -946,7 +961,7 @@ namespace GameCult.Caching
errors.Add($"slot {localMember.Slot} changed cardinality");
}
if (!string.Equals(localMember.TargetSchemaName, persistedMember.TargetSchemaName, StringComparison.Ordinal))
if (!gainedReference && !string.Equals(localMember.TargetSchemaName, persistedMember.TargetSchemaName, StringComparison.Ordinal))
{
errors.Add($"slot {localMember.Slot} changed target schema '{persistedMember.TargetSchemaName ?? "<none>"}' -> '{localMember.TargetSchemaName ?? "<none>"}'");
}

View file

@ -2,6 +2,16 @@
All notable changes to this package are documented in this file.
## [2.0.1] - 2026-10-22
### Fixed
- A store written by 1.0.x with a list of record references (`CultRecordRef<T>[]` or any `IEnumerable<CultRecordRef<T>>` slot)
opens again. 2.0.0 classified such a slot as a reference to `T`, 1.0.x had persisted it as a plain value, and the schema
comparison refused the store with "changed reference semantics" and "changed target schema". The payload is the same array
of keys, so gaining the reference classification on an otherwise identical slot is now compatible drift (migration warning
`gained_reference_semantics`). A reference that is lost or retargeted, and any change of type or cardinality, still refuses.
## [2.0.0] - 2026-10-22
### Breaking

View file

@ -1,7 +1,7 @@
{
"name": "org.gamecult.cultlib",
"displayName": "CultLib",
"version": "2.0.0",
"version": "2.0.1",
"unity": "2021.3",
"dependencies": {
"org.gamecult.cultmath": "0.5.0"