Contract: the cache owns the schema-id stamp, records resolve by schema id, writes may not retype
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
This commit is contained in:
parent
e6f9b2f8c1
commit
86dc2e33d0
1 changed files with 18 additions and 4 deletions
|
|
@ -124,7 +124,16 @@ the payload's first field says. The catalog is the store's own description of it
|
|||
|
||||
A writer keeps the same invariant: every record it writes carries a schema id that some catalog
|
||||
entry it writes publishes, as that entry's id or as one of its compatible ids. A cache stamps a
|
||||
record with its registered schema's id, whatever id the record arrived under.
|
||||
record with its registered schema's id, whatever id the record arrived under, when it loads the
|
||||
record and when it puts one. The cache is the only owner of that stamp: a store writer never
|
||||
changes the identity of a record it did not receive from its caller, so a record another writer
|
||||
changed since this cache read it is written back as that writer left it.
|
||||
|
||||
A cache resolves a record to a local type by the record's schema id: the registered type that owns
|
||||
the id, else one that lists it as compatible. The name the catalog entry carries is metadata. It
|
||||
names a local type only when no local type has the id, for a store written by a runtime whose
|
||||
schema ids this one cannot know (a Rust type's schema id is its entry type). A schema renamed under
|
||||
a stable id therefore opens in every runtime that holds the id.
|
||||
|
||||
A reader resolves a record's schema id to the entry that owns it, that entry's own `schemaId`, and
|
||||
only when no entry owns the id to an entry that lists it as a compatible id (the first such entry
|
||||
|
|
@ -138,9 +147,14 @@ own id, the descriptor wins: a rename or a stale content hash takes the descript
|
|||
members and compatible ids as they are. Entries are written as chosen, deduplicated by own id, with
|
||||
no union of compatible ids and no dependence on the order records arrive in; an entry no record needs
|
||||
is not written. A write is refused, and the store left as it was, when two entries of one tier share
|
||||
an own id and disagree on the schema name, when records of different types share a schema id, or when
|
||||
a record's id is published by no chosen entry. Each runtime refuses with one typed error naming the
|
||||
id, the schema names and a record key: `CultSchemaConflictException` (C#), `SchemaConflictError`
|
||||
an own id and disagree on the schema name, when records of different types share a schema id, when a
|
||||
write would change which type an existing record resolves to (the schema names of the records already
|
||||
in the store and of the records written differ), or when a record's id is published by no chosen entry.
|
||||
The retyping refusal has one exception, a rename: when the entries of both the existing records and
|
||||
the written ones own the id, the registered descriptor wins. (A C# cache stamps a record with its
|
||||
descriptor's own id, so it cannot write a record under an id its descriptor only lists, and the
|
||||
retyping refusal cannot arise there.) Each runtime refuses with one typed error naming the id, the
|
||||
schema names and a record key: `CultSchemaConflictException` (C#), `SchemaConflictError`
|
||||
(Rust, TypeScript, Python).
|
||||
|
||||
This is not decorative paperwork. It is what allows another CultCache
|
||||
|
|
|
|||
Loading…
Reference in a new issue