fix(histogram): three defects found by a full series-3 sweep — 11603/11603 clean

Swept every series-3 binary with the live decoder against five
independent checks: decode exceptions, zero samples, unequal geo channel
lengths, peaks above range full scale, decoded peak vs device-reported
PPV, and waveform length vs declared record time.

1. block[22] is NOT a constant and must not be tested.  Documented as
   always 0x00, it carries data on loud blocks, and rejecting those threw
   away the interval holding the event peak.  BE18350/T350L7HR.NL0H
   block 92 has block[22]=0x26 and a Tran peak of 0x0563 = 1379 counts =
   6.895 in/s — exactly the device-reported PPV — while the file decoded
   to 0.015 in/s.  block[0]==0, block[4]==0x0A and the 4-byte tail are
   six bytes of constraint, which is what keeps trailer content out.

2. Block-model dispatch now goes on signature strength rather than on
   whichever decoder returns first.  A multi-interval body also yields
   scattered standard-tail blocks by coincidence, so "first non-empty"
   handed 193 BE18193 files to the standard walker and produced peaks of
   149 in/s against a 10 in/s full scale.

3. Multi-interval stride detection requires the block counter to
   increment by exactly 1.  Without it the detector false-positives on
   ordinary standard-block bodies: they carry a header every 32 bytes,
   and 192 = 12 + 20*9 and 512 = 12 + 20*25 are both multiples of 32, so
   a stride "fits" while skipping 6 or 16 real blocks.  That misrouted
   9,082 files.

Partial-block garbage is trimmed within the final block only, stopping
at the first slot with a non-zero tail word or a geo peak above full
scale (2000 counts in 16-count units).  Trimming purely from the end
left garbage stranded behind a slot that happened to have a zero tail
word; trimming on the tail word alone truncated four BE9440 files by up
to 2,800 intervals.

Result: 11,603 / 11,603 series-3 binaries clean on every check.
Ground truth unchanged: 1211/1211 histograms exact per-interval, 75/75
waveform sample counts exact (73/75 fully exact, the 2 differ by 1 LSB
on rail samples), and the multi-interval fixture still matches its BW
ASCII export on all 45,680 values.

Tests: 259 passed, failure list unchanged from baseline.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01HgTe8CamXAHcAmaQ6QNcog
This commit is contained in:
2026-08-26 05:55:46 +00:00
co-authored by Claude Opus 5
parent 306104354b
commit a3b69a62a6
3 changed files with 122 additions and 19 deletions
+35
View File
@@ -8,6 +8,41 @@ All notable changes to seismo-relay are documented here.
### Fixed
- **Series-3 health sweep: 11,603 / 11,603 binaries now clean on every check.**
Swept every series-3 file with the live decoder against five independent
checks — decode exceptions, zero samples, unequal geo channel lengths, peaks
above range full scale, decoded peak vs the device-reported PPV, and waveform
length vs the declared record time. Three real defects surfaced and were
fixed:
- **`block[22]` is not a constant and must not be tested.** It was documented
as always `0x00` but carries data on loud blocks, and rejecting those threw
away the interval holding the event peak.
`BE18350/T350L7HR.NL0H` block 92 has `block[22]=0x26` and a Tran peak of
`0x0563` = 1379 counts = **6.895 in/s** — exactly the device-reported PPV —
while the file as a whole decoded to 0.015 in/s. `block[0]==0x00`,
`block[4]==0x0A` and the 4-byte tail are six bytes of constraint, which is
what keeps trailer content out.
- **Block-model dispatch now goes on signature strength, not on whichever
decoder returns first.** A multi-interval body also yields scattered
standard-tail blocks by coincidence; dispatching on "first non-empty"
handed 193 BE18193 files to the standard walker and produced peaks of
149 in/s against a 10 in/s full scale.
- **Multi-interval stride detection requires the block counter to increment
by exactly 1.** Without it the detector false-positives on ordinary
standard-block bodies: those carry a header every 32 bytes, and
`192 = 12 + 20×9` and `512 = 12 + 20×25` are both multiples of 32, so a
stride "fits" while actually skipping 6 or 16 real blocks. That misrouted
9,082 files.
Partial-block garbage is now trimmed within the final block only, stopping at
the first slot with a non-zero tail word or a geo peak above full scale.
Trimming purely from the end left garbage stranded behind one slot that
happened to have a zero tail word; trimming on the tail word alone truncated
four BE9440 files by up to 2,800 intervals.
- **Sub-minute histogram intervals are packed several to a block — 415 files
recovered.** The device always writes one minute of data per block, so a
shorter interval just means more intervals in a longer block: