Home IO Control
ESPHome add-on for IO-Homecontrol devices
Loading...
Searching...
No Matches
ADR 0023: `reference-material` as a fourth corpus origin, for real devices this project doesn't own

Status: Accepted · Recorded: 2026-08

Context

ADR 0010 established the corpus's core contract: real captured frames are the regression-test source of truth, validate.py enforces crypto and structural self-consistency regardless of where a capture came from, and every capture carries a source.origin explaining its provenance. Until now that field had three values, each implying a specific real-world process:

  • own-hardware — captured directly against a device the maintainer owns.
  • github-issue — a community member's own log, pasted into this project's issue tracker.
  • synthetic-bootstrap — hand-generated bytes for pipeline self-tests, not a real device at all.

All three assume the capture either came from this project's own hardware or was volunteered to this project's own support channel. That covers a real but narrow slice of the io-homecontrol device landscape — the specific Somfy motors on three radio chips the maintainer happens to own, plus whatever community members happened to file issues about. It does not, and structurally cannot, cover the much larger set of devices from other vendors and other markets (Velux gateways and sensors, French-market climate/heating actuators, other Somfy product lines) that nobody connected to this project has ever had in hand.

That gap is real, but other people have already done the work: other open-source implementations' own documentation contain genuine captured or precisely decoded frames for exactly these device families. Reusing own-hardware or github-issue to absorb that material would misrepresent how it was actually obtained — the same failure mode ADR 0010's own reasoning warns against ("a byte sequence someone invented to look plausible proves nothing when the question is what real hardware actually sends"; a byte sequence mislabeled as this project's own capture proves just as little the moment someone checks). synthetic-bootstrap is the wrong label too — this data describes real devices, it isn't self-test scaffolding.

Options considered

  • Leave the gap uncovered until matching hardware becomes available. Keeps the provenance model simple and never requires trusting anyone else's transcription. But the gap is permanent for devices this project will plausibly never own.
  • Reuse own-hardware or github-issue for this material. No schema change, fastest path. Rejected: both labels assert something false about how the bytes were obtained, and quietly eroding what a provenance label is allowed to mean undermines every other capture's label too.
  • Add a fourth origin, reference-material, naming the provenance. Extends coverage to devices this project has no hardware access to, without pretending otherwise, and without weakening validate.py's crypto/structural enforcement — that still applies identically regardless of origin.

Decision

Added reference-material as a fourth source.origin value (scripts/corpus/validate.py/build.py/ingest.py, tests/corpus/README.md). It covers a real device this project has no hardware access to, documented precisely enough elsewhere to build a faithful capture from — and is never used for a device family this project could plausibly capture itself; that would just be the "reuse an existing label" option above wearing a new name.

Two sub-cases exist under this one origin, and a capture must say in its description or a per-frame note which applies:

  1. Reconstructed. The source gives decoded protocol fields (command, addresses, payload) but not raw wire bytes — the hex/CRC bytes are then built with this project's own serialize()/crc_ccitt(). Wire-valid, but not literal captured bytes.
  2. Literal. The source publishes actual sniffed bytes (an SPI trace, an RF capture). Used as-is, after independently re-verifying every frame's CRC against this project's own crc_ccitt() before trusting the transcription.

A source's license or terms must be checked before it's used, and that check must actually be capable of blocking a source, not just recorded after the fact:

  • Prefer a source under an explicit permissive license (public domain, CC0, MIT/BSD/Apache-style) that clearly covers the material being reused, and name that license in the capture's description.
  • A source with no explicit content license (a forum post) or a copyleft software license not written with documentation in mind (e.g. GPL on a repo whose docs aren't separately licensed) does not get a free pass by default. It's usable only for the byte-level facts of what a real device actually transmitted — never the source's own descriptive prose, screenshots, tables, or formatting — on the reasoning that a mechanical record of transmitted bytes isn't itself original, copyrightable expression (the same reasoning that already lets own-hardware captures exist with no license question at all). If a capture can't be reduced to that byte-level fact without leaning on the source's own expression, it isn't added.

Either way, real third-party key material (a CMD_KEY_TRANSFER/0x32 payload) is never included, if applicable this is re-keyed using our projects system key protection mechanism. validate.py's existing crypto enforcement (ADR 0010) is used to verify this.

That mechanism assumed the re-keyer holds the real key (ingest.py --rekey --system-key-from), which is true for own-hardware and false by definition here. scripts/corpus/rekey_capture.py closes the gap without weakening anything: the 0x32 payload is encrypted under the public TRANSFER_KEY, so the key can be recovered from the capture itself, in memory, and fed to the same verify-and-rewrite pipeline — which is precisely why such a capture could never have been committed as published in the first place.

The complete set of source.origin values, for reference:

Origin Real device? Captured by this project? Used for
own-hardware Yes Yes The maintainer's own devices, captured directly.
github-issue Yes No (volunteered to this project) A community member's own log, pasted into this project's issue tracker.
reference-material Yes No (found elsewhere) A real device with no hardware access, documented precisely enough by a third party to reconstruct or reuse faithfully.
synthetic-bootstrap No — Hand-generated bytes for pipeline self-tests; not a device capture at all.

Consequences

  • Corpus coverage can now include real device families no one connected to this project has ever owned, as long as someone has documented them precisely enough — the first uses covered a Velux KLR200/KUX100 pairing exchange, an Atlantic Thermor-style climate device, and two unidentified 1W remotes.
  • Every reference-material capture carries new obligations beyond what the other three origins require: it must say which of the two sub-cases applies, so a future reader can tell "wire-valid but reconstructed" from "literal bytes, independently verified" at a glance.
  • issue now sometimes points at a genuinely external, non-project source (a forum thread, a third-party repository) — previously it only ever meant "this project's own GitHub issue tracker."