pub.leaflet.document

leaflet.pub

Samples

1202 randomly sampled records from the AT Protocol firehose

pub.leaflet.document (100 samples)
{
  "$type": "pub.leaflet.document",
  "pages": [
    {
      "$type": "pub.leaflet.pages.linearDocument",
      "blocks": [
        {
          "$type": "pub.leaflet.pages.linearDocument#block",
          "block": {
            "$type": "pub.leaflet.blocks.image",
            "image": {
              "ref": {
                "$link": "bafkreie6kww4kohm64rfwhoz4erxefjbcdkxlc5ghrhuxzo7utqxcrctae"
              },
              "size": 1037099,
              "$type": "blob",
              "mimeType": "image/jpeg"
            },
            "aspectRatio": {
              "width": 1500,
              "height": 429
            }
          }
        },
        {
          "$type": "pub.leaflet.pages.linearDocument#block",
          "block": {
            "$type": "pub.leaflet.blocks.text",
            "facets": [],
            "plaintext": ""
          }
        },
        {
          "$type": "pub.leaflet.pages.linearDocument#block",
          "block": {
            "$type": "pub.leaflet.blocks.header",
            "level": 2,
            "facets": [],
            "plaintext": "Gander Crowdfunding"
          }
        },
        {
          "$type": "pub.leaflet.pages.linearDocument#block",
          "block": {
            "$type": "pub.leaflet.blocks.text",
            "facets": [],
            "plaintext": "Gander Social, a Canadian atproto-based social media platform currently in private beta, launched an equity crowdfunding campaign through FrontFundr at the end of October. The campaign positioning itself as an opportunity for Canadians to co-own a social media platform built on values of digital sovereignty and independence from surveillance-based business models. Within hours of launching to their Early Access Program, Gander surpassed $500k CAD in investments, and within a week reached over $1 million with more than 1200 investors. Gander is planning to use the funds for hiring engineering and trust and safety staff, developing creator monetisation tools and moderation systems, and supporting a public launch planned for 2026."
          }
        },
        {
          "$type": "pub.leaflet.pages.linearDocument#block",
          "block": {
            "url": "https://www.youtube.com/embed/vQ6iHDqHxX8?rel=0",
            "$type": "pub.leaflet.blocks.iframe",
            "height": 300
          }
        },
        {
          "$type": "pub.leaflet.pages.linearDocument#block",
          "block": {
            "$type": "pub.leaflet.blocks.text",
            "facets": [],
            "plaintext": "Gander sells common shares starting at $255 CAD, and aims at a target raise of $1.5M CAD, with a valuation of Gander of $15M CAD. With more than a month to go, the campaign has raised over $1.3M, and an additional 400k in investments that are likely to close. "
          }
        },
        {
          "$type": "pub.leaflet.pages.linearDocument#block",
          "block": {
            "$type": "pub.leaflet.blocks.text",
            "facets": [],
            "plaintext": "This financial model and valuation means that Gander is already explicitly thinking about sustainable ways to generate revenue, and their pitch is feature subscriptions. The core app and functionality is free, and comes with a single account. A paid version features multiple accounts, and unspecified 'additional features'. Gander also is focused on enterprise and professional users, with features like branded accounts and team collaboration tools, as well as sponsored content."
          }
        },
        {
          "$type": "pub.leaflet.pages.linearDocument#block",
          "block": {
            "$type": "pub.leaflet.blocks.text",
            "facets": [],
            "plaintext": "What strikes me about Gander's crowdfunding is that it has not been a major part of the conversation on the atproto-focused dev communities on the feeds. Gander's first Bluesky post about the campaign came only after 1,500+ Canadians had already invested over $1.2M CAD. Gander's promotional material does not mention Bluesky at all, and sparsely mentions atproto, and the integration of Gander in a wider open public network is hardly mentioned."
          }
        },
        {
          "$type": "pub.leaflet.pages.linearDocument#block",
          "block": {
            "$type": "pub.leaflet.blocks.bskyPost",
            "postRef": {
              "cid": "bafyreih6gd6jgxx6lq2vuo47yha4kanbsrkkrdbe5px2nfafvqnhi6ukze",
              "uri": "at://did:plc:svgr4wuqdne6odvblimleso7/app.bsky.feed.post/3m4qeiv6z522y"
            }
          }
        },
        {
          "$type": "pub.leaflet.pages.linearDocument#block",
          "block": {
            "$type": "pub.leaflet.blocks.text",
            "facets": [],
            "plaintext": ""
          }
        },
        {
          "$type": "pub.leaflet.pages.linearDocument#block",
          "block": {
            "$type": "pub.leaflet.blocks.text",
            "facets": [],
            "plaintext": "It shows that Gander has found significant traction among people who aren't yet active on atproto platforms. They've built momentum outside the existing Bluesky community, which suggests broader interest in atproto-powered social media beyond its current user base."
          }
        },
        {
          "$type": "pub.leaflet.pages.linearDocument#block",
          "block": {
            "$type": "pub.leaflet.blocks.text",
            "facets": [],
            "plaintext": "Gander's crowdfunding shows that digital sovereignty sells to people who might not be already active in the space of open social networking protocols, and indicates that sovereignty framing is a viable funding path for platforms targeting populations with strong regional identity, independent of whether those populations are already bought into open protocol ideals."
          }
        },
        {
          "$type": "pub.leaflet.pages.linearDocument#block",
          "block": {
            "$type": "pub.leaflet.blocks.text",
            "facets": [],
            "plaintext": ""
          }
        },
        {
          "$type": "pub.leaflet.pages.linearDocument#block",
          "block": {
            "$type": "pub.leaflet.blocks.header",
            "level": 2,
            "facets": [],
            "plaintext": "IETF"
          }
        },
        {
          "$type": "pub.leaflet.pages.linearDocument#block",
          "block": {
            "$type": "pub.leaflet.blocks.text",
            "facets": [
              {
                "index": {
                  "byteEnd": 41,
                  "byteStart": 22
                },
                "features": [
                  {
                    "uri": "https://docs.bsky.app/blog/taking-at-to-ietf",
                    "$type": "pub.leaflet.richtext.facet#link"
                  }
                ]
              },
              {
                "index": {
                  "byteEnd": 450,
                  "byteStart": 433
                },
                "features": [
                  {
                    "uri": "https://bsky.app/profile/chadkoh.com/post/3m4vbmix2322l",
                    "$type": "pub.leaflet.richtext.facet#link"
                  }
                ]
              }
            ],
            "plaintext": "Bluesky has set their first official step to get (part of) atproto governed by the IETF. The Internet Engineering Task Force is the place where internet protocols become \"official standards\" through a formal but open process that requires multiple independent implementations and broad technical consensus, and also manages protocols like HTTP, DNS and OAuth. The first step for atproto is to host a 'Birds of a Feather meeting', to indicate interest from the community and if the IETF is a good fit for atproto."
          }
        },
        {
          "$type": "pub.leaflet.pages.linearDocument#block",
          "block": {
            "$type": "pub.leaflet.blocks.text",
            "facets": [],
            "plaintext": "This meeting, held last week, saw presentations from various organisations that are building on atproto, and an explanation of Bluesky which parts of atproto they want to bring to the IETF"
          }
        },
        {
          "$type": "pub.leaflet.pages.linearDocument#block",
          "block": {
            "$type": "pub.leaflet.blocks.bskyPost",
            "postRef": {
              "cid": "bafyreig63slnj3fzxec7rmshvjlplh445eoaofab7v2sl2q5gfnch4iisi",
              "uri": "at://did:plc:qvzuhns2asyclcnvcgh3lgbx/app.bsky.feed.post/3m4vctqcdgpw2"
            }
          }
        },
        {
          "$type": "pub.leaflet.pages.linearDocument#block",
          "block": {
            "$type": "pub.leaflet.blocks.text",
            "facets": [],
            "plaintext": "Bluesky plans to start with the core part of atproto, and the components that become IETF standards (like the repository data structure, CBOR encoding, and firehose mechanisms), any changes would require working group approval. This means Bluesky couldn't unilaterally modify these foundational pieces without going through the IETF process. However, IETF has no enforcement power - it's a voluntary standards body. Implementers choose whether to follow the standard."
          }
        },
        {
          "$type": "pub.leaflet.pages.linearDocument#block",
          "block": {
            "$type": "pub.leaflet.blocks.text",
            "facets": [],
            "plaintext": "The crucial part here is that the application layer remains outside of the IETF, and app features (and the schema systems that power them, such as Lexicons), are not part of the IETF. This gives people building on atproto flexibility, which the plumbing of data synchronisation stabilised as commons infrastructure."
          }
        },
        {
          "$type": "pub.leaflet.pages.linearDocument#block",
          "block": {
            "$type": "pub.leaflet.blocks.text",
            "facets": [],
            "plaintext": "This first meeting was not to determine if the IETF would form a Working Group to house atproto. I'm not a professional IETF watcher (or maybe I am now?), but my sense is that the closing comments of the IETF chair person indicated that things went well, and atproto is on a good trajectory to potentially become an IETF standard in the future."
          }
        },
        {
          "$type": "pub.leaflet.pages.linearDocument#block",
          "block": {
            "$type": "pub.leaflet.blocks.bskyPost",
            "postRef": {
              "cid": "bafyreigv74aw3oecx6qwa25iwycdk654tr6payrtyeun34lblmai56m5ii",
              "uri": "at://did:plc:mdjhvva6vlrswsj26cftjttd/app.bsky.feed.post/3m4vjmfunzs2v"
            }
          }
        },
        {
          "$type": "pub.leaflet.pages.linearDocument#block",
          "block": {
            "$type": "pub.leaflet.blocks.text",
            "facets": [
              {
                "index": {
                  "byteEnd": 58,
                  "byteStart": 1
                },
                "features": [
                  {
                    "uri": "https://www.youtube.com/watch?v=x9tTY6lTdXg",
                    "$type": "pub.leaflet.richtext.facet#link"
                  }
                ]
              }
            ],
            "plaintext": "(full video of the meeting for all my protocol sickos here)"
          }
        },
        {
          "$type": "pub.leaflet.pages.linearDocument#block",
          "block": {
            "$type": "pub.leaflet.blocks.header",
            "level": 2,
            "facets": [],
            "plaintext": "Feed convergence"
          }
        },
        {
          "$type": "pub.leaflet.pages.linearDocument#block",
          "block": {
            "$type": "pub.leaflet.blocks.text",
            "facets": [],
            "plaintext": "Bluesky is a baseball app now:"
          }
        },
        {
          "$type": "pub.leaflet.pages.linearDocument#block",
          "block": {
            "src": "https://bsky.social/about/blog/11-6-2025-baseball",
            "$type": "pub.leaflet.blocks.website",
            "title": "The World Series Was Electric — So Was Bluesky - Bluesky",
            "description": "“How can you not be romantic about baseball?” — Moneyball 2011",
            "previewImage": {
              "ref": {
                "$link": "bafkreiac5abtobsmvjpt2r6jxsnd2ktznsxzwi7ywuafjqzl6okm2hlamm"
              },
              "size": 32719,
              "$type": "blob",
              "mimeType": "image/png"
            }
          }
        },
        {
          "$type": "pub.leaflet.pages.linearDocument#block",
          "block": {
            "$type": "pub.leaflet.blocks.blockquote",
            "facets": [],
            "plaintext": "At least 3% of all posts made on November 1 (Game 7) were about baseball. The final game also resulted in a +30% bump in traffic to Bluesky, with engagement spikes up to +66% from previous days."
          }
        },
        {
          "$type": "pub.leaflet.pages.linearDocument#block",
          "block": {
            "$type": "pub.leaflet.blocks.text",
            "facets": [],
            "plaintext": ""
          }
        },
        {
          "$type": "pub.leaflet.pages.linearDocument#block",
          "block": {
            "$type": "pub.leaflet.blocks.text",
            "facets": [],
            "plaintext": "Bluesky is also the Zohran Mamdani app now:"
          }
        },
        {
          "$type": "pub.leaflet.pages.linearDocument#block",
          "block": {
            "src": "https://graze.leaflet.pub/3m4yjmbnyec2c",
            "$type": "pub.leaflet.blocks.website",
            "title": "About The Other Night... - Graze Newsletter",
            "description": "How Graze is defining the next era of a decentralized, open social attention economy.",
            "previewImage": {
              "ref": {
                "$link": "bafkreieoybrzvp54jxuoch32yojbvhzcjj6cy7amd3dlevbxt53n6t3rga"
              },
              "size": 28786,
              "$type": "blob",
              "mimeType": "image/png"
            }
          }
        },
        {
          "$type": "pub.leaflet.pages.linearDocument#block",
          "block": {
            "$type": "pub.leaflet.blocks.text",
            "facets": [],
            "plaintext": "During the NYC Mayoral election night, Bluesky partnered with Graze and NYC newspapers Gothamist and WNYC to create a custom feed for the election. This feed had curated content, posts from trusted soruces, pinned posts with the latest results, and more. Graze says that the feed had over 110k unique readers, and a peak traffic of 1,200 posts per second, doubling Graze's previous monthly high."
          }
        },
        {
          "$type": "pub.leaflet.pages.linearDocument#block",
          "block": {
            "$type": "pub.leaflet.blocks.text",
            "facets": [],
            "plaintext": ""
          }
        },
        {
          "$type": "pub.leaflet.pages.linearDocument#block",
          "block": {
            "$type": "pub.leaflet.blocks.horizontalRule"
          }
        },
        {
          "$type": "pub.leaflet.pages.linearDocument#block",
          "block": {
            "$type": "pub.leaflet.blocks.text",
            "facets": [],
            "plaintext": ""
          }
        },
        {
          "$type": "pub.leaflet.pages.linearDocument#block",
          "block": {
            "$type": "pub.leaflet.blocks.text",
            "facets": [
              {
                "index": {
                  "byteEnd": 59,
                  "byteStart": 50
                },
                "features": [
                  {
                    "uri": "https://Semble.so",
                    "$type": "pub.leaflet.richtext.facet#link"
                  }
                ]
              }
            ],
            "plaintext": "There is a ton more news this week (the launch of Semble.so, for example), that I'll get to in another edition of ATmosphere Report in the next few days."
          }
        }
      ]
    }
  ],
  "title": "ATmosphere Report #142 ",
  "author": "did:plc:mdjhvva6vlrswsj26cftjttd",
  "postRef": {
    "cid": "bafyreihzcfegw6nx52myx6cmy7vsl633iqzuewt4jy6x75xtrkojdum7ly",
    "uri": "at://did:plc:mdjhvva6vlrswsj26cftjttd/app.bsky.feed.post/3m5gygrlwsc2q",
    "commit": {
      "cid": "bafyreibwrr4suwiswgsheueenil47g2zvb2aqsdy5bwzvcmsfknjlxsjzy",
      "rev": "3m5gygrqq4k2l"
    },
    "validationStatus": "valid"
  },
  "description": "The Canadian atproto-powered platform Gander raises of 1.3M in fundraising, atproto at the IETF and Bluesky is the baseball app",
  "publication": "at://did:plc:mdjhvva6vlrswsj26cftjttd/pub.leaflet.publication/3lwyzotjqu22i",
  "publishedAt": "2025-11-12T15:41:26.489Z"
}

did:plc:mdjhvva6vlrswsj26cftjttd | at://did:plc:mdjhvva6vlrswsj26cftjttd/pub.leaflet.document/3m5gygipuxc2q

