A rotation reflection arrives as a run of partials and is cut into rocking events
wherever two successive frames are more than MAX_FRAME_GAP apart. That constant
was 2.0 frames, in five places, and the quantity it stands for is not a frame
count at all: it is an angle, a reflecting range of a tenth to half a degree. At a
tenth of a degree per image two frames is a fifth of a degree of dead rotation and
the bridge does what it was meant to; at a degree per image it is two degrees, as
wide as a whole event, and two genuine crossings of the Ewald sphere are joined
into one "full". Reconstructing the events on a paired control - the same photons
sliced two ways - the fraction of events whose partialities sum past 1.5 is 14.3%
at 1.0 degree against 6.0% at 0.1, the fused ones spanning a median of five frames.
So the gap becomes half a degree of rotation, floored at one frame so an event is
never cut at its own neighbours and capped at the two frames that were always
allowed. For any oscillation of 0.25 degrees or less the quotient is at least two
and the cap returns the literal 2.0f, so every finely sliced sweep is bridged
exactly as before, on both the CPU and the GPU path.
The value is taken once per run and carried to the device in CombineParams rather
than recomputed in the kernel, so the two paths compare the same float by
construction and the bit-parity contract the combine documents is preserved.
The defect above is measured; the repair is not. No arm has been run with this
change, which is why it is a commit of its own.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01EFEJG6WBQv8th4UJFNe53N