7a4688d9ca
Review finding: dashboard_client_last_seen() discarded the marker once it was >= 45s old, so after the client disconnected the gateway fell back to its own (much older) _last_inbound_at and suspended ~45-75s later, not idle_timeout later as the PR claimed. The staging release leg had in fact shown 46s. The marker mtime is a timestamp of real inbound; is_idle already judges recency. Drop the staleness cutoff entirely and always fold the raw mtime into the inbound clock (max with _last_inbound_at). An old marker is harmless: it is outside idle_timeout just like an old _last_inbound_at. Also: - touch the marker immediately after ws.accept(), before the ready/skin setup, so a client waiting on a slow ready frame is still visible - make the newer-message-wins test discriminating (timeout 10s, chat 5s, marker 40s: choosing the marker would read idle) - add < idle_timeout / >= idle_timeout / ancient-marker boundary tests Re-validated live on hermes-agent-stg-test-6698: last client frame 03:18:11Z -> going dormant 03:20:17Z (126s = 120s timeout + watcher tick) while the gateway's own inbound clock was 368s stale. Mutation check vs origin/main files: run.py hunk reverted -> 4 fail, ws.py reverted -> 3 fail, "prefer marker over max" -> 1 fail.