···387387388388 slog.Info("New firehose subscriber", "remote", conn.RemoteAddr(), "cursor", cursor, "currentSeq", currentSeq, "userAgent", userAgent)
389389390390+ // Send #account event first so relays know this DID is active.
391391+ // This is written directly to the WebSocket before backfill/handleSubscriber
392392+ // start, so there are no concurrent writers at this point.
393393+ if err := b.sendAccountEvent(conn); err != nil {
394394+ slog.Warn("Failed to send account event to subscriber", "error", err)
395395+ }
396396+390397 // Handle cursor-based backfill:
391398 // - cursor < 0: No backfill, stream new events only
392399 // - cursor >= 0: Backfill events from cursor onwards
···412419 go b.handleSubscriber(sub)
413420414421 return sub
422422+}
423423+424424+// sendAccountEvent writes an #account event directly to a WebSocket connection,
425425+// signaling that this DID is active on this host. This is critical for relays
426426+// that previously saw the DID deactivated on a different PDS.
427427+func (b *EventBroadcaster) sendAccountEvent(conn *websocket.Conn) error {
428428+ header := events.EventHeader{
429429+ Op: events.EvtKindMessage,
430430+ MsgType: "#account",
431431+ }
432432+433433+ wc, err := conn.NextWriter(websocket.BinaryMessage)
434434+ if err != nil {
435435+ return fmt.Errorf("failed to get websocket writer: %w", err)
436436+ }
437437+438438+ if err := header.MarshalCBOR(wc); err != nil {
439439+ wc.Close()
440440+ return fmt.Errorf("failed to write account event header: %w", err)
441441+ }
442442+443443+ acctEvt := &atproto.SyncSubscribeRepos_Account{
444444+ Active: true,
445445+ Did: b.holdDID,
446446+ Seq: 0, // Not sequenced in the commit stream
447447+ Time: time.Now().Format(time.RFC3339),
448448+ }
449449+450450+ var obj lexutil.CBOR = acctEvt
451451+ if err := obj.MarshalCBOR(wc); err != nil {
452452+ wc.Close()
453453+ return fmt.Errorf("failed to write account event body: %w", err)
454454+ }
455455+456456+ return wc.Close()
415457}
416458417459// Unsubscribe removes a WebSocket subscriber