You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
id(chat): presence heartbeat protocol over gossip (ephemeral, TTL-based) #2809
Follow-up from the IRC-first chat investigation (#2049, doc in PR #2807 §2.4; synthesis consumer #2051).
Build: presence as specified: per-node {node-id, channels[], status, ts} heartbeats over direct connections fanned out via the already-wired gossip ALPN, short TTL (60–90 s suggested), stale = gone, no leave messages. Roster = backing-group fold annotated with last-seen liveness. Presence is NEVER journaled, synced, or replayed.
Done when: two nodes show each other live/stale correctly across a simulated netsplit (kill -STOP / resume), and typing-indicator TTLs ride the same path. Hand the result to #2051.
Acceptance criteria
Two nodes exchange presence heartbeats ({node-id, channels[], status, ts}) over direct connections fanned out via the already-wired gossip ALPN, with a short TTL (60–90 s suggested); stale entries read as gone; no leave messages.
Roster = backing-group fold annotated with last-seen liveness, demonstrated across a simulated netsplit (kill -STOP / resume): both nodes show each other live, then stale, then live again correctly.
Presence is never journaled, synced, or replayed (verified in the implementation); typing-indicator TTLs ride the same path.
Notes: Spec is unusually complete for a follow-up (heartbeat shape, TTL range, roster definition, the never-journal rule). The body's "Done when" is formalized into the acceptance criteria section. Still live — no presence implementation has landed.
Risks: The failure mode to test hardest is the netsplit: stale detection must not flap on resume, and presence must stay out of the journal/sync path.
Suggested approach: Build directly to the §2.4 spec on the existing gossip ALPN; the kill -STOP/resume transcript is the verification artifact.
note: Presence protocol implemented as specified. pkgs/id/src/chat_presence.rs: signed per-node {node, channels[], status, ts} heartbeats, 75 s TTL (60–90 s band), no leave messages, stamp-based expiry (replays cannot extend a claim), roster = backing-group fold annotated with last-seen liveness, receipt-side membership filtering + viewer-scoped rosters for private channels, typing on a 12 s TTL over the same path. The table is in-memory only — never journaled, synced, or replayed. serve broadcasts/verifies presence frames on the existing gossip ALPN. Codex round (3 P2 findings: authentication, duplicate-extended expiry, pruning) fixed and replied on the PR threads.
handoff: result handed to id: design: ID chat v1 #2051 (comment there). Pre-existing unrelated failure found on main: id-core test target does not compile (vt100 used in world_presentation tests, not an id-core dev-dependency after the crate split).
Activity
dezren39 commentedon Oct 31, 2026
Intake review
dezren39 commentedon Nov 1, 2026
🤖 Agent note · handed off
19 remaining items
dezren39 commentedon Nov 1, 2026
agent-note:v1
fix(id): brace the presence/announcement receive branch (#2809)
fix(id): brace the presence/announcement receive branch; fmt chat_pre…
fix(id): dedupe heartbeat channels without moving the input; no expec…
fix(id): Codex review - authenticate presence sender, stamp-based exp…
fix(id): sign presence heartbeats - gossip does not authenticate auth…
fix(id): serve signs its presence heartbeat and verifies received ones (
Merge pull request #3956 from developing-today/queue/5799-2809-id-cha…
dezren39 commentedon Nov 1, 2026
agent-note:v1
pkgs/id/src/chat_presence.rs: signed per-node {node, channels[], status, ts} heartbeats, 75 s TTL (60–90 s band), no leave messages, stamp-based expiry (replays cannot extend a claim), roster = backing-group fold annotated with last-seen liveness, receipt-side membership filtering + viewer-scoped rosters for private channels, typing on a 12 s TTL over the same path. The table is in-memory only — never journaled, synced, or replayed. serve broadcasts/verifies presence frames on the existing gossip ALPN. Codex round (3 P2 findings: authentication, duplicate-extended expiry, pruning) fixed and replied on the PR threads.cargo test -p id chat_presence— 10 passed, 0 failed (TTL, two-node stop/resume frame exchange, roster annotation, private-channel scoping, typing TTL, replay/out-of-order refusal, duplicate-expiry, signature authentication, frame magic, memory-only).vt100used in world_presentation tests, not an id-core dev-dependency after the crate split).