- The throttle runs on a 64-bit clock in ms (esp_timer_get_time()), so a
slot left alone for 49.7 days isn't brought back by millis() wrapping
round to its old failure.
- Web.cpp turns the client into the throttle's key in one place, and
says that an IPv6 client would share key 0; names are clearer
(retryMs, vacantSlot).
- The shared slot's test now succeeds from the IP counted in it, so a
success that cleared the shared slot would fail it.
- GLOSSARY.md names it the login throttle, with lockouts, and
SECURITY_PLAN.md and ADR 0006 use that name.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
ADR 0005: the web UI and Home Assistant talk to the device over one
websocket protocol (ops on loop(), sync with next, a JSON envelope a
binary encoding can reuse, short keys described by a schema).
ADR 0006: two security modes and eleven HTTP routes on port 80.
ADR 0007: the firmware no longer updates itself from GitHub.
ADR 0002 is amended: its single-writer rule stands, but edits now get
one reply and reads no longer go through a ModelSnapshot.
SECURITY_PLAN.md is revised to match, and keeps the token key, login
backoff, CORS and Origin work. PROTOCOL.md starts as an outline, and
GLOSSARY.md gains the socket protocol and security terms.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>