bench: per-helper wire bench + shape-variety bench + multi-byte jit gates Three additions so future perf regressions are visible at the right granularity, not just averaged out by the single Person shape in bench/bench.lua. bench/wire_bench.lua (new). Microbenches every wire helper in isolation — encode/decode for varint at 1/2/3/5 bytes, zigzag, fixed widths, float/double, LEN, tag, skip_field, utf8 validator. Used when tuning wire.lua to confirm a change moved the helper-level ns/op as expected (e.g. encode_varint(150) 529 ns -> 68 ns from the 2-byte fast path). Run via `make bench-wire`. No baseline, no regression gate — this is a manual inspection tool. bench/shapes_bench.lua (new). Runs encode + decode against a handful of fundamentally different Person / Event / Result shapes — scalar-heavy, packed-int (100 and 1000 elements), nested-friends (10 and 100), maps (scalar-valued and message-valued), oneof, and WKT-heavy. Each shape dials one knob up so cost attribution stays clean. Shows alloc B/op alongside throughput. Run via `make bench-shapes`. Caught the packed-int / multi-byte-varint opportunity that bench/bench.lua (all 1-byte varints, fixed shape) doesn't surface. bench/jit_trace.lua + 4 gates. Two new fixtures per mode that specifically exercise encode_varint_slow's 2/3-byte Lua-number paths and decode_string's multi-byte LEN fallback (200-byte name + packed ints in [150..500000]). If a future change pushes encode_varint_slow past LuaJIT's inline budget the gate fires instead of the regression landing silently in shapes_bench. Total gate count: 19 -> 23. Makefile gains `bench-wire` and `bench-shapes` phony targets.