app.bsky.feed.post (nested within pub.leaflet.document) (100 samples)
{
  "$type": "pub.leaflet.document",
  "pages": [
    {
      "$type": "pub.leaflet.pages.linearDocument",
      "blocks": [
        {
          "$type": "pub.leaflet.pages.linearDocument#block",
          "block": {
            "$type": "pub.leaflet.blocks.image",
            "image": {
              "ref": {
                "$link": "bafkreidkjyc4ncheacrvrqebm5tuqc3zdgl3yp6gv7f5j4q3h5ipljqj6u"
              },
              "size": 1416162,
              "$type": "blob",
              "mimeType": "image/png"
            },
            "aspectRatio": {
              "width": 1500,
              "height": 904
            }
          }
        },
        {
          "$type": "pub.leaflet.pages.linearDocument#block",
          "block": {
            "$type": "pub.leaflet.blocks.text",
            "facets": [],
            "plaintext": "Six months ago I posted the following thought to my Bluesky account:"
          }
        },
        {
          "$type": "pub.leaflet.pages.linearDocument#block",
          "block": {
            "$type": "pub.leaflet.blocks.bskyPost",
            "postRef": {
              "cid": "bafyreidpxzuls44td2lz53nci7pespggncvj74cbff76q6nm5s26tgofp4",
              "uri": "at://did:plc:gq4fo3u6tqzzdkjlwzpb23tj/app.bsky.feed.post/3lggm2cavtc2l"
            }
          }
        },
        {
          "$type": "pub.leaflet.pages.linearDocument#block",
          "block": {
            "$type": "pub.leaflet.blocks.text",
            "facets": [],
            "plaintext": "At the time, I was working on other Bluesky-adjacent experiments as a way to learn how the underlying decentralized protocol worked:"
          }
        },
        {
          "$type": "pub.leaflet.pages.linearDocument#block",
          "block": {
            "$type": "pub.leaflet.blocks.unorderedList",
            "children": [
              {
                "$type": "pub.leaflet.blocks.unorderedList#listItem",
                "content": {
                  "$type": "pub.leaflet.blocks.text",
                  "facets": [
                    {
                      "index": {
                        "byteEnd": 102,
                        "byteStart": 0
                      },
                      "features": [
                        {
                          "uri": "https://dame.is/writing/blogs/how-i-made-an-automated-dynamic-avatar-for-my-bluesky-profile/",
                          "$type": "pub.leaflet.richtext.facet#link"
                        }
                      ]
                    }
                  ],
                  "plaintext": "I created an automated dynamic avatar that changed every hour of every day to match the sky's gradient"
                },
                "children": []
              },
              {
                "$type": "pub.leaflet.blocks.unorderedList#listItem",
                "content": {
                  "$type": "pub.leaflet.blocks.text",
                  "facets": [
                    {
                      "index": {
                        "byteEnd": 88,
                        "byteStart": 0
                      },
                      "features": [
                        {
                          "uri": "https://cred.blue/home",
                          "$type": "pub.leaflet.richtext.facet#link"
                        }
                      ]
                    }
                  ],
                  "plaintext": "I built a proof-of-concept social scoring system and analytics platform called cred.blue"
                },
                "children": []
              },
              {
                "$type": "pub.leaflet.blocks.unorderedList#listItem",
                "content": {
                  "$type": "pub.leaflet.blocks.text",
                  "facets": [
                    {
                      "index": {
                        "byteEnd": 112,
                        "byteStart": 0
                      },
                      "features": [
                        {
                          "uri": "https://dame.is/writing/blogs/creating-a-decentralized-bathroom-at-protocol/",
                          "$type": "pub.leaflet.richtext.facet#link"
                        }
                      ]
                    }
                  ],
                  "plaintext": "I created the world's first decentralized toilet and a bespoke, hype-niche social networking site called Flushes"
                },
                "children": []
              },
              {
                "$type": "pub.leaflet.blocks.unorderedList#listItem",
                "content": {
                  "$type": "pub.leaflet.blocks.text",
                  "facets": [
                    {
                      "index": {
                        "byteEnd": 97,
                        "byteStart": 0
                      },
                      "features": [
                        {
                          "uri": "https://dame.is/writing/blogs/why-i-started-posting-like-its-the-2000s-again/",
                          "$type": "pub.leaflet.richtext.facet#link"
                        }
                      ]
                    }
                  ],
                  "plaintext": "I returned to early 2000s status updates and incorporated them at the top of my personal website."
                },
                "children": []
              }
            ]
          }
        },
        {
          "$type": "pub.leaflet.pages.linearDocument#block",
          "block": {
            "$type": "pub.leaflet.blocks.text",
            "facets": [
              {
                "index": {
                  "byteEnd": 114,
                  "byteStart": 103
                },
                "features": [
                  {
                    "uri": "https://anisota.net",
                    "$type": "pub.leaflet.richtext.facet#link"
                  }
                ]
              }
            ],
            "plaintext": "Each of these projects taught me more about the ATmosphere and paved the way for me to eventually make anisota.net which was released as a beta this past week."
          }
        },
        {
          "$type": "pub.leaflet.pages.linearDocument#block",
          "block": {
            "$type": "pub.leaflet.blocks.text",
            "facets": [
              {
                "index": {
                  "byteEnd": 13,
                  "byteStart": 0
                },
                "features": [
                  {
                    "$type": "pub.leaflet.richtext.facet#bold"
                  }
                ]
              },
              {
                "index": {
                  "byteEnd": 24,
                  "byteStart": 13
                },
                "features": [
                  {
                    "$type": "pub.leaflet.richtext.facet#bold"
                  },
                  {
                    "uri": "https://anisota.net",
                    "$type": "pub.leaflet.richtext.facet#link"
                  }
                ]
              },
              {
                "index": {
                  "byteEnd": 108,
                  "byteStart": 24
                },
                "features": [
                  {
                    "$type": "pub.leaflet.richtext.facet#bold"
                  }
                ]
              }
            ],
            "plaintext": "At its core, anisota.net is an experimental social media interface and game for Bluesky and the AT Protocol. You don't \"scroll\" through an endless feed of posts. Instead, you flip through a finite deck of cards until you run out of stamina. You don't see engagement metrics front and center, instead each post has a \"rarity\" icon as if it were a trading card. You can collect post cards into curated decks that can then be shared with others. There are even in-game items, specimen collecting, and soon to be quests."
          }
        },
        {
          "$type": "pub.leaflet.pages.linearDocument#block",
          "block": {
            "$type": "pub.leaflet.blocks.text",
            "facets": [
              {
                "index": {
                  "byteEnd": 94,
                  "byteStart": 0
                },
                "features": [
                  {
                    "$type": "pub.leaflet.richtext.facet#bold"
                  }
                ]
              }
            ],
            "plaintext": "It's inspired by the last decade of my art practice, spiritual practice, and posting practice. It's \"homegrown\" in the mountains of Appalachia far away from silicon valley, startup culture, and whatever the hell they're doing at A16Z or Y Combinator."
          }
        },
        {
          "$type": "pub.leaflet.pages.linearDocument#block",
          "block": {
            "$type": "pub.leaflet.blocks.text",
            "facets": [],
            "plaintext": "My process involved sitting outside in my backyard at 1am observing moths. It looked like reading books on animals and anthropology instead of listening to podcasts about ARR and angel investors."
          }
        },
        {
          "$type": "pub.leaflet.pages.linearDocument#block",
          "block": {
            "$type": "pub.leaflet.blocks.text",
            "facets": [
              {
                "index": {
                  "byteEnd": 21,
                  "byteStart": 10
                },
                "features": [
                  {
                    "uri": "https://anisota.net",
                    "$type": "pub.leaflet.richtext.facet#link"
                  }
                ]
              }
            ],
            "plaintext": "I created anisota.net because I wanted a way to continue using social media without having to subject myself to many of the dynamics that are not as healthy or compatible with my lifestyle/values/demeanor. I love technology, but after a decade of experiencing the best and the worst that it has to offer, I realized that the status quo of the internet and social media was not sustainable, grounding, or conducive to human flourishing."
          }
        },
        {
          "$type": "pub.leaflet.pages.linearDocument#block",
          "block": {
            "$type": "pub.leaflet.blocks.text",
            "facets": [],
            "plaintext": "Anisota isn't going to magically fix all of this, but I think it can be a solid step in the right direction... something that can begin reconditioning my brain, changing my muscle memory, and reshaping my relationship to the internet."
          }
        },
        {
          "$type": "pub.leaflet.pages.linearDocument#block",
          "block": {
            "$type": "pub.leaflet.blocks.bskyPost",
            "postRef": {
              "cid": "bafyreidogmrjrodgu7gefxis7zb45tayzgst35qdzxeuemj73pil3wu4oi",
              "uri": "at://did:plc:gq4fo3u6tqzzdkjlwzpb23tj/app.bsky.feed.post/3ltmoieqnls27"
            }
          }
        },
        {
          "$type": "pub.leaflet.pages.linearDocument#block",
          "block": {
            "$type": "pub.leaflet.blocks.text",
            "facets": [
              {
                "index": {
                  "byteEnd": 38,
                  "byteStart": 27
                },
                "features": [
                  {
                    "uri": "https://anisota.net",
                    "$type": "pub.leaflet.richtext.facet#link"
                  }
                ]
              }
            ],
            "plaintext": "I've hesitated to describe anisota.net too much because it's still very early in the journey, and thus it has a lot of room to undergo metamorphosis."
          }
        },
        {
          "$type": "pub.leaflet.pages.linearDocument#block",
          "block": {
            "$type": "pub.leaflet.blocks.text",
            "facets": [],
            "plaintext": "You can listen to what I have to say about it, but here's what other people are saying about it so far too..."
          }
        },
        {
          "$type": "pub.leaflet.pages.linearDocument#block",
          "block": {
            "$type": "pub.leaflet.blocks.unorderedList",
            "children": [
              {
                "$type": "pub.leaflet.blocks.unorderedList#listItem",
                "content": {
                  "$type": "pub.leaflet.blocks.text",
                  "facets": [
                    {
                      "index": {
                        "byteEnd": 152,
                        "byteStart": 146
                      },
                      "features": [
                        {
                          "uri": "https://anisota.net/profile/goose.art/document/3lwwlwjw5vk2z",
                          "$type": "pub.leaflet.richtext.facet#link"
                        }
                      ]
                    }
                  ],
                  "plaintext": "\"If a few hours of using this website could force me to dramatically rethink my relationship to social media, it must be doing something right.\" (source)"
                },
                "children": []
              },
              {
                "$type": "pub.leaflet.blocks.unorderedList#listItem",
                "content": {
                  "$type": "pub.leaflet.blocks.text",
                  "facets": [
                    {
                      "index": {
                        "byteEnd": 66,
                        "byteStart": 60
                      },
                      "features": [
                        {
                          "uri": "https://anisota.net/profile/alilleybrinker.com/post/3lwts7k7ptc26",
                          "$type": "pub.leaflet.richtext.facet#link"
                        }
                      ]
                    }
                  ],
                  "plaintext": "\"Wow, this feels genuinely new in a way I did not expect!\" (source)"
                },
                "children": []
              },
              {
                "$type": "pub.leaflet.blocks.unorderedList#listItem",
                "content": {
                  "$type": "pub.leaflet.blocks.text",
                  "facets": [
                    {
                      "index": {
                        "byteEnd": 52,
                        "byteStart": 46
                      },
                      "features": [
                        {
                          "uri": "https://anisota.net/profile/byarielm.fyi/post/3lwubkrhgha24",
                          "$type": "pub.leaflet.richtext.facet#link"
                        }
                      ]
                    }
                  ],
                  "plaintext": "\"This is magic I forgot I needed in my life\" (source)"
                },
                "children": []
              },
              {
                "$type": "pub.leaflet.blocks.unorderedList#listItem",
                "content": {
                  "$type": "pub.leaflet.blocks.text",
                  "facets": [
                    {
                      "index": {
                        "byteEnd": 80,
                        "byteStart": 74
                      },
                      "features": [
                        {
                          "uri": "https://anisota.net/profile/shaven.beauty/post/3lwua5hqf7b2x",
                          "$type": "pub.leaflet.richtext.facet#link"
                        }
                      ]
                    }
                  ],
                  "plaintext": "\"love how anisota keeps me semi-productive by having a stamina meter <3\" (source)"
                },
                "children": []
              },
              {
                "$type": "pub.leaflet.blocks.unorderedList#listItem",
                "content": {
                  "$type": "pub.leaflet.blocks.text",
                  "facets": [
                    {
                      "index": {
                        "byteEnd": 105,
                        "byteStart": 99
                      },
                      "features": [
                        {
                          "uri": "https://anisota.net/profile/dholms.xyz/post/3lwtoin2ijk2s",
                          "$type": "pub.leaflet.richtext.facet#link"
                        }
                      ]
                    }
                  ],
                  "plaintext": "\"oh yeah this is super rad another example of bluesky getting remixed into something totally new\" (source)"
                },
                "children": []
              },
              {
                "$type": "pub.leaflet.blocks.unorderedList#listItem",
                "content": {
                  "$type": "pub.leaflet.blocks.text",
                  "facets": [
                    {
                      "index": {
                        "byteEnd": 93,
                        "byteStart": 87
                      },
                      "features": [
                        {
                          "uri": "https://anisota.net/profile/rachelvetica.bsky.social/post/3lwsf3oc2nq26",
                          "$type": "pub.leaflet.richtext.facet#link"
                        }
                      ]
                    }
                  ],
                  "plaintext": "\"it's very different than typical social media apps but in a good and intriguing way\" (source)"
                },
                "children": []
              },
              {
                "$type": "pub.leaflet.blocks.unorderedList#listItem",
                "content": {
                  "$type": "pub.leaflet.blocks.text",
                  "facets": [
                    {
                      "index": {
                        "byteEnd": 99,
                        "byteStart": 93
                      },
                      "features": [
                        {
                          "uri": "https://anisota.net/profile/cameron.pfiffer.org/post/3lwslawfm6z2z",
                          "$type": "pub.leaflet.richtext.facet#link"
                        }
                      ]
                    }
                  ],
                  "plaintext": "\"It's really a fascinating experience to be forced to look at only one post in anisota.net\" (source)"
                },
                "children": []
              },
              {
                "$type": "pub.leaflet.blocks.unorderedList#listItem",
                "content": {
                  "$type": "pub.leaflet.blocks.text",
                  "facets": [
                    {
                      "index": {
                        "byteEnd": 53,
                        "byteStart": 47
                      },
                      "features": [
                        {
                          "uri": "https://anisota.net/profile/goose.art/document/3lwwlwjw5vk2z",
                          "$type": "pub.leaflet.richtext.facet#link"
                        }
                      ]
                    }
                  ],
                  "plaintext": "\"Slowcial media in an era of constant hustle\" (source)"
                },
                "children": []
              },
              {
                "$type": "pub.leaflet.blocks.unorderedList#listItem",
                "content": {
                  "$type": "pub.leaflet.blocks.text",
                  "facets": [
                    {
                      "index": {
                        "byteEnd": 59,
                        "byteStart": 53
                      },
                      "features": [
                        {
                          "uri": "https://anisota.net/profile/davidcrespo.bsky.social/post/3lwsl566iok2k",
                          "$type": "pub.leaflet.richtext.facet#link"
                        }
                      ]
                    }
                  ],
                  "plaintext": "\"rare example of Art UI that also wants to be used\" (source)"
                },
                "children": []
              },
              {
                "$type": "pub.leaflet.blocks.unorderedList#listItem",
                "content": {
                  "$type": "pub.leaflet.blocks.text",
                  "facets": [
                    {
                      "index": {
                        "byteEnd": 194,
                        "byteStart": 188
                      },
                      "features": [
                        {
                          "uri": "https://anisota.net/profile/aparker.io/post/3lwsklcs63g2r",
                          "$type": "pub.leaflet.richtext.facet#link"
                        }
                      ]
                    }
                  ],
                  "plaintext": "\"honestly kinda stunned at how good anisota.net looks as a web app on iOS. really nice subtle animation touches. such a cool experimental way to do this format. seriously, check it out.\" (source)"
                },
                "children": []
              },
              {
                "$type": "pub.leaflet.blocks.unorderedList#listItem",
                "content": {
                  "$type": "pub.leaflet.blocks.text",
                  "facets": [
                    {
                      "index": {
                        "byteEnd": 63,
                        "byteStart": 57
                      },
                      "features": [
                        {
                          "uri": "https://anisota.net/profile/quillmatiq.com/post/3lwsr4wzp562p",
                          "$type": "pub.leaflet.richtext.facet#link"
                        }
                      ]
                    }
                  ],
                  "plaintext": "\"Posting from the literal art that is anisota.net 🐛\" (source)"
                },
                "children": []
              },
              {
                "$type": "pub.leaflet.blocks.unorderedList#listItem",
                "content": {
                  "$type": "pub.leaflet.blocks.text",
                  "facets": [
                    {
                      "index": {
                        "byteEnd": 360,
                        "byteStart": 354
                      },
                      "features": [
                        {
                          "uri": "https://anisota.net/profile/goose.art/document/3lwwlwjw5vk2z",
                          "$type": "pub.leaflet.richtext.facet#link"
                        }
                      ]
                    }
                  ],
                  "plaintext": "\"At first, I felt deeply uncomfortable using the app, like I had entered a physical space full of objects I didn't recognize and don't know how to use. But slowly, I began to feel comfortable swiping around, viewing profiles, even commenting on posts. I find these animated glow effects really beautiful and simple, the way they pulse is very calming.\" (source)"
                },
                "children": []
              },
              {
                "$type": "pub.leaflet.blocks.unorderedList#listItem",
                "content": {
                  "$type": "pub.leaflet.blocks.text",
                  "facets": [
                    {
                      "index": {
                        "byteEnd": 334,
                        "byteStart": 328
                      },
                      "features": [
                        {
                          "uri": "https://connectedplaces.online/reports/atmosphere-report-130/",
                          "$type": "pub.leaflet.richtext.facet#link"
                        }
                      ]
                    }
                  ],
                  "plaintext": "\"It is a highly opinionated client, themed around moths, which takes social media microblogging feeds in a very different direction. [It is] unlike any other microblogging client I’ve seen... I personally enjoy the aesthetic of Anisota, and how it adds calming nature sounds fits with the vibe that the client is going for.\" (source)"
                },
                "children": []
              },
              {
                "$type": "pub.leaflet.blocks.unorderedList#listItem",
                "content": {
                  "$type": "pub.leaflet.blocks.text",
                  "facets": [
                    {
                      "index": {
                        "byteEnd": 111,
                        "byteStart": 105
                      },
                      "features": [
                        {
                          "uri": "https://anisota.net/profile/blinkinglights.org/post/3lwwysos2722c",
                          "$type": "pub.leaflet.richtext.facet#link"
                        }
                      ]
                    }
                  ],
                  "plaintext": "\"I showed my wife a post in anisota and she said is that what Bluesky looks like? It’s super pretty!\" (source)"
                },
                "children": []
              }
            ]
          }
        },
        {
          "$type": "pub.leaflet.pages.linearDocument#block",
          "block": {
            "$type": "pub.leaflet.blocks.header",
            "level": 2,
            "facets": [],
            "plaintext": "what's the future of anisota.net look like?"
          }
        },
        {
          "$type": "pub.leaflet.pages.linearDocument#block",
          "block": {
            "$type": "pub.leaflet.blocks.text",
            "facets": [],
            "plaintext": "I have a lot of cool features and experiences planned. Many of them will be coming to the app very soon, while others are more ambitious and will likely be several months away at least. I eventually want the app to be fully independent of Bluesky."
          }
        },
        {
          "$type": "pub.leaflet.pages.linearDocument#block",
          "block": {
            "$type": "pub.leaflet.blocks.text",
            "facets": [
              {
                "index": {
                  "byteEnd": 21,
                  "byteStart": 10
                },
                "features": [
                  {
                    "uri": "https://anisota.net",
                    "$type": "pub.leaflet.richtext.facet#link"
                  }
                ]
              },
              {
                "index": {
                  "byteEnd": 226,
                  "byteStart": 215
                },
                "features": [
                  {
                    "uri": "https://anisota.net",
                    "$type": "pub.leaflet.richtext.facet#link"
                  }
                ]
              }
            ],
            "plaintext": "Currently anisota.net has no investors. It has a runway tied to my personal savings account. Within a few days of launch, it has 15 paying members totaling $150 in monthly recurring revenue. I would like to work on anisota.net and similar projects as my full-time vocation indefinitely. I already am working on it full-time, but I'm obviously not yet making enough to pay the bills."
          }
        },
        {
          "$type": "pub.leaflet.pages.linearDocument#block",
          "block": {
            "$type": "pub.leaflet.blocks.text",
            "facets": [],
            "plaintext": "My dream is to build a small, sustainable, and non-traditional business that makes software, experiences, and art that people love. I want it to be profitable enough that it can sustain the lifestyle of myself and maybe a few partners/employees. I don't want an IPO, I don't want to try to change the world, and I don't want growth at all costs."
          }
        },
        {
          "$type": "pub.leaflet.pages.linearDocument#block",
          "block": {
            "$type": "pub.leaflet.blocks.text",
            "facets": [],
            "plaintext": "Anisota is how I'm pursuing this at the moment."
          }
        },
        {
          "$type": "pub.leaflet.pages.linearDocument#block",
          "block": {
            "$type": "pub.leaflet.blocks.text",
            "facets": [
              {
                "index": {
                  "byteEnd": 94,
                  "byteStart": 53
                },
                "features": [
                  {
                    "uri": "https://anisota.net/settings/subscription",
                    "$type": "pub.leaflet.richtext.facet#link"
                  }
                ]
              }
            ],
            "plaintext": "If you're enjoying what I make and want to see more, consider becoming a member of anisota.net. If you commit to the annual \"Moth\" membership tier, you'll even get some physical zines that I'll be making and shipping out."
          }
        },
        {
          "$type": "pub.leaflet.pages.linearDocument#block",
          "block": {
            "src": "https://anisota.net/settings/subscription",
            "$type": "pub.leaflet.blocks.website",
            "title": "anisota for Bluesky & ATProto",
            "description": "a new, experimental way to use social media",
            "previewImage": {
              "ref": {
                "$link": "bafkreidfsxxn64ecphggh5263qjep2igvm3kb7wdkwh36pptfrvu72co54"
              },
              "size": 8006,
              "$type": "blob",
              "mimeType": "image/png"
            }
          }
        },
        {
          "$type": "pub.leaflet.pages.linearDocument#block",
          "block": {
            "$type": "pub.leaflet.blocks.text",
            "facets": [],
            "plaintext": ""
          }
        },
        {
          "$type": "pub.leaflet.pages.linearDocument#block",
          "block": {
            "$type": "pub.leaflet.blocks.text",
            "facets": [],
            "plaintext": ""
          }
        }
      ]
    }
  ],
  "title": "what is anisota.net?",
  "author": "did:plc:gq4fo3u6tqzzdkjlwzpb23tj",
  "description": "some personal reflections and details about the future from the creator",
  "publication": "at://did:plc:gq4fo3u6tqzzdkjlwzpb23tj/pub.leaflet.publication/3lpq72oeo3c2y",
  "publishedAt": "2025-08-25T18:39:47.611Z"
}

did:plc:gq4fo3u6tqzzdkjlwzpb23tj | at://did:plc:gq4fo3u6tqzzdkjlwzpb23tj/pub.leaflet.document/3lxankooyf22l

