Fix round 1 review findings:
1. Frame-matching strategy: add protocolFrameTypes set; next() now fails immediately
on an out-of-order protocol frame instead of silently discarding it. Ambient
frames (data, stats, triggerState, monotonicState) are logged and skipped.
nextSkipping() accepts explicitly-listed protocol frames that legitimately differ
in order across hubs (connect-time "sources" before "calibration" in C++).
2. BroadcastSources documented exception: the extra "sources" frame C++ emits after
reload is accepted and logged as [KNOWN DIFFERENCE] with full rationale; the
report recommendation to remove it has been retracted (it is required for correct
client-side source-list updates after reload-with-new-sources).
3. Sort-order constraint exercised: three calibration entries submitted in
reverse-sort order (src2/Beta, src1/Zeta, src1/Alpha); each broadcast and the
saved config file are asserted to be sorted by source then signal.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>