<rss
      xmlns:atom="http://www.w3.org/2005/Atom"
      xmlns:media="http://search.yahoo.com/mrss/"
      xmlns:content="http://purl.org/rss/1.0/modules/content/"
      xmlns:itunes="http://www.itunes.com/dtds/podcast-1.0.dtd"
      xmlns:dc="http://purl.org/dc/elements/1.1/"
      version="2.0"
    >
      <channel>
        <title><![CDATA[hodlbod]]></title>
        <description><![CDATA[Christian Bitcoiner and developer of the coracle.social nostr client.
Learn more at https://coracle.tools]]></description>
        <link>https://hodlbod.npub.pro/tag/coracle/</link>
        <atom:link href="https://hodlbod.npub.pro/tag/coracle/rss/" rel="self" type="application/rss+xml"/>
        <itunes:new-feed-url>https://hodlbod.npub.pro/tag/coracle/rss/</itunes:new-feed-url>
        <itunes:author><![CDATA[ hodlbod]]></itunes:author>
        <itunes:subtitle><![CDATA[Christian Bitcoiner and developer of the coracle.social nostr client.
Learn more at https://coracle.tools]]></itunes:subtitle>
        <itunes:type>episodic</itunes:type>
        <itunes:owner>
          <itunes:name><![CDATA[ hodlbod]]></itunes:name>
          <itunes:email><![CDATA[ hodlbod]]></itunes:email>
        </itunes:owner>
            
      <pubDate>Thu, 29 Aug 2024 00:50:27 GMT</pubDate>
      <lastBuildDate>Thu, 29 Aug 2024 00:50:27 GMT</lastBuildDate>
      
      <itunes:image href="https://i.nostr.build/AZ0L.jpg" />
      <image>
        <title><![CDATA[hodlbod]]></title>
        <link>https://hodlbod.npub.pro/tag/coracle/</link>
        <url>https://i.nostr.build/AZ0L.jpg</url>
      </image>
      <item>
      <title><![CDATA[What is the Outbox Model?]]></title>
      <description><![CDATA[An explainer on the Outbox Model, including what it is, where it came from, and why it's integral to making nostr work.]]></description>
             <itunes:subtitle><![CDATA[An explainer on the Outbox Model, including what it is, where it came from, and why it's integral to making nostr work.]]></itunes:subtitle>
      <pubDate>Thu, 29 Aug 2024 00:50:27 GMT</pubDate>
      <link>https://hodlbod.npub.pro/post/8yjqxm4sky-tauwjoflxs/</link>
      <comments>https://hodlbod.npub.pro/post/8yjqxm4sky-tauwjoflxs/</comments>
      <guid isPermaLink="false">naddr1qq2nskt2w9vx6dznfdvj64rpw4mk5nmxf3v9xq3qjlrs53pkdfjnts29kveljul2sm0actt6n8dxrrzqcersttvcuv3qxpqqqp65wzfj8s4</guid>
      <category>nostr</category>
      
        <media:content url="https://yakihonne.s3.ap-east-1.amazonaws.com/97c70a44366a6535c145b333f973ea86dfdc2d7a99da618c40c64705ad98e322/files/1724892627307-YAKIHONNES3.jpg" medium="image"/>
        <enclosure 
          url="https://yakihonne.s3.ap-east-1.amazonaws.com/97c70a44366a6535c145b333f973ea86dfdc2d7a99da618c40c64705ad98e322/files/1724892627307-YAKIHONNES3.jpg" length="0" 
          type="image/jpeg" 
        />
      <noteId>naddr1qq2nskt2w9vx6dznfdvj64rpw4mk5nmxf3v9xq3qjlrs53pkdfjnts29kveljul2sm0actt6n8dxrrzqcersttvcuv3qxpqqqp65wzfj8s4</noteId>
      <npub>npub1jlrs53pkdfjnts29kveljul2sm0actt6n8dxrrzqcersttvcuv3qdjynqn</npub>
      <dc:creator><![CDATA[ hodlbod]]></dc:creator>
      <content:encoded><![CDATA[<p>Nostr is a mess. It always has been and will always be. That's part of the appeal! But it's important that users be able to navigate the rolling seas of this highly partition-tolerant network of kaleidoscopically-interwoven people, bots, topics, relays, clients, events, recommendations, lists, feeds, micro-apps, macro-apps, Chinese spam, and "GM"s.</p>
<p>In order to do this, users must be able to articulate "what" they are looking for, and clients must be able to articulate "how" to find that thing. This "how" is divided into two parts: building a request that will match the desired content (very easy), and selecting a relay that is able to serve that content to the user requesting it (very very hard).</p>
<h1>Why guessing isn't good enough</h1>
<p>As a concrete example, let's say the user wants to find everyone in their "network" who is using a particular topic. The process would look something like this:</p>
<ol>
<li>The user clicks the "network" tab and types in the topic they want to browse. This is the "what".</li>
<li>The client then translates the term "network" to a list of public keys using whatever definition they prefer (Follows? WoT? Grapevine?), and builds a filter that might look something like this: <code>[{"authors": pubkeys, "#t": ["mytopic"]}]</code>. Any relay will happily accept, understand, and respond to that filter.</li>
<li>The client then has to decide which relays it should send that filter to. This is the <code>???</code> stage of the outbox model, which immediately precedes:</li>
<li>Profit</li>
</ol>
<p>It may not be immediately obvious why selecting the correct relays might be difficult. Most people post to relay.damus.io, and most people read from relay.damus.io, so in most cases you should be good, right?</p>
<p>This approach to relay selection has historically worked "well enough", but it depends on a flawed definition of success. If you only want to find 90% of the content that matches your query, using the top 10 relays will suffice. But nostr is intended to be censorship-resistant. What if those 10 hubs have banned a particular public key? Nostr clients should (at least in theory) be 100% successful in retrieving requested content. Even if someone only posts to their self-hosted relay, you should be able to find their notes if their account is set up properly.</p>
<h1>A naive solution to fixing the FOMO</h1>
<p>A 90% hit rate results in a feeling of flakiness, even if users aren't completely aware of what isn't working. Feeds will be incomplete, quoted notes will be missing, replies will be orphaned, user profiles won't load. The natural response to the FOMO this creates is for users to "try harder" by adding more relays.</p>
<p>On the read side, this means clients open more connections, resulting in much higher data transfer requirements, with massively diminishing returns, since there's no reason to expect that a randomly chosen relay will have a substantially different data set.</p>
<p>One the publish side, this means that clients end up publishing more copies of their data to more relays. This approach has been automated in the past by services like Blastr, which don't store a copy of events published to the relay, but instead forward events to the top 300 relays in the network. This results in a two-orders-of-magnitude increase in storage required, and only makes the read side of the problem worse, since it reduces the uniqueness of the data set each relay stores. This in turn means that more duplicates are retrieved when querying relays.</p>
<p>Both halves of this approach are equivalent to guessing. On the read side, users are guessing which relays will have any arbitrary content they might ask for in the future. On the write side, users are guessing which relays other people might use to find their notes. It is a brute-force method for finding content.</p>
<h1>Randomness results in centralization</h1>
<p>In theory, random relay selection would result in a perfect distribution of content across all relays in the network. But in practice, this method of selection isn't random at all, but is strongly influenced by user bias in what constitutes a "good" relay. While some users may check <a href="https://nostr.watch">nostr.watch</a> for ping times, geographical proximity, or uptime, most will choose relays based on familiar names or other people's recommendations.</p>
<p>In either case, these biases are entirely orthogonal to achieving a higher content retrieval hit rate, <em>except when bias in relay selection results in clustering</em> — i.e., centralization. In other words, the kind of randomness exhibited by users when selecting relays actually results in pretty much everyone picking the same few relays. We see this same effect when people try to come up with passwords or seed phrases — human-provided randomness is anything but random.</p>
<p>Clustering improves the hit rate when requesting events (slightly), but it results in nearly as much centralization as if only a single relay was used —&nbsp;and a lot more duplicate events.</p>
<h1>Something (anything) other than randomness</h1>
<p>In early 2023, Mike Dilger <a href="https://github.com/nostr-protocol/nips/pull/218">introduced NIP 65</a> (now known as the "Outbox Model") with a problem statement in the spirit of the original description of nostr: "Nostr should scale better. People should be able to find what they want."</p>
<p><em>Historical note: NIP 65 was formerly known as the "Gossip Model", derived from the name of Mike's <a href="https://github.com/mikedilger/gossip">desktop nostr client</a>, called "Gossip". This unfortunately created a lot of confusion, since <a href="https://en.wikipedia.org/wiki/Gossip_protocol">gossip protocols</a> work very differently from how nostr tends to work, hence the re-brand.</em></p>
<p>Before NIP 65, an informal standard existed in which <code>kind 3</code> user contact lists also included a list of relays that clients could use as something similar to Mastodon's "home servers". This list included the option to only read or write from a given relay. Unfortunately, it wasn't really clear what the semantics of this relay list were, so different clients handled them differently (and many clients ignored them). Usually this amounted to user-provided static relay configurations, which resulted in the naive relay selection approach described above.</p>
<p>NIP 65 used a very similar format (a list of relay urls with optional "read" or "write" directives), but with a very important semantic difference: relays listed in a user's <code>kind 10002</code> were intended to "advertise to others, not for configuring one's client." In other words, these relay selections were intended as a signal to other users that they should use certain relays when attempting to communicate with the author of the relay list.</p>
<p>I highly recommend reading the <a href="https://github.com/nostr-protocol/nips/blob/master/65.md">entire NIP</a>, which is very short and easy to read. But the mechanics of the spec are very simple:</p>
<blockquote>
<p>When seeking events&nbsp;<strong>from</strong>&nbsp;a user, Clients SHOULD use the WRITE relays of the user's&nbsp;<code>kind:10002</code>.</p>
<p>When seeking events&nbsp;<strong>about</strong>&nbsp;a user, where the user was tagged, Clients SHOULD use the READ relays of the user's&nbsp;<code>kind:10002</code>.</p>
<p>When broadcasting an event, Clients SHOULD:</p>
<ul>
<li>Broadcast the event to the WRITE relays of the author</li>
<li>Broadcast the event to all READ relays of each tagged user</li>
</ul>
</blockquote>
<p>For the first time, we had a way to differentiate relays in terms of <em>what content could be found where</em>.</p>
<p>When looking for a note by a particular user, a client could now look up the author's <code>write</code> relays according to their <code>kind 10002</code> event, and send its query there. The result is a much higher hit rate with much lower data transfer requirements, and fewer connections per query.</p>
<h1>Making Outbox Work</h1>
<p>There are of course some assumptions required to make this work. </p>
<p>First, the user must know which author they're looking for. This isn't always true when looking up a quote or parent note, but context and <a href="https://github.com/nostr-protocol/nips/pull/1171">pubkey hints</a> solve this difficulty in most cases.</p>
<p>The author must also publish a <code>kind 10002</code> event. This may not always be the case, but clients should prompt users to set up their relay list correctly. This isn't really a flaw in the Outbox Model, just in implementations of it.</p>
<p>Additionally, the user's client must be able to find the author's <code>kind 10002</code> event. This is the "bootstrapping" phase of the Outbox Model, during which the mechanisms the system provides for finding events aren't available. This requires us to fall back to randomly guessing which relays have the content we're looking for, which as we saw above doesn't work very well.</p>
<p>Other than guessing, there are a few different ways a client might find the relay selection event in question, each of which is applicable in different circumstances. In most cases, using one of a handful of indexer relays like <a href="wss://purplepag.es">purplepag.es</a> or <a href="wss://relay.nostr.band">relay.nostr.band</a> is a simple and efficient way to find user profiles and relay selections.</p>
<p>However, if an author's content has been aggressively purged from these indexers due to censorship, they obviously can't be relied upon. Even though the author in question hasn't been deplatformed from nostr itself (since he can always self-host a publicly accessible relay to store his content), he has been effectively shadow-banned.</p>
<p>To get around this, relay selections have to be communicated in some other way. Nostr has a few different mechanisms for this:</p>
<ul>
<li>If the author's NIP 05 address is known and properly configured (it may not be), clients can look up the author's NIP 05 endpoint to find some reasonable relay hints. Unfortunately, these are often neglected, and usually custodial, so they can run into the same problems.</li>
<li>If the author's pubkey is found in another signed event found on nostr, <a href="https://github.com/nostr-protocol/nips/blob/fade0164f52033314bf0a5ef9bd63c2483afae9b/10.md#marked-e-tags-preferred">relay hints</a> can be a way to propagate relay selections through the network. This relies on implementations picking reliable relay hints which can be difficult, and hints do tend to become less reliable over time. However, this strategy is very effective in resisting censorship because it makes banning viral — if a relay wants to completely purge a particular pubkey from their database, they have to purge every event that references it, since events are tamper-proof.</li>
<li>In extremis, relay recommendations can always be communicated out-of-band. This can be done using manual input, QR codes, DHTs, jsonl torrents full of <code>kind 10002</code> events, or any other mechanism client developers choose to resort to.</li>
</ul>
<p>Another, more technical assumption is that any given query can be fulfilled by few enough relays that a client can actually make all the connections needed, without running into resource limits. If you're trying to request content from 10,000 users across 1,000 relays, you're going to have a bad time. This was <a href="https://coracle.social/nevent1qythwumn8ghj76twvfhhstnwdaehgu3wwa5kuef0qyv8wumn8ghj7cm9d3kxzu3wdehhxarj9emkjmn99uq3samnwvaz7tmrwfjkzarj9ehx7um5wgh8w6twv5hsqgrn7l6zj7ht6ruyk76vvvtkfs4xrhyzc3tm64l3eyfvd40y26sz0gshmunh">pointed out</a> to me by Mazin of <a href="https://nostr.wine">nostr.wine</a>. He makes a good point, and it's definitely something to keep in mind. There are some mitigating factors though.</p>
<p>The first is that the current topology of the network probably won't persist forever. Because nostr is largely populated by self-hosting enthusiasts, the number of "tiny" relays is proportionally much higher than it will be if adoption picks up, even if the total number of relays grows. The trajectory is that nostr will drift toward fewer, larger relays, reducing the number of connections needed to fulfill any given query.</p>
<p>This is "centralizing", but it's important to understand that this isn't necessarily a bad thing. As long as there are more than one or two large hubs, there is user choice. And as long as it's possible to run a new relay, there is always an escape hatch. Nostr, like bitcoin, has no hard dependency on the biggest player in the network.</p>
<p>The other thing to consider is that there are lots of other techniques we can use to overcome the limits of the lowest-common denominator's limitations (mobile browser clients), including self hosted or third-party relay proxies. The trade-off here is that a little trust (aka centralization) can go a long way to reducing resource requirements needed to fulfill queries using the Outbox model.</p>
<p>If you're interested in more details on this topic, see <a href="https://habla.news/u/hodlbod@coracle.social/sfwV1rNaoQXd65PbIMYgm">this blog post</a>.</p>
<p>That was a long digression, but there is one other thing that the Outbox model assumes to be the case. Even if the correct relays are found and connected to, they still may not return all desired content, either because they don't have it, or because they refuse to return it to the user requesting it.</p>
<p>This can happen if the publishing client isn't following the Outbox Model, if the author had migrated from one relay set to another without copying their notes over, or if the relay in question chose not to retain the author's content for some reason.</p>
<p>The first two issues can be fixed by improving implementations, but the question of policy is a little more interesting.</p>
<h1>Relativistic relays</h1>
<p>The Outbox Model is a mechanical process; it's only as useful as user relay selections are. In order for it to work, users have to be able to make intelligent relay selections.</p>
<p>Every relay has trade-offs, depending on its policy. <a href="wss://140.f7z.io">140.f7z.io</a> would not be useful for long-form content, for example. Some relays might have a content retention policy that changes depending on whether you're a paying user. If you don't pay, you might find out too late that your content has been deleted from the relay.</p>
<p>So what makes a relay "good" for a particular use case? Well, it's complicated. Here are a few factors that go into that calculus:</p>
<ul>
<li>Is the relay in the same geographical as the user? Proximity reduces latency, but jurisdictional arbitrage might be desired. Users should probably have a variety of relays that fit different profiles.</li>
<li>Will the relay ban the user? Do the operators have a history of good behavior? Is the relay focused on particular types of content? Is the relay's focus consistent with the user's goal in adding that relay to their list?</li>
<li>What are the relay's retention policies? A user might want to set up an archival relay for her old content, or a multi-availability-zone relay so her notes are immediately accessible to the rest of the network.</li>
<li>Does the relay require payment? Paid relays are more aligned with their users, but obviously come at a financial cost.</li>
<li>Does the relay have policies for read-protecting content? If so, other users might not be able to find your posts published to that relay. On the other hand, some relays are configured to work as inboxes for direct messages, which can help preserve privacy.</li>
<li>Does the relay request that users authenticate? Authentication can help manage spam, but it also allows relays to correlate content requests with users, reducing user privacy.</li>
<li>Is the relay you use hosted by your client's developer? If so, you're in danger of getting banned from your client and your relay at the same time.</li>
<li>Is the relay a hub? Using hubs can help smooth out rough areas in Outbox Model implementations, at the cost of centralization.</li>
<li>Is the relay used by anyone else? One-off relays can be useful for archival purposes, but often won't be used by clients following the Outbox Model, depending on how they optimize requests.</li>
</ul>
<p>There are lots of ways to approach the problem of helping users select relays, but it's an inherently complex problem which very few people will have the patience to properly address on their own. Relay selection is a multi-dimensional problem, and requires satisfying multiple constraints with a limited number of relay selections.</p>
<p>In the future, special-purpose clients might be used to help people build relay sets. Clients also might provide curated "relay kits" that users can choose and customize. Or, we might see an increase in hybrid solutions, like smarter relay proxies or client-local relays that synchronize using other protocols or platforms.</p>
<h1>The Limitations of Outbox</h1>
<p>Outbox is not a complete solution, not because of any of the caveats listed above, but because NIP 65 per se only addresses the question of how to index content by pubkey in a broadcast social media context. But there are many other scenarios for relay selection that Outbox does not solve:</p>
<ul>
<li>Community, chat, and group posts might be best posted to relays dedicated to that context.</li>
<li>Direct messages shouldn't follow the same contours as public social media content.</li>
<li>Topic-oriented relays, or relays serving a custom feed might be useful independent of who uses them.</li>
<li>Relays focused on serving a particular kind of event, like music, long-form content, or relay selections, are useful independent of who reads from or writes to them.</li>
<li>Certain clients might need to fulfill particular use cases by using relays that support certain protocol features, like search, count, or sync commands.</li>
<li>Some events might not make sense to publish to relays, but should instead be shared only directly, out of band.</li>
</ul>
<p>Some of these use cases might be solved by new specifications similar to Outbox that prescribe where certain data belongs&nbsp;— for example, <a href="https://github.com/nostr-protocol/nips/blob/master/17.md">NIP 17</a> requires users to publish a different relay list before they can receive direct messages, while <a href="https://github.com/nostr-protocol/nips/blob/master/72.md">NIP 72</a> places community relay recommendations directly into the group's metadata object. A reasonably complete list of different relay types can be found in <a href="https://github.com/nostr-protocol/nips/issues/1282">this PR</a>, very few of which have a canonical way to manage selections.</p>
<p>Other use cases might be supported more informally, either by relays advertising their own value proposition, or via third-party <a href="https://github.com/nostr-protocol/nips/pull/230">NIP 66</a> metadata. Still others might be supported by scoping the network down to only certain relays through explicit relay selection — this is how white-labeled <a href="https://coracle.tools/">Coracle instances</a> work.</p>
<p>The basic idea here is that there are categories of events that don't have anything to do with where a particular person puts his or her "tweets". For every "what" on nostr, there should be a "how".</p>
<h1>Keep nostr weird</h1>
<p>Whatever additional systems we end up adopting for helping with relay selection, one thing is certain — people will continue to discover new, creative uses for relays, and we will always be playing catch up. This is one of the coolest things about nostr!</p>
<p>But it does mean that users will have to adapt their expectations to a network that partitions, re-configures, and evolves over time. Nostr is not a "worse" experience than legacy social media, but it is a version of social media that has itself been set free from the stagnant walled-garden model. Nostr is in many ways a living organism — we should be careful not to impose our expectations prematurely, leaving room to discover what this thing actually is, or can be.</p>
<p>If you enjoyed this post but want more take a look at the talk I gave at <a href="https://www.youtube.com/live/Nz15SyiwQFk?t=2751s">Nostrasia</a> last year. I also wrote up a <a href="https://habla.news/u/hodlbod@coracle.social/1700155417145">blog post</a> at about the same time that addresses some of the same issues, but focuses more on privacy concerns around relays and nostr groups. Finally, I recently wrote <a href="https://github.com/nostrability/nostrability/issues/69#issuecomment-2310524841">this comment</a>, which includes some details about challenges I've faced putting Outbox into Coracle.</p>
]]></content:encoded>
      <itunes:author><![CDATA[ hodlbod]]></itunes:author>
      <itunes:summary><![CDATA[<p>Nostr is a mess. It always has been and will always be. That's part of the appeal! But it's important that users be able to navigate the rolling seas of this highly partition-tolerant network of kaleidoscopically-interwoven people, bots, topics, relays, clients, events, recommendations, lists, feeds, micro-apps, macro-apps, Chinese spam, and "GM"s.</p>
<p>In order to do this, users must be able to articulate "what" they are looking for, and clients must be able to articulate "how" to find that thing. This "how" is divided into two parts: building a request that will match the desired content (very easy), and selecting a relay that is able to serve that content to the user requesting it (very very hard).</p>
<h1>Why guessing isn't good enough</h1>
<p>As a concrete example, let's say the user wants to find everyone in their "network" who is using a particular topic. The process would look something like this:</p>
<ol>
<li>The user clicks the "network" tab and types in the topic they want to browse. This is the "what".</li>
<li>The client then translates the term "network" to a list of public keys using whatever definition they prefer (Follows? WoT? Grapevine?), and builds a filter that might look something like this: <code>[{"authors": pubkeys, "#t": ["mytopic"]}]</code>. Any relay will happily accept, understand, and respond to that filter.</li>
<li>The client then has to decide which relays it should send that filter to. This is the <code>???</code> stage of the outbox model, which immediately precedes:</li>
<li>Profit</li>
</ol>
<p>It may not be immediately obvious why selecting the correct relays might be difficult. Most people post to relay.damus.io, and most people read from relay.damus.io, so in most cases you should be good, right?</p>
<p>This approach to relay selection has historically worked "well enough", but it depends on a flawed definition of success. If you only want to find 90% of the content that matches your query, using the top 10 relays will suffice. But nostr is intended to be censorship-resistant. What if those 10 hubs have banned a particular public key? Nostr clients should (at least in theory) be 100% successful in retrieving requested content. Even if someone only posts to their self-hosted relay, you should be able to find their notes if their account is set up properly.</p>
<h1>A naive solution to fixing the FOMO</h1>
<p>A 90% hit rate results in a feeling of flakiness, even if users aren't completely aware of what isn't working. Feeds will be incomplete, quoted notes will be missing, replies will be orphaned, user profiles won't load. The natural response to the FOMO this creates is for users to "try harder" by adding more relays.</p>
<p>On the read side, this means clients open more connections, resulting in much higher data transfer requirements, with massively diminishing returns, since there's no reason to expect that a randomly chosen relay will have a substantially different data set.</p>
<p>One the publish side, this means that clients end up publishing more copies of their data to more relays. This approach has been automated in the past by services like Blastr, which don't store a copy of events published to the relay, but instead forward events to the top 300 relays in the network. This results in a two-orders-of-magnitude increase in storage required, and only makes the read side of the problem worse, since it reduces the uniqueness of the data set each relay stores. This in turn means that more duplicates are retrieved when querying relays.</p>
<p>Both halves of this approach are equivalent to guessing. On the read side, users are guessing which relays will have any arbitrary content they might ask for in the future. On the write side, users are guessing which relays other people might use to find their notes. It is a brute-force method for finding content.</p>
<h1>Randomness results in centralization</h1>
<p>In theory, random relay selection would result in a perfect distribution of content across all relays in the network. But in practice, this method of selection isn't random at all, but is strongly influenced by user bias in what constitutes a "good" relay. While some users may check <a href="https://nostr.watch">nostr.watch</a> for ping times, geographical proximity, or uptime, most will choose relays based on familiar names or other people's recommendations.</p>
<p>In either case, these biases are entirely orthogonal to achieving a higher content retrieval hit rate, <em>except when bias in relay selection results in clustering</em> — i.e., centralization. In other words, the kind of randomness exhibited by users when selecting relays actually results in pretty much everyone picking the same few relays. We see this same effect when people try to come up with passwords or seed phrases — human-provided randomness is anything but random.</p>
<p>Clustering improves the hit rate when requesting events (slightly), but it results in nearly as much centralization as if only a single relay was used —&nbsp;and a lot more duplicate events.</p>
<h1>Something (anything) other than randomness</h1>
<p>In early 2023, Mike Dilger <a href="https://github.com/nostr-protocol/nips/pull/218">introduced NIP 65</a> (now known as the "Outbox Model") with a problem statement in the spirit of the original description of nostr: "Nostr should scale better. People should be able to find what they want."</p>
<p><em>Historical note: NIP 65 was formerly known as the "Gossip Model", derived from the name of Mike's <a href="https://github.com/mikedilger/gossip">desktop nostr client</a>, called "Gossip". This unfortunately created a lot of confusion, since <a href="https://en.wikipedia.org/wiki/Gossip_protocol">gossip protocols</a> work very differently from how nostr tends to work, hence the re-brand.</em></p>
<p>Before NIP 65, an informal standard existed in which <code>kind 3</code> user contact lists also included a list of relays that clients could use as something similar to Mastodon's "home servers". This list included the option to only read or write from a given relay. Unfortunately, it wasn't really clear what the semantics of this relay list were, so different clients handled them differently (and many clients ignored them). Usually this amounted to user-provided static relay configurations, which resulted in the naive relay selection approach described above.</p>
<p>NIP 65 used a very similar format (a list of relay urls with optional "read" or "write" directives), but with a very important semantic difference: relays listed in a user's <code>kind 10002</code> were intended to "advertise to others, not for configuring one's client." In other words, these relay selections were intended as a signal to other users that they should use certain relays when attempting to communicate with the author of the relay list.</p>
<p>I highly recommend reading the <a href="https://github.com/nostr-protocol/nips/blob/master/65.md">entire NIP</a>, which is very short and easy to read. But the mechanics of the spec are very simple:</p>
<blockquote>
<p>When seeking events&nbsp;<strong>from</strong>&nbsp;a user, Clients SHOULD use the WRITE relays of the user's&nbsp;<code>kind:10002</code>.</p>
<p>When seeking events&nbsp;<strong>about</strong>&nbsp;a user, where the user was tagged, Clients SHOULD use the READ relays of the user's&nbsp;<code>kind:10002</code>.</p>
<p>When broadcasting an event, Clients SHOULD:</p>
<ul>
<li>Broadcast the event to the WRITE relays of the author</li>
<li>Broadcast the event to all READ relays of each tagged user</li>
</ul>
</blockquote>
<p>For the first time, we had a way to differentiate relays in terms of <em>what content could be found where</em>.</p>
<p>When looking for a note by a particular user, a client could now look up the author's <code>write</code> relays according to their <code>kind 10002</code> event, and send its query there. The result is a much higher hit rate with much lower data transfer requirements, and fewer connections per query.</p>
<h1>Making Outbox Work</h1>
<p>There are of course some assumptions required to make this work. </p>
<p>First, the user must know which author they're looking for. This isn't always true when looking up a quote or parent note, but context and <a href="https://github.com/nostr-protocol/nips/pull/1171">pubkey hints</a> solve this difficulty in most cases.</p>
<p>The author must also publish a <code>kind 10002</code> event. This may not always be the case, but clients should prompt users to set up their relay list correctly. This isn't really a flaw in the Outbox Model, just in implementations of it.</p>
<p>Additionally, the user's client must be able to find the author's <code>kind 10002</code> event. This is the "bootstrapping" phase of the Outbox Model, during which the mechanisms the system provides for finding events aren't available. This requires us to fall back to randomly guessing which relays have the content we're looking for, which as we saw above doesn't work very well.</p>
<p>Other than guessing, there are a few different ways a client might find the relay selection event in question, each of which is applicable in different circumstances. In most cases, using one of a handful of indexer relays like <a href="wss://purplepag.es">purplepag.es</a> or <a href="wss://relay.nostr.band">relay.nostr.band</a> is a simple and efficient way to find user profiles and relay selections.</p>
<p>However, if an author's content has been aggressively purged from these indexers due to censorship, they obviously can't be relied upon. Even though the author in question hasn't been deplatformed from nostr itself (since he can always self-host a publicly accessible relay to store his content), he has been effectively shadow-banned.</p>
<p>To get around this, relay selections have to be communicated in some other way. Nostr has a few different mechanisms for this:</p>
<ul>
<li>If the author's NIP 05 address is known and properly configured (it may not be), clients can look up the author's NIP 05 endpoint to find some reasonable relay hints. Unfortunately, these are often neglected, and usually custodial, so they can run into the same problems.</li>
<li>If the author's pubkey is found in another signed event found on nostr, <a href="https://github.com/nostr-protocol/nips/blob/fade0164f52033314bf0a5ef9bd63c2483afae9b/10.md#marked-e-tags-preferred">relay hints</a> can be a way to propagate relay selections through the network. This relies on implementations picking reliable relay hints which can be difficult, and hints do tend to become less reliable over time. However, this strategy is very effective in resisting censorship because it makes banning viral — if a relay wants to completely purge a particular pubkey from their database, they have to purge every event that references it, since events are tamper-proof.</li>
<li>In extremis, relay recommendations can always be communicated out-of-band. This can be done using manual input, QR codes, DHTs, jsonl torrents full of <code>kind 10002</code> events, or any other mechanism client developers choose to resort to.</li>
</ul>
<p>Another, more technical assumption is that any given query can be fulfilled by few enough relays that a client can actually make all the connections needed, without running into resource limits. If you're trying to request content from 10,000 users across 1,000 relays, you're going to have a bad time. This was <a href="https://coracle.social/nevent1qythwumn8ghj76twvfhhstnwdaehgu3wwa5kuef0qyv8wumn8ghj7cm9d3kxzu3wdehhxarj9emkjmn99uq3samnwvaz7tmrwfjkzarj9ehx7um5wgh8w6twv5hsqgrn7l6zj7ht6ruyk76vvvtkfs4xrhyzc3tm64l3eyfvd40y26sz0gshmunh">pointed out</a> to me by Mazin of <a href="https://nostr.wine">nostr.wine</a>. He makes a good point, and it's definitely something to keep in mind. There are some mitigating factors though.</p>
<p>The first is that the current topology of the network probably won't persist forever. Because nostr is largely populated by self-hosting enthusiasts, the number of "tiny" relays is proportionally much higher than it will be if adoption picks up, even if the total number of relays grows. The trajectory is that nostr will drift toward fewer, larger relays, reducing the number of connections needed to fulfill any given query.</p>
<p>This is "centralizing", but it's important to understand that this isn't necessarily a bad thing. As long as there are more than one or two large hubs, there is user choice. And as long as it's possible to run a new relay, there is always an escape hatch. Nostr, like bitcoin, has no hard dependency on the biggest player in the network.</p>
<p>The other thing to consider is that there are lots of other techniques we can use to overcome the limits of the lowest-common denominator's limitations (mobile browser clients), including self hosted or third-party relay proxies. The trade-off here is that a little trust (aka centralization) can go a long way to reducing resource requirements needed to fulfill queries using the Outbox model.</p>
<p>If you're interested in more details on this topic, see <a href="https://habla.news/u/hodlbod@coracle.social/sfwV1rNaoQXd65PbIMYgm">this blog post</a>.</p>
<p>That was a long digression, but there is one other thing that the Outbox model assumes to be the case. Even if the correct relays are found and connected to, they still may not return all desired content, either because they don't have it, or because they refuse to return it to the user requesting it.</p>
<p>This can happen if the publishing client isn't following the Outbox Model, if the author had migrated from one relay set to another without copying their notes over, or if the relay in question chose not to retain the author's content for some reason.</p>
<p>The first two issues can be fixed by improving implementations, but the question of policy is a little more interesting.</p>
<h1>Relativistic relays</h1>
<p>The Outbox Model is a mechanical process; it's only as useful as user relay selections are. In order for it to work, users have to be able to make intelligent relay selections.</p>
<p>Every relay has trade-offs, depending on its policy. <a href="wss://140.f7z.io">140.f7z.io</a> would not be useful for long-form content, for example. Some relays might have a content retention policy that changes depending on whether you're a paying user. If you don't pay, you might find out too late that your content has been deleted from the relay.</p>
<p>So what makes a relay "good" for a particular use case? Well, it's complicated. Here are a few factors that go into that calculus:</p>
<ul>
<li>Is the relay in the same geographical as the user? Proximity reduces latency, but jurisdictional arbitrage might be desired. Users should probably have a variety of relays that fit different profiles.</li>
<li>Will the relay ban the user? Do the operators have a history of good behavior? Is the relay focused on particular types of content? Is the relay's focus consistent with the user's goal in adding that relay to their list?</li>
<li>What are the relay's retention policies? A user might want to set up an archival relay for her old content, or a multi-availability-zone relay so her notes are immediately accessible to the rest of the network.</li>
<li>Does the relay require payment? Paid relays are more aligned with their users, but obviously come at a financial cost.</li>
<li>Does the relay have policies for read-protecting content? If so, other users might not be able to find your posts published to that relay. On the other hand, some relays are configured to work as inboxes for direct messages, which can help preserve privacy.</li>
<li>Does the relay request that users authenticate? Authentication can help manage spam, but it also allows relays to correlate content requests with users, reducing user privacy.</li>
<li>Is the relay you use hosted by your client's developer? If so, you're in danger of getting banned from your client and your relay at the same time.</li>
<li>Is the relay a hub? Using hubs can help smooth out rough areas in Outbox Model implementations, at the cost of centralization.</li>
<li>Is the relay used by anyone else? One-off relays can be useful for archival purposes, but often won't be used by clients following the Outbox Model, depending on how they optimize requests.</li>
</ul>
<p>There are lots of ways to approach the problem of helping users select relays, but it's an inherently complex problem which very few people will have the patience to properly address on their own. Relay selection is a multi-dimensional problem, and requires satisfying multiple constraints with a limited number of relay selections.</p>
<p>In the future, special-purpose clients might be used to help people build relay sets. Clients also might provide curated "relay kits" that users can choose and customize. Or, we might see an increase in hybrid solutions, like smarter relay proxies or client-local relays that synchronize using other protocols or platforms.</p>
<h1>The Limitations of Outbox</h1>
<p>Outbox is not a complete solution, not because of any of the caveats listed above, but because NIP 65 per se only addresses the question of how to index content by pubkey in a broadcast social media context. But there are many other scenarios for relay selection that Outbox does not solve:</p>
<ul>
<li>Community, chat, and group posts might be best posted to relays dedicated to that context.</li>
<li>Direct messages shouldn't follow the same contours as public social media content.</li>
<li>Topic-oriented relays, or relays serving a custom feed might be useful independent of who uses them.</li>
<li>Relays focused on serving a particular kind of event, like music, long-form content, or relay selections, are useful independent of who reads from or writes to them.</li>
<li>Certain clients might need to fulfill particular use cases by using relays that support certain protocol features, like search, count, or sync commands.</li>
<li>Some events might not make sense to publish to relays, but should instead be shared only directly, out of band.</li>
</ul>
<p>Some of these use cases might be solved by new specifications similar to Outbox that prescribe where certain data belongs&nbsp;— for example, <a href="https://github.com/nostr-protocol/nips/blob/master/17.md">NIP 17</a> requires users to publish a different relay list before they can receive direct messages, while <a href="https://github.com/nostr-protocol/nips/blob/master/72.md">NIP 72</a> places community relay recommendations directly into the group's metadata object. A reasonably complete list of different relay types can be found in <a href="https://github.com/nostr-protocol/nips/issues/1282">this PR</a>, very few of which have a canonical way to manage selections.</p>
<p>Other use cases might be supported more informally, either by relays advertising their own value proposition, or via third-party <a href="https://github.com/nostr-protocol/nips/pull/230">NIP 66</a> metadata. Still others might be supported by scoping the network down to only certain relays through explicit relay selection — this is how white-labeled <a href="https://coracle.tools/">Coracle instances</a> work.</p>
<p>The basic idea here is that there are categories of events that don't have anything to do with where a particular person puts his or her "tweets". For every "what" on nostr, there should be a "how".</p>
<h1>Keep nostr weird</h1>
<p>Whatever additional systems we end up adopting for helping with relay selection, one thing is certain — people will continue to discover new, creative uses for relays, and we will always be playing catch up. This is one of the coolest things about nostr!</p>
<p>But it does mean that users will have to adapt their expectations to a network that partitions, re-configures, and evolves over time. Nostr is not a "worse" experience than legacy social media, but it is a version of social media that has itself been set free from the stagnant walled-garden model. Nostr is in many ways a living organism — we should be careful not to impose our expectations prematurely, leaving room to discover what this thing actually is, or can be.</p>
<p>If you enjoyed this post but want more take a look at the talk I gave at <a href="https://www.youtube.com/live/Nz15SyiwQFk?t=2751s">Nostrasia</a> last year. I also wrote up a <a href="https://habla.news/u/hodlbod@coracle.social/1700155417145">blog post</a> at about the same time that addresses some of the same issues, but focuses more on privacy concerns around relays and nostr groups. Finally, I recently wrote <a href="https://github.com/nostrability/nostrability/issues/69#issuecomment-2310524841">this comment</a>, which includes some details about challenges I've faced putting Outbox into Coracle.</p>
]]></itunes:summary>
      <itunes:image href="https://yakihonne.s3.ap-east-1.amazonaws.com/97c70a44366a6535c145b333f973ea86dfdc2d7a99da618c40c64705ad98e322/files/1724892627307-YAKIHONNES3.jpg"/>
      </item>
      
      <item>
      <title><![CDATA[Where is my coracle going?]]></title>
      <description><![CDATA[A meandering vision statement for the future of the Coracle nostr client.]]></description>
             <itunes:subtitle><![CDATA[A meandering vision statement for the future of the Coracle nostr client.]]></itunes:subtitle>
      <pubDate>Tue, 26 Sep 2023 23:53:37 GMT</pubDate>
      <link>https://hodlbod.npub.pro/post/where-is-my-coracle-going/</link>
      <comments>https://hodlbod.npub.pro/post/where-is-my-coracle-going/</comments>
      <guid isPermaLink="false">naddr1qqvhw6r9wfjj66tn94khjttrdaexzcmvv5kkwmmfdensygyhcu9ygdn2v56uz3dnx0uh865xmlwz675emfsccsxxguz6mx8rygpsgqqqw4rs9ch9mg</guid>
      <category>nostr</category>
      
        <media:content url="https://image.nostr.build/529222f4d6befc4ecf3014a3c959938fddea8a5ea38e12f4222e3c3197982aa4.jpg" medium="image"/>
        <enclosure 
          url="https://image.nostr.build/529222f4d6befc4ecf3014a3c959938fddea8a5ea38e12f4222e3c3197982aa4.jpg" length="0" 
          type="image/jpeg" 
        />
      <noteId>naddr1qqvhw6r9wfjj66tn94khjttrdaexzcmvv5kkwmmfdensygyhcu9ygdn2v56uz3dnx0uh865xmlwz675emfsccsxxguz6mx8rygpsgqqqw4rs9ch9mg</noteId>
      <npub>npub1jlrs53pkdfjnts29kveljul2sm0actt6n8dxrrzqcersttvcuv3qdjynqn</npub>
      <dc:creator><![CDATA[ hodlbod]]></dc:creator>
      <content:encoded><![CDATA[<p>I've never piloted one, but I'm inclined to think that a coracle would be very hard to steer. No rudder, no keel, the thing is circular, it's not exactly a seagoing vessel. I've found the same to be true of my eponymous software project. I have many definite ideas of where I want it to go, most of which are in tension with one another. Plus, I'm prone to getting distracted by adding new features that aren't really core to my mission (whatever it is).</p>
<h1>What it ain't</h1>
<p>That fact was brought home to me this week as I worked for the nth time to repair the damage my refactoring did to the public chat feature in Coracle. This was the first feature I added as a response to popular demand and hype over a new NIP being added to nostr, way back in December 2022. Coracle was (I believe) the first general-purpose client to support public chat, which I hoped would bolster its notoriety.</p>
<p>I don't know if it helped Coracle's popularity, but it has cost me several weeks of development time in maintenance and abstraction cost since it was introduced. While it wouldn't be hard to apply the same content filtering work I've added to feeds in Coracle to chat, I'm not sure I want to continue to have my time stolen by sunk cost. And with the increasing frequency with which chat groups are being hijacked by spammers of various kinds, I no longer have the option of leaving chat alone.</p>
<p>So I've decided to remove group chat from Coracle. The implementation is still available, at <a href="https://chat.coracle.social">chat.coracle.social</a>, but unless a wild maintainer appears, it won't be receiving any updates for the foreseeable future. Chat was never a goal of my project, and while it may be one of the more popular features of Coracle, it's one of the least crucial.</p>
<p>This is just one of many illustrative features. In the same release in which I removed chat, I also added a background music player for kind 1808s. This is equally frivolous —&nbsp;but even more fun. It will likely live for a while, and disappear again someday.</p>
<h1>Set a course for ???, warp speed</h1>
<p>Now that Coracle is basically working™️ I need to take a step back and figure out what I want it to be. Even if I don't know where I'm headed, I'm still moving pretty fast. In order to make the best use of my grant from OpenSats, it's imperative that I at least have a mission statement.</p>
<p>In explaining to Vitor why I was removing chat, I accidentally articulated a pretty good one:</p>
<p><np-embed nostr="nevent1qqsfwxqv4qq5ajdx8yaksg2fwcw0enpykxvkl9kf2meqgheaq7f3ycgpz3mhxue69uhhyetvv9ujuerpd46hxtnfdufeeexz"><a href="https://njump.me/nevent1qqsfwxqv4qq5ajdx8yaksg2fwcw0enpykxvkl9kf2meqgheaq7f3ycgpz3mhxue69uhhyetvv9ujuerpd46hxtnfdufeeexz">nostr:nevent1qqsfwxqv4qq5ajdx8yaksg2fwcw0enpykxvkl9kf2meqgheaq7f3ycgpz3mhxue69uhhyetvv9ujuerpd46hxtnfdufeeexz</a></np-embed></p>
<p>The reason for this emphasis comes from the people I originally set out to build for: my church community. These people are generally not "internet-native". They aren't active on reddit, twitter, discord, twitch, tiktok, or youtube. To the extent they use social media, they post pictures on instagram, and buy and sell goods on facebook marketplace.</p>
<p>The features required to support a facebook analog are fairly obvious, and include event calendars, private groups, and marketplaces. However, there are a few dimensions to the problem that make building such a product more challenging than building a twitter clone.</p>
<h2>Product complexity</h2>
<p>One of the most consistent pieces of advice I've received about building a facebook clone is: don't. Facebook succeeded because it bundled multiple standalone tools into a single interface, and tied them together with a single social graph.</p>
<p>This is one of the things nostr solves — no longer do you need an everything app, if you can use micro-apps on an everything protocol. When I built <a href="https://zephyr.coracle.social">zephyr</a> last week, I was again stunned at how powerful building on nostr is. In half a day I put together something that would be impossible with traditional technologies —&nbsp;because if you don't have the ability to produce content on a centralized platform, you don't have the ability to consume it either.</p>
<p>But protocols feel different from platforms, especially for the layman. The other half of facebook's value add is (was) a simple and intuitive user interface, which not only made the different components available, but made them accessible as well. I don't think micro-apps, web app stores, or nostr browsers are complete solutions to the UX problem. Nothing can replace a design tailored to your specific end user.</p>
<h2>Privacy and parochialism</h2>
<p>Social graph partitioning is an essential part of designing a social network. In twitter-like applications, an an effective strategy might be described as "whatever". In other words, as long as you are able to 1. connect to the people you want to follow and 2. discover new content, you're fine — there's no need to be exhaustive or exclusive.</p>
<p>But tighter-knit communities require exclusivity. And by "community" I should qualify that I do not mean a reddit-style common interest, but a real locus of interdependence — whether intellectual, economic, or familial. You don't self-select into true communities except by way of a long (sometimes very long) probationary period.</p>
<p>But, as we learned from mastodon's failures, people are also members of multiple overlapping communities simultaneously. This means that an application designed to serve a person in multiple roles across multiple communities needs to be able to address those differing social circles according to their permeability. Enforcing community privacy using encryption might be appropriate for very tight groups like families, while other groups might want more lax rules about content sharing or member admission.</p>
<p>On nostr, relays are an excellent primitive for implementing access controls, and may be sufficient for all but the most private communication. I've also experimented with <a href="https://github.com/nostr-protocol/nips/pull/706">encrypted groups</a> (nostr-in-nostr), but the juice might not be worth the squeeze — the additional complexity of gift wrapping might not be necessary if relays can be trusted not to leak data.</p>
<p>Two different approaches to group-specific relays could be used, depending on the level of trust required for the community: an Uncle Jim model where one or more admins host the infrastructure, or a virtual relay model where the group admin creates a private space on commoditized infrastructure.</p>
<h2>The value of decentralization at a small scale</h2>
<p>Now, of course if you have admins, you've basically opted back in to siloed, centralized platforms, unless shared identity is a value add. Single sign on could be attractive, but not overwhelmingly so —&nbsp;I think the thing that makes an identity shared across multiple platforms compelling is the ability to cross-post.</p>
<p>Unless content is protected by encryption, this is always possible, and would be very good for end users. Allowing content from outside a group to be pulled into a group allows the group to comment on it using its own idioms and values. It also enables loose coupling between weakly-related communities (for example a church and the town it is located in).</p>
<p>This would work very well for community groups, which aren't usually too picky about driving engagement, but would work less well for publishers or media brands, even if cross-posting of content would be beneficial to their curated communities. Instead of increasing the value of your community, it could be seen (and exploited) as advertising for competing siloes.</p>
<h2>Multiple types of engagement</h2>
<p>Finally, there are multiple types of relationship that might be emphasized to a greater or lesser degree in one community vs another. Facebook-style "friends" are generally less focused on ideas, and more on maintaining relationships. I wouldn't want to read what my mom posts on social media, but I do want to stay in touch with her. In contrast, twitter-style "follows" are more oriented towards the flow of information itself, rather than relationships. An application directed at handling both types of "community" would need to respect the difference between the two.</p>
<h1>Toward something, anything</h1>
<p>With all that in mind, here's an attempt at articulating my vision for Coracle, loosely based on the <a href="https://www.eosworldwide.com/">EOS model</a> (no, not that EOS).</p>
<p>While my focus above has been on individuals as members of real-life communities, in practice many of these groups can be defined by a common interest in a given content "publisher", which is a more concrete (and practical) use case. This might be something as big as a newspaper, or as small as a substack or patreon. The content provides something for members of the group to talk about.</p>
<p>It seems to me that groups that are not content-focused operate in much the same way, except that topics are selected by group members, rather than by administrators. So the general strategy would be to build a product that can be used more informally by primarily targeting content publishers.</p>
<h2>Core Values</h2>
<ol>
<li>Real life &gt; digital life</li>
<li>Inorganic advertising is cancer</li>
<li>Encourage purposeful engagement</li>
<li>Different communities should be distinct, but mutually beneficial</li>
</ol>
<h2>Mission Statement</h2>
<p>To enrich the social media experience of individuals in their capacity as members of multiple overlapping real-world intellectual, economic, or relational communities.</p>
<h2>Target Market</h2>
<p>Small publishers who want to create a place for subscribers to interact with the publisher's (public and paid) content and one another. Media brands who are open to the benefits of cross-posting across siloes.</p>
<h2>What does it look like?</h2>
<ul>
<li>Anyone can create a group hosted on self-hosted or commodity relays, or a mixture of both.</li>
<li>A mixture of public and encrypted content for a given group</li>
<li>Cross-posting of public content between groups</li>
<li>Private content exclusive to group members</li>
<li>Multiple tiers of group membership </li>
<li>Configurable access control: admins, moderators, write access, read access</li>
<li>Invite codes, including referral discounts/rewards</li>
<li>Integrated calendar events (public and private)</li>
<li>Integrated marketplaces (publisher merchandise or peer-to-peer)</li>
<li>Support topical threads (oriented around publisher content) and member microblogging</li>
</ul>
<h2>Goals</h2>
<ul>
<li>A relay implementation that supports virtual relays with all required access controls</li>
<li>A group spec that supports granular content permissions and visibility</li>
<li>An end-user interface that supports browsing multiple groups and non-group content</li>
<li>An admin interface for group administration</li>
<li>White-labeled configurable client implementation</li>
</ul>
<h1>Addendum: Ditto</h1>
<p>Alex Gleason has been working on <a href="https://gitlab.com/soapbox-pub/ditto">Ditto</a> of late, which is first of all a way to reconcile ActivityPub and Nostr using a server implementation that supports both protocols, but which has the interesting side effect of marrying the siloed, exclusive ActivityPub model with nostr identities. This could be a good solution for branded clients and tighter community control, especially since it allows for the use of existing tools from ActivityPub's more mature ecosystem.</p>
<p> I intend to keep a close eye on Ditto as it matures. I hope that even if the two projects have a significant amount of overlap, that the problem space is big enough to allow for variations in execution, especially since Coracle has the ability to be fully nostr-native.</p>
<h1>Conclusion</h1>
<p>If you're currently a user of Coracle, don't worry too much, I won't be making any drastic changes anytime soon. I do think that the twitter-like, group-independent part of nostr is valuable, at least as a supplement to more cohesive communities. However, in order to achieve such an ambitious project, I'll have to exercise the discipline to remain focused and cut out any fat that accumulates. We'll see how I do.</p>
]]></content:encoded>
      <itunes:author><![CDATA[ hodlbod]]></itunes:author>
      <itunes:summary><![CDATA[<p>I've never piloted one, but I'm inclined to think that a coracle would be very hard to steer. No rudder, no keel, the thing is circular, it's not exactly a seagoing vessel. I've found the same to be true of my eponymous software project. I have many definite ideas of where I want it to go, most of which are in tension with one another. Plus, I'm prone to getting distracted by adding new features that aren't really core to my mission (whatever it is).</p>
<h1>What it ain't</h1>
<p>That fact was brought home to me this week as I worked for the nth time to repair the damage my refactoring did to the public chat feature in Coracle. This was the first feature I added as a response to popular demand and hype over a new NIP being added to nostr, way back in December 2022. Coracle was (I believe) the first general-purpose client to support public chat, which I hoped would bolster its notoriety.</p>
<p>I don't know if it helped Coracle's popularity, but it has cost me several weeks of development time in maintenance and abstraction cost since it was introduced. While it wouldn't be hard to apply the same content filtering work I've added to feeds in Coracle to chat, I'm not sure I want to continue to have my time stolen by sunk cost. And with the increasing frequency with which chat groups are being hijacked by spammers of various kinds, I no longer have the option of leaving chat alone.</p>
<p>So I've decided to remove group chat from Coracle. The implementation is still available, at <a href="https://chat.coracle.social">chat.coracle.social</a>, but unless a wild maintainer appears, it won't be receiving any updates for the foreseeable future. Chat was never a goal of my project, and while it may be one of the more popular features of Coracle, it's one of the least crucial.</p>
<p>This is just one of many illustrative features. In the same release in which I removed chat, I also added a background music player for kind 1808s. This is equally frivolous —&nbsp;but even more fun. It will likely live for a while, and disappear again someday.</p>
<h1>Set a course for ???, warp speed</h1>
<p>Now that Coracle is basically working™️ I need to take a step back and figure out what I want it to be. Even if I don't know where I'm headed, I'm still moving pretty fast. In order to make the best use of my grant from OpenSats, it's imperative that I at least have a mission statement.</p>
<p>In explaining to Vitor why I was removing chat, I accidentally articulated a pretty good one:</p>
<p><np-embed nostr="nevent1qqsfwxqv4qq5ajdx8yaksg2fwcw0enpykxvkl9kf2meqgheaq7f3ycgpz3mhxue69uhhyetvv9ujuerpd46hxtnfdufeeexz"><a href="https://njump.me/nevent1qqsfwxqv4qq5ajdx8yaksg2fwcw0enpykxvkl9kf2meqgheaq7f3ycgpz3mhxue69uhhyetvv9ujuerpd46hxtnfdufeeexz">nostr:nevent1qqsfwxqv4qq5ajdx8yaksg2fwcw0enpykxvkl9kf2meqgheaq7f3ycgpz3mhxue69uhhyetvv9ujuerpd46hxtnfdufeeexz</a></np-embed></p>
<p>The reason for this emphasis comes from the people I originally set out to build for: my church community. These people are generally not "internet-native". They aren't active on reddit, twitter, discord, twitch, tiktok, or youtube. To the extent they use social media, they post pictures on instagram, and buy and sell goods on facebook marketplace.</p>
<p>The features required to support a facebook analog are fairly obvious, and include event calendars, private groups, and marketplaces. However, there are a few dimensions to the problem that make building such a product more challenging than building a twitter clone.</p>
<h2>Product complexity</h2>
<p>One of the most consistent pieces of advice I've received about building a facebook clone is: don't. Facebook succeeded because it bundled multiple standalone tools into a single interface, and tied them together with a single social graph.</p>
<p>This is one of the things nostr solves — no longer do you need an everything app, if you can use micro-apps on an everything protocol. When I built <a href="https://zephyr.coracle.social">zephyr</a> last week, I was again stunned at how powerful building on nostr is. In half a day I put together something that would be impossible with traditional technologies —&nbsp;because if you don't have the ability to produce content on a centralized platform, you don't have the ability to consume it either.</p>
<p>But protocols feel different from platforms, especially for the layman. The other half of facebook's value add is (was) a simple and intuitive user interface, which not only made the different components available, but made them accessible as well. I don't think micro-apps, web app stores, or nostr browsers are complete solutions to the UX problem. Nothing can replace a design tailored to your specific end user.</p>
<h2>Privacy and parochialism</h2>
<p>Social graph partitioning is an essential part of designing a social network. In twitter-like applications, an an effective strategy might be described as "whatever". In other words, as long as you are able to 1. connect to the people you want to follow and 2. discover new content, you're fine — there's no need to be exhaustive or exclusive.</p>
<p>But tighter-knit communities require exclusivity. And by "community" I should qualify that I do not mean a reddit-style common interest, but a real locus of interdependence — whether intellectual, economic, or familial. You don't self-select into true communities except by way of a long (sometimes very long) probationary period.</p>
<p>But, as we learned from mastodon's failures, people are also members of multiple overlapping communities simultaneously. This means that an application designed to serve a person in multiple roles across multiple communities needs to be able to address those differing social circles according to their permeability. Enforcing community privacy using encryption might be appropriate for very tight groups like families, while other groups might want more lax rules about content sharing or member admission.</p>
<p>On nostr, relays are an excellent primitive for implementing access controls, and may be sufficient for all but the most private communication. I've also experimented with <a href="https://github.com/nostr-protocol/nips/pull/706">encrypted groups</a> (nostr-in-nostr), but the juice might not be worth the squeeze — the additional complexity of gift wrapping might not be necessary if relays can be trusted not to leak data.</p>
<p>Two different approaches to group-specific relays could be used, depending on the level of trust required for the community: an Uncle Jim model where one or more admins host the infrastructure, or a virtual relay model where the group admin creates a private space on commoditized infrastructure.</p>
<h2>The value of decentralization at a small scale</h2>
<p>Now, of course if you have admins, you've basically opted back in to siloed, centralized platforms, unless shared identity is a value add. Single sign on could be attractive, but not overwhelmingly so —&nbsp;I think the thing that makes an identity shared across multiple platforms compelling is the ability to cross-post.</p>
<p>Unless content is protected by encryption, this is always possible, and would be very good for end users. Allowing content from outside a group to be pulled into a group allows the group to comment on it using its own idioms and values. It also enables loose coupling between weakly-related communities (for example a church and the town it is located in).</p>
<p>This would work very well for community groups, which aren't usually too picky about driving engagement, but would work less well for publishers or media brands, even if cross-posting of content would be beneficial to their curated communities. Instead of increasing the value of your community, it could be seen (and exploited) as advertising for competing siloes.</p>
<h2>Multiple types of engagement</h2>
<p>Finally, there are multiple types of relationship that might be emphasized to a greater or lesser degree in one community vs another. Facebook-style "friends" are generally less focused on ideas, and more on maintaining relationships. I wouldn't want to read what my mom posts on social media, but I do want to stay in touch with her. In contrast, twitter-style "follows" are more oriented towards the flow of information itself, rather than relationships. An application directed at handling both types of "community" would need to respect the difference between the two.</p>
<h1>Toward something, anything</h1>
<p>With all that in mind, here's an attempt at articulating my vision for Coracle, loosely based on the <a href="https://www.eosworldwide.com/">EOS model</a> (no, not that EOS).</p>
<p>While my focus above has been on individuals as members of real-life communities, in practice many of these groups can be defined by a common interest in a given content "publisher", which is a more concrete (and practical) use case. This might be something as big as a newspaper, or as small as a substack or patreon. The content provides something for members of the group to talk about.</p>
<p>It seems to me that groups that are not content-focused operate in much the same way, except that topics are selected by group members, rather than by administrators. So the general strategy would be to build a product that can be used more informally by primarily targeting content publishers.</p>
<h2>Core Values</h2>
<ol>
<li>Real life &gt; digital life</li>
<li>Inorganic advertising is cancer</li>
<li>Encourage purposeful engagement</li>
<li>Different communities should be distinct, but mutually beneficial</li>
</ol>
<h2>Mission Statement</h2>
<p>To enrich the social media experience of individuals in their capacity as members of multiple overlapping real-world intellectual, economic, or relational communities.</p>
<h2>Target Market</h2>
<p>Small publishers who want to create a place for subscribers to interact with the publisher's (public and paid) content and one another. Media brands who are open to the benefits of cross-posting across siloes.</p>
<h2>What does it look like?</h2>
<ul>
<li>Anyone can create a group hosted on self-hosted or commodity relays, or a mixture of both.</li>
<li>A mixture of public and encrypted content for a given group</li>
<li>Cross-posting of public content between groups</li>
<li>Private content exclusive to group members</li>
<li>Multiple tiers of group membership </li>
<li>Configurable access control: admins, moderators, write access, read access</li>
<li>Invite codes, including referral discounts/rewards</li>
<li>Integrated calendar events (public and private)</li>
<li>Integrated marketplaces (publisher merchandise or peer-to-peer)</li>
<li>Support topical threads (oriented around publisher content) and member microblogging</li>
</ul>
<h2>Goals</h2>
<ul>
<li>A relay implementation that supports virtual relays with all required access controls</li>
<li>A group spec that supports granular content permissions and visibility</li>
<li>An end-user interface that supports browsing multiple groups and non-group content</li>
<li>An admin interface for group administration</li>
<li>White-labeled configurable client implementation</li>
</ul>
<h1>Addendum: Ditto</h1>
<p>Alex Gleason has been working on <a href="https://gitlab.com/soapbox-pub/ditto">Ditto</a> of late, which is first of all a way to reconcile ActivityPub and Nostr using a server implementation that supports both protocols, but which has the interesting side effect of marrying the siloed, exclusive ActivityPub model with nostr identities. This could be a good solution for branded clients and tighter community control, especially since it allows for the use of existing tools from ActivityPub's more mature ecosystem.</p>
<p> I intend to keep a close eye on Ditto as it matures. I hope that even if the two projects have a significant amount of overlap, that the problem space is big enough to allow for variations in execution, especially since Coracle has the ability to be fully nostr-native.</p>
<h1>Conclusion</h1>
<p>If you're currently a user of Coracle, don't worry too much, I won't be making any drastic changes anytime soon. I do think that the twitter-like, group-independent part of nostr is valuable, at least as a supplement to more cohesive communities. However, in order to achieve such an ambitious project, I'll have to exercise the discipline to remain focused and cut out any fat that accumulates. We'll see how I do.</p>
]]></itunes:summary>
      <itunes:image href="https://image.nostr.build/529222f4d6befc4ecf3014a3c959938fddea8a5ea38e12f4222e3c3197982aa4.jpg"/>
      </item>
      
      <item>
      <title><![CDATA[How I learned to stop worrying and love the ostrich]]></title>
      <description><![CDATA[My Nostr story]]></description>
             <itunes:subtitle><![CDATA[My Nostr story]]></itunes:subtitle>
      <pubDate>Fri, 14 Apr 2023 17:15:01 GMT</pubDate>
      <link>https://hodlbod.npub.pro/post/1681485888115/</link>
      <comments>https://hodlbod.npub.pro/post/1681485888115/</comments>
      <guid isPermaLink="false">naddr1qqxnzd3cxy6rsdfc8qurzvf4qgsf03c2gsmx5ef4c9zmxvlew04gdh7u94afnknp33qvv3c94kvwxgsrqsqqqa28gzmvm8</guid>
      <category>nostr</category>
      
        <media:content url="https://coracle.us-southeast-1.linodeobjects.com/juniperphoton-_lwLalY6Yzg-unsplash.jpeg" medium="image"/>
        <enclosure 
          url="https://coracle.us-southeast-1.linodeobjects.com/juniperphoton-_lwLalY6Yzg-unsplash.jpeg" length="0" 
          type="image/jpeg" 
        />
      <noteId>naddr1qqxnzd3cxy6rsdfc8qurzvf4qgsf03c2gsmx5ef4c9zmxvlew04gdh7u94afnknp33qvv3c94kvwxgsrqsqqqa28gzmvm8</noteId>
      <npub>npub1jlrs53pkdfjnts29kveljul2sm0actt6n8dxrrzqcersttvcuv3qdjynqn</npub>
      <dc:creator><![CDATA[ hodlbod]]></dc:creator>
      <content:encoded><![CDATA[<p>The year was 2020 — the distant past. I had just had my classically liberal political philosophy beaten out of me with a stick. Joe Biden, the man who ran his campaign from his basement using the tagline <a href="https://www.vox.com/policy-and-politics/2019/12/3/20991841/joe-biden-no-malarkey">"No Malarkey"</a> was challenging the Drumpf for the highest office in the land. I had left the surveillance hellscape that is Facebook behind 4 years prior, but Twitter, I never expected it of you.</p>
<p><img src="https://coracle.us-southeast-1.linodeobjects.com/blog/2304/twitter3.png" alt="Healthy"></p>
<p>Long story short: you know what happened. Did Biden steal the election? Would Trump have won if the NY Post article hadn't been suppressed? These are questions that history is not likely to answer. But was social media acting as a propaganda arm of the state? Yeah.</p>
<h1>Follow the White Rabbit</h1>
<p>So in November 2020, I tried to answer for myself the question: "What alternatives to Twitter are there"?</p>
<p>See, I won't name names here, but my local church community had gotten some press from a handful of large mainstream media outlets in the months leading up to the election, mostly related to our protestation of Covid tyranny and the hysteria that fueled it. These protests culminated in a couple of arrests, all of which were (years) later thrown out by a federal judge as being clearly in violation of our first amendment rights.</p>
<p>So you might see how I would be concerned about what we Christians would refer to as "persecution" coming down the pike, beginning with our freedom of speech. Luckily, the rot has advanced more slowly than I originally feared, and we are not all residents of the gulag as yet. I know some people would laugh at this, saying that Christians are privileged and dominant in our western world. To them, I would say: "fasten your seat belt Dorothy, 'cause <a href="https://aaronrenn.substack.com/i/45894601/the-three-worlds">Kansas is going bye-bye</a>."</p>
<p>My survey of Twitter alternatives wasn't encouraging. While I didn't go as deep as <a href="https://www.youtube.com/watch?v=B6YQQC5Q_5g&amp;t=10143s">Rabble</a>, I think I hit most of the high points, the highest of which was <a href="https://www.scuttlebutt.nz/">Scuttlebutt</a>, which has some hard limits to scaling. So I shrugged my shoulders and said, "hopefully somebody comes up with a solution".</p>
<h1>I guess I'll do it</h1>
<p>A year later, I did another survey of the decentralized social media space, and it looked exactly the same. At that point I realized "hey, I'm somebody", and in January 2022 I wrote the <a href="https://github.com/blazepoint/docs/blob/master/whitepaper.pdf">Blazepoint white paper</a>. In it, I outlined the problems with current social media alternatives, and an innovative way to solve them using a novel multi-master architecture! I knew this was a huge project with an approximately 0% chance of success, so I committed to working on it for the next ten years.</p>
<p>Of course, unknown to me our good friend fiatjaf was already laboring away on a very similar protocol named after an ostrich or something. Two weeks or so after I wrote my white paper I came across Nostr, which had a very similar design. After unsuccessfully attempting to convince fiatjaf (via an extremely buggy DM implementation on <a href="https://github.com/fiatjaf/branle">branle</a>) that my protocol was better, I went back to refining my protocol on my free nights and weekends.</p>
<p>If you look at the Blazepoint repository, you can see that the last commit was on May 23rd, 2022. Life had gotten busy, and while I still fully intended to keep my commitment to myself, as it turns out building a protocol by yourself is not easy. So in November of 2022 I threw in the towel, and dove headfirst into Urbit!</p>
<h1>No, Just Kidding</h1>
<p>I lasted about four hours with Urbit before thinking "ain't nobody got time for this". My resistance to the allures of Nostr folded, and over Thanksgiving break while my kids hung out with my wife and her family, I sat in a freezing RV feverishly coding the first version of Coracle. If you want to play around with it, you can still access it at <a href="https://v1-coracle-social.onrender.com">here</a>. I also have a screencast uploaded <a href="https://coracle.us-southeast-1.linodeobjects.com/blog/2304/coracle-2211">here</a>. It basically works!</p>
<p>Late in the week, I pushed my work in progress to Github, and immediately got a message from fiatjaf about it. He wanted to see my work! It wasn't at all ready, but I deployed it and showed it off.</p>
<p><img src="https://coracle.us-southeast-1.linodeobjects.com/blog/2304/its-a-wip.png" alt="It's a WIP"></p>
<p>Everyone was very complimentary, which made me even more motivated to work on it. That kicked off 5 months (and counting) of waking up at 4 AM multiple times a week so I could put in more time.</p>
<p><img src="https://coracle.us-southeast-1.linodeobjects.com/blog/2304/super-good.png" alt="Super good"></p>
<p>The rest, as they say, is history. Jack followed me on Twitter, and tweeted about Coracle. He later told me that being able to switch easily between Damus and Coracle is what originally hooked him! Interoperability FTW.</p>
<p><img src="https://coracle.us-southeast-1.linodeobjects.com/blog/2304/jack-tweet.png" alt="Jack's tweet"><br><img src="https://coracle.us-southeast-1.linodeobjects.com/blog/2304/jack-nost.png" alt="Jack's post"></p>
<h1>What's Next</h1>
<p>It's now mid-April, 2023 and I'm finishing up a fellowship at <a href="https://futo.org/">FUTO</a> — they gave me a generous grant of $20k to spend three months working on Coracle full time, and I've tried not to disappoint. But my time is drawing to an end, and I'm wondering what to do next — find funding and start my own company? Go back to my old job? Something in between? I've got a few irons in the fire, so we'll see which one hatches first.</p>
<p>Finally, I would be remiss if I didn't give God the glory for this journey. All along the way I have been pushed out of my comfort zone, and over and over God has "worked all things out for good to those who... are called according to his purpose" just in time, and in unexpected ways. Coracle is God's project, and I pray every day that he would "establish the work of our hands for us, yes, establish the work of our hands."</p>
<p>So here's to the next 10 years of Nostr (that's 6 months in real-world years)! 🥂</p>
]]></content:encoded>
      <itunes:author><![CDATA[ hodlbod]]></itunes:author>
      <itunes:summary><![CDATA[<p>The year was 2020 — the distant past. I had just had my classically liberal political philosophy beaten out of me with a stick. Joe Biden, the man who ran his campaign from his basement using the tagline <a href="https://www.vox.com/policy-and-politics/2019/12/3/20991841/joe-biden-no-malarkey">"No Malarkey"</a> was challenging the Drumpf for the highest office in the land. I had left the surveillance hellscape that is Facebook behind 4 years prior, but Twitter, I never expected it of you.</p>
<p><img src="https://coracle.us-southeast-1.linodeobjects.com/blog/2304/twitter3.png" alt="Healthy"></p>
<p>Long story short: you know what happened. Did Biden steal the election? Would Trump have won if the NY Post article hadn't been suppressed? These are questions that history is not likely to answer. But was social media acting as a propaganda arm of the state? Yeah.</p>
<h1>Follow the White Rabbit</h1>
<p>So in November 2020, I tried to answer for myself the question: "What alternatives to Twitter are there"?</p>
<p>See, I won't name names here, but my local church community had gotten some press from a handful of large mainstream media outlets in the months leading up to the election, mostly related to our protestation of Covid tyranny and the hysteria that fueled it. These protests culminated in a couple of arrests, all of which were (years) later thrown out by a federal judge as being clearly in violation of our first amendment rights.</p>
<p>So you might see how I would be concerned about what we Christians would refer to as "persecution" coming down the pike, beginning with our freedom of speech. Luckily, the rot has advanced more slowly than I originally feared, and we are not all residents of the gulag as yet. I know some people would laugh at this, saying that Christians are privileged and dominant in our western world. To them, I would say: "fasten your seat belt Dorothy, 'cause <a href="https://aaronrenn.substack.com/i/45894601/the-three-worlds">Kansas is going bye-bye</a>."</p>
<p>My survey of Twitter alternatives wasn't encouraging. While I didn't go as deep as <a href="https://www.youtube.com/watch?v=B6YQQC5Q_5g&amp;t=10143s">Rabble</a>, I think I hit most of the high points, the highest of which was <a href="https://www.scuttlebutt.nz/">Scuttlebutt</a>, which has some hard limits to scaling. So I shrugged my shoulders and said, "hopefully somebody comes up with a solution".</p>
<h1>I guess I'll do it</h1>
<p>A year later, I did another survey of the decentralized social media space, and it looked exactly the same. At that point I realized "hey, I'm somebody", and in January 2022 I wrote the <a href="https://github.com/blazepoint/docs/blob/master/whitepaper.pdf">Blazepoint white paper</a>. In it, I outlined the problems with current social media alternatives, and an innovative way to solve them using a novel multi-master architecture! I knew this was a huge project with an approximately 0% chance of success, so I committed to working on it for the next ten years.</p>
<p>Of course, unknown to me our good friend fiatjaf was already laboring away on a very similar protocol named after an ostrich or something. Two weeks or so after I wrote my white paper I came across Nostr, which had a very similar design. After unsuccessfully attempting to convince fiatjaf (via an extremely buggy DM implementation on <a href="https://github.com/fiatjaf/branle">branle</a>) that my protocol was better, I went back to refining my protocol on my free nights and weekends.</p>
<p>If you look at the Blazepoint repository, you can see that the last commit was on May 23rd, 2022. Life had gotten busy, and while I still fully intended to keep my commitment to myself, as it turns out building a protocol by yourself is not easy. So in November of 2022 I threw in the towel, and dove headfirst into Urbit!</p>
<h1>No, Just Kidding</h1>
<p>I lasted about four hours with Urbit before thinking "ain't nobody got time for this". My resistance to the allures of Nostr folded, and over Thanksgiving break while my kids hung out with my wife and her family, I sat in a freezing RV feverishly coding the first version of Coracle. If you want to play around with it, you can still access it at <a href="https://v1-coracle-social.onrender.com">here</a>. I also have a screencast uploaded <a href="https://coracle.us-southeast-1.linodeobjects.com/blog/2304/coracle-2211">here</a>. It basically works!</p>
<p>Late in the week, I pushed my work in progress to Github, and immediately got a message from fiatjaf about it. He wanted to see my work! It wasn't at all ready, but I deployed it and showed it off.</p>
<p><img src="https://coracle.us-southeast-1.linodeobjects.com/blog/2304/its-a-wip.png" alt="It's a WIP"></p>
<p>Everyone was very complimentary, which made me even more motivated to work on it. That kicked off 5 months (and counting) of waking up at 4 AM multiple times a week so I could put in more time.</p>
<p><img src="https://coracle.us-southeast-1.linodeobjects.com/blog/2304/super-good.png" alt="Super good"></p>
<p>The rest, as they say, is history. Jack followed me on Twitter, and tweeted about Coracle. He later told me that being able to switch easily between Damus and Coracle is what originally hooked him! Interoperability FTW.</p>
<p><img src="https://coracle.us-southeast-1.linodeobjects.com/blog/2304/jack-tweet.png" alt="Jack's tweet"><br><img src="https://coracle.us-southeast-1.linodeobjects.com/blog/2304/jack-nost.png" alt="Jack's post"></p>
<h1>What's Next</h1>
<p>It's now mid-April, 2023 and I'm finishing up a fellowship at <a href="https://futo.org/">FUTO</a> — they gave me a generous grant of $20k to spend three months working on Coracle full time, and I've tried not to disappoint. But my time is drawing to an end, and I'm wondering what to do next — find funding and start my own company? Go back to my old job? Something in between? I've got a few irons in the fire, so we'll see which one hatches first.</p>
<p>Finally, I would be remiss if I didn't give God the glory for this journey. All along the way I have been pushed out of my comfort zone, and over and over God has "worked all things out for good to those who... are called according to his purpose" just in time, and in unexpected ways. Coracle is God's project, and I pray every day that he would "establish the work of our hands for us, yes, establish the work of our hands."</p>
<p>So here's to the next 10 years of Nostr (that's 6 months in real-world years)! 🥂</p>
]]></itunes:summary>
      <itunes:image href="https://coracle.us-southeast-1.linodeobjects.com/juniperphoton-_lwLalY6Yzg-unsplash.jpeg"/>
      </item>
      
      <item>
      <title><![CDATA[Building Relay Browsing Into Client Interfaces]]></title>
      <description><![CDATA[How should clients represent relays in user interfaces? Are they dimensions? coordinates? layers? buttons? checkboxes? topics? people? I don't know.]]></description>
             <itunes:subtitle><![CDATA[How should clients represent relays in user interfaces? Are they dimensions? coordinates? layers? buttons? checkboxes? topics? people? I don't know.]]></itunes:subtitle>
      <pubDate>Fri, 07 Apr 2023 16:03:19 GMT</pubDate>
      <link>https://hodlbod.npub.pro/post/1680874316525/</link>
      <comments>https://hodlbod.npub.pro/post/1680874316525/</comments>
      <guid isPermaLink="false">naddr1qqxnzd3cxqurwdpnxymr2v34qgsf03c2gsmx5ef4c9zmxvlew04gdh7u94afnknp33qvv3c94kvwxgsrqsqqqa28fqd9z9</guid>
      <category>nostr</category>
      
        <media:content url="https://coracle.us-southeast-1.linodeobjects.com/juniperphoton-5k_RL3Zc6G0-unsplash.jpeg" medium="image"/>
        <enclosure 
          url="https://coracle.us-southeast-1.linodeobjects.com/juniperphoton-5k_RL3Zc6G0-unsplash.jpeg" length="0" 
          type="image/jpeg" 
        />
      <noteId>naddr1qqxnzd3cxqurwdpnxymr2v34qgsf03c2gsmx5ef4c9zmxvlew04gdh7u94afnknp33qvv3c94kvwxgsrqsqqqa28fqd9z9</noteId>
      <npub>npub1jlrs53pkdfjnts29kveljul2sm0actt6n8dxrrzqcersttvcuv3qdjynqn</npub>
      <dc:creator><![CDATA[ hodlbod]]></dc:creator>
      <content:encoded><![CDATA[<p>Yesterday I was browsing bountsr and discovered a <a href="https://bountsr.org/relay-browsing/">new bounty</a> by fiatjaf for adding "relay browsing" to clients. This is the bounty Coracle was born to claim! However, it's a problem I've been putting off for some time now, because it's a very hard problem requiring some real creativity. In this post I'll survey the state of the art, try to articulate my vague ideas about what needs to be done, and sketch some next steps toward realizing this goal.</p>
<h1>The problem of relays</h1>
<p>Relays are a problem. They are simultaneously an implementation detail that users don't understand and don't want to deal with, and the very soul of Nostr. So far, no client has unleashed the power of Nostr's architecture, instead focusing on ease of adoption by starting users off with a hard-coded set of relays. Users are then left to dig through their settings to change which relays they want to connect to. Others, like Primal, attempt to elide the concept of relays altogether and provide a unified view of the entire network. </p>
<p>Various nods to the importance of relays do exist in various clients however, for example:</p>
<ul>
<li>Amethyst shows pretty granular controls and stats on their relay list.</li>
<li>Snort (and others) shows the list of relays other users connect to on their profile page.</li>
<li>Gossip has all kinds of settings for how many relays to use, how smart to be about relay discovery, and more.</li>
<li>Coracle shows which relays an event was seen on in the note's overflow menu, and asks new users to select relays during the onboarding process.</li>
</ul>
<p>Other common patterns include: color-coding relays, differentiating between read and write relays, and auto-selecting relays different from the user's own selections in order to fetch context related to a given note or feed.</p>
<p><img src="https://coracle.us-southeast-1.linodeobjects.com/blog/2304/relay-list.png" alt="Coracle's relay list"></p>
<p>All of these are great features, but they are baby steps, and don't fundamentally address the problem (or realize the possibility) of allowing users to navigate between overlapping venn diagrams of relays and their content.</p>
<h1>Let me tell you about my feelings</h1>
<p>I think it's generally a shared perception that these half-measures aren't enough, but nobody really knows what to do about it. Even fiatjaf, who has relentlessly pushed development efforts towards surfacing relays admits in the bounty cited above, "The app should make it seamless to browse these various scenarios, I have no idea how."</p>
<p>I share this utter sense of bewilderment. I feel unmoored when I try to think what a user interface that fully embraced  multiple relays would look like. Decades of using software with a single-master paradigm has broken my mind; designing something that could actually be used to seamlessly navigate between relays is a massive effort for my poor, tired brain.</p>
<p>The closest thing to a "vision" for what this would look like is what Arkin0x has built with <a href="https://onosendai.tech/">ONOSENDAI</a>: a vast, three-dimensional space that you can travel through. Although to solve the problem, they would have to use an address space focused on relationships between relays, pubkeys, and events, rather than event content simhashes.</p>
<p><img src="https://coracle.us-southeast-1.linodeobjects.com/blog/2304/onosendai.png" alt="ONOSENDAI"></p>
<p>This could be a workable approach, resulting in something similar to <a href="https://lninsights.com/">LN Insights</a>, a browser for lightning network topology, which adds node capacity and clustering as additional dimensions. But it's also true that this type of visualization quickly becomes disorienting, and is far less familiar than a traditional user interface with buttons and menus.</p>
<p><img src="https://coracle.us-southeast-1.linodeobjects.com/blog/2304/lninsights.png" alt="LN Insights"></p>
<p>There are examples of this kind of thing being executed successfully by tools like Figma which allow you to zoom in and out on your canvas to travel from one place to another. Games like Supreme Commander support zoom-to-navigate, in addition to showing multiple windowed views of the same game. Tools like Photoshop and vector graphics editors take a different approach and introduce an extra dimension by allowing you to group content into multiple layers.</p>
<p><img src="https://coracle.us-southeast-1.linodeobjects.com/blog/2304/supreme-commander.jpeg" alt="Supreme Commander"></p>
<p>Another way to think about the additional dimension that relays introduce is by imagining Nostr is a virtual world, with geography (relays), actors (pubkeys), and history (events). Users are mobile, and can travel at will through the world (unless denied access by a relay), viewing artifacts left by other users in the form of published events. The wrinkle is that events can happen in multiple places at the same time, or be replicated across space over time as events get re-broadcasted.</p>
<p>Take a look at the <a href="https://t.me/ONOSENDAITECH/302">conversation</a> I had with Arkin0x on telegram while writing this post for more ideas for representing Nostr in 3D space.</p>
<h1>Back to flatland</h1>
<p>In traditional user interfaces, relationships within the data model are not usually represented spatially, except in very purpose-built applications like UML diagrams or mind maps. Instead, space is taken up by an additional dimension: affordances for user interaction. Screens are designed according to functionality, and access to groups of those functions exist in navigation items or menus. Content is addressed by overlaying those groups of functionality either literally via modal dialogs, or dimensionally using "Uniform Resource Locators". There's no space left for representing the same address space in multiple dimensions, especially simultaneously.</p>
<p>So, what is required is either a new UI element or a re-purposed one that satisfies the same semantics as a checkbox group: a way to choose zero or more options for the same value. This isn't too hard, you could add a dropdown menu on feed views, and call it good. But this won't make any sense to users unless they know what differentiates relays from one another, and with 1,300 relays in the network and counting, it will be impossible to process that information without help from the software.</p>
<p><img src="https://coracle.us-southeast-1.linodeobjects.com/blog/2304/multi-select.webp" alt="Multi-selects"></p>
<p>So, relays need to be filtered and grouped. This can be partly accomplished by giving good names and metadata to relays, but the important thing is the content that lives on a given relay, which might be analyzed using the social graph, textually, or using some other heuristic. Unfortunately, with the current culture of cross-posting for reach, relays don't differ substantially from one another. For now, filters and groups have to be user-generated, which creates a chicken-and-egg problem, because remember? we are trying to make it easy for users to navigate Nostr!</p>
<p>Maybe a good place to start would be to create a tool that would allow users to analyze for themselves the factors contributing to relay differentiation, as specified in <a href="https://nostrbounties.com/b/naddr1qq9rzd3cxqcrjvesxqusygpm7rrrljungc6q0tuh5hj7ue863q73qlheu4vywtzwhx42a7j9n5psgqqqw4rs7umkzv">this bounty</a>. Then, those insights could be quantified and automatically integrated into a given client's implementation of groups and filters. Of course, that runs afoul of the <a href="https://blog.coracle.social/posts/c1c74b4b60f36a29b77c358e72eb0452bf742ed7fec1d5f5625e84b54c1cc05b">problem of centralization</a>.</p>
<p>Or, discovery could be built in to clients using crude tools like checkboxes, color codes, and modal dialogs, and as the network partitions and relays specialize due to scaling limitations users can begin to develop a gestalt for what kind of notes end up on a given relay. The naturally occurring social partitioning that would result would self-reinforce by allowing implementations to classify relay content by personalities or content central to content already hosted there.</p>
<h1>Conclusion</h1>
<p>This post has been far more stream-of-consciousness than usual, and for that I apologize. But I also thank you, dear reader, for helping me rubber-duck my way to profundity. Here are my take-aways (maybe yours are different):</p>
<ul>
<li>Multi-master content is a truly novel paradigm, and interface metaphors for surfacing it don't really exist.</li>
<li>The semantics of multi-master match multi-select and checkbox list interface elements.</li>
<li>Relays are not sufficiently differentiated to support intelligent filtering and grouping. Users cannot currently care about the distinctions between relays, because they don't currently exist.</li>
<li>The concept of "layers" in tools for video/image/graphics editing is probably the closest thing we have to a metaphor for representing two-dimensional content in multiple dimensions. Layers correspond well to dialogs, and so a first pass at this problem might be to show a feed's content modified by relay selection in a popover dialog.</li>
</ul>
<p>I'm sure I'm not the only one thinking about this problem, so please! Take a moment to leave a comment with your thoughts, opinions, or hallucinations.</p>
]]></content:encoded>
      <itunes:author><![CDATA[ hodlbod]]></itunes:author>
      <itunes:summary><![CDATA[<p>Yesterday I was browsing bountsr and discovered a <a href="https://bountsr.org/relay-browsing/">new bounty</a> by fiatjaf for adding "relay browsing" to clients. This is the bounty Coracle was born to claim! However, it's a problem I've been putting off for some time now, because it's a very hard problem requiring some real creativity. In this post I'll survey the state of the art, try to articulate my vague ideas about what needs to be done, and sketch some next steps toward realizing this goal.</p>
<h1>The problem of relays</h1>
<p>Relays are a problem. They are simultaneously an implementation detail that users don't understand and don't want to deal with, and the very soul of Nostr. So far, no client has unleashed the power of Nostr's architecture, instead focusing on ease of adoption by starting users off with a hard-coded set of relays. Users are then left to dig through their settings to change which relays they want to connect to. Others, like Primal, attempt to elide the concept of relays altogether and provide a unified view of the entire network. </p>
<p>Various nods to the importance of relays do exist in various clients however, for example:</p>
<ul>
<li>Amethyst shows pretty granular controls and stats on their relay list.</li>
<li>Snort (and others) shows the list of relays other users connect to on their profile page.</li>
<li>Gossip has all kinds of settings for how many relays to use, how smart to be about relay discovery, and more.</li>
<li>Coracle shows which relays an event was seen on in the note's overflow menu, and asks new users to select relays during the onboarding process.</li>
</ul>
<p>Other common patterns include: color-coding relays, differentiating between read and write relays, and auto-selecting relays different from the user's own selections in order to fetch context related to a given note or feed.</p>
<p><img src="https://coracle.us-southeast-1.linodeobjects.com/blog/2304/relay-list.png" alt="Coracle's relay list"></p>
<p>All of these are great features, but they are baby steps, and don't fundamentally address the problem (or realize the possibility) of allowing users to navigate between overlapping venn diagrams of relays and their content.</p>
<h1>Let me tell you about my feelings</h1>
<p>I think it's generally a shared perception that these half-measures aren't enough, but nobody really knows what to do about it. Even fiatjaf, who has relentlessly pushed development efforts towards surfacing relays admits in the bounty cited above, "The app should make it seamless to browse these various scenarios, I have no idea how."</p>
<p>I share this utter sense of bewilderment. I feel unmoored when I try to think what a user interface that fully embraced  multiple relays would look like. Decades of using software with a single-master paradigm has broken my mind; designing something that could actually be used to seamlessly navigate between relays is a massive effort for my poor, tired brain.</p>
<p>The closest thing to a "vision" for what this would look like is what Arkin0x has built with <a href="https://onosendai.tech/">ONOSENDAI</a>: a vast, three-dimensional space that you can travel through. Although to solve the problem, they would have to use an address space focused on relationships between relays, pubkeys, and events, rather than event content simhashes.</p>
<p><img src="https://coracle.us-southeast-1.linodeobjects.com/blog/2304/onosendai.png" alt="ONOSENDAI"></p>
<p>This could be a workable approach, resulting in something similar to <a href="https://lninsights.com/">LN Insights</a>, a browser for lightning network topology, which adds node capacity and clustering as additional dimensions. But it's also true that this type of visualization quickly becomes disorienting, and is far less familiar than a traditional user interface with buttons and menus.</p>
<p><img src="https://coracle.us-southeast-1.linodeobjects.com/blog/2304/lninsights.png" alt="LN Insights"></p>
<p>There are examples of this kind of thing being executed successfully by tools like Figma which allow you to zoom in and out on your canvas to travel from one place to another. Games like Supreme Commander support zoom-to-navigate, in addition to showing multiple windowed views of the same game. Tools like Photoshop and vector graphics editors take a different approach and introduce an extra dimension by allowing you to group content into multiple layers.</p>
<p><img src="https://coracle.us-southeast-1.linodeobjects.com/blog/2304/supreme-commander.jpeg" alt="Supreme Commander"></p>
<p>Another way to think about the additional dimension that relays introduce is by imagining Nostr is a virtual world, with geography (relays), actors (pubkeys), and history (events). Users are mobile, and can travel at will through the world (unless denied access by a relay), viewing artifacts left by other users in the form of published events. The wrinkle is that events can happen in multiple places at the same time, or be replicated across space over time as events get re-broadcasted.</p>
<p>Take a look at the <a href="https://t.me/ONOSENDAITECH/302">conversation</a> I had with Arkin0x on telegram while writing this post for more ideas for representing Nostr in 3D space.</p>
<h1>Back to flatland</h1>
<p>In traditional user interfaces, relationships within the data model are not usually represented spatially, except in very purpose-built applications like UML diagrams or mind maps. Instead, space is taken up by an additional dimension: affordances for user interaction. Screens are designed according to functionality, and access to groups of those functions exist in navigation items or menus. Content is addressed by overlaying those groups of functionality either literally via modal dialogs, or dimensionally using "Uniform Resource Locators". There's no space left for representing the same address space in multiple dimensions, especially simultaneously.</p>
<p>So, what is required is either a new UI element or a re-purposed one that satisfies the same semantics as a checkbox group: a way to choose zero or more options for the same value. This isn't too hard, you could add a dropdown menu on feed views, and call it good. But this won't make any sense to users unless they know what differentiates relays from one another, and with 1,300 relays in the network and counting, it will be impossible to process that information without help from the software.</p>
<p><img src="https://coracle.us-southeast-1.linodeobjects.com/blog/2304/multi-select.webp" alt="Multi-selects"></p>
<p>So, relays need to be filtered and grouped. This can be partly accomplished by giving good names and metadata to relays, but the important thing is the content that lives on a given relay, which might be analyzed using the social graph, textually, or using some other heuristic. Unfortunately, with the current culture of cross-posting for reach, relays don't differ substantially from one another. For now, filters and groups have to be user-generated, which creates a chicken-and-egg problem, because remember? we are trying to make it easy for users to navigate Nostr!</p>
<p>Maybe a good place to start would be to create a tool that would allow users to analyze for themselves the factors contributing to relay differentiation, as specified in <a href="https://nostrbounties.com/b/naddr1qq9rzd3cxqcrjvesxqusygpm7rrrljungc6q0tuh5hj7ue863q73qlheu4vywtzwhx42a7j9n5psgqqqw4rs7umkzv">this bounty</a>. Then, those insights could be quantified and automatically integrated into a given client's implementation of groups and filters. Of course, that runs afoul of the <a href="https://blog.coracle.social/posts/c1c74b4b60f36a29b77c358e72eb0452bf742ed7fec1d5f5625e84b54c1cc05b">problem of centralization</a>.</p>
<p>Or, discovery could be built in to clients using crude tools like checkboxes, color codes, and modal dialogs, and as the network partitions and relays specialize due to scaling limitations users can begin to develop a gestalt for what kind of notes end up on a given relay. The naturally occurring social partitioning that would result would self-reinforce by allowing implementations to classify relay content by personalities or content central to content already hosted there.</p>
<h1>Conclusion</h1>
<p>This post has been far more stream-of-consciousness than usual, and for that I apologize. But I also thank you, dear reader, for helping me rubber-duck my way to profundity. Here are my take-aways (maybe yours are different):</p>
<ul>
<li>Multi-master content is a truly novel paradigm, and interface metaphors for surfacing it don't really exist.</li>
<li>The semantics of multi-master match multi-select and checkbox list interface elements.</li>
<li>Relays are not sufficiently differentiated to support intelligent filtering and grouping. Users cannot currently care about the distinctions between relays, because they don't currently exist.</li>
<li>The concept of "layers" in tools for video/image/graphics editing is probably the closest thing we have to a metaphor for representing two-dimensional content in multiple dimensions. Layers correspond well to dialogs, and so a first pass at this problem might be to show a feed's content modified by relay selection in a popover dialog.</li>
</ul>
<p>I'm sure I'm not the only one thinking about this problem, so please! Take a moment to leave a comment with your thoughts, opinions, or hallucinations.</p>
]]></itunes:summary>
      <itunes:image href="https://coracle.us-southeast-1.linodeobjects.com/juniperphoton-5k_RL3Zc6G0-unsplash.jpeg"/>
      </item>
      
      </channel>
      </rss>
    