hermes-agent/gateway/relay
Ben 96af4bec30 feat(relay): add go_dormant() transport mode for scale-to-zero (0.E0)
Net-new WebSocketRelayTransport.go_dormant() + RelayAdapter.go_dormant() —
the third transport mode the scale-to-zero behaviour layer needs, distinct
from both disconnect() and an unexpected close (decisions.md D12/F14):

- disconnect() sets _closing=True and CANCELS the reconnect supervisor
  (terminal "shutting down for good") -> a suspended machine never re-dials
  on wake, stranding its buffered backlog.
- an unexpected close re-dials IMMEDIATELY -> the socket never stays down,
  so the platform proxy never suspends the machine.

go_dormant(): going_idle->ack (reuse go_idle), then close the socket WITHOUT
setting _closing, so the reader's fall-through still arms the reconnect
supervisor (wake path stays live) but on the longer _dormant_redial_s
cadence so it doesn't fight the platform suspend window. A successful re-dial
clears _dormant. Honors the §3.4 wake->reconnect->drain contract.

Tests: 6 new in test_relay_going_idle.py incl. the F14 regression guard
(routing dormancy through disconnect() fails exactly the 4 wake-path tests).
Full relay suite 140 passed.
2026-06-24 18:47:18 -07:00
..
__init__.py feat(relay): Phase 5 Unit C — wake primitive (gateway side) (#51595) 2026-06-24 11:00:11 +10:00
adapter.py feat(relay): add go_dormant() transport mode for scale-to-zero (0.E0) 2026-06-24 18:47:18 -07:00
auth.py feat(relay): connector⇄gateway channel auth + signed-HTTP inbound receiver + enroll CLI (#48147) 2026-06-18 12:01:54 +10:00
descriptor.py feat(relay): derive descriptor from PlatformEntry 2026-06-17 16:37:45 -07:00
transport.py feat(relay): Phase 5 §5.3 going-idle / buffered-flip primitive (gateway side) (#51572) 2026-06-24 09:50:30 +10:00
ws_transport.py feat(relay): add go_dormant() transport mode for scale-to-zero (0.E0) 2026-06-24 18:47:18 -07:00