D134 - Multi-operand kernels sweep the operand cross-product, in a new record that leaves the unary one untouched

Status: derived - fma, pow, min, max and division dispatch and record 539 lanes.

The GPU sweep now handles kernels with more than one input. A kernel declares obs-arity: N in its .comp; gen_shaders.py reads it and emits X(name, arity); sweep_kernel lays out the lane buffer as [in0..in_{k-1}, out] and dispatches over the cross-product of an edge operand set. Adding a multi-operand kernel is still just a .comp file and a regenerate.

The operand set is bits, and it is chosen for the edges

+0, -0, 1, 3, +inf, -inf, NaN - as raw bit patterns, because the operands that make these ops diverge cannot be written as finite decimals. Binary kernels sweep all 49 pairs, ternary all 343 triples. That is deliberately narrow and edge-aimed rather than broad: min/max propagation of NaN, division's 0/0 and x/0, and fma's fused-vs-two-step rounding all live at these points. Widening to a denser space is a later volume step.

A new record, because the old one's meaning is fixed

gpuop|kernel|lane|output|in0|in1|... - the single output first, the inputs trailing. Not a change to gpu: that record's input field is a single value and a consumer already parses it, so widening it would change a field's meaning, which the contract forbids. A separate record carries any arity and leaves the unary format exactly as it was. The layout was confirmed on llvmpipe: divf 0/0 -> NaN, 1/0 -> +inf, 1/3 -> 0x3eaaaaab.