Files
buzz/docs
Brad Seiler 4e28176f13 fix(relay): close legacy sockets after community FI upgrades (#8991)
## Summary

When a community starts requiring NIP-FI, the periodic community
revalidator now closes its existing legacy root and audio WebSockets
with Close 1008. It reads current policy from the writer by immutable
community ID, with a 500 ms budget per read. Failed reads retry on later
sweeps; late registrations are caught by the next pass.

Enforced FI admissions survive. Optional-shadow admissions remain
legacy. Off and repair mode retain their existing behavior. No client
request or Redis notification is needed.

The default sweep interval is 30 seconds, not a deadline during database
failure, overload or paused processes. Already-running requests and
descendant work may finish. Receipts prove policy acceptance and remain
`pending`. The `pending_reasons` value changes from
`registry_baseline_unverified` to `connection_closure_unverified`;
clients must tolerate unknown reasons. This change does not certify
fleet-wide completion.

### Related issue

[BUZZ-512](https://linear.app/squareup/issue/BUZZ-512), under the
revised eventual-closure scope. Builds on merged #8985 and #8988. The
replacement starts from main and adds no activation schema or migration.

### Rollout and limits

There is no new flag. Count already-required communities before
deployment: each relay closes their legacy sockets on its first
successful sweep. Closures within a community can cause simultaneous
reconnects. Keep new upgrades disabled until every serving relay runs
this version.

Observe `buzz_community_auth_policy_checks_total{outcome}` and
`buzz_community_auth_policy_disconnects_total` per relay, and verify
real idle root/audio Close 1008 probes plus FI reconnects. Counters
record checks and cancellation requests, not fleet completion. A binary
rollback requires no migration and restores the old pending reason, but
loses eventual closure; it does not undo durable policy. See the
[operator
contract](1c74532516/docs/community-auth-upgrades.md).

### Testing

The real-socket journey runs a local relay against isolated PostgreSQL
and Redis. It covers idle root/audio closure after a durable change
without pubsub, actual read timeouts and recovery, late registration on
both routes, FI reconnects, unrelated sockets, and Off/repair/Enforce
controls.

With local PostgreSQL and Redis configured per the repository's test
guide, run:

```sh
CARGO_TARGET_DIR=target/fi-closure-review scripts/postgres-test-run.sh -p buzz-relay --lib -E 'test(sweep_closes_idle_root_audio_and_late_registrations_after_read_recovery)'
```

Expected: one passing journey, covering both late-registration routes
and all socket controls.

The journey passed at `1c74532516f697c2f06498646326f8c479574b14` in a
branch-specific build target (5.56 seconds). Independent source review
has no remaining P1/P2 findings. Earlier shared-target results are
unreliable and are not acceptance evidence. All mandatory push hooks
passed in the same isolated target, including Rust unit tests, both
Tauri Clippy modes, Tauri tests and file-size checks. Hosted CI passed
at this head. The full local `just ci` chain was not completed. Human
runtime acceptance remains open. No merge or deployment is included.

Generated with Codex

---------

Signed-off-by: Brad Seiler <seiler@squareup.com>
Co-authored-by: Honor <e0bf479eeebe47dde1e35705212a4df70616a7bc834d907ddfb18cf0405f8b1b@seiler-test.communities.public.builderlabstaging.xyz>
2026-11-05 22:01:09 -05:00
..
2026-07-21 17:16:23 +00:00