pub.leaflet.blocks.blockquote (nested within pub.leaflet.document) (57 samples)
{
  "$type": "pub.leaflet.document",
  "pages": [
    {
      "$type": "pub.leaflet.pages.linearDocument",
      "blocks": [
        {
          "$type": "pub.leaflet.pages.linearDocument#block",
          "block": {
            "$type": "pub.leaflet.blocks.text",
            "facets": [
              {
                "index": {
                  "byteEnd": 15,
                  "byteStart": 6
                },
                "features": [
                  {
                    "uri": "https://marginalia.leaflet.pub/3m4knmtqmt227",
                    "$type": "pub.leaflet.richtext.facet#link"
                  }
                ]
              },
              {
                "index": {
                  "byteEnd": 57,
                  "byteStart": 46
                },
                "features": [
                  {
                    "uri": "https://atproto.com/guides/overview",
                    "$type": "pub.leaflet.richtext.facet#link"
                  }
                ]
              },
              {
                "index": {
                  "byteEnd": 120,
                  "byteStart": 117
                },
                "features": [
                  {
                    "$type": "pub.leaflet.richtext.facet#italic"
                  }
                ]
              }
            ],
            "plaintext": "In my last post, I talked about why I believe AT Protocol represents the future of scholarly communication. That's a big claim, so in this post, I want to unpack it all."
          }
        },
        {
          "$type": "pub.leaflet.pages.linearDocument#block",
          "block": {
            "$type": "pub.leaflet.blocks.text",
            "facets": [],
            "plaintext": "The problems in academic publishing are well-documented: proprietary platforms lock in content and communities, researchers lose control of their work, fragmented systems can't talk to each other, and opaque processes and proprietary platforms centralise power with a handful of gatekeepers."
          }
        },
        {
          "$type": "pub.leaflet.pages.linearDocument#block",
          "block": {
            "$type": "pub.leaflet.blocks.text",
            "facets": [
              {
                "index": {
                  "byteEnd": 119,
                  "byteStart": 112
                },
                "features": [
                  {
                    "$type": "pub.leaflet.richtext.facet#italic"
                  }
                ]
              }
            ],
            "plaintext": "Authors, editors, reviewers, funders, librarians, and institutions alike have been living with these issues for decades, but the fundamental ecosystem architecture has mostly remained unchanged. That situation is unsustainable and frankly, with all the global issues we face, it's unacceptable."
          }
        },
        {
          "$type": "pub.leaflet.pages.linearDocument#block",
          "block": {
            "$type": "pub.leaflet.blocks.text",
            "facets": [
              {
                "index": {
                  "byteEnd": 165,
                  "byteStart": 0
                },
                "features": [
                  {
                    "$type": "pub.leaflet.richtext.facet#bold"
                  }
                ]
              }
            ],
            "plaintext": "I believe that AT Protocol offers a set of feasible and viable technical enablers that can and will reshape how research is created, shared, verified, and preserved."
          }
        },
        {
          "$type": "pub.leaflet.pages.linearDocument#block",
          "block": {
            "$type": "pub.leaflet.blocks.text",
            "facets": [],
            "plaintext": ""
          }
        },
        {
          "$type": "pub.leaflet.pages.linearDocument#block",
          "block": {
            "$type": "pub.leaflet.blocks.header",
            "level": 1,
            "facets": [],
            "plaintext": "Verifiable Identities"
          }
        },
        {
          "$type": "pub.leaflet.pages.linearDocument#block",
          "block": {
            "$type": "pub.leaflet.blocks.text",
            "facets": [
              {
                "index": {
                  "byteEnd": 42,
                  "byteStart": 17
                },
                "features": [
                  {
                    "uri": "https://atproto.com/guides/identity",
                    "$type": "pub.leaflet.richtext.facet#link"
                  }
                ]
              }
            ],
            "plaintext": "AT Protocol uses decentralised identifiers (DIDs) to create persistent portable verifiable identities that users fully own and control."
          }
        },
        {
          "$type": "pub.leaflet.pages.linearDocument#block",
          "block": {
            "$type": "pub.leaflet.blocks.text",
            "facets": [
              {
                "index": {
                  "byteEnd": 42,
                  "byteStart": 10
                },
                "features": [
                  {
                    "$type": "pub.leaflet.richtext.facet#code"
                  }
                ]
              },
              {
                "index": {
                  "byteEnd": 89,
                  "byteStart": 83
                },
                "features": [
                  {
                    "$type": "pub.leaflet.richtext.facet#italic"
                  },
                  {
                    "uri": "https://atproto.com/specs/handle",
                    "$type": "pub.leaflet.richtext.facet#link"
                  }
                ]
              },
              {
                "index": {
                  "byteEnd": 104,
                  "byteStart": 91
                },
                "features": [
                  {
                    "$type": "pub.leaflet.richtext.facet#code"
                  }
                ]
              }
            ],
            "plaintext": "My DID is did:plc:s2rczyxit2v5vzedxqs326ri and connects to a human-readable alias (handle) @renderg.host (which I personalised) so that people can connect with me and recognise me everywhere on the network."
          }
        },
        {
          "$type": "pub.leaflet.pages.linearDocument#block",
          "block": {
            "$type": "pub.leaflet.blocks.text",
            "facets": [
              {
                "index": {
                  "byteEnd": 30,
                  "byteStart": 0
                },
                "features": [
                  {
                    "uri": "https://bsky.app/profile/renderg.host",
                    "$type": "pub.leaflet.richtext.facet#link"
                  }
                ]
              }
            ],
            "plaintext": "Connect with me on Bluesky →"
          }
        },
        {
          "$type": "pub.leaflet.pages.linearDocument#block",
          "block": {
            "$type": "pub.leaflet.blocks.text",
            "facets": [
              {
                "index": {
                  "byteEnd": 12,
                  "byteStart": 7
                },
                "features": [
                  {
                    "uri": "https://orcid.org/",
                    "$type": "pub.leaflet.richtext.facet#link"
                  }
                ]
              }
            ],
            "plaintext": "Unlike ORCID IDs and institutional email accounts, DIDs aren’t tied to any single organisation or platform. This means that reputation and attributions travel with the researcher throughout their career and remain valid regardless of affiliations and organisational changes."
          }
        },
        {
          "$type": "pub.leaflet.pages.linearDocument#block",
          "block": {
            "$type": "pub.leaflet.blocks.text",
            "facets": [],
            "plaintext": "When someone changes institutions or a platform disappears, their identity—and their record—stays intact. Editors can verify contributors directly. Funders can trace outputs without juggling fragmented systems."
          }
        },
        {
          "$type": "pub.leaflet.pages.linearDocument#block",
          "block": {
            "$type": "pub.leaflet.blocks.text",
            "facets": [],
            "plaintext": ""
          }
        },
        {
          "$type": "pub.leaflet.pages.linearDocument#block",
          "block": {
            "$type": "pub.leaflet.blocks.header",
            "level": 1,
            "facets": [],
            "plaintext": "Portable Personal Data"
          }
        },
        {
          "$type": "pub.leaflet.pages.linearDocument#block",
          "block": {
            "$type": "pub.leaflet.blocks.text",
            "facets": [
              {
                "index": {
                  "byteEnd": 84,
                  "byteStart": 69
                },
                "features": [
                  {
                    "uri": "https://atproto.com/specs/repository",
                    "$type": "pub.leaflet.richtext.facet#link"
                  }
                ]
              },
              {
                "index": {
                  "byteEnd": 125,
                  "byteStart": 105
                },
                "features": [
                  {
                    "uri": "https://atproto.com/guides/glossary#pds-personal-data-server",
                    "$type": "pub.leaflet.richtext.facet#link"
                  }
                ]
              },
              {
                "index": {
                  "byteEnd": 212,
                  "byteStart": 204
                },
                "features": [
                  {
                    "$type": "pub.leaflet.richtext.facet#bold"
                  }
                ]
              }
            ],
            "plaintext": "In AT Protocol, all your content, activity and connections live in a data repository that you control. A personal data server (PDS) hosts your data and connects you to the network, but the data itself is portable. This means you can move between hosts without losing your data, connections, or history."
          }
        },
        {
          "$type": "pub.leaflet.pages.linearDocument#block",
          "block": {
            "$type": "pub.leaflet.blocks.text",
            "facets": [
              {
                "index": {
                  "byteEnd": 38,
                  "byteStart": 0
                },
                "features": [
                  {
                    "uri": "https://atproto.at://did:plc:s2rczyxit2v5vzedxqs326ri",
                    "$type": "pub.leaflet.richtext.facet#link"
                  }
                ]
              }
            ],
            "plaintext": "Browse my personal data on Taproot →"
          }
        },
        {
          "$type": "pub.leaflet.pages.linearDocument#block",
          "block": {
            "$type": "pub.leaflet.blocks.text",
            "facets": [],
            "plaintext": "Institutions can run PDS hosting services for their communities while researchers retain full ownership and portability. When a host changes its systems, alters its terms, or shuts down, you simply move your repository to a different host. "
          }
        },
        {
          "$type": "pub.leaflet.pages.linearDocument#block",
          "block": {
            "$type": "pub.leaflet.blocks.text",
            "facets": [
              {
                "index": {
                  "byteEnd": 186,
                  "byteStart": 169
                },
                "features": [
                  {
                    "$type": "pub.leaflet.richtext.facet#italic"
                  }
                ]
              }
            ],
            "plaintext": "Users may rely on institutional or third-party hosts, but unlike today's platforms, you are guaranteed the ability to leave. Your repository belongs to you so moving is not a negotiation."
          }
        },
        {
          "$type": "pub.leaflet.pages.linearDocument#block",
          "block": {
            "$type": "pub.leaflet.blocks.text",
            "facets": [
              {
                "index": {
                  "byteEnd": 69,
                  "byteStart": 30
                },
                "features": [
                  {
                    "$type": "pub.leaflet.richtext.facet#bold"
                  }
                ]
              },
              {
                "index": {
                  "byteEnd": 164,
                  "byteStart": 140
                },
                "features": [
                  {
                    "$type": "pub.leaflet.richtext.facet#bold"
                  }
                ]
              },
              {
                "index": {
                  "byteEnd": 260,
                  "byteStart": 253
                },
                "features": [
                  {
                    "$type": "pub.leaflet.richtext.facet#italic"
                  }
                ]
              },
              {
                "index": {
                  "byteEnd": 362,
                  "byteStart": 331
                },
                "features": [
                  {
                    "$type": "pub.leaflet.richtext.facet#bold"
                  }
                ]
              }
            ],
            "plaintext": "For researchers, this means a complete authenticated scholarly record—publications, reviews, datasets, connections and more—exists as a unified self-owned asset rather than fragments scattered across platforms. Librarians can long-term preservation without depending on commercial platforms. Editors and reviewers can maintain complete contribution histories independent of any journal or publisher."
          }
        },
        {
          "$type": "pub.leaflet.pages.linearDocument#block",
          "block": {
            "$type": "pub.leaflet.blocks.text",
            "facets": [],
            "plaintext": ""
          }
        },
        {
          "$type": "pub.leaflet.pages.linearDocument#block",
          "block": {
            "$type": "pub.leaflet.blocks.header",
            "level": 1,
            "facets": [],
            "plaintext": "Open Shared Lexicons"
          }
        },
        {
          "$type": "pub.leaflet.pages.linearDocument#block",
          "block": {
            "$type": "pub.leaflet.blocks.text",
            "facets": [
              {
                "index": {
                  "byteEnd": 43,
                  "byteStart": 24
                },
                "features": [
                  {
                    "$type": "pub.leaflet.richtext.facet#bold"
                  }
                ]
              },
              {
                "index": {
                  "byteEnd": 53,
                  "byteStart": 45
                },
                "features": [
                  {
                    "$type": "pub.leaflet.richtext.facet#italic"
                  },
                  {
                    "uri": "https://atproto.com/specs/lexicon",
                    "$type": "pub.leaflet.richtext.facet#link"
                  }
                ]
              },
              {
                "index": {
                  "byteEnd": 54,
                  "byteStart": 53
                },
                "features": [
                  {
                    "$type": "pub.leaflet.richtext.facet#italic"
                  }
                ]
              }
            ],
            "plaintext": "The AT Protocol defines open shared schemas (lexicons) that describe how content is structured and exchanged, such as Bluesky posts and likes. These could also cover articles, preprints, datasets, reviews, citations, and other forms of scholarly output."
          }
        },
        {
          "$type": "pub.leaflet.pages.linearDocument#block",
          "block": {
            "$type": "pub.leaflet.blocks.text",
            "facets": [
              {
                "index": {
                  "byteEnd": 60,
                  "byteStart": 0
                },
                "features": [
                  {
                    "uri": "https://tangled.org/@renderg.host/at-scholarly-lexicons",
                    "$type": "pub.leaflet.richtext.facet#link"
                  }
                ]
              }
            ],
            "plaintext": "Browse hypothetical lexicons for scholarly communication →"
          }
        },
        {
          "$type": "pub.leaflet.pages.linearDocument#block",
          "block": {
            "$type": "pub.leaflet.blocks.text",
            "facets": [
              {
                "index": {
                  "byteEnd": 32,
                  "byteStart": 11
                },
                "features": [
                  {
                    "$type": "pub.leaflet.richtext.facet#bold"
                  }
                ]
              }
            ],
            "plaintext": "This means real interoperability across platforms and tools is possible. No more proprietary formats or closed ecosystems."
          }
        },
        {
          "$type": "pub.leaflet.pages.linearDocument#block",
          "block": {
            "$type": "pub.leaflet.blocks.text",
            "facets": [],
            "plaintext": "—"
          }
        },
        {
          "$type": "pub.leaflet.pages.linearDocument#block",
          "block": {
            "$type": "pub.leaflet.blocks.text",
            "facets": [
              {
                "index": {
                  "byteEnd": 16,
                  "byteStart": 12
                },
                "features": [
                  {
                    "$type": "pub.leaflet.richtext.facet#code"
                  }
                ]
              },
              {
                "index": {
                  "byteEnd": 58,
                  "byteStart": 50
                },
                "features": [
                  {
                    "uri": "https://bookhive.buzz/profile/renderg.host",
                    "$type": "pub.leaflet.richtext.facet#link"
                  }
                ]
              },
              {
                "index": {
                  "byteEnd": 95,
                  "byteStart": 88
                },
                "features": [
                  {
                    "uri": "https://popfeed.social/reviews?authorDid=did:plc:s2rczyxit2v5vzedxqs326ri&creativeWorkType=book",
                    "$type": "pub.leaflet.richtext.facet#link"
                  }
                ]
              }
            ],
            "plaintext": "📚 Shared book lexicons mean my reading list on BookHive also magically appears on my Popfeed profile."
          }
        },
        {
          "$type": "pub.leaflet.pages.linearDocument#block",
          "block": {
            "$type": "pub.leaflet.blocks.text",
            "facets": [],
            "plaintext": "—"
          }
        },
        {
          "$type": "pub.leaflet.pages.linearDocument#block",
          "block": {
            "$type": "pub.leaflet.blocks.text",
            "facets": [
              {
                "index": {
                  "byteEnd": 382,
                  "byteStart": 376
                },
                "features": [
                  {
                    "$type": "pub.leaflet.richtext.facet#italic"
                  }
                ]
              }
            ],
            "plaintext": "A preprint server, institutional repository, and journal submission system could all work with the same article format. Datasets link to publications through standardised relationships. Citation indexes become queryable across platforms. Funders can track outcomes by reporting on consistent metadata. Research integrity investigations can follow documented trails across the entire network—no more chasing down proprietary exports or scraping publisher websites."
          }
        },
        {
          "$type": "pub.leaflet.pages.linearDocument#block",
          "block": {
            "$type": "pub.leaflet.blocks.text",
            "facets": [],
            "plaintext": "Currently, different platform uses different formats and APIs, creating massive friction and lock-in that only benefits vendors and their expensive broken and outdated systems."
          }
        },
        {
          "$type": "pub.leaflet.pages.linearDocument#block",
          "block": {
            "$type": "pub.leaflet.blocks.text",
            "facets": [
              {
                "index": {
                  "byteEnd": 368,
                  "byteStart": 360
                },
                "features": [
                  {
                    "$type": "pub.leaflet.richtext.facet#italic"
                  }
                ]
              }
            ],
            "plaintext": "Shared lexicons eliminate this fragmentation, letting the community define standard formats and build universal tools and services that can work everywhere. Effective schemas require agreement between researchers, publishers, institutions, and funders. Early decisions matter, and the community needs governance and cooperation to develop standards that serve everyone."
          }
        },
        {
          "$type": "pub.leaflet.pages.linearDocument#block",
          "block": {
            "$type": "pub.leaflet.blocks.text",
            "facets": [],
            "plaintext": ""
          }
        },
        {
          "$type": "pub.leaflet.pages.linearDocument#block",
          "block": {
            "$type": "pub.leaflet.blocks.header",
            "level": 1,
            "facets": [],
            "plaintext": "Labellers"
          }
        },
        {
          "$type": "pub.leaflet.pages.linearDocument#block",
          "block": {
            "$type": "pub.leaflet.blocks.text",
            "facets": [
              {
                "index": {
                  "byteEnd": 9,
                  "byteStart": 0
                },
                "features": [
                  {
                    "uri": "https://docs.bsky.app/docs/advanced-guides/moderation",
                    "$type": "pub.leaflet.richtext.facet#link"
                  }
                ]
              },
              {
                "index": {
                  "byteEnd": 67,
                  "byteStart": 61
                },
                "features": [
                  {
                    "$type": "pub.leaflet.richtext.facet#italic"
                  },
                  {
                    "uri": "https://atproto.com/specs/label",
                    "$type": "pub.leaflet.richtext.facet#link"
                  }
                ]
              },
              {
                "index": {
                  "byteEnd": 91,
                  "byteStart": 83
                },
                "features": [
                  {
                    "$type": "pub.leaflet.richtext.facet#bold"
                  }
                ]
              },
              {
                "index": {
                  "byteEnd": 94,
                  "byteStart": 91
                },
                "features": [
                  {
                    "$type": "pub.leaflet.richtext.facet#bold"
                  },
                  {
                    "$type": "pub.leaflet.richtext.facet#italic"
                  }
                ]
              },
              {
                "index": {
                  "byteEnd": 100,
                  "byteStart": 94
                },
                "features": [
                  {
                    "$type": "pub.leaflet.richtext.facet#bold"
                  }
                ]
              }
            ],
            "plaintext": "Labellers* are independent services that can apply metadata (labels) as signals to content and users on the network. They could be used to mark peer-review status, flag integrity issues, classify topics, verify credentials, or indicate quality—whatever signals a community finds valuable."
          }
        },
        {
          "$type": "pub.leaflet.pages.linearDocument#block",
          "block": {
            "$type": "pub.leaflet.blocks.text",
            "facets": [
              {
                "index": {
                  "byteEnd": 34,
                  "byteStart": 0
                },
                "features": [
                  {
                    "uri": "https://www.bluesky-labelers.io/",
                    "$type": "pub.leaflet.richtext.facet#link"
                  }
                ]
              }
            ],
            "plaintext": "Browse some existing labellers →"
          }
        },
        {
          "$type": "pub.leaflet.pages.linearDocument#block",
          "block": {
            "$type": "pub.leaflet.blocks.text",
            "facets": [
              {
                "index": {
                  "byteEnd": 40,
                  "byteStart": 13
                },
                "features": [
                  {
                    "$type": "pub.leaflet.richtext.facet#bold"
                  }
                ]
              }
            ],
            "plaintext": "This creates distributed quality control without central gatekeepers. "
          }
        },
        {
          "$type": "pub.leaflet.pages.linearDocument#block",
          "block": {
            "$type": "pub.leaflet.blocks.text",
            "facets": [],
            "plaintext": "A scholarly society could run a labeller certifying domain expertise. A research institutions could flag ethical compliance or replication status. Funders could tag grant-supported work. Preprint servers could mark editorial assessments."
          }
        },
        {
          "$type": "pub.leaflet.pages.linearDocument#block",
          "block": {
            "$type": "pub.leaflet.blocks.text",
            "facets": [],
            "plaintext": "Multiple labellers can evaluate the same content from different perspectives—methodological rigour, epistemic status, reproducibility, clinical relevance—giving readers layered, transparent signals rather than a single journal's brand as a proxy for quality and integrity."
          }
        },
        {
          "$type": "pub.leaflet.pages.linearDocument#block",
          "block": {
            "$type": "pub.leaflet.blocks.text",
            "facets": [
              {
                "index": {
                  "byteEnd": 59,
                  "byteStart": 54
                },
                "features": [
                  {
                    "$type": "pub.leaflet.richtext.facet#italic"
                  }
                ]
              }
            ],
            "plaintext": "Currently, this signalling is almost entirely tied to where something is published. Journal prestige stands in for peer review quality, editorial standards, and research integrity—but these are opaque, inconsistent, and controlled by publishers."
          }
        },
        {
          "$type": "pub.leaflet.pages.linearDocument#block",
          "block": {
            "$type": "pub.leaflet.blocks.text",
            "facets": [
              {
                "index": {
                  "byteEnd": 68,
                  "byteStart": 31
                },
                "features": [
                  {
                    "$type": "pub.leaflet.richtext.facet#bold"
                  }
                ]
              },
              {
                "index": {
                  "byteEnd": 87,
                  "byteStart": 82
                },
                "features": [
                  {
                    "$type": "pub.leaflet.richtext.facet#italic"
                  }
                ]
              }
            ],
            "plaintext": "Labellers make quality signals explicit, verifiable, and competitive. Researchers et al can see who evaluated what and why, then decide which signals they trust."
          }
        },
        {
          "$type": "pub.leaflet.pages.linearDocument#block",
          "block": {
            "$type": "pub.leaflet.blocks.text",
            "facets": [],
            "plaintext": ""
          }
        },
        {
          "$type": "pub.leaflet.pages.linearDocument#block",
          "block": {
            "$type": "pub.leaflet.blocks.header",
            "level": 1,
            "facets": [],
            "plaintext": "Feeds"
          }
        },
        {
          "$type": "pub.leaflet.pages.linearDocument#block",
          "block": {
            "$type": "pub.leaflet.blocks.text",
            "facets": [
              {
                "index": {
                  "byteEnd": 5,
                  "byteStart": 0
                },
                "features": [
                  {
                    "uri": "https://bsky.social/about/blog/7-27-2023-custom-feeds",
                    "$type": "pub.leaflet.richtext.facet#link"
                  }
                ]
              }
            ],
            "plaintext": "Feeds* are algorithmic filters that anyone can build and subscribe to."
          }
        },
        {
          "$type": "pub.leaflet.pages.linearDocument#block",
          "block": {
            "$type": "pub.leaflet.blocks.text",
            "facets": [],
            "plaintext": "Instead of a single platform algorithm deciding what you see, you can choose from multiple feeds with transparent, customisable logic."
          }
        },
        {
          "$type": "pub.leaflet.pages.linearDocument#block",
          "block": {
            "$type": "pub.leaflet.blocks.text",
            "facets": [
              {
                "index": {
                  "byteEnd": 42,
                  "byteStart": 27
                },
                "features": [
                  {
                    "uri": "https://bsky.app/profile/renderg.host/feed/aaanhxqrztto6",
                    "$type": "pub.leaflet.richtext.facet#link"
                  }
                ]
              },
              {
                "index": {
                  "byteEnd": 55,
                  "byteStart": 44
                },
                "features": [
                  {
                    "uri": "https://bsky.app/profile/renderg.host/feed/aaajnmvcrx3k6",
                    "$type": "pub.leaflet.richtext.facet#link"
                  }
                ]
              },
              {
                "index": {
                  "byteEnd": 77,
                  "byteStart": 60
                },
                "features": [
                  {
                    "uri": "https://bsky.app/profile/renderg.host/feed/aaakb3gbladps",
                    "$type": "pub.leaflet.richtext.facet#link"
                  }
                ]
              },
              {
                "index": {
                  "byteEnd": 100,
                  "byteStart": 81
                },
                "features": [
                  {
                    "uri": "https://www.graze.social/",
                    "$type": "pub.leaflet.richtext.facet#link"
                  }
                ]
              }
            ],
            "plaintext": "Browse my custom feeds for Calls to Submit, Latest DOIs and Trending Academia or Build your own Feed"
          }
        },
        {
          "$type": "pub.leaflet.pages.linearDocument#block",
          "block": {
            "$type": "pub.leaflet.blocks.text",
            "facets": [],
            "plaintext": "Currently, discovery is controlled by platform algorithms optimising for engagement, journal email alerts with limited filtering, or manual searching across fragmented databases."
          }
        },
        {
          "$type": "pub.leaflet.pages.linearDocument#block",
          "block": {
            "$type": "pub.leaflet.blocks.text",
            "facets": [],
            "plaintext": "Feeds make discovery flexible, personalised, and shareable—communities can build specialised filters and experiment with discovery mechanisms that reflect how research actually works, rather than adapting to generic platform features often biased towards monetised engagement."
          }
        },
        {
          "$type": "pub.leaflet.pages.linearDocument#block",
          "block": {
            "$type": "pub.leaflet.blocks.unorderedList",
            "children": [
              {
                "$type": "pub.leaflet.blocks.unorderedList#listItem",
                "content": {
                  "$type": "pub.leaflet.blocks.text",
                  "facets": [
                    {
                      "index": {
                        "byteEnd": 53,
                        "byteStart": 45
                      },
                      "features": [
                        {
                          "uri": "https://bsky.app/profile/renderg.host/feed/aaajnmvcrx3k6",
                          "$type": "pub.leaflet.richtext.facet#link"
                        }
                      ]
                    },
                    {
                      "index": {
                        "byteEnd": 147,
                        "byteStart": 127
                      },
                      "features": [
                        {
                          "uri": "https://bsky.app/profile/renderg.host/feed/aaanhxqrztto6",
                          "$type": "pub.leaflet.richtext.facet#link"
                        }
                      ]
                    }
                  ],
                  "plaintext": "Researchers can subscribe to feeds surfacing new work in their subfield, papers citing their work, outputs from collaborators, calls for submission or talks at upcoming conferences"
                },
                "children": []
              },
              {
                "$type": "pub.leaflet.blocks.unorderedList#listItem",
                "content": {
                  "$type": "pub.leaflet.blocks.text",
                  "facets": [],
                  "plaintext": "Librarians can curate feeds highlighting institutional research or open datasets"
                },
                "children": []
              },
              {
                "$type": "pub.leaflet.blocks.unorderedList#listItem",
                "content": {
                  "$type": "pub.leaflet.blocks.text",
                  "facets": [],
                  "plaintext": "Funders can monitor grant-supported outputs"
                },
                "children": []
              },
              {
                "$type": "pub.leaflet.blocks.unorderedList#listItem",
                "content": {
                  "$type": "pub.leaflet.blocks.text",
                  "facets": [],
                  "plaintext": "Research groups can share feeds of essential reading or emerging methods or protocols"
                },
                "children": []
              },
              {
                "$type": "pub.leaflet.blocks.unorderedList#listItem",
                "content": {
                  "$type": "pub.leaflet.blocks.text",
                  "facets": [],
                  "plaintext": "Publishers can identify preprints as candidates for peer review"
                },
                "children": []
              }
            ]
          }
        },
        {
          "$type": "pub.leaflet.pages.linearDocument#block",
          "block": {
            "$type": "pub.leaflet.blocks.text",
            "facets": [
              {
                "index": {
                  "byteEnd": 181,
                  "byteStart": 172
                },
                "features": [
                  {
                    "$type": "pub.leaflet.richtext.facet#bold"
                  }
                ]
              }
            ],
            "plaintext": "Imagine discipline-specific feeds, citation-based recommendations, methodology filters, replication status trackers, epistemic categorisation, and more... The potential is limitless:"
          }
        },
        {
          "$type": "pub.leaflet.pages.linearDocument#block",
          "block": {
            "$type": "pub.leaflet.blocks.blockquote",
            "facets": [
              {
                "index": {
                  "byteEnd": 138,
                  "byteStart": 1
                },
                "features": [
                  {
                    "$type": "pub.leaflet.richtext.facet#italic"
                  }
                ]
              }
            ],
            "plaintext": "*Although Feeds and labellers are not officially supported by AT Protocol, Bluesky is showing the potential through their implementations."
          }
        },
        {
          "$type": "pub.leaflet.pages.linearDocument#block",
          "block": {
            "$type": "pub.leaflet.blocks.text",
            "facets": [],
            "plaintext": ""
          }
        },
        {
          "$type": "pub.leaflet.pages.linearDocument#block",
          "block": {
            "$type": "pub.leaflet.blocks.header",
            "level": 1,
            "facets": [
              {
                "index": {
                  "byteEnd": 24,
                  "byteStart": 9
                },
                "features": [
                  {
                    "$type": "pub.leaflet.richtext.facet#code"
                  }
                ]
              }
            ],
            "plaintext": "Join the ATProto Science Community"
          }
        },
        {
          "$type": "pub.leaflet.pages.linearDocument#block",
          "block": {
            "src": "https://discourse.atprotocol.community/c/atproto-science/22/none",
            "$type": "pub.leaflet.blocks.website",
            "title": "ATProto Science",
            "description": "ATProto Science is about using ATProto for science applications, such as publishing, curation, data sharing or social discourse around research.",
            "previewImage": {
              "ref": {
                "$link": "bafkreidnpgeqt3q3i2ahafbqpb3cvbz6h4x5buf7f5athoiam7da63bnmi"
              },
              "size": 12291,
              "$type": "blob",
              "mimeType": "image/png"
            }
          }
        }
      ]
    }
  ],
  "title": "AT Protocol is a game-changer for scholarly communication and academic publishing.",
  "author": "did:plc:s2rczyxit2v5vzedxqs326ri",
  "postRef": {
    "cid": "bafyreicuokwuc2xczoorqdoxueypsqovvsfv2bnnwba7lm3cfieckq2vde",
    "uri": "at://did:plc:s2rczyxit2v5vzedxqs326ri/app.bsky.feed.post/3m4nbgbchh22g",
    "commit": {
      "cid": "bafyreigoo3bjovdvpwkyfkthr5y67clwrpfzepm4ovdxmuzhsot7hsolrq",
      "rev": "3m4nbgbf4oc24"
    },
    "validationStatus": "valid"
  },
  "description": "How to make research more open, continuous, and collaborative, while preserving ownership, credit, and integrity.",
  "publication": "at://did:plc:s2rczyxit2v5vzedxqs326ri/pub.leaflet.publication/3m4di6yzkt22z",
  "publishedAt": "2025-11-02T10:13:03.912Z"
}

did:plc:s2rczyxit2v5vzedxqs326ri | at://did:plc:s2rczyxit2v5vzedxqs326ri/pub.leaflet.document/3m4nbg4bh422g

