Pre-release: feature/extend-source-generator @ b51d8af — feat(sourcegen): express create-path field visibility as flags
Pre-releaseBranch: feature/extend-source-generator
Commit: b51d8af75d83b42a7faa6c177086e7bb40f67132
feat(sourcegen): express create-path field visibility as flags
From the 5.5 engine on, the values blob for a create carries a leading
visibility byte — the client's UF::UpdateFieldFlag (Owner 0x01, PartyMember
0x02, UnitAll 0x04, Empath 0x08) — and the client gates its own reads on it.
The byte is a contract rather than a hint: declaring a bit obliges the writer
to emit every field that bit gates, or the client reads the next group from the
wrong offset, drifts, and faults. So the generator has to know, per field,
which groups it belongs to.
OwnerOnly could not say that — it is one boolean over a four-group space.
Replace it with a Visibility flags property, and replace the boolean carried
through the generator with the guard condition it produced, so the emit sites
print rather than decide.
V3_4_3 turns out to be on the same model already: WriteValuesCreate writes
IsOwner ? 0x03 : 0. It just never declares more than Owner|PartyMember or
nothing, so a boolean covered it. Keeping both spellings would have meant two
ways to say one thing across every descriptor the 2.5.6 port adds, so
OwnerOnly is gone: the builder now derives FieldVisibilityFlags from
IsOwner, the leading byte is written from it instead of a literal 0x03, and
the 35 field declarations say Visibility = FieldVisibility.Owner.
The wire does not move. The generated guard goes from if (IsOwner) to
if ((FieldVisibilityFlags & FieldVisibility.Owner) != 0), the same predicate
by construction, and the byte from IsOwner ? 0x03 : 0 to
(byte)(Owner | PartyMember), the same 3. The generated V3_4_3
ObjectUpdateBuilder differs from its baseline in exactly those 70 lines and
nothing else; the Verify snapshot is re-baselined to match.
Also rewrites HermesProxy.SourceGen/CLAUDE.md as a handbook. The old note
described the descriptor vocabulary but not the machine behind it, so every
capability added meant re-deriving the generator's shape from 1400 lines of
string emission — and it still documented OwnerOnly. It now covers the
four-stage pipeline, the mirrored-enum rule and why an inserted member silently
corrupts the wire, the recipe for adding a capability, the seam between the
generator and the hand-written builder, and the capabilities a 5.5-engine port
still needs.
Refs #108
Co-Authored-By: Claude Opus 5 (1M context) noreply@anthropic.com
Claude-Session: https://claude.ai/code/session_019p1wW7nkNtVwYdvxmo7PVq