_master_datagram_received and _peer_datagram_received each carried the same
32 lines: global SUB_ACL, the TG list for the frame's slot, then the system's
own three, every rejection logging once per stream through _laststrid. The two
copies were identical down to the wording of the six log messages, so a fix in
one could silently miss the other.
They now call _acl_rejects_dmrd, which keeps the legacy order, the same
messages and the same once-per-stream guard, and reads the TG list as
TG{slot}_ACL instead of spelling out slot 1 and slot 2. The frame's slot is
always 1 or 2 (it comes from bit 0x80), so no branch is lost.
tests/hbp/test_acl_gate.py covers both paths, the per-slot TG list and the
on-demand unit-service exemption; three of its four tests pass unchanged
against the previous code.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>