pub.leaflet.blocks.bskyPost (nested within pub.leaflet.document) (67 samples)
{
  "tags": [],
  "$type": "pub.leaflet.document",
  "pages": [
    {
      "id": "019b81b8-66ce-7229-a4f8-08d7a60e089d",
      "$type": "pub.leaflet.pages.linearDocument",
      "blocks": [
        {
          "$type": "pub.leaflet.pages.linearDocument#block",
          "block": {
            "$type": "pub.leaflet.blocks.header",
            "level": 2,
            "facets": [],
            "plaintext": "ある日、返信も引用もできない投稿を見つけた"
          }
        },
        {
          "$type": "pub.leaflet.pages.linearDocument#block",
          "block": {
            "$type": "pub.leaflet.blocks.text",
            "facets": [],
            "plaintext": "先日、Blueskyであるユーザーの投稿を見かけました。その人は誰かの投稿を引用して自分の意見を書いていたのですが、私がその投稿に反応しようとしたら、返信ボタンも引用ボタンも押せない。できるのはリポスト(そのまま転載)だけ。"
          }
        },
        {
          "$type": "pub.leaflet.pages.linearDocument#block",
          "block": {
            "$type": "pub.leaflet.blocks.text",
            "facets": [],
            "plaintext": "「あれ、ブロックされてる?」と一瞬思いましたが、違いました。その人が投稿するときに「返信と引用は受け付けない」という設定をしていたのです。"
          }
        },
        {
          "$type": "pub.leaflet.pages.linearDocument#block",
          "block": {
            "$type": "pub.leaflet.blocks.text",
            "facets": [
              {
                "index": {
                  "byteEnd": 238,
                  "byteStart": 181
                },
                "features": [
                  {
                    "$type": "pub.leaflet.richtext.facet#bold"
                  }
                ]
              }
            ],
            "plaintext": "Blueskyには、投稿ごとに「誰がどう反応できるか」を細かく設定できる機能があります。これ、単なる便利機能ではなく、よく考えると言葉の届け方そのものをデザインしているんですね。"
          }
        },
        {
          "$type": "pub.leaflet.pages.linearDocument#block",
          "block": {
            "$type": "pub.leaflet.blocks.text",
            "facets": [],
            "plaintext": "今回は、この機能を「発話行為論」という言語哲学の考え方から読み解いてみます。"
          }
        },
        {
          "$type": "pub.leaflet.pages.linearDocument#block",
          "block": {
            "$type": "pub.leaflet.blocks.horizontalRule"
          }
        },
        {
          "$type": "pub.leaflet.pages.linearDocument#block",
          "block": {
            "$type": "pub.leaflet.blocks.header",
            "level": 2,
            "facets": [],
            "plaintext": "設定できる3つのスイッチ"
          }
        },
        {
          "$type": "pub.leaflet.pages.linearDocument#block",
          "block": {
            "$type": "pub.leaflet.blocks.text",
            "facets": [],
            "plaintext": "Blueskyでは、投稿するときに以下の3つを個別にオン・オフできます。"
          }
        },
        {
          "$type": "pub.leaflet.pages.linearDocument#block",
          "block": {
            "$type": "pub.leaflet.blocks.unorderedList",
            "children": [
              {
                "$type": "pub.leaflet.blocks.unorderedList#listItem",
                "content": {
                  "$type": "pub.leaflet.blocks.text",
                  "facets": [
                    {
                      "index": {
                        "byteEnd": 6,
                        "byteStart": 0
                      },
                      "features": [
                        {
                          "$type": "pub.leaflet.richtext.facet#bold"
                        }
                      ]
                    }
                  ],
                  "plaintext": "返信:その投稿に直接コメントできるか"
                },
                "children": []
              },
              {
                "$type": "pub.leaflet.blocks.unorderedList#listItem",
                "content": {
                  "$type": "pub.leaflet.blocks.text",
                  "facets": [
                    {
                      "index": {
                        "byteEnd": 12,
                        "byteStart": 0
                      },
                      "features": [
                        {
                          "$type": "pub.leaflet.richtext.facet#bold"
                        }
                      ]
                    }
                  ],
                  "plaintext": "リポスト:そのまま自分のタイムラインに流せるか"
                },
                "children": []
              },
              {
                "$type": "pub.leaflet.blocks.unorderedList#listItem",
                "content": {
                  "$type": "pub.leaflet.blocks.text",
                  "facets": [
                    {
                      "index": {
                        "byteEnd": 6,
                        "byteStart": 0
                      },
                      "features": [
                        {
                          "$type": "pub.leaflet.richtext.facet#bold"
                        }
                      ]
                    }
                  ],
                  "plaintext": "引用:自分のコメントを付けて再投稿できるか"
                },
                "children": []
              }
            ]
          }
        },
        {
          "$type": "pub.leaflet.pages.linearDocument#block",
          "block": {
            "$type": "pub.leaflet.blocks.text",
            "facets": [],
            "plaintext": "この組み合わせで、投稿の「届き方」がまったく変わります。"
          }
        },
        {
          "$type": "pub.leaflet.pages.linearDocument#block",
          "block": {
            "$type": "pub.leaflet.blocks.horizontalRule"
          }
        },
        {
          "$type": "pub.leaflet.pages.linearDocument#block",
          "block": {
            "$type": "pub.leaflet.blocks.header",
            "level": 2,
            "facets": [],
            "plaintext": "組み合わせで変わる「投稿の性格」"
          }
        },
        {
          "$type": "pub.leaflet.pages.linearDocument#block",
          "block": {
            "$type": "pub.leaflet.blocks.text",
            "facets": [],
            "plaintext": "いくつか例を見てみましょう。"
          }
        },
        {
          "$type": "pub.leaflet.pages.linearDocument#block",
          "block": {
            "$type": "pub.leaflet.blocks.text",
            "facets": [
              {
                "index": {
                  "byteEnd": 60,
                  "byteStart": 0
                },
                "features": [
                  {
                    "$type": "pub.leaflet.richtext.facet#bold"
                  }
                ]
              }
            ],
            "plaintext": "すべてオン(返信○・リポスト○・引用○)"
          }
        },
        {
          "$type": "pub.leaflet.pages.linearDocument#block",
          "block": {
            "$type": "pub.leaflet.blocks.text",
            "facets": [],
            "plaintext": "もっとも開かれた状態。「みんなで話そう」「どんどん広めて」「好きに解釈して」という姿勢です。議論を呼びたいとき、集合知を集めたいときに向いています。"
          }
        },
        {
          "$type": "pub.leaflet.pages.linearDocument#block",
          "block": {
            "$type": "pub.leaflet.blocks.text",
            "facets": [
              {
                "index": {
                  "byteEnd": 67,
                  "byteStart": 0
                },
                "features": [
                  {
                    "$type": "pub.leaflet.richtext.facet#bold"
                  }
                ]
              }
            ],
            "plaintext": "リポストだけオン(返信×・リポスト○・引用×)"
          }
        },
        {
          "$type": "pub.leaflet.pages.linearDocument#block",
          "block": {
            "$type": "pub.leaflet.blocks.text",
            "facets": [],
            "plaintext": "冒頭で見かけたパターンがこれ。「この言葉をそのまま届けたい。でも議論はしたくないし、切り取られたくもない」という意図が読み取れます。声明や告知、意見表明に向いています。"
          }
        },
        {
          "$type": "pub.leaflet.pages.linearDocument#block",
          "block": {
            "$type": "pub.leaflet.blocks.text",
            "facets": [
              {
                "index": {
                  "byteEnd": 61,
                  "byteStart": 0
                },
                "features": [
                  {
                    "$type": "pub.leaflet.richtext.facet#bold"
                  }
                ]
              }
            ],
            "plaintext": "返信だけオン(返信○・リポスト×・引用×)"
          }
        },
        {
          "$type": "pub.leaflet.pages.linearDocument#block",
          "block": {
            "$type": "pub.leaflet.blocks.text",
            "facets": [],
            "plaintext": "「広まらなくていいから、フォロワーと静かに話したい」。クローズドな対話向きです。"
          }
        },
        {
          "$type": "pub.leaflet.pages.linearDocument#block",
          "block": {
            "$type": "pub.leaflet.blocks.text",
            "facets": [
              {
                "index": {
                  "byteEnd": 57,
                  "byteStart": 0
                },
                "features": [
                  {
                    "$type": "pub.leaflet.richtext.facet#bold"
                  }
                ]
              }
            ],
            "plaintext": "すべてオフ(返信×・リポスト×・引用×)"
          }
        },
        {
          "$type": "pub.leaflet.pages.linearDocument#block",
          "block": {
            "$type": "pub.leaflet.blocks.text",
            "facets": [],
            "plaintext": "完全に閉じた発話。日記や独白、あるいは「記録として残すだけ」の投稿。"
          }
        },
        {
          "$type": "pub.leaflet.pages.linearDocument#block",
          "block": {
            "$type": "pub.leaflet.blocks.horizontalRule"
          }
        },
        {
          "$type": "pub.leaflet.pages.linearDocument#block",
          "block": {
            "$type": "pub.leaflet.blocks.header",
            "level": 2,
            "facets": [],
            "plaintext": "「発話行為論」という考え方"
          }
        },
        {
          "$type": "pub.leaflet.pages.linearDocument#block",
          "block": {
            "$type": "pub.leaflet.blocks.text",
            "facets": [],
            "plaintext": "ここで少し言語哲学の話をします。"
          }
        },
        {
          "$type": "pub.leaflet.pages.linearDocument#block",
          "block": {
            "$type": "pub.leaflet.blocks.text",
            "facets": [],
            "plaintext": "1960年代、イギリスの哲学者オースティンは「言葉を発するとは、実は3つのことを同時にやっている」と指摘しました。これが「発話行為論」です。"
          }
        },
        {
          "$type": "pub.leaflet.pages.linearDocument#block",
          "block": {
            "$type": "pub.leaflet.blocks.unorderedList",
            "children": [
              {
                "$type": "pub.leaflet.blocks.unorderedList#listItem",
                "content": {
                  "$type": "pub.leaflet.blocks.text",
                  "facets": [
                    {
                      "index": {
                        "byteEnd": 12,
                        "byteStart": 0
                      },
                      "features": [
                        {
                          "$type": "pub.leaflet.richtext.facet#bold"
                        }
                      ]
                    }
                  ],
                  "plaintext": "発語行為:音や文字を発すること(「明日会議です」と言う)"
                },
                "children": []
              },
              {
                "$type": "pub.leaflet.blocks.unorderedList#listItem",
                "content": {
                  "$type": "pub.leaflet.blocks.text",
                  "facets": [
                    {
                      "index": {
                        "byteEnd": 15,
                        "byteStart": 0
                      },
                      "features": [
                        {
                          "$type": "pub.leaflet.richtext.facet#bold"
                        }
                      ]
                    }
                  ],
                  "plaintext": "発語内行為:その発話で何をしようとしているか(通知? 依頼? 命令?)"
                },
                "children": []
              },
              {
                "$type": "pub.leaflet.blocks.unorderedList#listItem",
                "content": {
                  "$type": "pub.leaflet.blocks.text",
                  "facets": [
                    {
                      "index": {
                        "byteEnd": 18,
                        "byteStart": 0
                      },
                      "features": [
                        {
                          "$type": "pub.leaflet.richtext.facet#bold"
                        }
                      ]
                    }
                  ],
                  "plaintext": "発語媒介行為:相手にどんな効果を与えるか(納得させる、怒らせる、行動させる)"
                },
                "children": []
              }
            ]
          }
        },
        {
          "$type": "pub.leaflet.pages.linearDocument#block",
          "block": {
            "$type": "pub.leaflet.blocks.text",
            "facets": [],
            "plaintext": "たとえば「明日会議です」という同じ言葉でも、「お知らせ」なのか「来いという命令」なのか「予定確認の質問」なのかで意味が違う。そして、相手が「わかりました」と納得するか「また会議か」とうんざりするかは、言った後の効果の話です。"
          }
        },
        {
          "$type": "pub.leaflet.pages.linearDocument#block",
          "block": {
            "$type": "pub.leaflet.blocks.horizontalRule"
          }
        },
        {
          "$type": "pub.leaflet.pages.linearDocument#block",
          "block": {
            "$type": "pub.leaflet.blocks.header",
            "level": 2,
            "facets": [],
            "plaintext": "SNSでは「届き方」が制御できなかった"
          }
        },
        {
          "$type": "pub.leaflet.pages.linearDocument#block",
          "block": {
            "$type": "pub.leaflet.blocks.text",
            "facets": [],
            "plaintext": "従来のSNS——たとえばX(旧Twitter)——では、投稿したら最後、どう届くかは投稿者の手を離れていました。"
          }
        },
        {
          "$type": "pub.leaflet.pages.linearDocument#block",
          "block": {
            "$type": "pub.leaflet.blocks.text",
            "facets": [],
            "plaintext": "賛同のリポストも、悪意ある引用も、炎上する返信ツリーも、すべて「野に放つ」モデル。発語媒介行為(相手への効果)は、事実上コントロール不能だったのです(現在、投稿の公開範囲や、リプライについてはある程度制御できます)。"
          }
        },
        {
          "$type": "pub.leaflet.pages.linearDocument#block",
          "block": {
            "$type": "pub.leaflet.blocks.horizontalRule"
          }
        },
        {
          "$type": "pub.leaflet.pages.linearDocument#block",
          "block": {
            "$type": "pub.leaflet.blocks.header",
            "level": 2,
            "facets": [],
            "plaintext": "Blueskyが変えたこと"
          }
        },
        {
          "$type": "pub.leaflet.pages.linearDocument#block",
          "block": {
            "$type": "pub.leaflet.blocks.text",
            "facets": [],
            "plaintext": "Blueskyでは、投稿するときに「誰がどう反応できるか」を設定できるようになりました。"
          }
        },
        {
          "$type": "pub.leaflet.pages.linearDocument#block",
          "block": {
            "$type": "pub.leaflet.blocks.text",
            "facets": [
              {
                "index": {
                  "byteEnd": 69,
                  "byteStart": 0
                },
                "features": [
                  {
                    "$type": "pub.leaflet.richtext.facet#bold"
                  }
                ]
              }
            ],
            "plaintext": "発語媒介行為を事前にデザインできるようになった"
          }
        },
        {
          "$type": "pub.leaflet.pages.linearDocument#block",
          "block": {
            "$type": "pub.leaflet.blocks.text",
            "facets": [],
            "plaintext": "返信をオフにすれば、議論は起きない。引用をオフにすれば、文脈を切り取られない。リポストだけ許可すれば、原文のまま届く。"
          }
        },
        {
          "$type": "pub.leaflet.pages.linearDocument#block",
          "block": {
            "$type": "pub.leaflet.blocks.text",
            "facets": [],
            "plaintext": "つまり、「何を言うか」だけでなく「どう届いてほしいか」まで含めて、投稿という発話行為が完成するようになったのです。"
          }
        },
        {
          "$type": "pub.leaflet.pages.linearDocument#block",
          "block": {
            "$type": "pub.leaflet.blocks.horizontalRule"
          }
        },
        {
          "$type": "pub.leaflet.pages.linearDocument#block",
          "block": {
            "$type": "pub.leaflet.blocks.header",
            "level": 2,
            "facets": [],
            "plaintext": "これは何を意味するのか"
          }
        },
        {
          "$type": "pub.leaflet.pages.linearDocument#block",
          "block": {
            "$type": "pub.leaflet.blocks.text",
            "facets": [
              {
                "index": {
                  "byteEnd": 72,
                  "byteStart": 21
                },
                "features": [
                  {
                    "$type": "pub.leaflet.richtext.facet#bold"
                  }
                ]
              }
            ],
            "plaintext": "言い換えると、ミームの伝播設計権が投稿者に移ったということです。"
          }
        },
        {
          "$type": "pub.leaflet.pages.linearDocument#block",
          "block": {
            "$type": "pub.leaflet.blocks.text",
            "facets": [],
            "plaintext": "従来は、投稿がどう広がり、どう解釈され、どう変容するかはプラットフォームとユーザーたちの「生態系」に委ねられていました。"
          }
        },
        {
          "$type": "pub.leaflet.pages.linearDocument#block",
          "block": {
            "$type": "pub.leaflet.blocks.text",
            "facets": [],
            "plaintext": "いまは、投稿者自身が「この言葉はこう届いてほしい」と設計できる。声明なのか、対話の呼びかけなのか、独白なのか——言葉の性格を、言葉を発する時点で決められる。"
          }
        },
        {
          "$type": "pub.leaflet.pages.linearDocument#block",
          "block": {
            "$type": "pub.leaflet.blocks.horizontalRule"
          }
        },
        {
          "$type": "pub.leaflet.pages.linearDocument#block",
          "block": {
            "$type": "pub.leaflet.blocks.header",
            "level": 2,
            "facets": [],
            "plaintext": "トレードオフもある"
          }
        },
        {
          "$type": "pub.leaflet.pages.linearDocument#block",
          "block": {
            "$type": "pub.leaflet.blocks.text",
            "facets": [],
            "plaintext": "もちろん、いいことばかりではありません。"
          }
        },
        {
          "$type": "pub.leaflet.pages.linearDocument#block",
          "block": {
            "$type": "pub.leaflet.blocks.unorderedList",
            "children": [
              {
                "$type": "pub.leaflet.blocks.unorderedList#listItem",
                "content": {
                  "$type": "pub.leaflet.blocks.text",
                  "facets": [],
                  "plaintext": "「なぜ返信できないんだ」という不満や摩擦"
                },
                "children": []
              },
              {
                "$type": "pub.leaflet.blocks.unorderedList#listItem",
                "content": {
                  "$type": "pub.leaflet.blocks.text",
                  "facets": [],
                  "plaintext": "対話の機会が失われるリスク"
                },
                "children": []
              },
              {
                "$type": "pub.leaflet.blocks.unorderedList#listItem",
                "content": {
                  "$type": "pub.leaflet.blocks.text",
                  "facets": [],
                  "plaintext": "設定が複雑で、投稿するたびに考えることが増える"
                },
                "children": []
              }
            ]
          }
        },
        {
          "$type": "pub.leaflet.pages.linearDocument#block",
          "block": {
            "$type": "pub.leaflet.blocks.text",
            "facets": [],
            "plaintext": "プラットフォームの「対話性」と「発話者の制御権」は、ある程度トレードオフの関係にあります。"
          }
        },
        {
          "$type": "pub.leaflet.pages.linearDocument#block",
          "block": {
            "$type": "pub.leaflet.blocks.horizontalRule"
          }
        },
        {
          "$type": "pub.leaflet.pages.linearDocument#block",
          "block": {
            "$type": "pub.leaflet.blocks.header",
            "level": 2,
            "facets": [],
            "plaintext": "おわりに"
          }
        },
        {
          "$type": "pub.leaflet.pages.linearDocument#block",
          "block": {
            "$type": "pub.leaflet.blocks.text",
            "facets": [],
            "plaintext": "ある投稿に返信できなかったことから、こんなことを考えました。"
          }
        },
        {
          "$type": "pub.leaflet.pages.linearDocument#block",
          "block": {
            "$type": "pub.leaflet.blocks.text",
            "facets": [],
            "plaintext": "SNSで言葉を発するとき、私たちは「何を言うか」だけでなく「どう届いてほしいか」も選べる時代に入っている。それは自由であると同時に、責任でもある。"
          }
        },
        {
          "$type": "pub.leaflet.pages.linearDocument#block",
          "block": {
            "$type": "pub.leaflet.blocks.text",
            "facets": [],
            "plaintext": "「返信できない投稿」を見かけたら、「なんで?」と思う前に、「この人はこの言葉をどう届けたかったんだろう」と考えてみると、少し見え方が変わるかもしれません。"
          }
        },
        {
          "$type": "pub.leaflet.pages.linearDocument#block",
          "block": {
            "$type": "pub.leaflet.blocks.horizontalRule"
          }
        },
        {
          "$type": "pub.leaflet.pages.linearDocument#block",
          "block": {
            "$type": "pub.leaflet.blocks.text",
            "facets": [
              {
                "index": {
                  "byteEnd": 13,
                  "byteStart": 0
                },
                "features": [
                  {
                    "$type": "pub.leaflet.richtext.facet#bold"
                  }
                ]
              }
            ],
            "plaintext": "📚|参考"
          }
        },
        {
          "$type": "pub.leaflet.pages.linearDocument#block",
          "block": {
            "$type": "pub.leaflet.blocks.unorderedList",
            "children": [
              {
                "$type": "pub.leaflet.blocks.unorderedList#listItem",
                "content": {
                  "$type": "pub.leaflet.blocks.text",
                  "facets": [
                    {
                      "index": {
                        "byteEnd": 43,
                        "byteStart": 0
                      },
                      "features": [
                        {
                          "uri": "https://www.kodansha.co.jp/book/products/0000314385",
                          "$type": "pub.leaflet.richtext.facet#link"
                        }
                      ]
                    }
                  ],
                  "plaintext": "J.L.オースティン『言語と行為』"
                },
                "children": []
              },
              {
                "$type": "pub.leaflet.blocks.unorderedList#listItem",
                "content": {
                  "$type": "pub.leaflet.blocks.text",
                  "facets": [],
                  "plaintext": "Bluesky公式ブログ「New Anti-Toxicity Features on Bluesky」(2024年8月28日)"
                },
                "children": []
              }
            ]
          }
        },
        {
          "$type": "pub.leaflet.pages.linearDocument#block",
          "block": {
            "src": "https://bsky.social/about/blog/08-28-2024-anti-toxicity-features",
            "$type": "pub.leaflet.blocks.website",
            "title": "New Anti-Toxicity Features on Bluesky - Bluesky",
            "description": "Trust and Safety (T&S) affects everything — from community policy and spam detection, all the way to the order that replies show up on a post. At Bluesky, the product team works hand-in-hand with T&S to design features that balance safety, ease of use, and fun.",
            "previewImage": {
              "ref": {
                "$link": "bafkreifvtyy52ytos5vf5sriwym2u5lasf5qtl7zxfncxclx27y3ur2464"
              },
              "size": 31557,
              "$type": "blob",
              "mimeType": "image/png"
            }
          }
        },
        {
          "$type": "pub.leaflet.pages.linearDocument#block",
          "block": {
            "$type": "pub.leaflet.blocks.unorderedList",
            "children": [
              {
                "$type": "pub.leaflet.blocks.unorderedList#listItem",
                "content": {
                  "$type": "pub.leaflet.blocks.text",
                  "facets": [],
                  "plaintext": "Bluesky公式アカウント、Thread Reply Controls発表(2023年12月11日)"
                },
                "children": []
              }
            ]
          }
        },
        {
          "$type": "pub.leaflet.pages.linearDocument#block",
          "block": {
            "$type": "pub.leaflet.blocks.bskyPost",
            "postRef": {
              "cid": "bafyreieivqzjch2t3a4nyx6bilzmptixi52tfqhnfwlqqeaatbv4l3zzjm",
              "uri": "at://did:plc:z72i7hdynmk6r22z27h6tvur/app.bsky.feed.post/3kgbyzaeyee22"
            }
          }
        }
      ]
    }
  ],
  "title": "「返信できない投稿」には意味がある——SNSの新しい\"伝え方\"設計",
  "author": "did:plc:aajyn6qzw67cnmwf7zxzbjdy",
  "postRef": {
    "cid": "bafyreicgiylwfrckfsmxoqgumombemai3sqq5exjixtkmjxst6aycjg7gq",
    "uri": "at://did:plc:aajyn6qzw67cnmwf7zxzbjdy/app.bsky.feed.post/3mbifqmimps2u",
    "commit": {
      "cid": "bafyreicj3hfqgxqquynugjd6tfhx43kxawyd4u7nwsaftwlpkkg4bmnvk4",
      "rev": "3mbifqmluua2q"
    },
    "validationStatus": "valid"
  },
  "description": "",
  "publication": "at://did:plc:aajyn6qzw67cnmwf7zxzbjdy/pub.leaflet.publication/3lyuurwxkbk24",
  "publishedAt": "2026-01-03T02:53:05.419Z"
}

did:plc:aajyn6qzw67cnmwf7zxzbjdy | at://did:plc:aajyn6qzw67cnmwf7zxzbjdy/pub.leaflet.document/3mbifqhburs2u

pub.leaflet.blocks.button (nested within pub.leaflet.document) (9 samples)
{
  "$type": "pub.leaflet.document",
  "pages": [
    {
      "id": "019acc88-be14-7335-96ad-0080b99170d1",
      "$type": "pub.leaflet.pages.linearDocument",
      "blocks": [
        {
          "$type": "pub.leaflet.pages.linearDocument#block",
          "block": {
            "$type": "pub.leaflet.blocks.text",
            "facets": [],
            "plaintext": "We're exciting to be releasing our first batch of tickets, speakers, and side events."
          }
        },
        {
          "$type": "pub.leaflet.pages.linearDocument#block",
          "block": {
            "$type": "pub.leaflet.blocks.text",
            "facets": [],
            "plaintext": "The Main Conference is Saturday and Sunday (March 28th & 29th), with two tracks each day, plus flex space for extra discussions, and includes breakfast, lunch, and coffee break snacks."
          }
        },
        {
          "$type": "pub.leaflet.pages.linearDocument#block",
          "block": {
            "$type": "pub.leaflet.blocks.text",
            "facets": [],
            "plaintext": "Side events of extended discussions, workshops, and more are happening on Thursday and Friday (March 26th & 27th) and are also included in your base ticket."
          }
        },
        {
          "$type": "pub.leaflet.pages.linearDocument#block",
          "block": {
            "$type": "pub.leaflet.blocks.text",
            "facets": [
              {
                "index": {
                  "byteEnd": 13,
                  "byteStart": 4
                },
                "features": [
                  {
                    "uri": "https://atproto.science",
                    "$type": "pub.leaflet.richtext.facet#link"
                  }
                ]
              }
            ],
            "plaintext": "The ATScience event is already listed as an option in your ticket registration, plus two Bluesky Developer Workshops are also listed, which you'll hear more detail about next week."
          }
        },
        {
          "$type": "pub.leaflet.pages.linearDocument#block",
          "block": {
            "$type": "pub.leaflet.blocks.text",
            "facets": [],
            "plaintext": "This is a community conference, so we aim to make tickets as affordable as possible, as well as setting aside budget for a travel support fund. At the same time, know that your individual tickets end up being the single largest revenue source!"
          }
        },
        {
          "$type": "pub.leaflet.pages.linearDocument#block",
          "block": {
            "alt": "A grid of concert tickets. In the lower right hand corner, a mysterious new goose appears.",
            "$type": "pub.leaflet.blocks.image",
            "image": {
              "ref": {
                "$link": "bafkreic5j7rfjovo74yj2432c7f6zunflpxp7qxdy3v4snq3pnsb5hdqye"
              },
              "size": 103481,
              "$type": "blob",
              "mimeType": "image/jpeg"
            },
            "aspectRatio": {
              "width": 1000,
              "height": 396
            }
          }
        },
        {
          "$type": "pub.leaflet.pages.linearDocument#block",
          "block": {
            "$type": "pub.leaflet.blocks.header",
            "level": 1,
            "facets": [],
            "plaintext": "Early Bird Tickets on sale now!"
          }
        },
        {
          "$type": "pub.leaflet.pages.linearDocument#block",
          "block": {
            "$type": "pub.leaflet.blocks.text",
            "facets": [
              {
                "index": {
                  "byteEnd": 69,
                  "byteStart": 14
                },
                "features": [
                  {
                    "uri": "https://bsky.app/profile/atprotocol.dev/post/3m5penfy7gk22",
                    "$type": "pub.leaflet.richtext.facet#link"
                  }
                ]
              }
            ],
            "plaintext": "We've already seen people making plans to take the train from Chicago and other such shenanigans, so it's definitely time to put tickets officially on sale."
          }
        },
        {
          "$type": "pub.leaflet.pages.linearDocument#block",
          "block": {
            "url": "https://ti.to/atmosphereconf/atmosphereconf2026/discount/EARLYBIRD",
            "text": "Buy Early Bird Tickets",
            "$type": "pub.leaflet.blocks.button"
          }
        },
        {
          "$type": "pub.leaflet.pages.linearDocument#block",
          "block": {
            "$type": "pub.leaflet.blocks.header",
            "level": 2,
            "facets": [],
            "plaintext": "Early Bird"
          }
        },
        {
          "$type": "pub.leaflet.pages.linearDocument#block",
          "block": {
            "$type": "pub.leaflet.blocks.text",
            "facets": [],
            "plaintext": "Our tickets are sliding scale. Early Bird is suggested at $199USD, but can go as low as $149USD."
          }
        },
        {
          "$type": "pub.leaflet.pages.linearDocument#block",
          "block": {
            "$type": "pub.leaflet.blocks.header",
            "level": 2,
            "facets": [],
            "plaintext": "Corporate Supporter"
          }
        },
        {
          "$type": "pub.leaflet.pages.linearDocument#block",
          "block": {
            "$type": "pub.leaflet.blocks.text",
            "facets": [],
            "plaintext": "Our Corporate Supporter tickets are like a mini-sponsorship. Buy this ticket to help support community travel, speaker support, and low-cost tickets for all."
          }
        },
        {
          "$type": "pub.leaflet.pages.linearDocument#block",
          "block": {
            "$type": "pub.leaflet.blocks.text",
            "facets": [],
            "plaintext": "You'll be recognized with a supporter badge in your conference profile and thanked for supporting our community conference! Tickets are listed as $349USD, with a suggested minimum of $249USD."
          }
        },
        {
          "$type": "pub.leaflet.pages.linearDocument#block",
          "block": {
            "$type": "pub.leaflet.blocks.header",
            "level": 2,
            "facets": [],
            "plaintext": "T-Shirts"
          }
        },
        {
          "$type": "pub.leaflet.pages.linearDocument#block",
          "block": {
            "$type": "pub.leaflet.blocks.text",
            "facets": [],
            "plaintext": "We're going to be making conference t-shirts this year, but we're not including them in the base price of the tickets — we don't want to be giving out things that people don't want."
          }
        },
        {
          "$type": "pub.leaflet.pages.linearDocument#block",
          "block": {
            "$type": "pub.leaflet.blocks.text",
            "facets": [],
            "plaintext": "The design isn't totally finalized, but you'll see the option to add a t-shirt purchase to your ticket, and you'll have other options to purchase, including remote shipping."
          }
        },
        {
          "$type": "pub.leaflet.pages.linearDocument#block",
          "block": {
            "$type": "pub.leaflet.blocks.header",
            "level": 2,
            "facets": [],
            "plaintext": "Remote Attendance"
          }
        },
        {
          "$type": "pub.leaflet.pages.linearDocument#block",
          "block": {
            "$type": "pub.leaflet.blocks.text",
            "facets": [
              {
                "index": {
                  "byteEnd": 47,
                  "byteStart": 36
                },
                "features": [
                  {
                    "uri": "https://stream.place",
                    "$type": "pub.leaflet.richtext.facet#link"
                  }
                ]
              }
            ],
            "plaintext": "Yes, we will be streaming thanks to Streamplace's sponsorship again this year. Two tracks of the main conference will be streamed, and some select pre-conference activities and workshops will also be available remotely."
          }
        },
        {
          "$type": "pub.leaflet.pages.linearDocument#block",
          "block": {
            "$type": "pub.leaflet.blocks.text",
            "facets": [
              {
                "index": {
                  "byteEnd": 47,
                  "byteStart": 19
                },
                "features": [
                  {
                    "uri": "https://discourse.atprotocol.community/t/attending-atmosphereconf-remotely/282",
                    "$type": "pub.leaflet.richtext.facet#link"
                  }
                ]
              }
            ],
            "plaintext": "We've written up a FAQ about attending remotely, and will have more remote / hybrid activities to announce. "
          }
        },
        {
          "$type": "pub.leaflet.pages.linearDocument#block",
          "block": {
            "$type": "pub.leaflet.blocks.text",
            "facets": [],
            "plaintext": "We'll release remote tickets once we have more to confirm, which will be pay-what-you-want, include a no charge option so everyone can participate."
          }
        },
        {
          "$type": "pub.leaflet.pages.linearDocument#block",
          "block": {
            "$type": "pub.leaflet.blocks.header",
            "level": 2,
            "facets": [],
            "plaintext": "Conference Hotel"
          }
        },
        {
          "$type": "pub.leaflet.pages.linearDocument#block",
          "block": {
            "$type": "pub.leaflet.blocks.text",
            "facets": [
              {
                "index": {
                  "byteEnd": 85,
                  "byteStart": 59
                },
                "features": [
                  {
                    "uri": "https://discourse.atprotocol.community/t/conference-hotel/295",
                    "$type": "pub.leaflet.richtext.facet#link"
                  }
                ]
              }
            ],
            "plaintext": "Our conference hotel is now available for booking. See the FAQ entry for full details."
          }
        },
        {
          "$type": "pub.leaflet.pages.linearDocument#block",
          "block": {
            "alt": "Studio room with kitchenette, $189CAD per night right next to the main conference venue.",
            "$type": "pub.leaflet.blocks.image",
            "image": {
              "ref": {
                "$link": "bafkreiem3jan3c7qrwbbunkb7hkex2leykwipsx3mrajuyodda7yjpnfja"
              },
              "size": 17595,
              "$type": "blob",
              "mimeType": "image/jpeg"
            },
            "aspectRatio": {
              "width": 500,
              "height": 330
            }
          }
        },
        {
          "$type": "pub.leaflet.pages.linearDocument#block",
          "block": {
            "$type": "pub.leaflet.blocks.header",
            "level": 1,
            "facets": [],
            "plaintext": "Speaker Announcement"
          }
        },
        {
          "$type": "pub.leaflet.pages.linearDocument#block",
          "block": {
            "$type": "pub.leaflet.blocks.text",
            "facets": [
              {
                "index": {
                  "byteEnd": 135,
                  "byteStart": 108
                },
                "features": [
                  {
                    "uri": "https://news.atmosphereconf.org/3m6z2b7ovyk2i",
                    "$type": "pub.leaflet.richtext.facet#link"
                  }
                ]
              }
            ],
            "plaintext": "We're running a mix of invited, curated speaker invitations, as well as an open call for proposals which we published earlier this week. (thanks to organizer Nick, who is wrangling the CFP!)"
          }
        },
        {
          "$type": "pub.leaflet.pages.linearDocument#block",
          "block": {
            "$type": "pub.leaflet.blocks.text",
            "facets": [],
            "plaintext": "Today, we are happy to announce a short list of speakers that have already committed to presenting."
          }
        },
        {
          "$type": "pub.leaflet.pages.linearDocument#block",
          "block": {
            "$type": "pub.leaflet.blocks.unorderedList",
            "children": [
              {
                "$type": "pub.leaflet.blocks.unorderedList#listItem",
                "content": {
                  "$type": "pub.leaflet.blocks.text",
                  "facets": [
                    {
                      "index": {
                        "byteEnd": 32,
                        "byteStart": 12
                      },
                      "features": [
                        {
                          "uri": "https://blacksky.community/profile/did:plc:w4xbfzo7kqfes5zb7r6qv3rw",
                          "$type": "pub.leaflet.richtext.facet#link"
                        }
                      ]
                    },
                    {
                      "index": {
                        "byteEnd": 67,
                        "byteStart": 48
                      },
                      "features": [
                        {
                          "uri": "https://blackskyweb.xyz/",
                          "$type": "pub.leaflet.richtext.facet#link"
                        }
                      ]
                    }
                  ],
                  "plaintext": "Rudy Fraser @rude1.blacksky.team, founder & ceo Blacksky Algorithms, the intercommunal net, scaling safe communities with shared resources & democratic tools"
                },
                "children": []
              },
              {
                "$type": "pub.leaflet.blocks.unorderedList#listItem",
                "content": {
                  "$type": "pub.leaflet.blocks.text",
                  "facets": [
                    {
                      "index": {
                        "byteEnd": 34,
                        "byteStart": 12
                      },
                      "features": [
                        {
                          "uri": "https://bsky.app/profile/tessa.germnetwork.com",
                          "$type": "pub.leaflet.richtext.facet#link"
                        }
                      ]
                    },
                    {
                      "index": {
                        "byteEnd": 59,
                        "byteStart": 47
                      },
                      "features": [
                        {
                          "uri": "https://www.germnetwork.com/",
                          "$type": "pub.leaflet.richtext.facet#link"
                        }
                      ]
                    }
                  ],
                  "plaintext": "Tessa Brown @tessa.germnetwork.com, founder of Germ Network, secure chat software for multifaceted humans"
                },
                "children": []
              },
              {
                "$type": "pub.leaflet.blocks.unorderedList#listItem",
                "content": {
                  "$type": "pub.leaflet.blocks.text",
                  "facets": [
                    {
                      "index": {
                        "byteEnd": 31,
                        "byteStart": 20
                      },
                      "features": [
                        {
                          "uri": "https://bsky.app/profile/anirudh.fi",
                          "$type": "pub.leaflet.richtext.facet#link"
                        }
                      ]
                    },
                    {
                      "index": {
                        "byteEnd": 40,
                        "byteStart": 33
                      },
                      "features": [
                        {
                          "uri": "https://tangled.org",
                          "$type": "pub.leaflet.richtext.facet#link"
                        }
                      ]
                    }
                  ],
                  "plaintext": "Anirudh Oppiliappan @anirudh.fi, Tangled, social coding with decentralized Git hosting and collaboration"
                },
                "children": []
              },
              {
                "$type": "pub.leaflet.blocks.unorderedList#listItem",
                "content": {
                  "$type": "pub.leaflet.blocks.text",
                  "facets": [
                    {
                      "index": {
                        "byteEnd": 20,
                        "byteStart": 7
                      },
                      "features": [
                        {
                          "uri": "https://bsky.app/profile/chipnick.com",
                          "$type": "pub.leaflet.richtext.facet#link"
                        }
                      ]
                    },
                    {
                      "index": {
                        "byteEnd": 37,
                        "byteStart": 22
                      },
                      "features": [
                        {
                          "uri": "https://northskysocial.com/",
                          "$type": "pub.leaflet.richtext.facet#link"
                        }
                      ]
                    }
                  ],
                  "plaintext": "Evelyn @chipnick.com, Northsky Social, safer social media experience for 2SLGBTQIA+ people"
                },
                "children": []
              },
              {
                "$type": "pub.leaflet.blocks.unorderedList#listItem",
                "content": {
                  "$type": "pub.leaflet.blocks.text",
                  "facets": [
                    {
                      "index": {
                        "byteEnd": 29,
                        "byteStart": 15
                      },
                      "features": [
                        {
                          "uri": "https://bsky.app/profile/ngerakines.me",
                          "$type": "pub.leaflet.richtext.facet#link"
                        }
                      ]
                    },
                    {
                      "index": {
                        "byteEnd": 56,
                        "byteStart": 44
                      },
                      "features": [
                        {
                          "uri": "https://smokesignal.events/",
                          "$type": "pub.leaflet.richtext.facet#link"
                        }
                      ]
                    },
                    {
                      "index": {
                        "byteEnd": 67,
                        "byteStart": 58
                      },
                      "features": [
                        {
                          "uri": "https://bsky.app/profile/did:web:atwork.place",
                          "$type": "pub.leaflet.richtext.facet#link"
                        }
                      ]
                    }
                  ],
                  "plaintext": "Nick Gerakines @ngerakines.me, developer of Smoke Signal, at://work, and many more (and ATmosphereConf 2026 organizer!)"
                },
                "children": []
              }
            ]
          }
        },
        {
          "$type": "pub.leaflet.pages.linearDocument#block",
          "block": {
            "$type": "pub.leaflet.blocks.text",
            "facets": [
              {
                "index": {
                  "byteEnd": 142,
                  "byteStart": 128
                },
                "features": [
                  {
                    "uri": "https://discourse.atprotocol.community/t/travel-and-accommodation-support/301",
                    "$type": "pub.leaflet.richtext.facet#link"
                  }
                ]
              }
            ],
            "plaintext": "Thanks to all of the speakers for spending their time on preparing talks and taking time to travel and join us. We do have some travel support available.  "
          }
        },
        {
          "$type": "pub.leaflet.pages.linearDocument#block",
          "block": {
            "$type": "pub.leaflet.blocks.header",
            "level": 1,
            "facets": [],
            "plaintext": "Sponsor Support"
          }
        },
        {
          "$type": "pub.leaflet.pages.linearDocument#block",
          "block": {
            "$type": "pub.leaflet.blocks.text",
            "facets": [
              {
                "index": {
                  "byteEnd": 7,
                  "byteStart": 0
                },
                "features": [
                  {
                    "uri": "https://bsky.social/about/faq",
                    "$type": "pub.leaflet.richtext.facet#link"
                  }
                ]
              },
              {
                "index": {
                  "byteEnd": 55,
                  "byteStart": 44
                },
                "features": [
                  {
                    "uri": "https://stream.place",
                    "$type": "pub.leaflet.richtext.facet#link"
                  }
                ]
              }
            ],
            "plaintext": "Bluesky is our title sponsor this year, and Streamplace is our video sponsor."
          }
        },
        {
          "$type": "pub.leaflet.pages.linearDocument#block",
          "block": {
            "$type": "pub.leaflet.blocks.text",
            "facets": [
              {
                "index": {
                  "byteEnd": 5,
                  "byteStart": 0
                },
                "features": [
                  {
                    "uri": "https://graze.social",
                    "$type": "pub.leaflet.richtext.facet#link"
                  }
                ]
              },
              {
                "index": {
                  "byteEnd": 68,
                  "byteStart": 54
                },
                "features": [
                  {
                    "uri": "https://cosmik.network",
                    "$type": "pub.leaflet.richtext.facet#link"
                  }
                ]
              },
              {
                "index": {
                  "byteEnd": 111,
                  "byteStart": 102
                },
                "features": [
                  {
                    "uri": "https://atproto.science/",
                    "$type": "pub.leaflet.richtext.facet#link"
                  }
                ]
              }
            ],
            "plaintext": "Graze came on board as a Major Sponsor this year, and Cosmik Network is a Major Sponsor producing the ATScience side event."
          }
        },
        {
          "$type": "pub.leaflet.pages.linearDocument#block",
          "block": {
            "$type": "pub.leaflet.blocks.text",
            "facets": [
              {
                "index": {
                  "byteEnd": 139,
                  "byteStart": 127
                },
                "features": [
                  {
                    "uri": "https://forms.atprotocol.community/r/nPadKP",
                    "$type": "pub.leaflet.richtext.facet#link"
                  }
                ]
              }
            ],
            "plaintext": "We have a few more new sponsors to announce next week in a dedicated post, and still have sponsorship opportunities available. Get in touch if you'd like to discuss getting involved."
          }
        },
        {
          "$type": "pub.leaflet.pages.linearDocument#block",
          "block": {
            "$type": "pub.leaflet.blocks.horizontalRule"
          }
        },
        {
          "$type": "pub.leaflet.pages.linearDocument#block",
          "block": {
            "$type": "pub.leaflet.blocks.text",
            "facets": [
              {
                "index": {
                  "byteEnd": 5,
                  "byteStart": 0
                },
                "features": [
                  {
                    "$type": "pub.leaflet.richtext.facet#italic"
                  }
                ]
              },
              {
                "index": {
                  "byteEnd": 25,
                  "byteStart": 5
                },
                "features": [
                  {
                    "$type": "pub.leaflet.richtext.facet#italic"
                  },
                  {
                    "uri": "https://bsky.app/profile/jonathanwarden.com/post/3m76d7szofc2n",
                    "$type": "pub.leaflet.richtext.facet#link"
                  }
                ]
              },
              {
                "index": {
                  "byteEnd": 78,
                  "byteStart": 25
                },
                "features": [
                  {
                    "$type": "pub.leaflet.richtext.facet#italic"
                  }
                ]
              }
            ],
            "plaintext": "P.S. Congrats to jonathan for scooping our ticket sales before we hit publish."
          }
        }
      ]
    }
  ],
  "title": "Early Bird Tickets and Speaker Announcement",
  "author": "did:plc:lehcqqkwzcwvjvw66uthu5oq",
  "postRef": {
    "cid": "bafyreidukcov7n3osgxvg7e637njs4yvrcebwuaxwzwi5bddau2wrac2va",
    "uri": "at://did:plc:lehcqqkwzcwvjvw66uthu5oq/app.bsky.feed.post/3m76dj6h6s22w",
    "commit": {
      "cid": "bafyreibpbmgs5rwy5yw72pl5xpq3jfc5ulp46mtiy6uf6qpwoyt7m2p53i",
      "rev": "3m76dj6jkhj2x"
    },
    "validationStatus": "valid"
  },
  "description": "Buy your tickets now to join us in Vancouver, March 2026",
  "publication": "at://did:plc:lehcqqkwzcwvjvw66uthu5oq/pub.leaflet.publication/3m367bemk3c2i",
  "publishedAt": "2025-12-04T15:56:06.039Z"
}

