From 4c09f4de3cddc6927a6108baaa4be3a11eef49c4 Mon Sep 17 00:00:00 2001 From: Adam Soltys Date: Sun, 13 Sep 2026 22:57:42 -0700 Subject: The feed reads the relays it was already willing to open. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The gap was not where I said it was. "283 of 400 authors have no relay list" sounded like the thing to fix — but those authors turned up in the sample BECAUSE our own relays carry them, and outboxPlan already asks our relays about everyone. The legacy kind-3 relay map, the fallback I proposed for them, recovers 2 of 220. Neither is worth writing. The real gap is that covering every author once was the wrong goal. People publish to several relays and each holds a different slice: of 60 sampled authors with a write list, 45 declared MORE than the three we took, and seven of twenty-five had posts living only on their fourth or later relay. Meanwhile the greedy stopped the moment everyone was covered — nineteen sockets of a twenty-four socket budget, with posts sitting unread on the five it never opened. So it takes six relays per author instead of three, and keeps picking until the budget is spent rather than until coverage is met. Measured over the same 250 authors, twice: 1265 notes before, 1549 after, 502 of them notes the old plan never saw. Same socket count we already allowed. Raising the per-author number ALONE makes it worse, which is worth knowing: more relays per author let a few fat ones cover everybody in nine sockets, and the feed read less than before (1089 against 1312). The two changes only work together. feed-follow-test now seeds one author with six write relays and asserts all six are dialled, so neither knob can drift back on its own. Co-Authored-By: Claude Opus 5 (1M context) Claude-Session: https://claude.ai/code/session_019mrt228Upn9nNCwGixzSLx --- tools/feed-follow-test.js | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) (limited to 'tools') diff --git a/tools/feed-follow-test.js b/tools/feed-follow-test.js index ae486a6..9537e9c 100644 --- a/tools/feed-follow-test.js +++ b/tools/feed-follow-test.js @@ -100,6 +100,29 @@ try { check('...and our own relays are still asked as well', dialled.some((u) => u.includes('relay.coinos.io')), dialled.length + ' sockets'); + // Covering every author once is not the same as reading them. People + // publish to several relays and each holds a different slice — measured + // over 250 real authors, seven of twenty-five sampled had posts living + // only on their fourth or later write relay, and spending the whole socket + // budget instead of stopping at first coverage found a quarter more posts. + // So a lone author with six relays must be read on all six, not three. + await page.evaluate(([k, a]) => { + localStorage.setItem(k + ':follows', JSON.stringify({ tags: [['p', a]], c: '', at: Math.floor(Date.now() / 1000) })); + localStorage.setItem(k + ':relayLists', JSON.stringify({ + [a]: { r: [1, 2, 3, 4, 5, 6].map((n) => 'wss://r' + n + '.example.invalid'), t: Date.now() }, + })); + }, [base, FOLLOWED]); + await page.reload({ waitUntil: 'domcontentloaded' }); + await waitText('receive', 20000); + await page.evaluate(() => { const b = [...document.querySelectorAll('button')].find((e) => /message/i.test(e.getAttribute('aria-label') || '')); if (b) b.click(); }); + await sleep(1000); + await clickItem('feed'); + await sleep(6000); + const wide = await page.evaluate(() => window.__dialled || []); + const hit = [1, 2, 3, 4, 5, 6].filter((n) => wide.some((u) => u.includes('r' + n + '.example.invalid'))); + check('an author who publishes to six relays is read on all six', + hit.length === 6, 'reached ' + (hit.join(',') || 'none')); + // The feed opens at twenty posts and grows as you reach the bottom, however // many it is holding. await page.evaluate((k) => { -- cgit v1.2.3