2 Commits
Author SHA1 Message Date
thePR0M3TH3ANandClaude Opus 4.8 6b63625d88 test(feed): update subscribeVideos spec for reserved live defaults
Spec correction following de515462 (feed always reserves live default
aggregators). The existing "uses the healthy relays when they are available"
case asserted deepEqual(subRelayArgs, healthy) — i.e. ONLY the healthy relays.
That expectation is now wrong: the feed deliberately also reserves known-good
defaults so a healthy-looking but dead user list can't hang the feed. Replaced
with a stricter behavioral assertion (healthy relays still present AND a default
reserved AND bounded to the read cap). Mutation-verified: reverting
buildFeedRelaySet to the old healthy-only logic fails the updated case.

test_integrity_note:
  change_type: ["spec_correction"]
  scenarios:
    - id: SCN-feed-reserve-live-defaults
      given: "the user has healthy-looking relays that may actually be dead"
      when: "the feed subscription is created via subscribeVideos"
      then: "the relay set includes the user's healthy relays AND at least one default aggregator, bounded to MAX_SUBSCRIBE_RELAYS"
  observable_outcomes:
    - "the relay array passed to pool.sub()"
  determinism_controls:
    - "mocked pool.sub captures the boundary relay list; getHealthyRelays stubbed"
  anti_cheat_rationale:
    prevents:
      - "over-mocking internal logic"
      - "snapshot rubber-stamping"
  relaxation:
    did_relax_any_assertion: false
    if_true_explain_spec_basis: "old deepEqual replaced with stricter superset+liveness+bound assertions"

Co-Authored-By: Claude Opus 4.8 <[email protected]>
2026-06-20 12:25:27 -04:00
thePR0M3TH3ANandClaude Opus 4.8 818fe16254 fix(feed): fall back to default relays in subscribeVideos on cold start
subscribeVideos called pool.sub(getHealthyRelays(this.relays)) with no
empty-relay fallback, unlike the fetch paths in the same file. On a cold first
load the 5s relay connect probe can time out, marking every relay unreachable;
init() only warns and schedules a background reconnect (it does not throw), so
boot proceeds and the feed subscribes to ZERO relays. The background reconnect
later succeeds but nothing re-issues the subscription, so the feed stays empty
until the user refreshes (when the SWR cache renders) — the reported
"notes don't load on first visit / need a refresh" symptom.

Fall back to DEFAULT_RELAY_URLS when no relays are healthy, mirroring the
established pattern. Because the fallback bypasses the unreachable cooldown, the
subscription retries those relays directly and self-heals instead of staying
dead until refresh.

Adds tests/nostr/subscribeVideosRelayFallback.test.mjs: empty healthy set =>
default relays (never zero), populated healthy set => uses those relays.

Co-Authored-By: Claude Opus 4.8 <[email protected]>
2026-06-12 09:41:17 -04:00