did:plc:lehcqqkwzcwvjvw66uthu5oq | at://did:plc:lehcqqkwzcwvjvw66uthu5oq/pub.leaflet.document/3m76dixo4is2w

pub.leaflet.blocks.code (nested within pub.leaflet.document) (41 samples)
{
  "$type": "pub.leaflet.document",
  "pages": [
    {
      "$type": "pub.leaflet.pages.linearDocument",
      "blocks": [
        {
          "$type": "pub.leaflet.pages.linearDocument#block",
          "block": {
            "$type": "pub.leaflet.blocks.text",
            "facets": [
              {
                "$type": "pub.leaflet.richtext.facet",
                "index": {
                  "$type": "pub.leaflet.richtext.facet#byteSlice",
                  "byteEnd": 45,
                  "byteStart": 25
                },
                "features": [
                  {
                    "uri": "/3lfv5767w4336",
                    "$type": "pub.leaflet.richtext.facet#link"
                  }
                ]
              }
            ],
            "plaintext": "As the final phase of my database experiments, I've been playing recently with optimizing the speed of processing in the firehose process."
          }
        },
        {
          "$type": "pub.leaflet.pages.linearDocument#block",
          "block": {
            "$type": "pub.leaflet.blocks.text",
            "facets": [
              {
                "$type": "pub.leaflet.richtext.facet",
                "index": {
                  "$type": "pub.leaflet.richtext.facet#byteSlice",
                  "byteEnd": 192,
                  "byteStart": 188
                },
                "features": [
                  {
                    "uri": "https://cbor.io",
                    "$type": "pub.leaflet.richtext.facet#link"
                  }
                ]
              }
            ],
            "plaintext": "The Bluesky firehose is a streaming API that sends you every single thing happening on the network in real time – every post, like, follow, everything (encoded in a binary format called CBOR). And my firehose process is a client connecting to that stream, pulling data from it and saving the relevant parts (the posts)."
          }
        },
        {
          "$type": "pub.leaflet.pages.linearDocument#block",
          "block": {
            "$type": "pub.leaflet.blocks.text",
            "facets": [
              {
                "$type": "pub.leaflet.richtext.facet",
                "index": {
                  "$type": "pub.leaflet.richtext.facet#byteSlice",
                  "byteEnd": 550,
                  "byteStart": 519
                },
                "features": [
                  {
                    "uri": "https://www.cnbc.com/2024/09/04/social-media-platform-bluesky-attracts-millions-in-brazil-after-judge-bans-musks-x-.html",
                    "$type": "pub.leaflet.richtext.facet#link"
                  }
                ]
              },
              {
                "$type": "pub.leaflet.richtext.facet",
                "index": {
                  "$type": "pub.leaflet.richtext.facet#byteSlice",
                  "byteEnd": 306,
                  "byteStart": 289
                },
                "features": [
                  {
                    "uri": "https://cdn.bsky.app/img/feed_fullsize/plain/did:plc:oio4hkxaop4ao4wz2pp3f4cr/bafkreickjkjffrmqcq7wdezei2tuytra2hjpnyiesfzc5rkxsobkzpufju@jpeg",
                    "$type": "pub.leaflet.richtext.facet#link"
                  }
                ]
              }
            ],
            "plaintext": "At the moment, the firehose flow ranges between ~300 and 700 events per second during the day (\"event\" being one \"action\" like created or deleted record of any kind), with the bottom around 7-9:00 UTC and the top around 17-22:00 UTC. But the highest bandwidth we've seen so far was around 1.8-2.0k events/s in mid November, when a massive new wave of new users joined in the aftermath of the US elections, and we've seen the traffic go up rapidly by a few hundred % within days before too, e.g. in early September when the whole Brazil joined Bluesky. The firehose protocol also includes a lot of extra data, needed for cryptographic verification and full replication of data repositories, but not used in a simple case like this – so the total data bandwidth to stream and process is an average ~20-30 Mbps right now (with the smaller traffic than before)."
          }
        },
        {
          "$type": "pub.leaflet.pages.linearDocument#block",
          "block": {
            "$type": "pub.leaflet.blocks.text",
            "facets": [],
            "plaintext": "My server was struggling back then in November, processing the 1.8k events per second, which is a big part of the reason why I started looking for a better suited database than SQLite, to be able to handle the next wave. I had a few improvements lined up, which I now started applying one by one (trying to do one at a time, so I can measure which one does what difference), each time pausing the reading for a day or so, and then catching up for several hours at full speed, so I can check what's the maximum speed it can do."
          }
        },
        {
          "$type": "pub.leaflet.pages.linearDocument#block",
          "block": {
            "$type": "pub.leaflet.blocks.text",
            "facets": [],
            "plaintext": "I was also doing very simple profiling on the way, measuring which parts take how much time and where I can still save some extra microseconds:"
          }
        },
        {
          "$type": "pub.leaflet.pages.linearDocument#block",
          "block": {
            "$type": "pub.leaflet.blocks.image",
            "image": {
              "ref": {
                "$link": "bafkreiekcq32kjpvvwmwl2ssfwnqwmthtkelbrlvg26burlu6on6sesfka"
              },
              "size": 587235,
              "$type": "blob",
              "mimeType": "image/png"
            },
            "aspectRatio": {
              "width": 1134,
              "height": 781
            }
          }
        },
        {
          "$type": "pub.leaflet.pages.linearDocument#block",
          "block": {
            "$type": "pub.leaflet.blocks.text",
            "facets": [],
            "plaintext": "Overall, I managed to bring the number from around 2k evt/s to around 4k over a period of about a week (similarly in the MySQL and Postgres versions) – so not bad at all."
          }
        },
        {
          "$type": "pub.leaflet.pages.linearDocument#block",
          "block": {
            "$type": "pub.leaflet.blocks.image",
            "image": {
              "ref": {
                "$link": "bafkreifekt4lyn5lyfr6cymlvjj7qdoqju6fpjayqkcca527l5jguideby"
              },
              "size": 48642,
              "$type": "blob",
              "mimeType": "image/jpeg"
            },
            "aspectRatio": {
              "width": 497,
              "height": 275
            }
          }
        },
        {
          "$type": "pub.leaflet.pages.linearDocument#block",
          "block": {
            "$type": "pub.leaflet.blocks.text",
            "facets": [],
            "plaintext": "These are the changes I've tried:"
          }
        },
        {
          "$type": "pub.leaflet.pages.linearDocument#block",
          "block": {
            "$type": "pub.leaflet.blocks.horizontalRule"
          }
        },
        {
          "$type": "pub.leaflet.pages.linearDocument#block",
          "block": {
            "$type": "pub.leaflet.blocks.header",
            "level": 2,
            "facets": [],
            "plaintext": "Partial indexes"
          }
        },
        {
          "$type": "pub.leaflet.pages.linearDocument#block",
          "block": {
            "$type": "pub.leaflet.blocks.text",
            "facets": [
              {
                "$type": "pub.leaflet.richtext.facet",
                "index": {
                  "$type": "pub.leaflet.richtext.facet#byteSlice",
                  "byteEnd": 376,
                  "byteStart": 355
                },
                "features": [
                  {
                    "$type": "pub.leaflet.richtext.facet#code"
                  }
                ]
              },
              {
                "$type": "pub.leaflet.richtext.facet",
                "index": {
                  "$type": "pub.leaflet.richtext.facet#byteSlice",
                  "byteEnd": 317,
                  "byteStart": 309
                },
                "features": [
                  {
                    "$type": "pub.leaflet.richtext.facet#code"
                  }
                ]
              },
              {
                "$type": "pub.leaflet.richtext.facet",
                "index": {
                  "$type": "pub.leaflet.richtext.facet#byteSlice",
                  "byteEnd": 280,
                  "byteStart": 271
                },
                "features": [
                  {
                    "$type": "pub.leaflet.richtext.facet#code"
                  }
                ]
              },
              {
                "$type": "pub.leaflet.richtext.facet",
                "index": {
                  "$type": "pub.leaflet.richtext.facet#byteSlice",
                  "byteEnd": 151,
                  "byteStart": 142
                },
                "features": [
                  {
                    "$type": "pub.leaflet.richtext.facet#code"
                  }
                ]
              },
              {
                "$type": "pub.leaflet.richtext.facet",
                "index": {
                  "$type": "pub.leaflet.richtext.facet#byteSlice",
                  "byteEnd": 137,
                  "byteStart": 129
                },
                "features": [
                  {
                    "$type": "pub.leaflet.richtext.facet#code"
                  }
                ]
              },
              {
                "$type": "pub.leaflet.richtext.facet",
                "index": {
                  "$type": "pub.leaflet.richtext.facet#byteSlice",
                  "byteEnd": 56,
                  "byteStart": 41
                },
                "features": [
                  {
                    "uri": "https://www.postgresql.org/docs/current/indexes-partial.html",
                    "$type": "pub.leaflet.richtext.facet#link"
                  }
                ]
              }
            ],
            "plaintext": "I've switched two indexes in Postgres to partial indexes (MySQL doesn't support that). I have two indexes in the posts table, on quote_id and thread_id, which set a reference to a quoted post and the root of the thread respectively, which are NULL for some of the posts (thread_id for like half of the posts, quote_id for the vast majority), so I added a WHERE ... IS NOT NULL condition to those two."
          }
        },
        {
          "$type": "pub.leaflet.pages.linearDocument#block",
          "block": {
            "$type": "pub.leaflet.blocks.text",
            "facets": [
              {
                "$type": "pub.leaflet.richtext.facet",
                "index": {
                  "$type": "pub.leaflet.richtext.facet#byteSlice",
                  "byteEnd": 7,
                  "byteStart": 0
                },
                "features": [
                  {
                    "$type": "pub.leaflet.richtext.facet#bold"
                  }
                ]
              }
            ],
            "plaintext": "Effect: no noticeable change in performance, but it least the indexes take less space now."
          }
        },
        {
          "$type": "pub.leaflet.pages.linearDocument#block",
          "block": {
            "$type": "pub.leaflet.blocks.horizontalRule"
          }
        },
        {
          "$type": "pub.leaflet.pages.linearDocument#block",
          "block": {
            "$type": "pub.leaflet.blocks.header",
            "level": 2,
            "facets": [],
            "plaintext": "ActiveRecord"
          }
        },
        {
          "$type": "pub.leaflet.pages.linearDocument#block",
          "block": {
            "$type": "pub.leaflet.blocks.text",
            "facets": [
              {
                "$type": "pub.leaflet.richtext.facet",
                "index": {
                  "$type": "pub.leaflet.richtext.facet#byteSlice",
                  "byteEnd": 203,
                  "byteStart": 176
                },
                "features": [
                  {
                    "uri": "https://github.com/rails/rails/pull/50371",
                    "$type": "pub.leaflet.richtext.facet#link"
                  }
                ]
              }
            ],
            "plaintext": "I updated ActiveRecord – from v. 6.1 that I had before to 7.2 (Rails 8 was released in November, but it feels a bit too fresh right now). Ironically, AR 8.0 seems to finally fix my longstanding problem with concurrency errors in SQLite, just when I'm getting rid of it…"
          }
        },
        {
          "$type": "pub.leaflet.pages.linearDocument#block",
          "block": {
            "$type": "pub.leaflet.blocks.text",
            "facets": [
              {
                "$type": "pub.leaflet.richtext.facet",
                "index": {
                  "$type": "pub.leaflet.richtext.facet#byteSlice",
                  "byteEnd": 7,
                  "byteStart": 0
                },
                "features": [
                  {
                    "$type": "pub.leaflet.richtext.facet#bold"
                  }
                ]
              }
            ],
            "plaintext": "Effect: around +10% processing speed."
          }
        },
        {
          "$type": "pub.leaflet.pages.linearDocument#block",
          "block": {
            "$type": "pub.leaflet.blocks.horizontalRule"
          }
        },
        {
          "$type": "pub.leaflet.pages.linearDocument#block",
          "block": {
            "$type": "pub.leaflet.blocks.header",
            "level": 2,
            "facets": [],
            "plaintext": "Ruby update + YJIT"
          }
        },
        {
          "$type": "pub.leaflet.pages.linearDocument#block",
          "block": {
            "$type": "pub.leaflet.blocks.text",
            "facets": [
              {
                "$type": "pub.leaflet.richtext.facet",
                "index": {
                  "$type": "pub.leaflet.richtext.facet#byteSlice",
                  "byteEnd": 304,
                  "byteStart": 298
                },
                "features": [
                  {
                    "$type": "pub.leaflet.richtext.facet#italic"
                  }
                ]
              },
              {
                "$type": "pub.leaflet.richtext.facet",
                "index": {
                  "$type": "pub.leaflet.richtext.facet#byteSlice",
                  "byteEnd": 251,
                  "byteStart": 246
                },
                "features": [
                  {
                    "uri": "https://bugs.ruby-lang.org/issues/20209",
                    "$type": "pub.leaflet.richtext.facet#link"
                  }
                ]
              },
              {
                "$type": "pub.leaflet.richtext.facet",
                "index": {
                  "$type": "pub.leaflet.richtext.facet#byteSlice",
                  "byteEnd": 47,
                  "byteStart": 43
                },
                "features": [
                  {
                    "uri": "https://shopify.engineering/ruby-yjit-is-production-ready",
                    "$type": "pub.leaflet.richtext.facet#link"
                  }
                ]
              }
            ],
            "plaintext": "I updated Ruby from 3.2 to 3.4 and enabled YJIT, a new optional JIT written in Rust. I had tested YJIT before on 3.2 and there was a noticeable improvement, but I've noticed some kind of memory leak then that they've apparently fixed only around 3.3.1. Interestingly, my code seems to run slightly slower on 3.3 and 3.4 without YJIT, but enabling it more than makes up for it."
          }
        },
        {
          "$type": "pub.leaflet.pages.linearDocument#block",
          "block": {
            "$type": "pub.leaflet.blocks.text",
            "facets": [
              {
                "$type": "pub.leaflet.richtext.facet",
                "index": {
                  "$type": "pub.leaflet.richtext.facet#byteSlice",
                  "byteEnd": 7,
                  "byteStart": 0
                },
                "features": [
                  {
                    "$type": "pub.leaflet.richtext.facet#bold"
                  }
                ]
              }
            ],
            "plaintext": "Effect: around +15%."
          }
        },
        {
          "$type": "pub.leaflet.pages.linearDocument#block",
          "block": {
            "$type": "pub.leaflet.blocks.horizontalRule"
          }
        },
        {
          "$type": "pub.leaflet.pages.linearDocument#block",
          "block": {
            "$type": "pub.leaflet.blocks.header",
            "level": 2,
            "facets": [],
            "plaintext": "Batch inserts"
          }
        },
        {
          "$type": "pub.leaflet.pages.linearDocument#block",
          "block": {
            "$type": "pub.leaflet.blocks.text",
            "facets": [],
            "plaintext": "I was already previously grouping posts into a queue, waiting until I got 10, and then saving them all in one transaction, using code like this:"
          }
        },
        {
          "$type": "pub.leaflet.pages.linearDocument#block",
          "block": {
            "$type": "pub.leaflet.blocks.code",
            "language": "ruby",
            "plaintext": "ActiveRecord::Base.transaction do\n  @post_queue.each do |p|\n    p.save!\n  end\nend",
            "syntaxHighlightingTheme": "catppuccin-latte"
          }
        },
        {
          "$type": "pub.leaflet.pages.linearDocument#block",
          "block": {
            "$type": "pub.leaflet.blocks.text",
            "facets": [],
            "plaintext": "This was already faster than the initial way of saving of each post separately, directly in the block where it's built from the processed event. But that was still multiple INSERTs, and I wasn't sure I could do it in just one while using the ORM."
          }
        },
        {
          "$type": "pub.leaflet.pages.linearDocument#block",
          "block": {
            "$type": "pub.leaflet.blocks.text",
            "facets": [
              {
                "$type": "pub.leaflet.richtext.facet",
                "index": {
                  "$type": "pub.leaflet.richtext.facet#byteSlice",
                  "byteEnd": 52,
                  "byteStart": 38
                },
                "features": [
                  {
                    "uri": "https://dev.to/lorankloeze/creating-lots-of-records-in-rails-with-insertall-1bhe",
                    "$type": "pub.leaflet.richtext.facet#link"
                  }
                ]
              }
            ],
            "plaintext": "Apparently I can, with the use of the insert_all API. The catch is that it takes an array of raw argument hashes, skips validations and doesn't handle child records (my Post records have linked FeedPost entries if they are included in a feed). So I validate the records separately earlier (I was actually already validating them first before, which means the validations were running twice), and for those that have FeedPosts, I save them separately next."
          }
        },
        {
          "$type": "pub.leaflet.pages.linearDocument#block",
          "block": {
            "$type": "pub.leaflet.blocks.text",
            "facets": [],
            "plaintext": "So the whole thing looks like this:"
          }
        },
        {
          "$type": "pub.leaflet.pages.linearDocument#block",
          "block": {
            "$type": "pub.leaflet.blocks.code",
            "language": "ruby",
            "plaintext": "def process_post(msg)\n  post = Post.new(...)\n\n  if !post.valid?\n    log \"Error: post is invalid: ...\"\n    return\n  end\n\n  @post_queue << post\n\n  if @post_queue.length >= POSTS_BATCH_SIZE\n    save_queued_posts\n  end\nend\n\ndef save_queued_posts\n  matched, unmatched = @post_queue.partition { |x| !x.feed_posts.empty? }\n\n  if unmatched.length > 0\n    values = unmatched.map { |p| p.attributes.except('id') }\n    Post.insert_all(values)\n  end\n\n  @post_queue = matched\n  return if @post_queue.empty?\n\n  ActiveRecord::Base.transaction do\n    @post_queue.each do |p|\n      p.save!(validate: false)\n    end\n  end\n\n  @post_queue = []\nrescue StandardError => e\n  # ... try to save valid posts one by one\nend",
            "syntaxHighlightingTheme": "catppuccin-latte"
          }
        },
        {
          "$type": "pub.leaflet.pages.linearDocument#block",
          "block": {
            "$type": "pub.leaflet.blocks.text",
            "facets": [
              {
                "$type": "pub.leaflet.richtext.facet",
                "index": {
                  "$type": "pub.leaflet.richtext.facet#byteSlice",
                  "byteEnd": 7,
                  "byteStart": 0
                },
                "features": [
                  {
                    "$type": "pub.leaflet.richtext.facet#bold"
                  }
                ]
              }
            ],
            "plaintext": "Effect: up to around +30% in the Postgres version, less in MySQL one."
          }
        },
        {
          "$type": "pub.leaflet.pages.linearDocument#block",
          "block": {
            "$type": "pub.leaflet.blocks.horizontalRule"
          }
        },
        {
          "$type": "pub.leaflet.pages.linearDocument#block",
          "block": {
            "$type": "pub.leaflet.blocks.header",
            "level": 2,
            "facets": [],
            "plaintext": "Rust native module for regex matching"
          }
        },
        {
          "$type": "pub.leaflet.pages.linearDocument#block",
          "block": {
            "$type": "pub.leaflet.blocks.text",
            "facets": [],
            "plaintext": "Last year I wrote a little native module in Rust (which I didn't know at all before) to speed up matching of post contents with a large number of regexps for the feeds:"
          }
        },
        {
          "$type": "pub.leaflet.pages.linearDocument#block",
          "block": {
            "$type": "pub.leaflet.blocks.bskyPost",
            "postRef": {
              "cid": "bafyreicmmgyryrgwlrwaqvznd3lchcq6zzcr3zehljvvq6fzee4jevkw6a",
              "uri": "at://did:plc:oio4hkxaop4ao4wz2pp3f4cr/app.bsky.feed.post/3kqb7cgeeah22"
            }
          }
        },
        {
          "$type": "pub.leaflet.pages.linearDocument#block",
          "block": {
            "$type": "pub.leaflet.blocks.text",
            "facets": [],
            "plaintext": "I haven't enabled it on production yet though, because there are some edge cases I need to get fixed, and I only used it for manual feed rebuilding so far. So as the next step, I enabled that Rust module in the firehose process. (I'd love to eventually make that available as a gem you can easily add to your app.)"
          }
        },
        {
          "$type": "pub.leaflet.pages.linearDocument#block",
          "block": {
            "$type": "pub.leaflet.blocks.text",
            "facets": [
              {
                "$type": "pub.leaflet.richtext.facet",
                "index": {
                  "$type": "pub.leaflet.richtext.facet#byteSlice",
                  "byteEnd": 7,
                  "byteStart": 0
                },
                "features": [
                  {
                    "$type": "pub.leaflet.richtext.facet#bold"
                  }
                ]
              }
            ],
            "plaintext": "Effect: +15%."
          }
        },
        {
          "$type": "pub.leaflet.pages.linearDocument#block",
          "block": {
            "$type": "pub.leaflet.blocks.horizontalRule"
          }
        },
        {
          "$type": "pub.leaflet.pages.linearDocument#block",
          "block": {
            "$type": "pub.leaflet.blocks.header",
            "level": 2,
            "facets": [],
            "plaintext": "Asynchronous transaction commits"
          }
        },
        {
          "$type": "pub.leaflet.pages.linearDocument#block",
          "block": {
            "$type": "pub.leaflet.blocks.text",
            "facets": [
              {
                "$type": "pub.leaflet.richtext.facet",
                "index": {
                  "$type": "pub.leaflet.richtext.facet#byteSlice",
                  "byteEnd": 107,
                  "byteStart": 73
                },
                "features": [
                  {
                    "$type": "pub.leaflet.richtext.facet#code"
                  }
                ]
              },
              {
                "$type": "pub.leaflet.richtext.facet",
                "index": {
                  "$type": "pub.leaflet.richtext.facet#byteSlice",
                  "byteEnd": 55,
                  "byteStart": 31
                },
                "features": [
                  {
                    "$type": "pub.leaflet.richtext.facet#code"
                  }
                ]
              }
            ],
            "plaintext": "Next, I turned on two options: synchronous_commit = off in Postgres, and innodb-flush-log-at-trx-commit = 0 in MySQL. These basically make it so that when you commit a transaction, you don't wait until it's synced to disk first, but the request returns just leaving the data in memory, and the data is synced to disk later (but like, up to a second later). So if the whole instance hard-reboots for some reason, you can lose maybe one second of data (but it wouldn't corrupt the database, since the transaction is either saved or not)."
          }
        },
        {
          "$type": "pub.leaflet.pages.linearDocument#block",
          "block": {
            "$type": "pub.leaflet.blocks.text",
            "facets": [],
            "plaintext": "This is possibly still dangerous if you're saving user's private data from a webapp, but in this case, I'm streaming public data that I can scroll back through a bit if needed. So in the highly unlikely case that I lose a second of data somehow, I just replay a very slightly older cursor."
          }
        },
        {
          "$type": "pub.leaflet.pages.linearDocument#block",
          "block": {
            "$type": "pub.leaflet.blocks.text",
            "facets": [
              {
                "$type": "pub.leaflet.richtext.facet",
                "index": {
                  "$type": "pub.leaflet.richtext.facet#byteSlice",
                  "byteEnd": 7,
                  "byteStart": 0
                },
                "features": [
                  {
                    "$type": "pub.leaflet.richtext.facet#bold"
                  }
                ]
              }
            ],
            "plaintext": "Effect: no noticeable improvement… probably because with the batched inserts, it was already doing just a few inserts per second, so there wasn't any more time to save here."
          }
        },
        {
          "$type": "pub.leaflet.pages.linearDocument#block",
          "block": {
            "$type": "pub.leaflet.blocks.horizontalRule"
          }
        },
        {
          "$type": "pub.leaflet.pages.linearDocument#block",
          "block": {
            "$type": "pub.leaflet.blocks.header",
            "level": 2,
            "facets": [],
            "plaintext": "Optimizing JSON handling and Time parsing"
          }
        },
        {
          "$type": "pub.leaflet.pages.linearDocument#block",
          "block": {
            "$type": "pub.leaflet.blocks.text",
            "facets": [
              {
                "$type": "pub.leaflet.richtext.facet",
                "index": {
                  "$type": "pub.leaflet.richtext.facet#byteSlice",
                  "byteEnd": 198,
                  "byteStart": 185
                },
                "features": [
                  {
                    "$type": "pub.leaflet.richtext.facet#code"
                  }
                ]
              },
              {
                "$type": "pub.leaflet.richtext.facet",
                "index": {
                  "$type": "pub.leaflet.richtext.facet#byteSlice",
                  "byteEnd": 118,
                  "byteStart": 114
                },
                "features": [
                  {
                    "$type": "pub.leaflet.richtext.facet#code"
                  }
                ]
              }
            ],
            "plaintext": "I had a place in the processing function where it encodes a record parsed from CBOR into JSON, to be saved into a data column and for logging purposes, but for complicated reasons that JSON.generate was called twice with slightly different versions of record. So I refactored that to let it skip one encode."
          }
        },
        {
          "$type": "pub.leaflet.pages.linearDocument#block",
          "block": {
            "$type": "pub.leaflet.blocks.text",
            "facets": [
              {
                "$type": "pub.leaflet.richtext.facet",
                "index": {
                  "$type": "pub.leaflet.richtext.facet#byteSlice",
                  "byteEnd": 464,
                  "byteStart": 454
                },
                "features": [
                  {
                    "$type": "pub.leaflet.richtext.facet#code"
                  }
                ]
              },
              {
                "$type": "pub.leaflet.richtext.facet",
                "index": {
                  "$type": "pub.leaflet.richtext.facet#byteSlice",
                  "byteEnd": 331,
                  "byteStart": 321
                },
                "features": [
                  {
                    "$type": "pub.leaflet.richtext.facet#code"
                  }
                ]
              },
              {
                "$type": "pub.leaflet.richtext.facet",
                "index": {
                  "$type": "pub.leaflet.richtext.facet#byteSlice",
                  "byteEnd": 237,
                  "byteStart": 233
                },
                "features": [
                  {
                    "$type": "pub.leaflet.richtext.facet#italic"
                  }
                ]
              },
              {
                "$type": "pub.leaflet.richtext.facet",
                "index": {
                  "$type": "pub.leaflet.richtext.facet#byteSlice",
                  "byteEnd": 131,
                  "byteStart": 121
                },
                "features": [
                  {
                    "$type": "pub.leaflet.richtext.facet#code"
                  }
                ]
              },
              {
                "$type": "pub.leaflet.richtext.facet",
                "index": {
                  "$type": "pub.leaflet.richtext.facet#byteSlice",
                  "byteEnd": 83,
                  "byteStart": 79
                },
                "features": [
                  {
                    "$type": "pub.leaflet.richtext.facet#code"
                  }
                ]
              }
            ],
            "plaintext": "There was also some time spent parsing the record time and the event time into Time objects from an ISO8601 string using Time.parse; but I had a feeling that this could probably be speeded up using some native code, especially if it only accepts ISO8601 formats, and only in forms that actually appear in the data (since Time.parse handles many, many possible formats). With the help of Mr. GPT I made a little C module with a single function to replace Time.parse, and that indeed ended up being faster. (I'll also try to turn that into a micro-gem.)"
          }
        },
        {
          "$type": "pub.leaflet.pages.linearDocument#block",
          "block": {
            "$type": "pub.leaflet.blocks.text",
            "facets": [
              {
                "$type": "pub.leaflet.richtext.facet",
                "index": {
                  "$type": "pub.leaflet.richtext.facet#byteSlice",
                  "byteEnd": 7,
                  "byteStart": 0
                },
                "features": [
                  {
                    "$type": "pub.leaflet.richtext.facet#bold"
                  }
                ]
              }
            ],
            "plaintext": "Effect: +8% (this finally pushed it over the 4k level)"
          }
        },
        {
          "$type": "pub.leaflet.pages.linearDocument#block",
          "block": {
            "$type": "pub.leaflet.blocks.horizontalRule"
          }
        },
        {
          "$type": "pub.leaflet.pages.linearDocument#block",
          "block": {
            "$type": "pub.leaflet.blocks.header",
            "level": 2,
            "facets": [],
            "plaintext": "Jetstream"
          }
        },
        {
          "$type": "pub.leaflet.pages.linearDocument#block",
          "block": {
            "$type": "pub.leaflet.blocks.text",
            "facets": [
              {
                "$type": "pub.leaflet.richtext.facet",
                "index": {
                  "$type": "pub.leaflet.richtext.facet#byteSlice",
                  "byteEnd": 283,
                  "byteStart": 276
                },
                "features": [
                  {
                    "uri": "https://github.com/mackuba/skyfall",
                    "$type": "pub.leaflet.richtext.facet#link"
                  }
                ]
              },
              {
                "$type": "pub.leaflet.richtext.facet",
                "index": {
                  "$type": "pub.leaflet.richtext.facet#byteSlice",
                  "byteEnd": 86,
                  "byteStart": 77
                },
                "features": [
                  {
                    "uri": "https://github.com/bluesky-social/jetstream",
                    "$type": "pub.leaflet.richtext.facet#link"
                  }
                ]
              }
            ],
            "plaintext": "Finally, just to check for now, I've switched from the full CBOR firehose to Jetstream, which is a kind of pre-processed stream that strips all the signatures and Merkle tree stuff and outputs a simplified JSON stream. I've already added support for it to my firehose library Skyfall in October, but I'm not using it everywhere yet."
          }
        },
        {
          "$type": "pub.leaflet.pages.linearDocument#block",
          "block": {
            "$type": "pub.leaflet.blocks.text",
            "facets": [
              {
                "$type": "pub.leaflet.richtext.facet",
                "index": {
                  "$type": "pub.leaflet.richtext.facet#byteSlice",
                  "byteEnd": 7,
                  "byteStart": 0
                },
                "features": [
                  {
                    "$type": "pub.leaflet.richtext.facet#bold"
                  }
                ]
              }
            ],
            "plaintext": "Effect: +30-40%, although the speed was suspiciously capped at almost precisely ~4989 evt/s on both servers… so I'm guessing I might have hit some kind of rate limit of the Jetstream server. But I could also host it myself if needed."
          }
        },
        {
          "$type": "pub.leaflet.pages.linearDocument#block",
          "block": {
            "$type": "pub.leaflet.blocks.text",
            "facets": [],
            "plaintext": "(Edit: yup:)"
          }
        },
        {
          "$type": "pub.leaflet.pages.linearDocument#block",
          "block": {
            "$type": "pub.leaflet.blocks.bskyPost",
            "postRef": {
              "cid": "bafyreifxh52gremjuzrwcx6tbjwfxpxvih3i5i3h7x6wsmc7mauztbf7xq",
              "uri": "at://did:plc:4nsduwlpivpuur4mqkbfvm6a/app.bsky.feed.post/3lkobu26k222n"
            }
          }
        },
        {
          "$type": "pub.leaflet.pages.linearDocument#block",
          "block": {
            "$type": "pub.leaflet.blocks.horizontalRule"
          }
        },
        {
          "$type": "pub.leaflet.pages.linearDocument#block",
          "block": {
            "$type": "pub.leaflet.blocks.header",
            "level": 2,
            "facets": [],
            "plaintext": "Potential ceiling"
          }
        },
        {
          "$type": "pub.leaflet.pages.linearDocument#block",
          "block": {
            "$type": "pub.leaflet.blocks.text",
            "facets": [
              {
                "$type": "pub.leaflet.richtext.facet",
                "index": {
                  "$type": "pub.leaflet.richtext.facet#byteSlice",
                  "byteEnd": 541,
                  "byteStart": 526
                },
                "features": [
                  {
                    "uri": "https://github.com/socketry/async",
                    "$type": "pub.leaflet.richtext.facet#link"
                  }
                ]
              },
              {
                "$type": "pub.leaflet.richtext.facet",
                "index": {
                  "$type": "pub.leaflet.richtext.facet#byteSlice",
                  "byteEnd": 511,
                  "byteStart": 496
                },
                "features": [
                  {
                    "uri": "https://github.com/socketry/async-websocket",
                    "$type": "pub.leaflet.richtext.facet#link"
                  }
                ]
              },
              {
                "$type": "pub.leaflet.richtext.facet",
                "index": {
                  "$type": "pub.leaflet.richtext.facet#byteSlice",
                  "byteEnd": 445,
                  "byteStart": 433
                },
                "features": [
                  {
                    "uri": "https://github.com/eventmachine/eventmachine",
                    "$type": "pub.leaflet.richtext.facet#link"
                  }
                ]
              },
              {
                "$type": "pub.leaflet.richtext.facet",
                "index": {
                  "$type": "pub.leaflet.richtext.facet#byteSlice",
                  "byteEnd": 389,
                  "byteStart": 372
                },
                "features": [
                  {
                    "uri": "https://github.com/faye/faye-websocket-ruby",
                    "$type": "pub.leaflet.richtext.facet#link"
                  }
                ]
              }
            ],
            "plaintext": "I also did a test with all processing completely skipped, so the app would just read the data packets from the websocket and discard them, not even decode the CBOR. This did around 6k evt/s with the full firehose (possibly more for Jetstream, but I couldn't test this) – so it looks like this is the max I can do without switching to something completely different. The library I'm using for websocket connection uses the very old eventmachine library underneath, and I was told that the newer async-websocket that uses the Async framework could be faster, but in brief tests I wasn't able to see any improvement so far."
          }
        },
        {
          "$type": "pub.leaflet.pages.linearDocument#block",
          "block": {
            "$type": "pub.leaflet.blocks.text",
            "facets": [
              {
                "$type": "pub.leaflet.richtext.facet",
                "index": {
                  "$type": "pub.leaflet.richtext.facet#byteSlice",
                  "byteEnd": 179,
                  "byteStart": 165
                },
                "features": [
                  {
                    "uri": "https://github.com/sugyan/atrium/tree/main/examples/firehose",
                    "$type": "pub.leaflet.richtext.facet#link"
                  }
                ]
              }
            ],
            "plaintext": "Finally, just to see what the limit would be if I were to abandon Ruby (at least for that part), I ran a quick test in Rust, specifically using the example from the Atrium library. It did… 25k evt/s 😱 So yeah, there are still more options ;)"
          }
        },
        {
          "$type": "pub.leaflet.pages.linearDocument#block",
          "block": {
            "$type": "pub.leaflet.blocks.text",
            "facets": [
              {
                "$type": "pub.leaflet.richtext.facet",
                "index": {
                  "$type": "pub.leaflet.richtext.facet#byteSlice",
                  "byteEnd": 25,
                  "byteStart": 14
                },
                "features": [
                  {
                    "uri": "https://www.netcup.com/en/server/root-server",
                    "$type": "pub.leaflet.richtext.facet#link"
                  }
                ]
              }
            ],
            "plaintext": "That said, my current VPS will max out the allowed traffic at a sustained 300 Mbps, which if I'm counting correctly would be something like 7.8k evt/s from the full firehose, so above that level this would be the main problem."
          }
        },
        {
          "$type": "pub.leaflet.pages.linearDocument#block",
          "block": {
            "$type": "pub.leaflet.blocks.horizontalRule"
          }
        },
        {
          "$type": "pub.leaflet.pages.linearDocument#block",
          "block": {
            "$type": "pub.leaflet.blocks.text",
            "facets": [],
            "plaintext": "Update: part 2 here:"
          }
        },
        {
          "$type": "pub.leaflet.pages.linearDocument#block",
          "block": {
            "src": "https://mackuba.leaflet.pub/3lseg4a7s74tb",
            "$type": "pub.leaflet.blocks.website",
            "title": "Firehose go brrr - Kuba's Lab Notes 🧪",
            "description": "About some more optimizations in the firehose consumer, and the PR I made for the faye-websocket library",
            "previewImage": {
              "ref": {
                "$link": "bafkreiaiieujnu2be7vs4jjro2xbauqgxuokgbcqykvsvsp56giuuulkna"
              },
              "size": 30606,
              "$type": "blob",
              "mimeType": "image/png"
            }
          }
        }
      ]
    }
  ],
  "title": "Speeding up the firehose",
  "author": "did:plc:oio4hkxaop4ao4wz2pp3f4cr",
  "description": "About the recent changes I made in my code & database config to bring the firehose processing speed from ~2k evt/s to 4k+",
  "publication": "at://did:plc:oio4hkxaop4ao4wz2pp3f4cr/pub.leaflet.publication/3lxc7nyufxk2x",
  "publishedAt": "2025-03-18T16:26:20.000Z"
}

