Skip to content

fix: #620 a reset wake probe reached a live peer, so it isn't offline - #623

Merged
nolnoch merged 1 commit into
masterfrom
fix/620-false-offline
Nov 6, 2026
Merged

nolnoch merged 1 commit into
masterfrom
fix/620-false-offline

Conversation

@nolnoch

@nolnoch nolnoch commented Nov 6, 2026 •

Copy link
Copy Markdown
Owner

Problem

  • Local dm_send can tell the sender a live peer is offline, though the peer was woken and got the message. poke counts a connect as failed when the listener accepted and closed it first (Bun: ECONNRESET).

Value

  • delivered_now and the "Recipient offline" note can be trusted, and peer_list and the other poke callers stop reading a live holder as absent for this reason.
  • Sends lose the retry delay (up to about 150 ms) and the extra wakes it caused.

Solution

  • canConnect returns true on ECONNRESET. A stale socket reports ECONNREFUSED and still takes the retry ladder, then reads as offline.
  • Client side only, because a sender can't assume its peer's listener runs a newer build.

Details

Refs #620, which stays open until this is checked in real sessions (see below).

Test: src/local/wakeup.test.ts runs a listener in its own process and requires exactly one wake per poke, with every poke true, plus a stale-file and a missing-file case. The first test failed 20 of 20 runs on the old code, 15 of them with an outright false offline, and passes 12 of 12 with the fix.

Suite: full root suite 2022 pass, 0 fail, with HOME in a scratch directory.

Not established: the rate seen in real Claude Code sessions (about 4 of 6 reads) did not reproduce with real grayboard mcp children on the old code: 0 of 500 sends, from source or compiled, at 100 ms or 3 s gaps, or pinned to one core. Those runs did show retries, up to nearly the whole ladder. The bare listener's rate depends heavily on timing, which may be the difference, but nothing here measures it. So this fixes a proven cause; whether it's the only cause of that rate needs a rerun in real sessions.

Parity: no docs/parity.md cell changes; this corrects a result in local mode, whose cells already claim it. Hosted delivery doesn't use this probe.

Docs gate: pushed with DOCS_GATE_BYPASS=1 because of the existing drift in #615. No docs describe this behaviour.

🤖 Generated with Claude Code

The listener ends each connection as it opens. When that beats the sender's
event loop to the connect, Bun rejects it with ECONNRESET, though the wake has
run. poke counted that as a failure and retried, and after the ladder reported
a live peer as offline. A stale socket reports ECONNREFUSED, so the two stay
distinct.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@nolnoch nolnoch added bug Something isn't working local src/local + local mode labels Nov 6, 2026
@nolnoch
nolnoch merged commit 5383eac into master Nov 6, 2026
11 checks passed
@nolnoch
nolnoch deleted the fix/620-false-offline branch November 6, 2026 20:20
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug Something isn't working local src/local + local mode

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant