SIGN IN SIGN UP

fix(wire): union fixtures carry every variant, not just the first

Greptile P2 on #629, and it is right. The emitter carried every TAG of an enum
but only the FIRST variant of a union — inconsistent, and it meant
ActivityFrame's fleet_response_chunk, tool_call_completed and tool_call_progress
arms, and ExecutionResult.Outcome's failed arm, were never byte-compared against
Zig. The payload shape of a variant nothing sampled is exactly what drifts
unnoticed between two implementations, which is what these fixtures exist to
catch.

A union's own fixture now carries every variant, the way an enum's carries every
tag. The reflection also walks one level of nested type declarations, because
ExecutionResult.Outcome is declared INSIDE a struct: the module walk never
reached it, and the enclosing struct can only hold one arm at a time, so its
failed shape had no way to be compared at all.

On the Rust side ActivityFrame's payloads become named structs matching the Zig
union field for field. The encoding is identical either way — serde renders a
newtype variant over a struct exactly as it renders an inline variant body — and
the named form is what lets each payload carry its own fixture.

Fixtures 57 to 64, tests 166 to 180, still 100% lines and functions. Proven not
vacuous by seeding drift into the THIRD variant and into the failed arm: both go
red now, and neither would have before this commit.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
K
Kishore Kumar committed
f38c402850688a16ff3ab99b797c96a985e9d83b
Parent: 6a08ff6