docs(series4): BD download works -- and event keys COLLIDE across units

UM20147, event 055d4a81, 4,796 B, type read as histogram from the 0x0C byte and
decoded as .IDFH on the first try.  The chunk walk, the offset arithmetic, the
11-byte chunk prefix and the record-type byte all hold on the Thor firmware
line unchanged.  That closes the last BD gap.

The type byte is now 7 events across both firmware lines -- 4 waveform, 3
histogram -- correct every time.  Still not a large sample; the fallback stays.

THE FINDING THAT MATTERS: UM20147's first event key is 055d4a81.  So is
UM12947's.  Different units, different sizes (4,796 vs 4,076 B), different
contents, identical key.

This confirms keys are a sequential counter, and adds the consequence: the
counter starts from the same value on every unit, so a key is MEANINGLESS
WITHOUT ITS SERIAL.  Anything that stores, deduplicates or addresses Series IV
events must key on (serial, event_key).  A store keyed on the event key alone
silently treats one unit's event as a duplicate of another's, and the failure is
invisible -- the second event is simply never ingested.

Series III has a related hazard the ACH server already handles: its counter
resets after an erase, so keys are reused WITHIN a unit, which is why
ach_state.json tracks max_downloaded_key per serial.  Series IV inherits that
and adds cross-unit collision on top.

Incidentally resolved: memory free is a usable signal after all.  Run 1 showed
15,000,000 free and no events; run 3 showed 14,799,296 free, idle, with events
stored.  The earlier ambiguity was monitoring overhead confounding it, not
memory being meaningless.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Ru8Lg9HkkYvX9VWWo65SmL
This commit is contained in:
2026-09-30 14:24:03 -04:00
co-authored by Claude Opus 5
parent 080fb92ba2
commit 7d1b033a05
+30 -5
View File
@@ -964,12 +964,37 @@ block: it would return `PInstantel` on one unit and `VInstantel` on the other.
Read the vendor at the fixed offset content[4]; the model is at content[26] on
both lines, but anchor on `MM/` since only its tail varies.
### Still not covered
### ✅ Download from a BD unit (2026-09-30)
- **A download from a BD unit.** UM20147 had no events stored, so the chunk
walk is verified on `11.0CB` only. Nothing suggests it differs — the `0x5A`
prefix and the offset arithmetic are not firmware-line dependent in anything
observed — but it is untested.
UM20147, event `055d4a81`, 4,796 B, **type read as histogram from the `0x0C`
byte and decoded as `.IDFH` on the first try.** The chunk walk, the offset
arithmetic, the 11-byte chunk prefix and the record-type byte all hold on the
Thor firmware line unchanged.
The type byte is now **7 events across both firmware lines** — 4 waveform,
3 histogram — and has predicted correctly every time. Still not a large
sample, and the fallback stays.
### 🔑 EVENT KEYS COLLIDE ACROSS UNITS — dedup must be (serial, key)
UM20147's first event is `055d4a81`. So is UM12947's. **Different units,
different sizes (4,796 B vs 4,076 B), different contents, identical key.**
This confirms *keys are a sequential counter* (already recorded) and adds the
consequence: **the counter starts from the same value on every unit, so a key is
meaningless without its serial.**
⚠ **Anything that stores, deduplicates or addresses Series IV events must key on
`(serial, event_key)`.** A store keyed on the event key alone will silently
treat one unit's event as a duplicate of another's — and the failure is invisible,
because the second event is simply never ingested.
Series III has a related hazard the ACH server already handles: after an erase
its counter resets, so keys are reused *within* a unit, which is why
`ach_state.json` tracks `max_downloaded_key` per serial. Series IV inherits that
and adds cross-unit collision on top.
### Still not covered
- **A unit that is monitoring**, and a unit with a nearly-full event buffer.
- **The inbound call-home session** — still the one protocol unknown.