did:plc:oio4hkxaop4ao4wz2pp3f4cr | at://did:plc:oio4hkxaop4ao4wz2pp3f4cr/pub.leaflet.document/3lko3iqvg5c5t

pub.leaflet.blocks.header (nested within pub.leaflet.document) (100 samples)
{
  "$type": "pub.leaflet.document",
  "pages": [
    {
      "$type": "pub.leaflet.pages.linearDocument",
      "blocks": [
        {
          "$type": "pub.leaflet.pages.linearDocument#block",
          "block": {
            "$type": "pub.leaflet.blocks.header",
            "level": 1,
            "facets": [],
            "plaintext": "Discoexistence(異見共存)"
          }
        },
        {
          "$type": "pub.leaflet.pages.linearDocument#block",
          "block": {
            "$type": "pub.leaflet.blocks.text",
            "facets": [
              {
                "index": {
                  "byteEnd": 66,
                  "byteStart": 0
                },
                "features": [
                  {
                    "$type": "pub.leaflet.richtext.facet#bold"
                  }
                ]
              }
            ],
            "plaintext": "──合わない相手とも同じクラスタで生き抜く力"
          }
        },
        {
          "$type": "pub.leaflet.pages.linearDocument#block",
          "block": {
            "$type": "pub.leaflet.blocks.text",
            "facets": [],
            "plaintext": ""
          }
        },
        {
          "$type": "pub.leaflet.pages.linearDocument#block",
          "block": {
            "$type": "pub.leaflet.blocks.text",
            "facets": [
              {
                "index": {
                  "byteEnd": 252,
                  "byteStart": 184
                },
                "features": [
                  {
                    "$type": "pub.leaflet.richtext.facet#bold"
                  }
                ]
              }
            ],
            "plaintext": "SNSや職場、学校など、私たちは日常的に「合わない人」と同じ空間にいることがあります。そんな状況でもうまくやっていく力を、私は Discoexistence(ディスコエグジステンス/異見共存) と呼んでいます。"
          }
        },
        {
          "$type": "pub.leaflet.pages.linearDocument#block",
          "block": {
            "$type": "pub.leaflet.blocks.text",
            "facets": [],
            "plaintext": ""
          }
        },
        {
          "$type": "pub.leaflet.pages.linearDocument#block",
          "block": {
            "$type": "pub.leaflet.blocks.text",
            "facets": [],
            "plaintext": "👉"
          }
        },
        {
          "$type": "pub.leaflet.pages.linearDocument#block",
          "block": {
            "$type": "pub.leaflet.blocks.blockquote",
            "facets": [
              {
                "index": {
                  "byteEnd": 53,
                  "byteStart": 0
                },
                "features": [
                  {
                    "$type": "pub.leaflet.richtext.facet#bold"
                  }
                ]
              },
              {
                "index": {
                  "byteEnd": 65,
                  "byteStart": 58
                },
                "features": [
                  {
                    "$type": "pub.leaflet.richtext.facet#italic"
                  }
                ]
              },
              {
                "index": {
                  "byteEnd": 92,
                  "byteStart": 81
                },
                "features": [
                  {
                    "$type": "pub.leaflet.richtext.facet#italic"
                  }
                ]
              }
            ],
            "plaintext": "Discoexistence(ディスコエグジスタンス) ― discord(不和)と coexistence(共存)のブレンド語であり、緊張や不一致の中でも適切な距離を保ちながら共に生きる力を意味する。"
          }
        },
        {
          "$type": "pub.leaflet.pages.linearDocument#block",
          "block": {
            "$type": "pub.leaflet.blocks.text",
            "facets": [],
            "plaintext": ""
          }
        },
        {
          "$type": "pub.leaflet.pages.linearDocument#block",
          "block": {
            "$type": "pub.leaflet.blocks.header",
            "level": 2,
            "facets": [],
            "plaintext": "Discoexistenceとは何か"
          }
        },
        {
          "$type": "pub.leaflet.pages.linearDocument#block",
          "block": {
            "$type": "pub.leaflet.blocks.text",
            "facets": [],
            "plaintext": "Discoexistenceは単なる接点の有無ではなく、合わない相手とも同じクラスタで心理的に適切な距離を保ちながら共存する力です。"
          }
        },
        {
          "$type": "pub.leaflet.pages.linearDocument#block",
          "block": {
            "$type": "pub.leaflet.blocks.unorderedList",
            "children": [
              {
                "$type": "pub.leaflet.blocks.unorderedList#listItem",
                "content": {
                  "$type": "pub.leaflet.blocks.text",
                  "facets": [
                    {
                      "index": {
                        "byteEnd": 39,
                        "byteStart": 0
                      },
                      "features": [
                        {
                          "$type": "pub.leaflet.richtext.facet#bold"
                        }
                      ]
                    }
                  ],
                  "plaintext": "合わない人とも生き延びる力"
                },
                "children": []
              },
              {
                "$type": "pub.leaflet.blocks.unorderedList#listItem",
                "content": {
                  "$type": "pub.leaflet.blocks.text",
                  "facets": [
                    {
                      "index": {
                        "byteEnd": 66,
                        "byteStart": 0
                      },
                      "features": [
                        {
                          "$type": "pub.leaflet.richtext.facet#bold"
                        }
                      ]
                    }
                  ],
                  "plaintext": "イヤなやつも含めてクラスタ内でやっていける力"
                },
                "children": []
              },
              {
                "$type": "pub.leaflet.blocks.unorderedList#listItem",
                "content": {
                  "$type": "pub.leaflet.blocks.text",
                  "facets": [
                    {
                      "index": {
                        "byteEnd": 87,
                        "byteStart": 0
                      },
                      "features": [
                        {
                          "$type": "pub.leaflet.richtext.facet#bold"
                        }
                      ]
                    }
                  ],
                  "plaintext": "排除や戦争ではなく、互いの存在を認めつつ距離を取る共存感覚"
                },
                "children": []
              }
            ]
          }
        },
        {
          "$type": "pub.leaflet.pages.linearDocument#block",
          "block": {
            "$type": "pub.leaflet.blocks.text",
            "facets": [],
            "plaintext": "例えば、SNSでの相互フォロー関係が変化したときにも起こりやすい現象です。Aさん、Bさん、Cさんが相互フォローだったのに、AさんとCさんがアンフォロー関係になった場合など、直接的な関係が途絶えても間接的な接点が残ることで心理的距離の取り方が試されます。離婚した元配偶者と子どもを介して接点が断絶できない状況も同様です。"
          }
        },
        {
          "$type": "pub.leaflet.pages.linearDocument#block",
          "block": {
            "$type": "pub.leaflet.blocks.text",
            "facets": [],
            "plaintext": ""
          }
        },
        {
          "$type": "pub.leaflet.pages.linearDocument#block",
          "block": {
            "$type": "pub.leaflet.blocks.header",
            "level": 2,
            "facets": [],
            "plaintext": "SNSにおけるDiscoexistence"
          }
        },
        {
          "$type": "pub.leaflet.pages.linearDocument#block",
          "block": {
            "$type": "pub.leaflet.blocks.text",
            "facets": [],
            "plaintext": "SNSでは、心理的距離や内集団/外集団の可視性、発言ルーティンなども含めた対人認知のデザインが重要です。これまで私は様々なソーシャル・ネットワークを利用してきましたが、そこでの観察で得た知見として、仲がよくない人や違和感のある人でも、ミュートやブロックではなく、存在を認識しつつ交流できない仕組みが必要ではないかと思うようになりました。たとえば、TwitterライクなUIを持つBluesky Socialではまだ以下の機能実装が十分ではないと考えます。"
          }
        },
        {
          "$type": "pub.leaflet.pages.linearDocument#block",
          "block": {
            "$type": "pub.leaflet.blocks.unorderedList",
            "children": [
              {
                "$type": "pub.leaflet.blocks.unorderedList#listItem",
                "content": {
                  "$type": "pub.leaflet.blocks.text",
                  "facets": [
                    {
                      "index": {
                        "byteEnd": 33,
                        "byteStart": 0
                      },
                      "features": [
                        {
                          "$type": "pub.leaflet.richtext.facet#bold"
                        }
                      ]
                    }
                  ],
                  "plaintext": "接し方のアーキテクチャ:近いけど仲がよくない人との心理的距離の取り方"
                },
                "children": []
              },
              {
                "$type": "pub.leaflet.blocks.unorderedList#listItem",
                "content": {
                  "$type": "pub.leaflet.blocks.text",
                  "facets": [
                    {
                      "index": {
                        "byteEnd": 16,
                        "byteStart": 0
                      },
                      "features": [
                        {
                          "$type": "pub.leaflet.richtext.facet#bold"
                        }
                      ]
                    }
                  ],
                  "plaintext": "第3のボタン:ミュート・ブロックに代わる、合わない人の投稿を無意味化する機能"
                },
                "children": []
              },
              {
                "$type": "pub.leaflet.blocks.unorderedList#listItem",
                "content": {
                  "$type": "pub.leaflet.blocks.text",
                  "facets": [
                    {
                      "index": {
                        "byteEnd": 21,
                        "byteStart": 0
                      },
                      "features": [
                        {
                          "$type": "pub.leaflet.richtext.facet#bold"
                        }
                      ]
                    }
                  ],
                  "plaintext": "公共圏での共存:小グループに閉じこもらず、見えていても交流できない形式"
                },
                "children": []
              }
            ]
          }
        },
        {
          "$type": "pub.leaflet.pages.linearDocument#block",
          "block": {
            "$type": "pub.leaflet.blocks.text",
            "facets": [],
            "plaintext": "これは、例えばゲーム『ワールド・オブ・ウォークラフト』のアライアンスとホードの関係に似ています。対峙はできるが、チャットすると文字が無意味化される──そんな形で「不和を許容する場の設計」が可能です。"
          }
        },
        {
          "$type": "pub.leaflet.pages.linearDocument#block",
          "block": {
            "$type": "pub.leaflet.blocks.text",
            "facets": [],
            "plaintext": ""
          }
        },
        {
          "$type": "pub.leaflet.pages.linearDocument#block",
          "block": {
            "$type": "pub.leaflet.blocks.header",
            "level": 2,
            "facets": [],
            "plaintext": "Discoexistenceの意義"
          }
        },
        {
          "$type": "pub.leaflet.pages.linearDocument#block",
          "block": {
            "$type": "pub.leaflet.blocks.text",
            "facets": [],
            "plaintext": "SNSや物理空間での「苦」の多くは、利用者の増加による多様性と衝突から生まれます。エコーチェンバーや愚痴ループが発生しやすい現代において、Discoexistenceは次のような意味を持ちます。"
          }
        },
        {
          "$type": "pub.leaflet.pages.linearDocument#block",
          "block": {
            "$type": "pub.leaflet.blocks.unorderedList",
            "children": [
              {
                "$type": "pub.leaflet.blocks.unorderedList#listItem",
                "content": {
                  "$type": "pub.leaflet.blocks.text",
                  "facets": [],
                  "plaintext": "小規模な場では、空気や景気を活かした自然な交流が可能"
                },
                "children": []
              },
              {
                "$type": "pub.leaflet.blocks.unorderedList#listItem",
                "content": {
                  "$type": "pub.leaflet.blocks.text",
                  "facets": [],
                  "plaintext": "多様性を認めつつ、衝突を最小化できる"
                },
                "children": []
              },
              {
                "$type": "pub.leaflet.blocks.unorderedList#listItem",
                "content": {
                  "$type": "pub.leaflet.blocks.text",
                  "facets": [],
                  "plaintext": "合わない人とも共存できることで、コミュニティの成熟が促される"
                },
                "children": []
              }
            ]
          }
        },
        {
          "$type": "pub.leaflet.pages.linearDocument#block",
          "block": {
            "$type": "pub.leaflet.blocks.text",
            "facets": [],
            "plaintext": "SNS設計においても、ユーザーが意図的に干渉するのではなく、場のアフォーダンスを活かして自然に交流できる仕組みを作ることが鍵です。"
          }
        },
        {
          "$type": "pub.leaflet.pages.linearDocument#block",
          "block": {
            "$type": "pub.leaflet.blocks.horizontalRule"
          }
        },
        {
          "$type": "pub.leaflet.pages.linearDocument#block",
          "block": {
            "$type": "pub.leaflet.blocks.text",
            "facets": [],
            "plaintext": "Discoexistenceは、単なる我慢や表面的な友好ではありません。合わない人がいても心理的距離を保ち、同じクラスタで生き抜く力。それを身につけることが、SNSでもリアルでも、健全なコミュニティ生活の秘訣となるのです。"
          }
        },
        {
          "$type": "pub.leaflet.pages.linearDocument#block",
          "block": {
            "$type": "pub.leaflet.blocks.horizontalRule"
          }
        },
        {
          "$type": "pub.leaflet.pages.linearDocument#block",
          "block": {
            "$type": "pub.leaflet.blocks.text",
            "facets": [
              {
                "index": {
                  "byteEnd": 9,
                  "byteStart": 0
                },
                "features": [
                  {
                    "$type": "pub.leaflet.richtext.facet#bold"
                  }
                ]
              }
            ],
            "plaintext": "まとめ"
          }
        },
        {
          "$type": "pub.leaflet.pages.linearDocument#block",
          "block": {
            "$type": "pub.leaflet.blocks.blockquote",
            "facets": [],
            "plaintext": "“Some people are just not your vibe, but that’s discoexistence.” 「合わない人もいるけど、それもディスコエグジステンス」"
          }
        },
        {
          "$type": "pub.leaflet.pages.linearDocument#block",
          "block": {
            "$type": "pub.leaflet.blocks.blockquote",
            "facets": [],
            "plaintext": "“Mastering discoexistence is the key to thriving in any community.” 「どんなコミュニティでも生き抜く鍵は、衝突を含めた共存力だ」"
          }
        },
        {
          "$type": "pub.leaflet.pages.linearDocument#block",
          "block": {
            "$type": "pub.leaflet.blocks.text",
            "facets": [],
            "plaintext": ""
          }
        },
        {
          "$type": "pub.leaflet.pages.linearDocument#block",
          "block": {
            "$type": "pub.leaflet.blocks.text",
            "facets": [
              {
                "index": {
                  "byteEnd": 9,
                  "byteStart": 0
                },
                "features": [
                  {
                    "$type": "pub.leaflet.richtext.facet#bold"
                  }
                ]
              }
            ],
            "plaintext": "追記:"
          }
        },
        {
          "$type": "pub.leaflet.pages.linearDocument#block",
          "block": {
            "$type": "pub.leaflet.blocks.text",
            "facets": [],
            "plaintext": "ソーシャル・ネットワークを使う人には二つの姿勢がある。 ひとつは、そこにDiscexistence(存在の分散や消耗)があることを受け入れ、巻き込まれるままに動く。 もうひとつは、そうした要素を厭い距離を置き、自分にとって居心地のよい、自分の「いつも通り」や理想の状態を維持することに勤しむ。"
          }
        },
        {
          "$type": "pub.leaflet.pages.linearDocument#block",
          "block": {
            "$type": "pub.leaflet.blocks.text",
            "facets": [],
            "plaintext": "身体性が希薄で自他の境界が曖昧なネット空間では、後者の戦略──自分にとって居心地のよい状態を守る──は、一方的で非対称的ではあるものの、妥当な戦略と言える。 ソーシャル・グラフを拡大するために、すべての人に配慮し続けるアプローチでは、かえって「俺の頭の中に入ってくるな」という状況を招きかねない。"
          }
        },
        {
          "$type": "pub.leaflet.pages.linearDocument#block",
          "block": {
            "$type": "pub.leaflet.blocks.text",
            "facets": [],
            "plaintext": "しかし、そのように調整された空間においてさえ、Discoexistenceが入り込むスキマはあり得る。 その際の痛みは、普段からDiscoexistenceに身を投じている人よりも大きいかもしれない。"
          }
        },
        {
          "$type": "pub.leaflet.pages.linearDocument#block",
          "block": {
            "$type": "pub.leaflet.blocks.text",
            "facets": [],
            "plaintext": "身体性が希薄なソーシャル・ネットワークにおける「自己存在の維持」と、それに伴って生じるDiscoexistenceによる心理的負荷は、社会的な生きものである人間に課せられた二日酔いのアルデヒドのようなものだ。 私たちはそれを厭いながらも、酒をやめられない。"
          }
        }
      ]
    }
  ],
  "title": "Discoexistenceについて",
  "author": "did:plc:aajyn6qzw67cnmwf7zxzbjdy",
  "postRef": {
    "cid": "bafyreicwguwmiu36kzigdjwyrotl66vf2frdnv4eularrqocxh63tk6fta",
    "uri": "at://did:plc:aajyn6qzw67cnmwf7zxzbjdy/app.bsky.feed.post/3lzkgnprk3k2p",
    "commit": {
      "cid": "bafyreifxqrvyhm2xu55qd44khlrf7hxkfqoolcuidwz3hfu46jxhot6kja",
      "rev": "3lzkgnpv7sf2m"
    },
    "validationStatus": "valid"
  },
  "description": "",
  "publication": "at://did:plc:aajyn6qzw67cnmwf7zxzbjdy/pub.leaflet.publication/3lyuurwxkbk24",
  "publishedAt": "2025-09-24T02:53:03.434Z"
}

