From a20ee76aa751f4ad98affdc83d424a97d02f3731 Mon Sep 17 00:00:00 2001 From: Meta Vens Date: Sun, 13 Sep 2026 21:58:37 +0200 Subject: [PATCH] Record Cut 4's slot authority, generic resolver rule, and generator findings Operator decisions: MessagePack's integer [Key] is the only slot authority and the cache core references MessagePack.Annotations directly, since .cc is canonically MessagePack; a generic document's resolvers come from its own assembly. Also records the generator and registry disagreements Soul found with old-versus-new consumer probes and the shape of the fixes. Co-Authored-By: Claude Opus 5 --- docs/cultcache-migration-cut.md | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/docs/cultcache-migration-cut.md b/docs/cultcache-migration-cut.md index a066642d3..b270230b2 100644 --- a/docs/cultcache-migration-cut.md +++ b/docs/cultcache-migration-cut.md @@ -783,6 +783,28 @@ per assembly, used by `SerializeUntyped`/`DeserializeUntyped` emitted `var options = ...` (`CultDocumentMessagePackGenerator.cs:290, 308`, which becomes `OptionsFor(typeof(X).Assembly)`). +**Slot authority and generic documents (operator decisions 2026-09-13).** +MessagePack's integer `[Key]` is the single slot authority for schema identity, +catalog, compatibility and serialization. `GameCult.Caching` references +`MessagePack.Annotations` directly and matches `KeyAttribute` and +`IgnoreMemberAttribute` by type instead of by name string: the core was once +meant to be serializer-independent, but `.cc` is canonically MessagePack, so +that indirection is dropped. A generic document's declared resolvers come only +from the document type's own assembly (`typeof(Doc).Assembly`). + +**Generator and registry agreement (Soul, Cut 4).** Old-versus-new consumer +probes found what the single agreement test missed: per-declaring-type accessor +names collide when two documents share a base with `[CultName]`/`[CultIndex]`; +the generator read a base declaration where reflection read the override, which +changed ids and in one case bytes; duplicate slots (including `new`-hidden +members) went unchecked once MessagePack's analyzer stopped reaching consumers; +inherited private setters stopped compiling; and the typed +`Serialize`/`Deserialize` helpers bypassed per-assembly options. The fixes +name accessors per document, use the most-derived declaration in both paths, +reject duplicate slots and string keys with one message each, and route the +typed helpers through the untyped path, proven by a descriptor-equality sweep +across member shapes with a byte pin for overrides. + **Security.** `CultMessagePackSecurity : MessagePackSecurity` copies `UntrustedData` and overrides `GetHashCollisionResistantEqualityComparer()` to return, for `CultRecordRef`, a comparer over `Key.Value` built from