# Control iD (REP iDClass) integration conventions - Transport quirk: the device's firmware sends LF-only line terminators for most headers but still closes with `\r\n\r\n` before the body — this breaks strict HTTP/1.1 parsers (Node's `llhttp`). Communicate via raw socket (`net`/`tls`), building the request manually, with a tolerant response parser trying multiple header/body boundary separators. - Credential storage: AES-256-GCM, reversible (the app must recover the plaintext password to authenticate against the device on demand) — see `eden-security` skill's `encryption.md`. - No persistent device session — login fresh on every operation. - CPF is the device's own user identifier (mode 671) — no separate "controlid_user_id" concept. - CPF travels as a `Number` in the Control iD API (loses leading zeros by design of their API) — always re-pad to 11 digits when reading back. - All device operations run sequentially, never in parallel — embedded devices are low-throughput; batch operations (test-all-connections, sync-all-employees) iterate one device/employee at a time. - Categorize errors (auth/timeout/http/invalid-response/unreachable/tls/unknown) and translate to a user-facing message — never leak raw technical error text to the end user.