did:plc:aajyn6qzw67cnmwf7zxzbjdy | at://did:plc:aajyn6qzw67cnmwf7zxzbjdy/pub.leaflet.document/3lzkgnftkck24

pub.leaflet.blocks.horizontalRule (nested within pub.leaflet.document) (26 samples)
{
  "tags": [],
  "$type": "pub.leaflet.document",
  "pages": [
    {
      "id": "019920f4-3145-7881-9593-77a1dbf2c223",
      "$type": "pub.leaflet.pages.linearDocument",
      "blocks": [
        {
          "$type": "pub.leaflet.pages.linearDocument#block",
          "block": {
            "$type": "pub.leaflet.blocks.text",
            "facets": [],
            "plaintext": "Exercise your vote in the market. Choose products that reflect your values. Build towards a future you want to experience. When you can, don't use anything made by these people. I say this as I write from a MacBook. "
          }
        },
        {
          "$type": "pub.leaflet.pages.linearDocument#block",
          "block": {
            "$type": "pub.leaflet.blocks.bskyPost",
            "postRef": {
              "cid": "bafyreig6cldfgawnb3hu7t4vhkporherjfhtikvdrum2nlqw523x6yhg5u",
              "uri": "at://did:plc:66lbtw2porscqpmair6mir37/app.bsky.feed.post/3ly6tyokzfk2x"
            }
          }
        },
        {
          "$type": "pub.leaflet.pages.linearDocument#block",
          "block": {
            "$type": "pub.leaflet.blocks.text",
            "facets": [],
            "plaintext": "Some of my alternatives are aspirational. I plan to / hope to move to them in the future. I will mark those as such."
          }
        },
        {
          "$type": "pub.leaflet.pages.linearDocument#block",
          "block": {
            "$type": "pub.leaflet.blocks.header",
            "level": 1,
            "facets": [],
            "plaintext": "Hardware"
          }
        },
        {
          "$type": "pub.leaflet.pages.linearDocument#block",
          "block": {
            "$type": "pub.leaflet.blocks.header",
            "level": 2,
            "facets": [],
            "plaintext": "Laptop"
          }
        },
        {
          "$type": "pub.leaflet.pages.linearDocument#block",
          "block": {
            "$type": "pub.leaflet.blocks.text",
            "facets": [
              {
                "index": {
                  "byteEnd": 29,
                  "byteStart": 15
                },
                "features": [
                  {
                    "uri": "https://support.apple.com/en-us/111883",
                    "$type": "pub.leaflet.richtext.facet#link"
                  }
                ]
              }
            ],
            "plaintext": "Currently on a MacBook Air M1. I love the thing. I'm willing to use macOS but am interested in Nix. I never want to look at Windows again."
          }
        },
        {
          "$type": "pub.leaflet.pages.linearDocument#block",
          "block": {
            "$type": "pub.leaflet.blocks.text",
            "facets": [],
            "plaintext": "For my next laptop, I am looking at the Framework 13. I can get storage and memory for a better price than what Framework sells. Otherwise this is my desired config."
          }
        },
        {
          "$type": "pub.leaflet.pages.linearDocument#block",
          "block": {
            "src": "https://frame.work/share-my-laptop?token=f419e7aca2e",
            "$type": "pub.leaflet.blocks.website",
            "title": "Configure Framework Laptop 13 DIY Edition (AMD Ryzen™ AI 300 Series)",
            "description": "Choose from AMD and Intel system options, select your preferred memory and storage, operating system, and more customizations. Available in DIY and pre-built configurations.",
            "previewImage": {
              "ref": {
                "$link": "bafkreih2fuyfzwvrgvrejvccuxroxcsmqjfcsgnzpg2mylnkrm3qvgvr4a"
              },
              "size": 43356,
              "$type": "blob",
              "mimeType": "image/png"
            }
          }
        },
        {
          "$type": "pub.leaflet.pages.linearDocument#block",
          "block": {
            "$type": "pub.leaflet.blocks.header",
            "level": 2,
            "facets": [],
            "plaintext": "Phone"
          }
        },
        {
          "$type": "pub.leaflet.pages.linearDocument#block",
          "block": {
            "$type": "pub.leaflet.blocks.text",
            "facets": [
              {
                "index": {
                  "byteEnd": 114,
                  "byteStart": 101
                },
                "features": [
                  {
                    "uri": "https://support.apple.com/en-us/111849",
                    "$type": "pub.leaflet.richtext.facet#link"
                  }
                ]
              },
              {
                "index": {
                  "byteEnd": 131,
                  "byteStart": 120
                },
                "features": [
                  {
                    "uri": "https://shop.fairphone.com/the-fairphone-gen-6",
                    "$type": "pub.leaflet.richtext.facet#link"
                  }
                ]
              }
            ],
            "plaintext": "Again, I am ok with using Apple hardware but stay away from depending on their services. I am on the iPhone 14 Pro. The Fairphone 6 is looking pretty decent. Probably want to own a camera if you go that route. These days iOS gives a lot of the customization I would want out of Android anyway, and I love the Shortcuts app. I find Apple more benevolent than Google in aggregate."
          }
        },
        {
          "$type": "pub.leaflet.pages.linearDocument#block",
          "block": {
            "$type": "pub.leaflet.blocks.header",
            "level": 2,
            "facets": [],
            "plaintext": "E-reader"
          }
        },
        {
          "$type": "pub.leaflet.pages.linearDocument#block",
          "block": {
            "$type": "pub.leaflet.blocks.text",
            "facets": [
              {
                "index": {
                  "byteEnd": 12,
                  "byteStart": 0
                },
                "features": [
                  {
                    "uri": "https://www.amazon.com/Kindle-Touch-e-Reader-Touch-Screen-Wi-Fi-Special-Offers/dp/B005890G8Y",
                    "$type": "pub.leaflet.richtext.facet#link"
                  }
                ]
              },
              {
                "index": {
                  "byteEnd": 206,
                  "byteStart": 199
                },
                "features": [
                  {
                    "uri": "https://calibre-ebook.com/",
                    "$type": "pub.leaflet.richtext.facet#link"
                  }
                ]
              }
            ],
            "plaintext": "Kindle Touch. Got it out of a drawer at the in-laws place. It's so old it doesn't connect to wifi but the firmware is too new to jailbreak, so I just plug it into my laptop and push books to it from Calibre. Works a treat."
          }
        },
        {
          "$type": "pub.leaflet.pages.linearDocument#block",
          "block": {
            "$type": "pub.leaflet.blocks.header",
            "level": 2,
            "facets": [],
            "plaintext": "Machines"
          }
        },
        {
          "$type": "pub.leaflet.pages.linearDocument#block",
          "block": {
            "$type": "pub.leaflet.blocks.text",
            "facets": [
              {
                "index": {
                  "byteEnd": 194,
                  "byteStart": 183
                },
                "features": [
                  {
                    "uri": "https://www.orcaslicer.com/",
                    "$type": "pub.leaflet.richtext.facet#link"
                  }
                ]
              }
            ],
            "plaintext": "Bambu makes the best appliance-tier 3D printers right now. I got the combo with the AMS for automatic material switching for a great deal from Microcenter. I use it in local mode and Orca slicer so there is not communication with Bambu services."
          }
        },
        {
          "$type": "pub.leaflet.pages.linearDocument#block",
          "block": {
            "src": "https://bambulab.com/en-us/a1-mini",
            "$type": "pub.leaflet.blocks.website",
            "title": "Bambu Lab A1 mini",
            "description": "Ultimate performance in compact build volume, Bambu Lab A1 mini offers ease of use 3D printing with features once found only in high-end models for beginners.",
            "previewImage": {
              "ref": {
                "$link": "bafkreih3qghdnkv6ni5devd7z6ykdx4tchetc27xpcu7fdkds3s5oj3osm"
              },
              "size": 42596,
              "$type": "blob",
              "mimeType": "image/png"
            }
          }
        },
        {
          "$type": "pub.leaflet.pages.linearDocument#block",
          "block": {
            "src": "https://cricut.com/en-au/cricut-explore",
            "$type": "pub.leaflet.blocks.website",
            "title": "Cricut Explore® 3 | Cricut.com",
            "description": "Cricut Shop",
            "previewImage": {
              "ref": {
                "$link": "bafkreifq3pzmermpjf4i5nv7n5u4yg2g4ekxwxdfvbrp6kh7iibju6775y"
              },
              "size": 38859,
              "$type": "blob",
              "mimeType": "image/png"
            }
          }
        },
        {
          "$type": "pub.leaflet.pages.linearDocument#block",
          "block": {
            "src": "https://epson.com/For-Work/Printers/Inkjet/EcoTank-ET-15000-All-in-One-Cartridge-Free-Supertank-Printer/p/C11CH96201",
            "$type": "pub.leaflet.blocks.website",
            "title": "EcoTank ET-15000 All-in-One Cartridge-Free Supertank Printer | Products | Epson US",
            "description": "The EcoTank ET-15000 wireless all-in-one offers Cartridge-Free Printing with easy-to-fill supersized ink tanks. Save up to 90 percent on ink with low-cost replacement bottles — as little as 1 cent per color ISO page vs. 20 cents with ink cartridges1. This all-in-one delivers vibrant prints up to 13 x 19 (through rear-feed tray) and scans up to 8.5 x 14 (via the ADF). Print for up to 2 years with each included or replacement ink bottle set2 — each replacement set includes enough ink to print up to 6,000 pages3. That’s equivalent to about 80 individual cartridges4. And, there’s zero cartridge waste. The ET-15000 features a 250-sheet front tray paper capacity and rear specialty-paper feed, plus a 2.7 color touchscreen and hands-free voice-activated printing5.",
            "previewImage": {
              "ref": {
                "$link": "bafkreie7q5dmexncoyye5tpppyc7i523hnvzha2r6ij2zdiknqwev3slkm"
              },
              "size": 28057,
              "$type": "blob",
              "mimeType": "image/png"
            }
          }
        },
        {
          "$type": "pub.leaflet.pages.linearDocument#block",
          "block": {
            "$type": "pub.leaflet.blocks.header",
            "level": 1,
            "facets": [],
            "plaintext": "Software"
          }
        },
        {
          "$type": "pub.leaflet.pages.linearDocument#block",
          "block": {
            "$type": "pub.leaflet.blocks.header",
            "level": 2,
            "facets": [],
            "plaintext": "Browser"
          }
        },
        {
          "$type": "pub.leaflet.pages.linearDocument#block",
          "block": {
            "$type": "pub.leaflet.blocks.text",
            "facets": [
              {
                "index": {
                  "byteEnd": 3,
                  "byteStart": 0
                },
                "features": [
                  {
                    "uri": "https://arc.net/download",
                    "$type": "pub.leaflet.richtext.facet#link"
                  }
                ]
              }
            ],
            "plaintext": "Arc is dead, long live Arc. I loved the Arc browser dearly until Josh Miller decided his core user base is unimportant. Zen is a great successor built on Firefox by just a couple devs. They've replicated all of the differentiating experiences from Arc. It's a good time. "
          }
        },
        {
          "$type": "pub.leaflet.pages.linearDocument#block",
          "block": {
            "src": "https://zen-browser.app/",
            "$type": "pub.leaflet.blocks.website",
            "title": "Zen Browser",
            "description": "Beautifully designed, privacy-focused, and packed with features.",
            "previewImage": {
              "ref": {
                "$link": "bafkreiggthc373nz66ks5mhcqrjbz5wz2guypsclufsc74ugegyn3yovqy"
              },
              "size": 6712,
              "$type": "blob",
              "mimeType": "image/png"
            }
          }
        },
        {
          "$type": "pub.leaflet.pages.linearDocument#block",
          "block": {
            "$type": "pub.leaflet.blocks.text",
            "facets": [],
            "plaintext": "I don't have a replacement for Arc Search yet. It's a fantastic UI that nobody has copied yet in a mobile browser."
          }
        },
        {
          "$type": "pub.leaflet.pages.linearDocument#block",
          "block": {
            "src": "https://arc.net/search",
            "$type": "pub.leaflet.blocks.website",
            "title": "Arc Search — A fast, ad-free mobile browser",
            "description": "Arc Search is a new AI-enabled, default mobile browser by The Browser Company — designed to be the fastest way to search, and the lightest way to browse on mobile. Available on iOS and Android.",
            "previewImage": {
              "ref": {
                "$link": "bafkreif7hrquhkswmb2sk5dm3urrdhuehbbeka4a442tqcrihqqq2vz5ri"
              },
              "size": 43736,
              "$type": "blob",
              "mimeType": "image/png"
            }
          }
        },
        {
          "$type": "pub.leaflet.pages.linearDocument#block",
          "block": {
            "$type": "pub.leaflet.blocks.header",
            "level": 2,
            "facets": [],
            "plaintext": "Search"
          }
        },
        {
          "$type": "pub.leaflet.pages.linearDocument#block",
          "block": {
            "$type": "pub.leaflet.blocks.text",
            "facets": [],
            "plaintext": "Google-schmoogle. Want an easy way to not participate in the search advertising economy? Pay for search."
          }
        },
        {
          "$type": "pub.leaflet.pages.linearDocument#block",
          "block": {
            "src": "https://kagi.com/",
            "$type": "pub.leaflet.blocks.website",
            "title": "Kagi Search - A Premium Search Engine",
            "description": "Better search results with no ads. Welcome to Kagi (pronounced kah-gee), a paid search engine that gives power back to the user.",
            "previewImage": {
              "ref": {
                "$link": "bafkreif5i44po52wk52atyoc4pviq7ct3z4cxzhxqlidypylbig56x4ogq"
              },
              "size": 25436,
              "$type": "blob",
              "mimeType": "image/png"
            }
          }
        },
        {
          "$type": "pub.leaflet.pages.linearDocument#block",
          "block": {
            "$type": "pub.leaflet.blocks.header",
            "level": 2,
            "facets": [],
            "plaintext": "Chat"
          }
        },
        {
          "$type": "pub.leaflet.pages.linearDocument#block",
          "block": {
            "src": "https://signal.org/",
            "$type": "pub.leaflet.blocks.website",
            "title": "Signal Messenger: Speak Freely",
            "description": "Say \"hello\" to a different messaging experience. An unexpected focus on privacy, combined with all of the features you expect.",
            "previewImage": {
              "ref": {
                "$link": "bafkreidab3agpjpijvlxo7tdr2p4uuzshdj5zd4deeynalqeyd33qw4kpy"
              },
              "size": 38264,
              "$type": "blob",
              "mimeType": "image/png"
            }
          }
        },
        {
          "$type": "pub.leaflet.pages.linearDocument#block",
          "block": {
            "$type": "pub.leaflet.blocks.text",
            "facets": [],
            "plaintext": "iMessage and RCS."
          }
        },
        {
          "$type": "pub.leaflet.pages.linearDocument#block",
          "block": {
            "$type": "pub.leaflet.blocks.text",
            "facets": [],
            "plaintext": "Discord. This is one I desperately want to get away from. It's a data mining scheme with gotcha monetization. I still have communities on there while alternatives are on the path to viability."
          }
        },
        {
          "$type": "pub.leaflet.pages.linearDocument#block",
          "block": {
            "$type": "pub.leaflet.blocks.text",
            "facets": [
              {
                "index": {
                  "byteEnd": 69,
                  "byteStart": 55
                },
                "features": [
                  {
                    "uri": "https://www.firstinspires.org/",
                    "$type": "pub.leaflet.richtext.facet#link"
                  }
                ]
              }
            ],
            "plaintext": "Slack. A bunch of communities talk there, including my FIRST Robotics teams I mentor."
          }
        },
        {
          "$type": "pub.leaflet.pages.linearDocument#block",
          "block": {
            "$type": "pub.leaflet.blocks.header",
            "level": 2,
            "facets": [],
            "plaintext": "Email"
          }
        },
        {
          "$type": "pub.leaflet.pages.linearDocument#block",
          "block": {
            "src": "https://proton.me/mail",
            "$type": "pub.leaflet.blocks.website",
            "title": "Proton Mail: Get a free email account with privacy and encryption | Proton",
            "description": "Proton Mail is the world’s largest secure email service with over 100 million users. Available on Web, iOS, Android, and desktop. Protected by Swiss privacy law.",
            "previewImage": {
              "ref": {
                "$link": "bafkreiaasggwjxqtmsif6ab2p6tdgns3o3yd3sfqhmpwhrklweph3lihhm"
              },
              "size": 27692,
              "$type": "blob",
              "mimeType": "image/png"
            }
          }
        },
        {
          "$type": "pub.leaflet.pages.linearDocument#block",
          "block": {
            "$type": "pub.leaflet.blocks.header",
            "level": 2,
            "facets": [],
            "plaintext": "Calendar"
          }
        },
        {
          "$type": "pub.leaflet.pages.linearDocument#block",
          "block": {
            "$type": "pub.leaflet.blocks.text",
            "facets": [
              {
                "index": {
                  "byteEnd": 11,
                  "byteStart": 0
                },
                "features": [
                  {
                    "uri": "https://flexibits.com/fantastical",
                    "$type": "pub.leaflet.richtext.facet#link"
                  }
                ]
              }
            ],
            "plaintext": "Fantastical is still the best calendar app. "
          }
        },
        {
          "$type": "pub.leaflet.pages.linearDocument#block",
          "block": {
            "$type": "pub.leaflet.blocks.header",
            "level": 2,
            "facets": [],
            "plaintext": "PKM"
          }
        },
        {
          "$type": "pub.leaflet.pages.linearDocument#block",
          "block": {
            "src": "https://obsidian.md/",
            "$type": "pub.leaflet.blocks.website",
            "title": "Obsidian - Sharpen your thinking",
            "description": "The free and flexible app for your private thoughts.",
            "previewImage": {
              "ref": {
                "$link": "bafkreicxe7rvhhzagc5hh62gkfwxejxz4cfnzmbmnvfqu5j6l6ydualoeu"
              },
              "size": 27464,
              "$type": "blob",
              "mimeType": "image/png"
            }
          }
        },
        {
          "$type": "pub.leaflet.pages.linearDocument#block",
          "block": {
            "src": "https://www.notion.com/",
            "$type": "pub.leaflet.blocks.website",
            "title": "The AI workspace that works for you. | Notion",
            "description": "A tool that connects everyday work into one space. It gives you and your teams AI tools—search, writing, note-taking—inside an all-in-one, flexible workspace.",
            "previewImage": {
              "ref": {
                "$link": "bafkreib5id24nrl6ntp6xrenabvr7ljutf6gdamdbvjg3qhkwvfu4n54sm"
              },
              "size": 31807,
              "$type": "blob",
              "mimeType": "image/png"
            }
          }
        },
        {
          "$type": "pub.leaflet.pages.linearDocument#block",
          "block": {
            "src": "https://clay.earth",
            "$type": "pub.leaflet.blocks.website",
            "title": "Clay - Be more thoughtful with the people in your network.",
            "description": "Clay is a beautiful rolodex and CRM for iPhone, Mac, Windows, and web, built automatically to help you manage your personal and professional relationships.",
            "previewImage": {
              "ref": {
                "$link": "bafkreibclf6mblh5hyte2unl3bzy2dcn5mgoqrpwhebev4xj3tku2vprqa"
              },
              "size": 40765,
              "$type": "blob",
              "mimeType": "image/png"
            }
          }
        },
        {
          "$type": "pub.leaflet.pages.linearDocument#block",
          "block": {
            "$type": "pub.leaflet.blocks.header",
            "level": 2,
            "facets": [],
            "plaintext": "Todos"
          }
        },
        {
          "$type": "pub.leaflet.pages.linearDocument#block",
          "block": {
            "src": "https://todoist.com",
            "$type": "pub.leaflet.blocks.website",
            "title": "Todoist | A To-Do List to Organize Your Work & Life",
            "description": "Trusted by 30 million people and teams. Todoist is the world's favorite task manager and to-do list app. Finally become focused, organized and calm.",
            "previewImage": {
              "ref": {
                "$link": "bafkreieb5ntcesmkvllx4vfmhzlcjpfvki2v6lkby4jqmezkpezvblkp4u"
              },
              "size": 25882,
              "$type": "blob",
              "mimeType": "image/png"
            }
          }
        },
        {
          "$type": "pub.leaflet.pages.linearDocument#block",
          "block": {
            "$type": "pub.leaflet.blocks.header",
            "level": 2,
            "facets": [],
            "plaintext": "Media"
          }
        },
        {
          "$type": "pub.leaflet.pages.linearDocument#block",
          "block": {
            "$type": "pub.leaflet.blocks.text",
            "facets": [],
            "plaintext": "I’ve finally cancelled my Spotify Premium subscription. I prefer supporting artists over funding attack drones and ICE adverts. My replacement is a combination of Qobuz for streaming and a self hosted Navidrome instance with my personal library. Arpeggi is a great iOS client for Navidrome, although it is still in TestFlight. I purchase music for my library on Bandcamp."
          }
        },
        {
          "$type": "pub.leaflet.pages.linearDocument#block",
          "block": {
            "src": "https://www.qobuz.com/us-en/discover",
            "$type": "pub.leaflet.blocks.website",
            "title": "Qobuz - Unlimited high quality streaming (United States)",
            "description": "More than 100 million tracks available for unlimited streaming in high sound quality. Qobuz is also the worldwide leader in 24-Bit Hi-Res downloads.",
            "previewImage": {
              "ref": {
                "$link": "bafkreiejd3j6mp6ai5h2kfkeotq467zbdkfvyew3ziypbhi2mhtrn2pdum"
              },
              "size": 33991,
              "$type": "blob",
              "mimeType": "image/png"
            }
          }
        },
        {
          "$type": "pub.leaflet.pages.linearDocument#block",
          "block": {
            "src": "https://bandcamp.com/",
            "$type": "pub.leaflet.blocks.website",
            "title": "Bandcamp",
            "description": "Discover amazing music and directly support the artists who make it."
          }
        },
        {
          "$type": "pub.leaflet.pages.linearDocument#block",
          "block": {
            "$type": "pub.leaflet.blocks.text",
            "facets": [],
            "plaintext": "On the reading side, I’ve gone fully off big tech. I get all my news from Bluesky feeds and RSS. NetNewsWire clients on all my devices pull content from my FreshRSS instance on my server. "
          }
        },
        {
          "$type": "pub.leaflet.pages.linearDocument#block",
          "block": {
            "src": "https://sill.social/",
            "$type": "pub.leaflet.blocks.website",
            "title": "Sill",
            "description": "Sill streamlines your Bluesky and Mastodon feeds to give you a clear picture of what's happening.",
            "previewImage": {
              "ref": {
                "$link": "bafkreid7f2hkdgavplue637u77t33eknj4nok2hvsohta6lnbitlcbepke"
              },
              "size": 21801,
              "$type": "blob",
              "mimeType": "image/png"
            }
          }
        },
        {
          "$type": "pub.leaflet.pages.linearDocument#block",
          "block": {
            "src": "https://netnewswire.com/",
            "$type": "pub.leaflet.blocks.website",
            "title": "NetNewsWire",
            "description": "NetNewsWire is a free and open source RSS reader for Mac.",
            "previewImage": {
              "ref": {
                "$link": "bafkreibnuptmyyxmn23tyl6uz7qhe4ywknaxrxizatsfftlledltw7ioze"
              },
              "size": 19259,
              "$type": "blob",
              "mimeType": "image/png"
            }
          }
        },
        {
          "$type": "pub.leaflet.pages.linearDocument#block",
          "block": {
            "src": "https://freshrss.org/index.html",
            "$type": "pub.leaflet.blocks.website",
            "title": "FreshRSS, a free, self-hostable feeds aggregator",
            "description": "FreshRSS is lightweight, easy to work with, powerful, and customizable.",
            "previewImage": {
              "ref": {
                "$link": "bafkreifwn5qra2nhyrk733k6xl3g4kp7spvv75cehw352pyd4rd7mza7km"
              },
              "size": 25157,
              "$type": "blob",
              "mimeType": "image/png"
            }
          }
        },
        {
          "$type": "pub.leaflet.pages.linearDocument#block",
          "block": {
            "$type": "pub.leaflet.blocks.text",
            "facets": [],
            "plaintext": "Entertainment is a combo of YouTube Premium and independent creator platforms. "
          }
        },
        {
          "$type": "pub.leaflet.pages.linearDocument#block",
          "block": {
            "src": "https://nebula.tv/",
            "$type": "pub.leaflet.blocks.website",
            "title": "Nebula – Indie Streaming",
            "description": "Nebula is smart, thoughtful videos, podcasts, and classes from your favorite creators.",
            "previewImage": {
              "ref": {
                "$link": "bafkreibylohotm6ootlzdmfxv2cfscsypsrlktwxhtjiy2mikdjqpwzf4m"
              },
              "size": 64214,
              "$type": "blob",
              "mimeType": "image/png"
            }
          }
        },
        {
          "$type": "pub.leaflet.pages.linearDocument#block",
          "block": {
            "src": "https://www.2ndtry.tv/",
            "$type": "pub.leaflet.blocks.website",
            "title": "2nd try - Trying stuff, ad-free | The Try Guys",
            "description": "Trying stuff, ad-free & uncensored. Your new home for all things Try Guys!",
            "previewImage": {
              "ref": {
                "$link": "bafkreiejji3pwcu224jf4iyehyr4wjzyr6gucxb5aobzyk25tzgpzearhm"
              },
              "size": 66084,
              "$type": "blob",
              "mimeType": "image/png"
            }
          }
        },
        {
          "$type": "pub.leaflet.pages.linearDocument#block",
          "block": {
            "src": "https://www.dropout.tv/",
            "$type": "pub.leaflet.blocks.website",
            "title": "",
            "description": "The game show where there's a new, surprise premise every episode.",
            "previewImage": {
              "ref": {
                "$link": "bafkreibm6un7czfrqjguzfgpowyzpxao5msp3mgdfsvphwqqm6mkgyozcu"
              },
              "size": 29756,
              "$type": "blob",
              "mimeType": "image/png"
            }
          }
        },
        {
          "$type": "pub.leaflet.pages.linearDocument#block",
          "block": {
            "$type": "pub.leaflet.blocks.header",
            "level": 2,
            "facets": [],
            "plaintext": "Creative"
          }
        },
        {
          "$type": "pub.leaflet.pages.linearDocument#block",
          "block": {
            "$type": "pub.leaflet.blocks.text",
            "facets": [],
            "plaintext": "Affinity suite. These are made in the UK, recently purchased by Canva who are based in Australia. Perpetual license. One filetype for their whole suite of tools."
          }
        },
        {
          "$type": "pub.leaflet.pages.linearDocument#block",
          "block": {
            "$type": "pub.leaflet.blocks.unorderedList",
            "children": [
              {
                "$type": "pub.leaflet.blocks.unorderedList#listItem",
                "content": {
                  "$type": "pub.leaflet.blocks.text",
                  "facets": [],
                  "plaintext": "Affinity Publisher (Adobe InDesign replacement)"
                },
                "children": []
              },
              {
                "$type": "pub.leaflet.blocks.unorderedList#listItem",
                "content": {
                  "$type": "pub.leaflet.blocks.text",
                  "facets": [],
                  "plaintext": "Affinity Photo (Adobe Photoshop replacement)"
                },
                "children": []
              },
              {
                "$type": "pub.leaflet.blocks.unorderedList#listItem",
                "content": {
                  "$type": "pub.leaflet.blocks.text",
                  "facets": [],
                  "plaintext": "Affinity Designer (Adobe Illustrator replacement)"
                },
                "children": []
              }
            ]
          }
        },
        {
          "$type": "pub.leaflet.pages.linearDocument#block",
          "block": {
            "src": "https://affinity.serif.com/en-us/publisher/",
            "$type": "pub.leaflet.blocks.website",
            "title": "Affinity Publisher 2",
            "description": "Affinity Publisher has everything you need to design spectacular layouts ready for publication. Get a free trial of the top page layout software today.",
            "previewImage": {
              "ref": {
                "$link": "bafkreigbdbyd74gpknblci7aq626jhbydydxgzpornfunsgqytais47bzy"
              },
              "size": 38912,
              "$type": "blob",
              "mimeType": "image/png"
            }
          }
        },
        {
          "$type": "pub.leaflet.pages.linearDocument#block",
          "block": {
            "src": "https://affinity.serif.com/en-us/photo/",
            "$type": "pub.leaflet.blocks.website",
            "title": "Affinity Photo 2",
            "description": "The first-choice photo editor of millions of photographers, artists, and other professionals around the world – try Affinity Photo for free today!",
            "previewImage": {
              "ref": {
                "$link": "bafkreiel5u5otcdlvhnzkqcjwh2a2r64n7uuehfetyafmt73rlntvcxnry"
              },
              "size": 39401,
              "$type": "blob",
              "mimeType": "image/png"
            }
          }
        },
        {
          "$type": "pub.leaflet.pages.linearDocument#block",
          "block": {
            "src": "https://affinity.serif.com/en-us/designer/",
            "$type": "pub.leaflet.blocks.website",
            "title": "Affinity Designer 2",
            "description": "The best app for creatives and other professionals looking to create high-quality designs, concept art, illustrations, mock-ups and more. Get a free trial!",
            "previewImage": {
              "ref": {
                "$link": "bafkreihqfamzdtcmei5nkbsssjtbrgopcwmjm45thwtwnzq6vk4kn45uqu"
              },
              "size": 41265,
              "$type": "blob",
              "mimeType": "image/png"
            }
          }
        },
        {
          "$type": "pub.leaflet.pages.linearDocument#block",
          "block": {
            "$type": "pub.leaflet.blocks.text",
            "facets": [],
            "plaintext": "For video, I use Blackmagic Davinci Resolve. It's free, and quickly becoming favored in the professional industry over Adobe Premiere Pro."
          }
        },
        {
          "$type": "pub.leaflet.pages.linearDocument#block",
          "block": {
            "src": "https://www.blackmagicdesign.com/products/davinciresolve/",
            "$type": "pub.leaflet.blocks.website",
            "title": "DaVinci Resolve | Blackmagic Design",
            "description": "Professional video editing, color correction, visual effects and audio post production all in a single application. Free and paid versions for Mac, Windows and Linux.",
            "previewImage": {
              "ref": {
                "$link": "bafkreiegxnqynp5g67wavrjzlle2fpo5pursvdlfsuhv5snagbd4g4imd4"
              },
              "size": 17236,
              "$type": "blob",
              "mimeType": "image/png"
            }
          }
        },
        {
          "$type": "pub.leaflet.pages.linearDocument#block",
          "block": {
            "$type": "pub.leaflet.blocks.text",
            "facets": [
              {
                "index": {
                  "byteEnd": 101,
                  "byteStart": 97
                },
                "features": [
                  {
                    "$type": "pub.leaflet.richtext.facet#italic"
                  }
                ]
              }
            ],
            "plaintext": "Penpot. The open source self hostable Figma alternative. Features are still a little early (they just added component variants), but all the files are non-proprietary. Why do I prefer an alternative to Figma? Any monopoly is bad. I'd rather pay no subscription and control my software and files. Also, donate to open source 🫶🏻."
          }
        },
        {
          "$type": "pub.leaflet.pages.linearDocument#block",
          "block": {
            "src": "https://penpot.app/",
            "$type": "pub.leaflet.blocks.website",
            "title": "Penpot: The Design Tool for Design & Code Collaboration",
            "description": "Penpot is the open-source free design software that connects designers and developers with no handoff drama. Prototyping, UI design and code - all in one app.",
            "previewImage": {
              "ref": {
                "$link": "bafkreiflbd3y25ch7g63s25ax6bizhn5rw7w7zpja4f6bw27ijtueaxey4"
              },
              "size": 42692,
              "$type": "blob",
              "mimeType": "image/png"
            }
          }
        },
        {
          "$type": "pub.leaflet.pages.linearDocument#block",
          "block": {
            "src": "https://excalidraw.com/",
            "$type": "pub.leaflet.blocks.website",
            "title": "Excalidraw — Collaborative whiteboarding made easy",
            "description": "Excalidraw is a virtual collaborative whiteboard tool that lets you easily sketch diagrams that have a hand-drawn feel to them.",
            "previewImage": {
              "ref": {
                "$link": "bafkreibw4nera7dt3ouvk5k5hl36qneumwbjeg7t3wu5nk7s575n35ukaq"
              },
              "size": 6915,
              "$type": "blob",
              "mimeType": "image/png"
            }
          }
        },
        {
          "$type": "pub.leaflet.pages.linearDocument#block",
          "block": {
            "$type": "pub.leaflet.blocks.header",
            "level": 2,
            "facets": [],
            "plaintext": "Code"
          }
        },
        {
          "$type": "pub.leaflet.pages.linearDocument#block",
          "block": {
            "$type": "pub.leaflet.blocks.text",
            "facets": [
              {
                "index": {
                  "byteEnd": 36,
                  "byteStart": 33
                },
                "features": [
                  {
                    "uri": "https://zed.dev",
                    "$type": "pub.leaflet.richtext.facet#link"
                  }
                ]
              }
            ],
            "plaintext": "Cursor. Been playing around with Zed too. I'm not a developer by trade. I did pursue a CS minor while in school, bailing after a few useful classes when I realized I take 5 prerequisites for 2 minor courses. Not worth. With the help of robots I can get my ideas to a works-like-ish prototype."
          }
        },
        {
          "$type": "pub.leaflet.pages.linearDocument#block",
          "block": {
            "src": "https://cursor.com/home?from=agents",
            "$type": "pub.leaflet.blocks.website",
            "title": "Cursor: The best way to code with AI",
            "description": "Built to make you extraordinarily productive, Cursor is the best way to code with AI.",
            "previewImage": {
              "ref": {
                "$link": "bafkreidxdzibqvlkhy4tosmahoo2urjaoxvshdqguf3ggf3na2ep7rtgiu"
              },
              "size": 41067,
              "$type": "blob",
              "mimeType": "image/png"
            }
          }
        },
        {
          "$type": "pub.leaflet.pages.linearDocument#block",
          "block": {
            "$type": "pub.leaflet.blocks.text",
            "facets": [],
            "plaintext": "For Git I am between GitHub and Tangled. GitHub is the incumbent monopoly, not ideal. Tangled is built on the AT Protocol, awesome!"
          }
        },
        {
          "$type": "pub.leaflet.pages.linearDocument#block",
          "block": {
            "src": "https://tangled.org",
            "$type": "pub.leaflet.blocks.website",
            "title": "timeline · tangled",
            "description": "tightly-knit social coding",
            "previewImage": {
              "ref": {
                "$link": "bafkreibrrw2cq4fj6oza3xuft26wjurwoadmaopsvck7o23tf6h6ej2dvy"
              },
              "size": 27304,
              "$type": "blob",
              "mimeType": "image/png"
            }
          }
        },
        {
          "$type": "pub.leaflet.pages.linearDocument#block",
          "block": {
            "$type": "pub.leaflet.blocks.header",
            "level": 2,
            "facets": [],
            "plaintext": "Utilities"
          }
        },
        {
          "$type": "pub.leaflet.pages.linearDocument#block",
          "block": {
            "src": "https://raycast.com",
            "$type": "pub.leaflet.blocks.website",
            "title": "Raycast - Your shortcut to everything",
            "description": "A collection of powerful productivity tools all within an extendable launcher.",
            "previewImage": {
              "ref": {
                "$link": "bafkreihc67ee2fpjls26rqa6sjmtxf42o7yaakixaq55ea4lqhmvp5wcs4"
              },
              "size": 12305,
              "$type": "blob",
              "mimeType": "image/png"
            }
          }
        },
        {
          "$type": "pub.leaflet.pages.linearDocument#block",
          "block": {
            "src": "https://github.com/jordanbaird/Ice",
            "$type": "pub.leaflet.blocks.website",
            "title": "GitHub - jordanbaird/Ice: Powerful menu bar manager for macOS",
            "description": "Powerful menu bar manager for macOS. Contribute to jordanbaird/Ice development by creating an account on GitHub.",
            "previewImage": {
              "ref": {
                "$link": "bafkreihb7vz27dlij6saymuwj7gll3el4ygpm624yikiffomlst274iyhq"
              },
              "size": 31350,
              "$type": "blob",
              "mimeType": "image/png"
            }
          }
        },
        {
          "$type": "pub.leaflet.pages.linearDocument#block",
          "block": {
            "src": "https://mac-stats.com/",
            "$type": "pub.leaflet.blocks.website",
            "title": "Stats - Monitor your Mac with ease",
            "description": "Stats - macOS system monitor in your menu bar",
            "previewImage": {
              "ref": {
                "$link": "bafkreidzxnptpl3lg62cchs6wivs3xm3eybsc33ivtrxfyidmu7pc2y6fu"
              },
              "size": 30324,
              "$type": "blob",
              "mimeType": "image/png"
            }
          }
        },
        {
          "$type": "pub.leaflet.pages.linearDocument#block",
          "block": {
            "src": "https://linearmouse.app/",
            "$type": "pub.leaflet.blocks.website",
            "title": "LinearMouse | The mouse and trackpad utility for Mac.",
            "description": "Customize mouse and trackpad's scrolling direction, pointer acceleration, pointer speed and so on...",
            "previewImage": {
              "ref": {
                "$link": "bafkreidmzaez5byg3sl42rlynzrxu35qg72sxfltnn5ugdyrthjurv3bjm"
              },
              "size": 16961,
              "$type": "blob",
              "mimeType": "image/png"
            }
          }
        },
        {
          "$type": "pub.leaflet.pages.linearDocument#block",
          "block": {
            "$type": "pub.leaflet.blocks.header",
            "level": 1,
            "facets": [],
            "plaintext": "Self Hosting"
          }
        },
        {
          "$type": "pub.leaflet.pages.linearDocument#block",
          "block": {
            "$type": "pub.leaflet.blocks.text",
            "facets": [
              {
                "index": {
                  "byteEnd": 112,
                  "byteStart": 98
                },
                "features": [
                  {
                    "uri": "https://riskofrain.2k.com/",
                    "$type": "pub.leaflet.richtext.facet#link"
                  }
                ]
              }
            ],
            "plaintext": "I converted my PC to a home server a few months ago. I only ever used it for infrequently playing Risk of Rain 2. Now I host a bunch of services on it as I trudge towards digital independence."
          }
        },
        {
          "$type": "pub.leaflet.pages.linearDocument#block",
          "block": {
            "src": "https://www.zimaspace.com/zimaos",
            "$type": "pub.leaflet.blocks.website",
            "title": "ZimaOS: A Simplified, Focused and Open NAS OS Supports all X86-64 hardware.",
            "description": "Meet ZimaOS, the NAS operating system that makes data management easy. Effortlessly back up files, stream media, and run apps like a pro. Unlock powerful features without the complicated setup. Download now to build your perfect private cloud.",
            "previewImage": {
              "ref": {
                "$link": "bafkreig3zbfilzj3puk5ld7tge2mfte72y2o2atdud46c36gakdjpoz4hu"
              },
              "size": 27648,
              "$type": "blob",
              "mimeType": "image/png"
            }
          }
        },
        {
          "$type": "pub.leaflet.pages.linearDocument#block",
          "block": {
            "src": "https://www.home-assistant.io/",
            "$type": "pub.leaflet.blocks.website",
            "title": "Home Assistant",
            "description": "Open source home automation that puts local control and privacy first. Powered by a worldwide community of tinkerers and DIY enthusiasts. Perfect to run on a Raspberry Pi or a local server.",
            "previewImage": {
              "ref": {
                "$link": "bafkreifas4o4d3gm4hhd4tryy5llzdfpg33usn5lw37j762ae5hrczk6i4"
              },
              "size": 24753,
              "$type": "blob",
              "mimeType": "image/png"
            }
          }
        },
        {
          "$type": "pub.leaflet.pages.linearDocument#block",
          "block": {
            "src": "https://immich.app/",
            "$type": "pub.leaflet.blocks.website",
            "title": "Immich",
            "description": "Self-hosted photo and video management solution. Easily back up, organize, and manage your photos on your own server. Immich helps you browse, search and organize your photos and videos with ease, without sacrificing your privacy.",
            "previewImage": {
              "ref": {
                "$link": "bafkreiaviit5nnc76iixrzakhlonyt4soed4i5w44kqsmt2drkw6mhzxei"
              },
              "size": 14971,
              "$type": "blob",
              "mimeType": "image/png"
            }
          }
        },
        {
          "$type": "pub.leaflet.pages.linearDocument#block",
          "block": {
            "src": "https://www.navidrome.org/",
            "$type": "pub.leaflet.blocks.website",
            "title": "Navidrome",
            "description": "Welcome to Navidrome! Learn More Download Your Personal Streaming Service Navidrome allows you to enjoy your music collection from anywhere, by making it available through a modern Web UI and through a wide range of third-party compatible mobile apps, for both iOS and Android devices.",
            "previewImage": {
              "ref": {
                "$link": "bafkreibcuktvm2z3lb7dtuaa5baexvxk4phgsfim4j5ufsl7k3eviszx4y"
              },
              "size": 73687,
              "$type": "blob",
              "mimeType": "image/png"
            }
          }
        },
        {
          "$type": "pub.leaflet.pages.linearDocument#block",
          "block": {
            "src": "https://jellyfin.org/",
            "$type": "pub.leaflet.blocks.website",
            "title": "The Free Software Media System | Jellyfin",
            "description": "The volunteer-built media solution that puts you in control of your media. Stream to any device from your own server, with no strings attached.",
            "previewImage": {
              "ref": {
                "$link": "bafkreiaqsixczfek3vfr6r7xz6tql7canmrgxewr5gst7xmt7rgay54hzi"
              },
              "size": 34861,
              "$type": "blob",
              "mimeType": "image/png"
            }
          }
        },
        {
          "$type": "pub.leaflet.pages.linearDocument#block",
          "block": {
            "src": "https://nextcloud.com/",
            "$type": "pub.leaflet.blocks.website",
            "title": "Nextcloud - Open source content collaboration platform",
            "description": "The most popular open source content collaboration platform for tens of millions of users at thousands of organizations across the globe",
            "previewImage": {
              "ref": {
                "$link": "bafkreib4xh5ynsdjguhgaxtkgkdfnqrk44rxefkg25rwswgbrdbgglzeh4"
              },
              "size": 38016,
              "$type": "blob",
              "mimeType": "image/png"
            }
          }
        },
        {
          "$type": "pub.leaflet.pages.linearDocument#block",
          "block": {
            "src": "https://pi-hole.net/",
            "$type": "pub.leaflet.blocks.website",
            "title": "Home",
            "description": "You can run Pi-hole in a container, or deploy it directly to a supported operating system via our automated installer.",
            "previewImage": {
              "ref": {
                "$link": "bafkreiawdfydmbywqrnjqmasv53kv6gvyajplpmwwy34xa6wm37kdhiepq"
              },
              "size": 41249,
              "$type": "blob",
              "mimeType": "image/png"
            }
          }
        },
        {
          "$type": "pub.leaflet.pages.linearDocument#block",
          "block": {
            "$type": "pub.leaflet.blocks.horizontalRule"
          }
        },
        {
          "$type": "pub.leaflet.pages.linearDocument#block",
          "block": {
            "$type": "pub.leaflet.blocks.text",
            "facets": [],
            "plaintext": "I'll add or update if I realize I missed something later. Wouldn't it be cool if this were all organized in a native AT Protocol lexicon where you could share your stack and compare with others? I think so too. See that idea and many others in my blog post."
          }
        },
        {
          "$type": "pub.leaflet.pages.linearDocument#block",
          "block": {
            "src": "https://blog.tynanpurdy.com/3lwgzk2ovnk2c",
            "$type": "pub.leaflet.blocks.website",
            "title": "A running list of ATproto ideas  - Tynan's Leaflets",
            "description": "Updated when the brain has more",
            "previewImage": {
              "ref": {
                "$link": "bafkreiheys4l6rp3pgdkilvc5s62upj7oyoecywuj53oqiw7wwuchvb3zq"
              },
              "size": 21707,
              "$type": "blob",
              "mimeType": "image/png"
            }
          }
        }
      ]
    }
  ],
  "title": "Tynan Uses",
  "author": "did:plc:6ayddqghxhciedbaofoxkcbs",
  "postRef": {
    "cid": "bafyreif5va7ub42ntucaibics7qk4wsbfen4dal5zrn2eax263aq52kdfe",
    "uri": "at://did:plc:6ayddqghxhciedbaofoxkcbs/app.bsky.feed.post/3lzwazc6bpk2e",
    "commit": {
      "cid": "bafyreidqe3xkzfq5e2thtqux6wemhzcpo6dgt3sytw7r4rhp2u2t7ad2k4",
      "rev": "3lzwazccel22i"
    },
    "validationStatus": "valid"
  },
  "description": "a collection of tools, alternatives where feasible",
  "publication": "at://did:plc:6ayddqghxhciedbaofoxkcbs/pub.leaflet.publication/3lptvotm3ms2o",
  "publishedAt": "2025-09-28T19:43:59.874Z"
}

did:plc:6ayddqghxhciedbaofoxkcbs | at://did:plc:6ayddqghxhciedbaofoxkcbs/pub.leaflet.document/3lzways66yk25

Lexicon Garden

@